Manual Index

Please use desktop sidebar for the full 19-chapter index in this preview.

Updated for Ansible v2.21+

Learn Ansible Modern Reference Guide

Welcome to the 2026 definitive guide. This manual strips away outdated legacy habits (Ansible 2.9 era) and focuses entirely on the modern ansible-core ecosystem. You will learn containerized execution, strict typing, supply chain security, GitOps, and Event-Driven automation.


Part 1: The Foundation

Chapter 1: The Modern Ansible Landscape

Ansible fundamentally changed. The old "batteries included" ansible package was split. Today, we use ansible-core (the raw engine) and Collections (the modules). Ansible remains agentless, using a push-model via SSH or WinRM, but how we package and run it has modernized.

Minimalist Getting Started:

  • Understand the Control Node (where Ansible runs) vs Managed Nodes (what Ansible configures).
  • Stop installing the monolithic `ansible` pip package.
  • Embrace Collections: They are packaged sets of playbooks, roles, modules, and plugins.

Chapter 2: Setting Up the Environment

In the past, you used Python virtual environments. Today, enterprise automation runs entirely inside containers called Execution Environments (EEs) using ansible-navigator. This eliminates the "it works on my laptop" problem.

Minimalist Getting Started:

  • Install Docker or Podman on your Control Node.
  • Install ansible-navigator via pipx: pipx install ansible-navigator
  • Configure your ansible-navigator.yml to point to a standard EE image.
Lesson Learned: ansible.cfg placement.
Always place your ansible.cfg in your project root directory, not in /etc/ansible/. This ensures your project is portable and Git-controlled.
ansible.cfg
[defaults]
inventory = ./inventory.yml
host_key_checking = False
jinja2_native = True # Crucial modern setting

Chapter 3: Inventories & Connections

Inventories tell Ansible *where* to run. YAML is the modern standard for static inventories. However, in the cloud, static files are useless. You must learn dynamic inventories.

Minimalist Getting Started:

  • Write static inventories in YAML, not INI, to support nested variables cleanly.
  • Group servers logically (e.g., webservers, databases).
  • Use connection variables like ansible_user and ansible_connection.
inventory.aws_ec2.yml (Dynamic)
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
keyed_groups:
  - key: tags.Role
    prefix: role

Chapter 4: Ad-Hoc Commands & FQCNs

Ad-hoc commands are great for quick tasks (like restarting a service across 50 nodes). Modern Ansible strictly requires Fully Qualified Collection Names (FQCNs) for modules.

Minimalist Getting Started:

  • Stop using short names (e.g., ping). Use ansible.builtin.ping.
  • Use ansible-navigator exec to run ad-hoc commands inside an Execution Environment.
Terminal
# The modern way to ping all webservers
ansible-navigator exec "ansible webservers -m ansible.builtin.ping"

Part 2: Core Automation Building Blocks

Chapter 5: Playbooks & Idempotence

A playbook is declarative. It should describe the *end state*, not a list of commands. A truly idempotent playbook can be run 100 times in a row safely; if the state is already correct, it makes 0 changes.

Minimalist Getting Started:

  • A Playbook contains Plays. A Play maps Hosts to Tasks.
  • Use become: true for privilege escalation (sudo).
  • Always aim for "OK" (no changes made) on a second run.
Gotcha: The shell trap.
Using ansible.builtin.shell or command destroys idempotence because Ansible cannot know if the shell script actually changed anything. It will report "Changed" every time. If you *must* use it, use the creates or removes arguments.
- name: Run custom setup script
  ansible.builtin.command: /opt/setup.sh
  args:
    creates: /etc/setup_done.conf # Forces Idempotence

Chapter 6: Variables, Facts & State

Ansible gathers facts (system data like OS, IP address, disks) automatically. However, variable precedence (the order in which variables override each other) is the #1 cause of bugs in complex deployments.

Minimalist Getting Started:

  • Variables defined in group_vars/ override defaults. Variables in the playbook override group_vars. Extra vars (-e) override everything.
  • Use register: my_var to capture the output of a task.
  • Turn off fact gathering (gather_facts: false) if you don't need system data to massively speed up plays.

Chapter 7: Control Flow & Loops

Ansible is not a programming language, but it offers control flow. You use when for conditionals and loop for iteration. Handlers are special tasks triggered only when a state changes.

Minimalist Getting Started:

  • Stop using deprecated with_items. Use loop.
  • Use loop_control: label to prevent spamming your logs with massive JSON objects during iteration.
- name: Create multiple users
  ansible.builtin.user:
    name: "{{ item.name }}"
    state: present
  loop:
    - { name: 'alice' }
    - { name: 'bob' }
  when: create_users_flag | bool

Chapter 8: Templates & Data Manipulation

Ansible uses Jinja2 for templating. Modern Ansible requires you to enable native types to avoid string-casting nightmares.

Minimalist Getting Started:

  • Use the ansible.builtin.template module to inject variables into config files (.j2).
  • Use Jinja2 filters like | to_json or | default('fallback').
  • Use ansible.utils.validate to check variable schemas before running plays.

Part 3: Structuring & Distributing Content

Chapter 9: Roles (Legacy vs Modern)

Roles allow you to break complex playbooks into reusable directories (tasks, handlers, vars). While standalone roles were the standard in Ansible 2.9, they are now typically packaged *inside* Collections.

Minimalist Getting Started:

  • Generate a skeleton role with ansible-galaxy role init my_role.
  • Keep roles focused on a single responsibility (e.g., installing Nginx).
  • Call them in your playbook using include_role for dynamic execution.

Chapter 10: Ansible Collections

Collections are the modern distribution format. They package roles, modules, plugins, and playbooks together. Your enterprise should build internal Collections for its business logic.

requirements.yml
collections:
  - name: amazon.aws
    version: ">=6.0.0"
  - name: community.general

Install them via: ansible-galaxy collection install -r requirements.yml

Chapter 11: Execution Environments & Builder

You must bundle your Collections and Python dependencies into immutable container images (Execution Environments) using ansible-builder v3.

Enterprise Best Practice: Container Scanning.
Because EEs are just OCI-compliant containers, you can and should scan them with tools like Trivy or Clair before pushing them to your private registry to ensure software supply chain security.

Part 4: Advanced Operations & QA

Chapter 12: Secrets Management

Ansible Vault encrypts files, but modern GitOps relies on dynamic secret fetching.

Minimalist Getting Started:

  • Use ansible-vault encrypt_string for quick inline secrets.
  • For enterprise, use lookup plugins to pull from HashiCorp Vault or AWS Secrets Manager.
  • Always use no_log: true on tasks handling secrets to prevent log leaks.
- name: Database Task
  mysql_db:
    password: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=database/creds:password') }}"
  no_log: true # CRITICAL

Chapter 13: Error Handling & Strategies

Production servers fail. You need resilient code. Use block, rescue, and always to catch errors and gracefully roll back changes.

Minimalist Getting Started:

  • Wrap risky operations in a block.
  • Use rescue to trigger a rollback task if the block fails.
  • Use serial: 1 (Rolling updates) instead of the default linear strategy to update webservers one at a time behind a load balancer.

Chapter 14: Testing & Linting

If you treat Infrastructure as Code, you must test it like code. Unlinted YAML leads to syntax failures in production.

Minimalist Getting Started:

  • Run ansible-lint on every Git commit using pre-commit hooks.
  • Use Molecule to spin up a container, run your role, and verify the outcome (integration testing).
  • Run playbooks with --check --diff for dry-runs.

Part 5: Enterprise Scaling & CI/CD

Chapter 15: AAP / AWX

Ansible Automation Platform (AAP) or the upstream open-source AWX project provides a GUI, API, and RBAC over your Ansible code. It moves execution from a developer's laptop to a centralized, auditable server cluster.

Minimalist Getting Started:

  • Sync your Git repo to AWX as a Project.
  • Map your Playbook, Inventory, and EE image together into a Job Template.
  • Use Workflows to chain multiple Job Templates together.

Chapter 16: CI/CD Pipelines

Ansible should be deployed via CI/CD. When code is merged, a pipeline should lint it, test it, and update the AWX project via API.

.github/workflows/ansible.yml
name: Ansible CI
on: [push]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run ansible-lint
        run: pipx run ansible-lint site.yml

Chapter 17: Event-Driven Ansible (EDA)

The ultimate shift from reactive manual administration to self-healing infrastructure. EDA allows Ansible to listen to monitoring tools and trigger playbooks automatically.

Minimalist Getting Started:

  • Write a rulebook.yml defining Sources, Rules, and Actions.
  • Run it using the ansible-rulebook CLI.
  • Implement rule dampening (e.g., throttle) to prevent action floods during mass outages.
---
- name: Webserver Auto-Remediation
  hosts: all
  sources:
    - ansible.eda.webhook:
        host: 0.0.0.0
        port: 5000
  rules:
    - name: Restart service on failure
      condition: event.payload.status == "down"
      action:
        run_playbook:
          name: restart_service.yml

Part 6: Modern Use Cases

Chapter 18: Cloud & IaC

Ansible complements Terraform. Terraform provisions the raw infrastructure (VPCs, EC2 instances), and Ansible configures the OS and applications running on them. Use the cloud.terraform collection to orchestrate Terraform directly from Ansible if needed.

Minimalist Getting Started:

  • Use the amazon.aws or azure.azcollection collections.
  • Don't manage Terraform state files directly with Ansible logic. Treat them as separate pipelines.

Chapter 19: Network & Edge Automation

Ansible isn't just for Linux servers. It manages Cisco routers, Juniper switches, and Edge IoT devices natively.

Minimalist Getting Started:

  • Network devices don't have Python installed. You must use the network_cli connection type instead of SSH.
  • This forces Ansible to run the Python logic locally on the Control Node and only send CLI commands to the switch.