Skip to main contentSkip to user menuSkip to navigation

Ansible

Master Ansible: configuration management, automation playbooks, and infrastructure orchestration.

35 min readIntermediate
Not Started
Loading...

What is Ansible?

Ansible is an automation platform that applies repeatable changes to managed systems. A control node reads an inventory, selects hosts, and executes playbook tasks through modules. For common Linux management, the target usually needs SSH and Python rather than a permanently running Ansible agent.

The core promise is convergence: a well-designed playbook moves each host toward a declared state, reports what changed, and becomes quiet when that state is already correct. YAML alone does not provide this property. The chosen module, task arguments, failure policy, and external command behavior determine whether a repeat run is safe.

Ansible is a push-based executor, not a continuous reconciler. A successful run proves what happened during that execution; it does not guarantee that a host will remain compliant afterward.

Build a play from four explicit contracts

Who

Inventory

Hosts, groups, and variables define the known managed estate. Patterns and --limit select a subset from that inventory; they cannot target a host the inventory does not contain.

Where and how

Play

A play maps a host pattern to ordered tasks and execution controls such as privilege escalation, strategy, serial, and failure thresholds.

Desired operation

Module

A module inspects target state and returns a result such as ok, changed, failed, or skipped. Prefer fully qualified collection names so the implementation is unambiguous.

Change-triggered effect

Handler

A task notifies a handler only when it reports changed. This keeps expensive reloads and restarts tied to real configuration changes.

  1. 1

    Select

    Resolve inventory

    Load inventory sources, compose groups and variables, and evaluate the play's host pattern plus any command-line limit.

  2. 2

    Observe and act

    Execute each task

    For the current task, run its action against the eligible hosts according to the selected execution strategy and concurrency controls.

  3. 3

    Classify

    Record host results

    Track ok, changed, failed, unreachable, and skipped independently for every host. A failure normally removes that host from later tasks in the play.

  4. 4

    Apply side effects

    Flush notified handlers

    Run each notified handler once per host at the configured handler boundary, unless an earlier failure prevents it or the play explicitly flushes handlers.

Prove convergence with a second execution

Idempotency means that repeating an operation against the same starting state produces the same target state without repeating unnecessary side effects. An Ansible module can support idempotency, but the playbook author still has to supply a complete desired state and avoid hidden work in commands, templates, callbacks, or APIs.

Use the lab to start from a missing, drifted, or compliant file. Run each task design twice and compare the reported result, resulting host state, and handler behavior.

Execution and idempotency lab

Load the convergence model

The lesson-owned host states and task behaviors are loading.

Loading execution states...

Express desired state instead of procedural guesses

The first run is not the proof. The stronger test is whether a second run reports no change while the host remains correct.

A convergent configuration with a change-triggered handler

Run a narrow dry run with ansible-playbook --check --diff --limit <host>, then run the same play in a disposable environment. Check mode is a simulation: modules may support it partially or not at all, registered results can differ from a real run, and diff output can expose secrets unless sensitive tasks disable it.

Treat these results as separate evidence

  • ok: the task observed no required change for that host.
  • changed: the task claims it modified state; this can trigger handlers.
  • failed: the module or an explicit condition rejected the result.
  • unreachable: Ansible could not establish the managed-node connection.
  • skipped: a condition, tag, check-mode rule, or other control omitted the task.

Do not hide a non-idempotent command with changed_when: false. That changes reporting, not the command's side effect.

Make inventory selection a safety boundary

Inventory is more than a host list. It expresses environment, function, location, and other operational groups that a play can intersect or exclude. A host pattern selects from those groups, while --limit narrows the result further for a particular run.

Name environments explicitly

Keep production and non-production membership visible in inventory. Do not infer the environment from a hostname substring inside a task.

Preview the target set

Use ansible-inventory --graph, --list-hosts, and a reviewed job template or command to confirm exactly which hosts match before a destructive run.

Bound each rollout batch

serial limits concurrent exposure. max_fail_percentage is evaluated per batch and aborts only when the failure percentage is greater than the configured threshold.

Inventory groups that separate environment, role, and canary membership

Contain a failed rollout before it becomes a fleet event

A rolling deployment needs two independent boundaries: the inventory expression limits which hosts are eligible, and serial limits how many eligible hosts enter one batch. The failure threshold decides whether Ansible advances after that batch.

Change the host pattern, batch size, threshold, and injected failures. The model uses Ansible's strict “greater than” rule, so one failure in a three-host batch is 33.3% and exceeds a threshold of 33.

Inventory and rollout lab

Load the failure-containment model

The lesson-owned inventory, patterns, and host groups are loading.

Loading inventory and rollout states...

Design the rollout around user-visible health

A bounded production rollout with an explicit health gate

Before promoting this pattern, answer these operational questions:

  • Target proof: Which reviewed inventory query or job-template preview proves the matched host set?
  • Batch health: Which application check must pass before a host returns to service? A running process is not necessarily a healthy application.
  • Abort semantics: Should one failed host stop only its batch, the entire play, or a larger multi-play procedure? Use max_fail_percentage and any_errors_fatal deliberately.
  • Recovery: Is rollback another idempotent playbook, an immutable artifact switch, or a restore? Test the recovery path instead of assuming rerun equals rollback.
  • Concurrency: Can the dependency behind the task tolerate the chosen forks and batch size without rate limits, lock contention, or a restart storm?
  • Secrets: Are Vault and external-secret lookups protected from stdout, diff output, callback plugins, and retained job artifacts?

For a batch of N hosts, choose a threshold below 100 / N when any single failure must abort. Because equality does not abort, a three-host batch needs 33 rather than 34.

Know where Ansible stops

Use Ansible when an operator or delivery system should push a bounded procedure across known targets: configure operating systems, deploy application artifacts, rotate settings, or orchestrate a maintenance sequence.

  • Use Terraform when the primary problem is creating and changing infrastructure resources through a dependency graph and persisted state.
  • Use image building when hosts should start from a tested immutable artifact rather than accumulate configuration history.
  • Use a Kubernetes operator or GitOps controller when the system needs continuous reconciliation after the automation command has finished.
  • Use a workflow engine when a procedure spans long waits, durable external events, compensation, and resumable state beyond one playbook execution.

Current reference points: Ansible's official documentation for inventory patterns, execution strategies, and playbook error handling.

No quiz questions available
Could not load questions file
Spotted an issue or have a better explanation? This page is open source.Edit on GitHub·Suggest an improvement