Configuration management
What Ansible and Terraform provide: declarative intent, idempotence, and push versus pull orchestration at CCNA depth.
Ansible, Terraform and peers
Configuration management tools declare the desired state of systems and enforce it repeatedly. The CCNA names Ansible and Terraform; Chef and Puppet are the usual distractors. The key concepts: declarative intent, idempotent application, and a push or pull delivery model.
Tool comparison at blueprint depth
| Property | Ansible | Terraform |
|---|---|---|
| Model | Push — runs tasks over SSH/agentless | Client → provider APIs |
| Language | YAML playbooks | HCL declarative configs |
| State | Stateless (no central state file) | Tracks managed state in a state file |
| Focus | Config + orchestration on devices/servers | Provisioning infrastructure resources |
| Idempotent? | Yes — modules check before changing | Yes — plan shows only needed changes |
Push versus pull
| Model | How it works | Example |
|---|---|---|
| Push | Controller initiates changes to targets | Ansible playbook run |
| Pull | Agents check in and fetch their config | Puppet/Chef agents |
Declarative and idempotent
Idempotent means running the same task twice produces the same result — a property tools strive for, not a guarantee: an imperative script can be written idempotent and a declarative module can misbehave. A declarative file says *what* should exist, not *how* to change things; the tool diffs desired vs actual and applies only the delta. Chef/Puppet work on the same declarative principle with agents that pull their desired state.
- Task
- Playbook ensures 'vlan 20 name SALES' on 40 switches
- Run 1: creates the VLAN where missing, skips it where present.
- Run 2 (weekly schedule): touches nothing already correct — the report shows 'ok', not 'changed'.
- A naive script would append
vlan 20blocks or error on existing objects.
Desired-state tools converge; imperative scripts accumulate.
Verification
Verifying runs
- Ansible: run with --check (dry run) where the module supports it, and inspect 'changed' vs 'ok' results per device.
- Terraform:
terraform planpreviews the diff before any apply — a preview, not a safety guarantee. - Post-run: spot-verify a few devices — automation reports intent, you confirm reality.
Common mistakes
- Thinking Ansible needs agents — it's agentless over SSH/APIs.
- Believing Terraform never addresses drift — it reconciles drift for provider-managed resources on plan/apply; unmanaged local changes simply don't appear in its state.
- Confusing 'declarative' with 'no logic' — templates and conditionals exist; the declared end-state is the contract.
- Skipping --check/plan — the preview is a safety step, not a guarantee: --check support varies by module and plan only predicts what the provider reports.
Observation: The same playbook always reports 'changed' for a task.
- Task isn't idempotent — it appends/duplicates each run
- Module writes config that the device normalizes differently
- Version-specific module behavior
| Check | Indicates |
|---|---|
| Diff the device config before/after two runs | What's actually accumulating. |
| Run with --diff | Shows the exact delta — but diffs can reveal secrets; use no_log where sensitive values might print. |
Correction: Make the task check-before-change — and investigate persistent 'changed' reports rather than accepting them as harmless drift.
Second run reports 'ok' — idempotent convergence achieved.
Related resources
Sources
- Cisco CCNA 200-301 v1.1 Exam Topics (official PDF) — reviewed 2026-11-02
Targets CCNA 200-301 v1.1 objectives. Supplemental blocks are labeled beyond exam scope.