Ansible may no longer be ideal for use with Atomic or Immutable Operating Systems like bootc. But for anyone with a lot of Ansible automation it will be hard to pivot to “the next thing”.
Anti-pattern: Ansible for bootc configuration changes on a running system
What I’m going to describe is an anti-pattern in the bootc world. Your running system needs configuration changes, what do you do? You should update the bootc image and apply the new image on the host. You could even run Ansible at during the build of the bootc image (kind of). But what if this isn’t possible? Before continuing, be sure to read the bootc documentation about Dynamic reconfiguration. This will cause configuration drift.
For example, if you dynamically create users how can you automate the changes? Rebuild the bootc image with every change? I already have an Ansible Role to manage users, and I’d like to have the same configuration for my bootc based servers as well as the rest.
If you must still use Ansible to push changes to a bootc (Atomic) server what do you do? I guess since you aren’t supposed to be doing it, Ansible currently doesn’t differentiate a bootc based host verses a regularly installed, non-Atomic host. If you must still use Ansible, you need it to understand it can’t install packages, among other things. This means either having completely separate Ansible playbooks (which causes a lot of re-work), or modify existing Ansible playbooks in a way that can skip anything a bootc host simply cannot do.
So then, how to detect a bootc based host?
Force Ansible to detect a bootc server
The simplest way to get Ansible to recognize it is on a bootc based server is to change the “ansible_distribution” to something unique.
To do this, when building the bootc image add this into the Containerfile / Dockerfile:
# Allow Ansible to identify it's bootc/CoreOS/Atomic/Immutable
echo "RedHat-atomic" > /etc/bootc-release
ln -fs /etc/bootc-release /etc/redhat-release
After the bootc image is deployed to a server, the files Ansible uses to determine the OS it’s on will be changed, now reflecting a bootc/Atomic host.
This changes the Ansible variable: ansible_distribution
to be “RedHat-atomic”
Now modify any Ansible Playbooks/Roles where you still need to do a task on the bootc host to include that ansible_distribution
. Or more likely, exclude the bootc host:
when:
- ansible_distribution == "RedHat"
- not ansible_distribution == "RedHat-atomic"
Conclusion
Ansible will now detect a unique ansible_distribution variable so any Ansible Role or Playbook can be modified to include (or exclude) a bootc based host when needed.