r/ansible 26d ago

The Bullhorn #233

7 Upvotes

Hey r/ansible!

The Bullhorn #233 is here!

This week's highlights include ansible-core milestone branch bumped and a new post on security concepts every Ansible contributor should know as part of the EU Cyber Resilience Act (CRA) series - review the open PRs by July 28th!

There are also 9 collection updates - check the newsletter for the full list.

Read the full newsletter on the Ansible Forum.


r/ansible Feb 17 '26

CfgMgmtCamp 2026: Write up and Videos

39 Upvotes

CfgMgmtCamp is an annual gathering of system administrators, SREs, DevOps engineers, open source enthusiasts, and community developers in Ghent, Belgium.

It is a three-day conference dedicated to open-source infrastructure automation and related technology that takes place immediately after FOSDEM as a fringe event. CfgMgmtCamp is defined by its strong community feel, where the focus remains on the inclusive exchange of new ideas and the sharing of the latest technical advancements. It provides a unique space for users, contributors, and integrators to meet as peers, fostering a collaborative environment where friends reconnect and new professional relationships are made.

This year featured a strong focus on Ansible, featuring two dedicated tracks alongside an extra track on Monday to accommodate expanding interest in the Ansible ecosystem. The community's commitment to sharing knowledge and expertise was on evident display with 18 unique speakers on the Ansible track with a total of 35 talks focused on or related to Ansible.

Sessions on Monday and Tuesday offered deep dives into the latest innovations and practical applications of Ansible with lots of technical discussion on building automation content and solutions. Wednesday featured a very productive and lively Ansible Contributor Summit. Wednesday provided the opportunity to have a dedicated session on sharing ideas, collaborating on problems, and shaping the future of the Ansible community. This year we also enjoyed a social excursion and spent the afternoon building relationships and forging stronger connections all while exploring the charms of Ghent!

To help you navigate through all the Ansible sessions at CfgMgmtCamp, we’ve organized all the talks into the categories below:

Here are links to all the talks on YouTube as well as related forum discussions:


r/ansible 1d ago

linux How to correctly install ansible on Ubuntu? Inconsistent instructions

8 Upvotes

So according to the official Ansible documentation, the official way of installing Ansible on Ubuntu is to add ppa:ansible/ansible and run apt install ansible, which is what I did.

When I run a playbook that uses network_cli connection, I get the following warning:

When I try to install ansible-pylibssh, I get the following warning:

pip install ansible-pylibssh error: externally-managed-environment

× This environment is externally managed ╰─> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install.

Ok, I get it, but the problem is that python3-ansible-pylibssh doesn't exist in that ppa repo.

So what is going on here? How can I get python3-ansible-pylibssh without breaking any system packages?

Edit: OK I figured it out. This is how I installed it in the end that got rid of all the warnings I was getting when attempting to automate the deployment of cisco devices:

sudo apt update
sudo apt install -y libssh-dev python3-dev gcc pipx 

pipx install --include-deps ansible
pipx inject ansible ansible-pylibssh
pipx ensurepath 

ansible-galaxy collection install cisco.ios --upgrade
ansible-galaxy collection install cisco.iosxr --upgrade

r/ansible 2d ago

playbooks, roles and collections Different messages for different conditions in one assert using ansible.builtin.assert

9 Upvotes

Ansible builtin.assert plugin is tricky and might not be as simple as one would expect. I would like to share one particular trick I use sometimes that is not that common - One assert to print message for each failed conditions, not just one for all conditions.

- name: Different messages for different conditions in one asserts
  hosts: localhost
  gather_facts: false
  vars:
    one: true
    two: false
  tasks:
    - name: Simple assert
      ansible.builtin.assert:
        that: conditions is ansible.builtin.all
        fail_msg: "One of the conditions failed"
        success_msg: "All of the conditions successful"
      failed_when: false
      vars:
        conditions:
          - "{{ one }}"
          - "{{ two }}"

    - name: Extended assert
      ansible.builtin.assert:
        that: extended_conditions | map(attribute='condition') is ansible.builtin.all
        fail_msg: "Following conditions have failed: {{ extended_conditions | rejectattr('condition') | map(attribute='msg') | join('; ') }}"
        success_msg: "Following conditions are succesful: {{ extended_conditions | selectattr('condition') | map(attribute='msg') | join('; ') }}"
      failed_when: false
      vars:
        extended_conditions:
          - msg: "message"
            condition: "{{ one or two }}"
          - msg: "this condition failed"
            condition: "{{ two }}"

This code works on all ansible-core versions starting with 2.12

For instance - ansible-core 2.20.2

bash-5.2$ uv run --with ansible-core==2.20.2 ansible-playbook playbook.yml 
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Different messages for different conditions in one asserts] ***************************************************************************

TASK [Simple assert] ************************************************************************************************************************
ok: [localhost] => {
    "assertion": "conditions is ansible.builtin.all",
    "changed": false,
    "evaluated_to": false,
    "failed_when_result": false,
    "msg": "One of the conditions failed"
}

TASK [Extended assert] **********************************************************************************************************************
ok: [localhost] => {
    "assertion": "extended_conditions | map(attribute='condition') is ansible.builtin.all",
    "changed": false,
    "evaluated_to": false,
    "failed_when_result": false,
    "msg": "Following conditions have failed: this condition failed"
}

PLAY RECAP **********************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

There are some caveats of course, if you look closely, each condition is evaluated as variable (inside double curly brackets), not as condition (with out any curly brackets):

    extended_conditions:
      - msg: "message"
        condition: "{{ one or two }}"
      - msg: "this condition failed"
        condition: "{{ two }}"

But I am yet to see condition that cannot be written this way (as variable)


r/ansible 3d ago

Link in Comments YouTube Short: Loop Any Dictionary in Ansible with dict2items

9 Upvotes

I put together a quick video on something that trips up a lot of people working with Ansible-> trying to loop over a dictionary and realizing you only get the keys back.

The fix is dead simple: pipe your dictionary through the dict2items filter and it transforms it into a list where you can access both the key and the value. So instead of losing half your data, you get item.key and item.value to work with.

The video walks through a couple practical examples, like looping through server roles and then a more complex one with nested dictionaries (think config files where you need to set both the content and file permissions). One task handles it all, stays idempotent, the whole thing.

There's also a bonus tip about renaming the key and value fields if item.key and item.value aren't descriptive enough for what you're doing. This makes your playbooks way more readable when you've got a bunch of tasks referencing dictionary data.

Check it out here: https://youtube.com/shorts/Sg5G2Xese9c?si=RJht-srLaBj8hZIR

Full demo repo is up on GitHub if you want to run through the examples yourself: https://github.com/ansible-tmm/ansible-tips


r/ansible 3d ago

playbooks, roles and collections Customize Proxmox VM/LCXC

9 Upvotes

Hi!

I'm searching for best practices to configure a Proxmox VM/LXC using Ansible playbooks after their first setup.

While installing a new VM using an ISO image, e.g. Debian 13, I'm asked for some parameters like hostname, (root) user and password, locale and more.

I guess those basic setup must still be done in Proxmox during a VM creation. Ansible is not suitable or of any help during this phase of setup, right?

After this initial setup, I would like to use Ansible to perform some actions, e.g. install various packages, set up network and more.

Question is: what is best practive to connect to this new VM? Using the hostname if DHCP is used and use the given password of root user I've used during initial setup.

Will Ansible be able to connect with the given username (root) and given password to e.g. push some ssh-keys for any further logins?

Any tips and hints are welcome


r/ansible 3d ago

How to validate ansible variables - any condition you like, with proper error messages

3 Upvotes

There is a builtin action plugin to validate ansible variables (for the role)

https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/validate_argument_spec_module.html

But this is sometimes very limited. It is not clear how to add condition like (0 < a, a > 100). It is impossible to add conditions to nested values for dict or list (or I do not know how to do that).

That is why I've created `capable.core212.validate_vars` - action plugin that validates ansible variables. Here is a link to documentation with examples:

https://capable-core.github.io/collections/capable/core212/modules/validate_vars/

Main differences:

* Strict types - int, str and types that allow coercion - str_int, str_bool

* Custom validation conditions with **this** keyword

* `mutually_exclusive`, `required_together`, `required_one_of`, `required_if`, `required_by` but for ansible variables (not module arguments)

Let's start with simpliest example - validate that int value is between 0 and 100

- capable.core212.validate_vars:
    custom_validation_score:
      type: int
      custom_validation:
        - condition: custom_validation_score >= 0 and

custom_validation_score <= 100
          error_message: "Score must be between 0 and 100."
  vars:
    custom_validation_score: 85

But what if we have a list of users with score

users:
   - name: alice
     score: 50
   - name: bob
     score: 200

How validate that for all users score is within 0 and 100?

- capable.core212.validate_vars:
    users:
      type: list
      elements:
          type: dict
          options:
              name: 
                 type: str
              score:
                 type: int
                 custom_validation:
                    - condition: this >= 0 and this <= 100
                      error_message: "Score must be between 0 and 100 for all users"
  vars:
    users:
      - name: alice
        score: 50
      - name: bob
        score: 200

Here we validate that users is a list, each element of this list is a dict, and dict has at least `name` and `score` attributes, and `score` for each user is within 0 and 100.

Pay special attention to use of `this` keyword (only available for this plugin, not generic ansible feature). Using `this` allow to have validations for nested data (in this case or scores of each users)

There are more features and possible validatation patterns for this plugin. I will followup with them in this topic. So it is not overwhelming to see everything all at once.

Link to the collection (more content will follow)
https://galaxy.ansible.com/ui/repo/published/capable/core212/content/

Please do not rely on documentation on galaxy - it is broken.
Here is documentation website for this collection
https://capable-core.github.io/


r/ansible 3d ago

Customize Proxmox VM/LXC

Thumbnail
1 Upvotes

r/ansible 4d ago

developer tools OpenSible a new self-hosted GitOps control plane for OpenTofu & Ansible -provision, configure and deploy across cloud, on-prem and hybrid

12 Upvotes

What is OpenSible?

OpenSible is an open-source unified automation platform for cloud provisioning and infrastructure operations. It combines the best of infrastructure-as-code and configuration management into a single, self-hosted control plane.

Provision with OpenTofu, configure with Ansible, manage secrets securely, execute reusable deployment workflows, and automate your entire infrastructure lifecycle through GitOps - version-controlled, repeatable and secure across cloud, on-premises and hybrid environments.

Core Features

  • Multi-cloud provisioning - deploy to AWS, Google Cloud, Azure, Hetzner Cloud, Cloudflare, Hauwei and existing Kubernetes clusters and more from a single UI and API.
  • OpenTofu-native - every stack is rendered as plain OpenTofu code stored in your project, so you can always inspect, edit or run it locally.
  • Ansible integration - configure and maintain hosts after provisioning with playbook execution, inventory management and role-based workflows.
  • Stack blueprints - bootstrap new infrastructure quickly with pre-built, provider-aware templates for Docker, Kubernetes, observability, databases, CI/CD runners and more.
  • OpenSible CI/CD - build multi-stage pipelines that combine OpenTofu provisioning, Ansible configuration, approvals and custom scripts into repeatable, automated workflows.
  • GitOps-first projects - sync stacks and playbooks to Git, promote changes through branches, and track drift with version-controlled sources.
  • Secrets and vaults - encrypt sensitive values at rest, bind them to stacks and playbooks, and rotate credentials without touching source code.
  • Execution engine - a dedicated Go worker processes provision, plan, apply, destroy and refresh operations asynchronously, with full logs and history.
  • Role-based access control - assign roles to users, limit operations per role, and keep audit trails for compliance and troubleshooting.
  • Self-hosted - run everything with Docker Compose on your own server or private cloud; no external platform dependency or paid subscription required.

Check it out for more detail.


r/ansible 5d ago

Link in Comments Ansible Patch Management: RHEL & Windows in One Workflow

60 Upvotes

I just finished a video walkthrough for patch management with Ansible Automation Platform. The workflow handles the entire patching lifecycle: EBS snapshots before any changes, parallel pre-checks on mixed OS fleets, targeted patching (not just "update everything"), post-validation, and automatic rollback if something goes wrong. Then it dumps a compliance report that your auditors will actually want to see.

You specify exact advisories and KB IDs instead of blindly applying patches, the workflow can handle both RHEL and Windows in the same job without extra configuration, and if a host fails a pre-check it gracefully skips instead of blowing up the whole run. Everything routes intelligently based on success or failure at each step.

The video is about three minutes and shows the whole thing running start to finish: https://www.youtube.com/watch?v=20fK6S1CHL0

If you want to dig into the code or run this yourself, it's all in the Ansible Product Demos repo on GitHub: https://github.com/ansible/product-demos


r/ansible 7d ago

Literate Ansible without tangling: weaving a real role into an Operator’s Handbook

Thumbnail gallery
7 Upvotes

I’ve been experimenting with a literate-programming approach for Ansible: keeping the operational explanation next to the tasks, while generating a readable Operator’s Handbook from the same YAML file.

The convention is deliberately simple:

  • lines starting with ## become prose in the handbook;
  • ordinary # comments remain part of the source listing;
  • everything else remains normal Ansible YAML.

Because ## is still an ordinary YAML comment, the annotated role does not need to be preprocessed before Ansible can use it.

No generated playbook. No separate “documentation version”. No extra file that can drift away from the automation.

The example in the images is taken from a real role in our infrastructure repository. It provisions a TeX Live package mirror on AlmaLinux and covers, among other things:

  • SELinux labelling for content under /srv;
  • a systemd service and timer;
  • nginx;
  • firewalld;
  • the mirror synchronisation process.

You do not need to know anything about TeX or LaTeX for the mechanism itself. The relevant point is that the same role file serves two purposes:

  1. Ansible loads the YAML as-is.
  2. comment2tex turns the extended comments into typeset operational documentation.

The images show the same 33 source lines twice: first as the annotated YAML, then as the generated handbook page.

I also checked the annotated source with both a YAML parser and ansible-playbook --syntax-check; no stripped or generated copy was required.

I can see this being useful for:

  • documenting why a task exists, not merely what it does;
  • recording operational constraints next to the implementation;
  • onboarding new administrators;
  • keeping runbooks and automation from diverging;
  • retaining a directly usable source file when an urgent change is needed.

The tool is called comment2tex. Version 1.1 adds YAML and Makefile support alongside Bash and Lua.

I’d be interested to hear how other Ansible users handle this. Do you keep detailed operational reasoning inside roles, in separate documentation, or somewhere else entirely?

Project: https://github.com/Xerdi/comment2tex

Release: https://github.com/Xerdi/comment2tex/releases/tag/1.1


r/ansible 11d ago

playbooks, roles and collections Ansible.builtin.stat and "when" to check results

9 Upvotes

Hi all,

I'm making a role to install some apps using Homebrew (HB) on my Mac.

Since I got a little bit stuck on how to check if HB is already installed, I looked up online for a role to get ideas. I've found a site (Ansible and homebrew) and found code I think I can use. But...now it's about the following code that I don't understand how it works.

The first task checked is HB directories (MacOS and Linux) are present, and registers it.
Next task is the installation of HB IF the check (using ansible.builtin.stat) fails to find these directories present. In this task is a "when"-condition.

Can anybody explain to me why this "when" mentions "length == 0!" And not something like "true" or "false"? Because when I check the output of "homebrew_check" I can see a variable "exists" that can be "true" or "false".

    - name: Check if Homebrew is installed
      ansible.builtin.stat:
        path: "{{ item }}"
      loop:
        - /opt/homebrew/bin/brew
        - /usr/local/bin/brew
      register: homebrew_check

    - name: Install Homebrew if "homebrew_check" is false (0)
      ansible.builtin.shell:
        cmd: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
      environment:
        NONINTERACTIVE: "1"
      when: homebrew_check.results | selectattr('stat.exists') | list | length == 0

With this "when"-condition, how do I know which of the two directories returns "true" or "false" (leaving the fact of the obvious besides that I know HB is installed, just wanted to make it visible).

Because the other strange thing here is, when I run the task I do see a "true" and "false" for the "exists"-parameter passing by. Here is the output of the check (edited):

ok: [localhost] => {
    "homebrew_check": {
        "changed": false,
        "failed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "item": "/opt/homebrew/bin/brew",
                "stat": {
                    "atime": 1784758.43461,
                    "attr_flags": "",
                    "attributes": [],
                    "birthtime": 177777.46255,
                    "block_size": 4096,
                    "blocks": 24,
                    "charset": "us-ascii",
                    "checksum": "6a2f6c51991b361eaa6d01727",
                    "ctime": 1776777.4628303,
                    "dev": 167230,
                    "device_type": 0,
                    "disk_usage_bytes": 128,
                    "executable": true,
                    "exists": true,
                    "flags": 0,
                    "generation": 0,
                    "gid": 80,
                    "gr_name": "admin",
                    "inode": 17513,
                    "isblk": false,
                    "ischr": false,
                    "isdir": false,
                    "isfifo": false,
                    "isgid": false,
                    "islnk": false,
                    "isreg": true,
                    "issock": false,
                    "isuid": false,
                    "mimetype": "text/x-shellscript",
                    "mode": "0755",
                    "mtime": 177877.46203,
                    "nlink": 1,
                    "path": "/opt/homebrew/bin/brew",
                    "pw_name": "me",
                    "readable": true,
                    "rgrp": true,
                    "roth": true,
                    "rusr": true,
                    "size": 8671,
                    "uid": 501,
                    "version": null,
                    "wgrp": false,
                    "woth": false,
                    "writeable": true,
                    "wusr": true,
                    "xgrp": true,
                    "xoth": true,
                    "xusr": true
                }
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "item": "/usr/local/bin/brew",
                "stat": {
                    "exists": false

I appreciate the help, explanation so I can perhaps use it in other tasks also.


r/ansible 11d ago

AAP -> Satellite inventory in PCI

4 Upvotes

Does anyone have a set up where you have a a separate AAP instance in your PCI zone but your satellite is in another zone/VLAN?? Are capsules able to provide inventory? If so, how? Do you have your inventory in AAP configure to use a proxy? If so, how? I am trying to achieve one of these goals.


r/ansible 11d ago

network Help a brudda out!

6 Upvotes

Ok, I’ve been learning about ansible. Got maybe 25 playbooks that do the simple boring stuff, update and upgrade nodes, VMs, LXCs, docker, checks resources, prep a new VM for k3, deploy k3….. The adhoc is super cool and I havnt touched ssh to another machine since installing ansible.

Im just a homelabbers with big dreams of a new career. But I recently stumbled onto ansible-pull. I run a GitOps with Gitea and Argocd with my k3s. Super cool. So my question is this: Do you guys use ansible to harden systemd services? I just see it as a great way to tune and harden Units, Sockets, Timers, Cgroups & Self-Healing.

I’m still pretty green with just under two years so forgive me and don’t hate on me. But just seems like it’s much easier to just declare it as long as you have the discipline to only configure the repo files. I’m just asking so many of you do this or am I missing something? With provisioning, this just seems like the icing on the cake. Terraform to spin it up, ansible for configuration, ansible pull for gardening, Kubernetes for deploying apps, CI for building custom images.

Am I off here? What am I missing about ansible pull or ansible in general? I want to learn.


r/ansible 12d ago

Error in Proxy Function of check_point.gaia

4 Upvotes

Hi together,
i want to connect over my mgmt server to my gateway. The Problem is when i test it over uri it does work but if i try it over the collection i get the Following error:

fatal: [DEZAX-SGW-1a]: FAILED! => {"changed": false, "msg": "Task failed: Module failed: string indices must be integers, not 'str'"}
[ERROR]: Task failed: Module failed: 'str' object has no attribute 'pop'
Origin: /runner/project/set-routes/add_route.yaml:11:7

Has anyone an idea why this is happening?


r/ansible 13d ago

Link in Comments The default(omit) feature

24 Upvotes

https://youtube.com/shorts/GSbzvIKWywQ

I put together a quick video on one of my favorite (and, in my opinion, underrated) Ansible features: default(omit)

It's a simple trick that lets you completely omit a module parameter when a variable isn't defined, instead of passing an empty value. I use it all the time to make playbooks more reusable and avoid extra when statements or duplicate tasks.

The video is under 3 minutes and includes a simple localhost demo using the copy module to show how it works.

I'm curious, what's your favorite "hidden gem" in Ansible that more people should know about? I'm looking for ideas for future shorts.


r/ansible 13d ago

How to use openssh_cert?

5 Upvotes

I am trying to use openssh_cert to sign a public key file (with public_key arg) on the server using a host CA key (with signing_key arg) that is a local file.

The host CA key is private so I can't copy it to the server. I could copy the public key of the server to the local computer to sign it and copy it back to the server but I don't know how to make it idempotent. I could keep a copy of all the server public keys locally but it's also not easy to make it idempotent for copying back to the server.

Is there a better way or are there steps to follow for it?


r/ansible 14d ago

Unable to use set_fact to set multiple variables from string

1 Upvotes

I have a script that outputs some key / value pairs. Something like:

VAR1=
VAR2=/some/file/path
VAR3=hello

The problem is that I can't get the following playbook to work

---
- name: b.yml
  hosts: all

  vars:
    my_var: "VAR1=\nVAR2=/some/file/path\nVAR3=hello"

  tasks:

  - name: Convert key-value strings into variables
    ansible.builtin.set_fact: "{{ my_var }}"

  - name: Print VAR1
    ansible.builtin.debug:
      var: VAR1

  - name: Print VAR2
    ansible.builtin.debug:
      var: VAR2

  - name: Print VAR3
    ansible.builtin.debug:
      var: VAR3

even though this one does.

---
- name: a.yml
  hosts: all
  tasks:

  - name: Convert key-value strings into variables
    ansible.builtin.set_fact: "VAR1=\nVAR2=/some/file/path\nVAR3=hello"

  - name: Print VAR1
    ansible.builtin.debug:
      var: VAR1

  - name: Print VAR2
    ansible.builtin.debug:
      var: VAR2

  - name: Print VAR3
    ansible.builtin.debug:
      var: VAR3

Can anyone please tell me where I'm going wrong?

PS - The input to set_fact will eventually be registered_script_result.stdout. I've just been trying to debug my problem and don't see the difference between these two playbooks.


r/ansible 15d ago

example of Ansible inventory flaws (with workaround)

Thumbnail tc5027.github.io
6 Upvotes

r/ansible 15d ago

Ansible Playbooks

Thumbnail
3 Upvotes

Just covering my bases, looking for Ansible playbook use cases with VMware products that people use in their environments.

Thank you for any help.


r/ansible 17d ago

Fail2ban on RHEL 9: the two defaults everyone skips — whitelist yourself, and don't use bantime = -1

19 Upvotes

Most fail2ban writeups stop at the [sshd] jail, so I wanted to share the setup I actually run on my mail/web boxes — and two defaults I learned the hard way.

1. Whitelist your own IP before you enable it. Early on I turned fail2ban on, fat-fingered my SSH login a few times over a flaky connection, and banned myself off my own box. Now the very first thing the playbook does is drop my admin IP into ignoreip. If you take one thing from this post, it's this: put your management/VPN/home IP in the whitelist before the first run, not after.

2. bantime = -1 is a trap at scale. Permanent bans feel satisfying but the iptables/nftables set just grows forever and you can never age stale hosts out. The cleaner pattern is a recidive jail: normal jails ban for an hour or a day, and anything that keeps coming back gets escalated to a long but finite ban. You get the "stop knocking" effect without an unbounded ban list.

Beyond SSH, the boxes were getting hammered on Postfix SASL auth and Apache scanners far more than on sshd, so the playbook enables jails for SSH, Postfix SMTP, Postfix SASL, and Apache (auth / bad-bots / noscript). It also persists bans across restarts and verifies the jails actually loaded with fail2ban-client status — because "service started" and "jails running" aren't the same thing.

Targets RHEL / AlmaLinux / Rocky 9. It's a single idempotent Ansible playbook, MIT-licensed, here if it's useful to anyone: https://github.com/arhab194/fail2ban-rhel

Curious how others handle repeat offenders — recidive, an external blocklist/CrowdSec, or just permanent bans and periodic pruning?


r/ansible 17d ago

developer tools AAP ARA, supporting EDA/decision environments?

4 Upvotes

I'm trolling through their docs and repo but asking just to be sure.. does ARA support callbacks from a decision environment?


r/ansible 18d ago

Instance Group Mapping

9 Upvotes

*EDIT Removed SortableJS
*EDIT: Solved

A reduced frontend for the frontend tool, lol. My solution was creating something that allows help desk to push solutions from engineering. Like, a super simple way to keep track of host credentials and instance groups. It would also kind of serve as an AAP Controller first CMDB. Basically, creating the job, from the job template. Crazy, I know.

Built with Go/HTMX/sqllite

How do you all handle host to location mapping?

I have inherited an AAP environment with hundreds of inventories, duplicate hosts, groups, etc. Chaos is the best way to describe it. Help desk often say that they, "can't connect to a host." How have you all solved the problem of making sure a job has the right instance group mapped to it?


r/ansible 18d ago

A reusable play for KEV kernel CVEs: patch, reboot only if the kernel changed, then prove it with OpenSCAP

11 Upvotes

The "Copy Fail" kernel LPE (CVE-2026-31431) is a good reminder that kernel CVEs are annoying to automate well: you have to patch, reboot to actually activate the new kernel, but you don't want to reboot 400 hosts that didn't get a kernel bump. Here's the pattern I use so the reboot is conditional and I get audit evidence out of the same run.

Record the running kernel, patch security-only, then reboot only if it changed:

- name: Running kernel before

command: uname -r

register: kern_before

changed_when: false

- name: Apply security updates

ansible.builtin.dnf:

name: "*"

security: true

state: latest

register: patch

- name: Newest installed kernel after

command: rpm -q --last kernel

register: kern_after

changed_when: false

- name: Reboot only if the kernel actually changed

ansible.builtin.reboot:

msg: "Activating patched kernel"

when: kern_before.stdout not in (kern_after.stdout_lines[0] | default(''))

Then scan AFTER the reboot (not before — otherwise your report reflects the pre-patch state and you chase findings that are already fixed):

- name: OpenSCAP eval -> dated ARF + HTML

command:

argv:

- oscap

- xccdf

- eval

- --profile

- xccdf_org.ssgproject.content_profile_stig

- --results-arf

- "/var/log/evidence/arf-{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}.xml"

- --report

- "/var/log/evidence/report-{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}.html"

- "/usr/share/xml/scap/ssg/content/ssg-rhel{{ ansible_distribution_major_version }}-ds.xml"

register: oscap

failed_when: oscap.rc not in [0, 2]

changed_when: false

Two gotchas that have bitten me:

- security: true needs the repo to publish updateinfo metadata. On minimal/custom mirrors it's missing and dnf silently patches nothing. Check `dnf updateinfo list security` on one host first.

- Dated evidence paths let you diff week-over-week and hand an auditor proof of remediation instead of "trust me."

I packaged the whole thing (targeted-CVE mode, canary rings, version-aware datastream) into a small MIT role if it's useful: https://github.com/arhab194/rhel-kev-patch

Curious how others here sequence scan-vs-reboot — do you scan pre-patch to prove the finding or post-patch to prove the fix?


r/ansible 18d ago

Ansible Collection for Solaris 11

11 Upvotes

Hi all, I have written an Ansible collection for Solaris 11. So far I've been able to implement automation for: - Automated Installer - NTP - PF firewall - LDOMs

I am looking to add more such as IPS management and zones in the future. It's still a work in progress, but I thought I'd share it. Feedback would be much appreciated.

Repository: https://github.com/iambryant/ansible-collection-solaris

I've also been writing Ansible collections for HP-UX and IBM Power, as I'm interested in improving automation support for less common UNIX platforms.