Ansible - Architecture & Core Concepts

@amitmund July 30, 2026

Chapter 1 — Architecture & Core Concepts

1. Theory

Ansible's architecture has four core pieces: the control node (where Ansible runs), the inventory (host list + grouping), modules (idempotent units of work — e.g. "ensure package X is installed"), and playbooks (ordered lists of plays/tasks declaring desired state). Idempotency is the central design principle: running the same playbook twice should produce the same end state without duplicating side effects.

2. Internal Working

A playbook run compiles into an internal task list per host, executed largely in parallel across hosts (default 5 forks) but sequentially task-by-task within a single host, unless a strategy like free is used. Each module checks current state before acting — e.g. the package module queries whether the package is already installed and reports changed: false if nothing needed to happen.

3. Diagram

Inventory ──▶ Playbook ──▶ Play (hosts: web) ──▶ Task 1 ──▶ Task 2 ──▶ Task 3
                                   │
                                   ▼
                     ┌─────────────────────────────┐
                     │ For each host (parallel,     │
                     │ default forks=5):            │
                     │   run Task 1 → check/change   │
                     │   run Task 2 → check/change   │
                     └─────────────────────────────┘

4. Commands

ansible-doc -l | grep package        # list modules matching "package"
ansible-doc apt                      # full docs for a specific module
ansible-playbook site.yml -vvv       # verbose, shows exact module invocation
ansible-playbook site.yml --check    # dry-run, no changes applied
ansible-playbook site.yml --diff     # show file content diffs

5. Code Examples

# site.yml — a minimal playbook demonstrating idempotency
- name: Ensure nginx is installed and running
  hosts: web
  become: true
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
      register: install_result

    - name: Show whether anything changed
      debug:
        msg: "Changed: {{ install_result.changed }}"

    - name: Ensure nginx service is running
      service:
        name: nginx
        state: started
        enabled: true

Running this twice: the first run shows changed: true for install, the second shows changed: false — proof of idempotency.

6. Real-world Example

A new engineer joins and needs their laptop's dev environment to match everyone else's. Instead of a wiki page of manual steps, they run the team's existing bootstrap.yml playbook against localhost — the same playbook used for servers — and get an identical, reproducible setup in minutes.

7. Production Example

Production Ansible runs are typically triggered from CI/CD (not laptops), against a locked inventory, with --check --diff run first as a required pipeline gate so a human reviews the plan before real execution — mirroring how Terraform plan/apply is treated.

8. Common Mistakes

  • Assuming all tasks run across all hosts simultaneously — within one host, tasks are strictly sequential; only the host-level parallelism is concurrent.
  • Writing tasks that aren't actually idempotent (e.g. shell: echo "x" >> file.conf appends every run) and being surprised when repeated runs change more than intended.
  • Treating changed: false output as "nothing happened" without realizing it means the module determined the desired state already existed.

9. Troubleshooting

Symptom Likely Cause Fix
Task shows changed: true every run Non-idempotent module usage (e.g. raw shell/command) Use a purpose-built module (lineinfile, copy, template) or add creates/removes guards
Playbook hangs on one host Forks limit + a slow/unreachable host blocking a batch Increase forks, or use strategy: free
Wrong module version behavior Multiple Ansible versions installed Check ansible --version and which ansible for conflicts

10. Security Notes

  • become: true gives task-level root — treat playbooks with become the same way you'd treat sudo access itself: reviewed, version-controlled, and access-restricted.
  • Idempotent modules reduce security risk indirectly: fewer surprise side-effects means fewer unreviewed state changes creeping into infrastructure over time.

11. Interview Questions

  1. What makes a module idempotent? It checks current state before acting and only changes what's needed to reach the declared state.
  2. What's the default parallelism model? Host-level parallel (default 5 forks), task-level sequential per host.
  3. What does --check do? Simulates the run without applying changes (dry-run), though not all modules support it perfectly.
  4. Why prefer package/copy/template over raw shell/command? They're idempotent and structured; shell/command are imperative and re-run every time.
  5. What is a "play" vs a "task" vs a "playbook"? Playbook = file containing one or more plays; play = hosts + tasks; task = single module invocation.

12. Hands-on Lab

  1. Write the nginx playbook above targeting a local container.
  2. Run it once, note changed: true.
  3. Run it again, confirm changed: false for the install task.
  4. Replace the apt task with shell: apt-get install -y nginx and observe it reports changed: true on every run — demonstrating non-idempotent behavior.

13. Hacks

  • ansible-playbook site.yml --list-tasks previews exactly what will run without executing anything.
  • register + debug is the fastest way to inspect a module's raw JSON return value while learning a new module.

14. Workarounds

  • For genuinely one-off imperative commands with no matching module, use command/shell with a creates: or unless:-style guard (via when on a prior stat check) to restore idempotency manually.

15. Exercises

  • Convert a shell: touch /tmp/marker task into an idempotent equivalent using file.
  • Time a playbook run with forks=5 vs forks=20 against 20 local containers and compare.

16. Quiz

  1. What are the four core architectural pieces of Ansible?
  2. Default fork count?
  3. What flag previews planned changes without applying them?
  4. True/False: tasks within a single host run in parallel by default.
  5. Name one module that's a safer idempotent alternative to shell for installing packages.

Answer Key

  1. Control node, inventory, modules, playbooks
  2. 5
  3. --check
  4. False
  5. package/apt/yum (any package manager module)
0 Likes
45 Views
0 Comments

Filters

No filters available for this view.

Reset All