freedzhost.cloud

Rebuild your machines in one command, and know what you changed by hand (Ansible)

Level IntermediateEstimated time half a dayA word you don't know? Glossary

After a few months, every machine holds changes made by hand that nobody remembers: a package here, a settings file there, a service edited in place. Ansible describes what a machine should be, in plain files you keep in Git, and makes it so. Its most useful command does not change anything: it tells you what is different.

Repositorythe desired state--check --difflists the drift, touches nothingLaptopapplyServer2nd run: 0 changed
The repository describes what each machine should be. --check --diff compares it with what the machine really is and lists every difference, without touching anything. Applying makes the machine match; running it twice changes nothing the second time.

A bit of history

Ansible was created in 2012 by Michael DeHaan, with an idea that set it apart: no agent to install on the machines, only SSH and a readable description of the desired state in YAML. Red Hat acquired it in 2015. Run twice, a good playbook changes nothing the second time: that property, idempotence, is what makes a machine rebuildable.

1. Install

pipx install --include-deps ansible
ansible --version

Ansible only needs SSH on the machines it manages: nothing to install on them.

2. An inventory and a first check

# inventory.ini
[workstations]
laptop ansible_host=192.0.2.20
server ansible_host=192.0.2.30
ansible -i inventory.ini all -m ping

3. A first playbook

# site.yml
- hosts: workstations
  become: true
  tasks:
    - name: The tools I always want
      ansible.builtin.package:
        name: [git, htop, rsync]
        state: present
    - name: My shell settings
      ansible.builtin.template:
        src: bashrc.j2
        dest: /home/{{ ansible_user }}/.bashrc
        mode: '0644'
ansible-playbook -i inventory.ini site.yml --ask-become-pass

Run it twice: the second run must report 0 changed. That is idempotence, and it is what makes the playbook safe to run anytime.

4. The command you will use most

ansible-playbook -i inventory.ini site.yml --check --diff

It compares the description with the machines and prints every difference, without touching anything. It answers the question nobody else can: "what did I change by hand?"

Traps for beginners

YAML indents with spaces, two per level, never tabs. Quote file modes: mode: '0644', otherwise the number can be read as octal or decimal depending on the version.

Some distributions report a parent name: CachyOS shows up as Archlinux in ansible_facts.distribution. Print the facts once (ansible laptop -m setup) before writing conditions.

Ansible configures machines that exist; creating them (VMs, networks) is the job of OpenTofu, the open-source fork of Terraform. Do not stretch one tool to do the other's job.

If you install Ansible through a version manager, check after each update of that manager that the commands still run: a configuration format change once left us with installed versions and no working command, behind a warning that was really a failure.

Sources

Found this useful? Tell us what to measure next.