Skip to main content
RunBook Academy

Git, CI/CD & GitOpsCVIII · Infrastructure-as-Code IntegrationAnsible

Ansible in the pipeline — the role, the limits, the dry-run

Advanced⏱ ~26 mingitansible

What you'll learn

  • Place Ansible at the host-configuration layer of the IaC model
  • Explain why idempotent execution is not the same as plan-then-apply
  • Use ansible-playbook --check as a CI gate
  • Recognise the cases where Ansible is the wrong tool in a modern pipeline

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

Ansible belongs at the host-configuration layer of the IaC model. It runs after Terraform has provisioned a host and before the orchestrator has work to do. Its posture is idempotent execution over a fleet: run the same playbook twice and the world should look the same as after the first run. This posture is useful, but it is not the same as Terraform’s plan-then-apply or Kubernetes’s reconcile-loop, and conflating them is a recurring source of pipeline confusion.

Where Ansible sits in the flow

flowchart LR
    A["Git commit of playbook"] --> B["ansible-lint"]
    B --> C["ansible-playbook --check"]
    C --> D["ansible-playbook with diff mode"]
    D --> E["Inventory and credentials"]
    E --> F["Apply against target hosts"]
    F --> G["Callback and audit log"]

Three properties of this flow are worth pulling out:

  • The dry-run is not the artefact. ansible-playbook --check reports what would change; it does not produce a serialised change set. The apply re-derives intent at run time. This is the architectural difference from Terraform.
  • Lint and check are CI gates. They run on every pull request. The apply runs after merge, against a real inventory, with real credentials.
  • Inventory and credentials are not in the playbook. The playbook describes intent; the inventory says which hosts; the credentials say who may apply. All three live in different places and join at run time.

The dry-run gate

The CI gate for Ansible is ansible-playbook --check:

ansible-playbook --check playbook.yml

In check mode, Ansible reports what it would change without making the change. Tasks that support it report changed or ok per host; tasks that do not are skipped. A --check run that reports no changes is a strong signal that the hosts already match the playbook’s desired state.

ansible-playbook --check --diff playbook.yml

Adding --diff makes the change visible: file edits as unified diffs, package installs as version transitions, service state as before-and-after. --check --diff is the closest Ansible comes to Terraform’s plan output, but the apply still re-derives intent at run time. The check is a gate, not an artefact.

The limits

Ansible is the wrong tool in three recurring cases:

  • Declarative workload orchestration. When the desired state is a set of pods, services, and replicas, the right tool is Kubernetes with a GitOps controller. Ansible can call kubectl apply, but at that point it is an imperative wrapper that has lost the reconcile-loop.
  • Cloud resource provisioning. When the desired state is a VPC, subnet, or IAM role, the right tool is Terraform. Ansible collections exist but model cloud APIs imperatively.
  • Immutable image construction. When the desired state is a base image with packages baked in, the right tool is Packer (or Dockerfile). Ansible can run inside a Packer build, but Packer is producing the artefact.

The pipeline is the right place to sequence these tools. Ansible runs against the host Terraform provisioned; the host image is baked by Packer; the workload is declared in Kubernetes. Wrong-tool Ansible shows up as a playbook wrapping a cloud call, calling kubectl apply, or building a Docker image.

Production discipline

The production framing of Ansible in a pipeline has three rules:

  1. Lint, check, diff, apply - in that order. A CI job that skips ansible-lint and --check ships untested configuration. The same gate sequence runs on every PR.
  2. The inventory is per-environment. Staging and production inventories are different files, both in the repository, both reviewed, both with their own credential scope.
  3. AWX or Automation Controller is the production entry point. The controller brokers credentials, records audit logs, schedules runs, and gates approvals.

Cross-course references

  • Ansible for Production Sysadmins - Parts XXXVII-XL (RepoArch) cover the playbook, inventory, and credentials layout this lesson assumes.
  • Terraform for Production Sysadmins - Parts IX-XII (State) cover the Terraform-to-Ansible handoff.
  • Containers for Production Sysadmins - Parts IV-VI (Immutability) cover baking hosts with Packer.
  • Observability for Production Sysadmins - Parts XV-XVIII (Audit) cover the AWX callback and audit log.

Quiz

Knowledge check · 4 questions

  1. Q1. What does `ansible-playbook --check playbook.yml` do in a CI pipeline?

  2. Q2. Ansible is the right tool to declaratively manage a Kubernetes cluster's workload set in a CI/CD pipeline.

  3. Q3. Which of the following is a real architectural limitation of Ansible in a CI/CD pipeline?

  4. Q4. Diagnose a pipeline that runs Ansible without check mode and applies directly from a developer's laptop.

    A team runs Ansible directly from a developer's laptop using a personal SSH key. The playbook manages 30 production hosts and was last edited six months ago. Last week, a task that does not declare itself idempotent ran twice on a host and added the same line to /etc/hosts twice, producing a duplicate entry that broke a service mesh sidecar.

Passing score: 75%. Answers are checked in this browser.