Git, CI/CD & GitOpsCVIII · Infrastructure-as-Code IntegrationOverview
The IaC tooling landscape — Terraform, Ansible, Kubernetes, Docker, and the boundaries
What you'll learn
- Place Terraform, Ansible, Kubernetes, and Docker on a layered model of infrastructure concerns
- Identify the boundary between desired-state and imperative execution in each tool
- Recognise why the four tools have different CI/CD postures
- Explain why network and OS configuration often fall outside all four
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
The four infrastructure-as-code tool families that dominate production pipelines are Terraform, Ansible, Kubernetes, and Docker. They look similar from the outside - each has files in a repository, each runs in a pipeline, each produces a change - but they sit at different layers of the stack, model state differently, and integrate with CI/CD in different ways. Treating them as interchangeable is the most common architectural mistake in this part of the course.
The layered model
The four tools cover four distinct concerns. Drawing the layers explicitly is the first step toward a coherent pipeline. Each layer has its own lifecycle, its own state model, and its own place in the delivery chain.
flowchart TB
subgraph L1["Application layer"]
D["Docker images and OCI artefacts"]
end
subgraph L2["Workload orchestration layer"]
K["Kubernetes manifests and controllers"]
end
subgraph L3["OS and host configuration layer"]
A["Ansible playbooks and roles"]
end
subgraph L4["Cloud and platform resource layer"]
T["Terraform modules and providers"]
end
D --> K
K --> A
A --> T
- Terraform declares cloud and platform resources and talks to the cloud control plane.
- Ansible describes how a host is configured once it exists and runs commands, files, and services.
- Kubernetes declares workload shape - pods, services, ingresses, RBAC - on a cluster it manages.
- Docker produces the artefact a workload runs as. It sits below Kubernetes, not above.
The boundaries
The boundaries are sharp, and the most useful question to ask of any pipeline step is which layer is this step acting on.
- Terraform does not build images. It cannot run a Dockerfile. When a pipeline calls Docker from inside a Terraform provisioner, it has crossed a boundary the tooling is warning you about.
- Ansible does not declare desired cluster state. It can call
kubectl apply, but at that point it is functioning as an imperative wrapper, not as Ansible. - Kubernetes does not configure the host kernel. The node image is built by something else - Packer, cloud-init, Ansible - and Kubernetes only schedules pods onto what already exists.
- Docker does not provision the cloud. It builds images; what runs them is someone else’s problem.
Why pipelines treat them differently
Each tool has a different CI/CD posture because each tool models change differently. The four postures drive every decision in this part of the course.
- Terraform is plan-then-apply. The
planis an artefact that lives in the pipeline; theapplyconsumes it. - Ansible is idempotent execution. The same playbook run twice converges to the same state. CI can lint and dry-run.
- Kubernetes is reconcile-loop. A GitOps controller reads desired state from Git and converges the cluster to it.
- Docker is deterministic build. Same inputs, same digest out.
These postures determine where the pipeline inserts gating, where human approval lives, and where rollback begins.
Production discipline
The production framing of the tooling landscape has three rules:
- Pick the tool by the layer. Cloud resource -> Terraform. Host -> Ansible. Workload -> Kubernetes. Familiarity is a cost-of-change argument, not an architectural one.
- Treat the boundaries as load-bearing. When a tool is asked to do another tool’s job, the pipeline loses auditability. Sequence in the pipeline; do not fuse inside a module.
- One repo per layer is a sane default. A Terraform repo, an Ansible repo, a Kubernetes repo, and a Docker repo each have their own CI posture. A monorepo is allowed but requires more discipline, not less.
Cross-course references
- Terraform for Production Sysadmins - Parts V-VIII (Modules) cover the Terraform-specific layer discipline.
- Ansible for Production Sysadmins - Parts XXI-XXIV (Immutability) cover the case for treating hosts as cattle.
- Kubernetes for Production Sysadmins - Parts XI-XIV (GitOps controllers) cover the reconcile-loop posture.
- Containers for Production Sysadmins - Parts VII-X (BuildKit and registries) cover content-addressable caching.
Quiz
Knowledge check · 4 questions
Q1. Which layer does Terraform primarily operate at in a layered IaC architecture?
Q2. A Terraform module can build a Docker image directly without calling out to an external process, and this is the recommended pattern.
Q3. Why do production pipelines treat Terraform, Ansible, Kubernetes, and Docker with different gate semantics?
Q4. Diagnose an architectural mistake in a pipeline that fuses Terraform and Ansible, and prescribe the correction.
A team has a Terraform module that provisions an EC2 instance and then runs an Ansible playbook inside a `local-exec` provisioner to configure the host. The apply takes 40 minutes, the state file is large, and a junior engineer accidentally committed a change that causes the Ansible run to fail halfway through. The instance is left half-configured, and rolling back means re-running Terraform from scratch.
Passing score: 75%. Answers are checked in this browser.