Mental model
Cisco objective 5.5 says “Describe the principles of infrastructure as code”.
Infrastructure as Code = the desired state of your infrastructure (servers, VLANs, firewall rules, DNS entries) lives in text files in a Git repository. A tool reads those files and reconciles the live infrastructure to match.
Instead of:
- Admin SSHes to router, types config, saves, hopes it is right.
You get:
- Developer commits a change to the configs repo.
- Pipeline runs lint and dry-run.
- Reviewer approves.
- Pipeline pushes to prod. Diff of before/after is in Git history forever.
Five principles
1. Declarative
Describe what you want, not how to get there. The tool figures out the diff.
Declarative (Terraform):
resource "cisco_vlan" "data" {
vlan_id = 10
name = "data"
}
Imperative (bash):
ssh switch "configure terminal; vlan 10; name data; end; wr mem"
Declarative wins because it handles both “create this VLAN” and “ensure this VLAN exists” with the same code. If the VLAN already exists, Terraform notices and does nothing.
2. Idempotent
Running the same code N times leaves the system in the same final state as running it once. No side effects on repeat runs.
Why it matters: pipelines re-run, scripts resume after failures, humans mash the Run button twice. Non-idempotent code creates duplicate VLANs or crashes on the second run.
3. Version controlled
Every change goes through Git. You get:
- History — who changed what, when, why.
- Review — PR / MR workflow before anything hits prod.
- Rollback —
git revertand re-apply. - Diff — see the exact lines that changed.
4. Automated application
A pipeline (CI/CD) applies the change, not a human running commands. Removes the “late Friday night SSH” risk and ensures the same process every time.
5. Immutable preferred
Prefer replacing an entire resource over mutating it in place. On servers: build a new image, launch new instances, retire old. On network: replace a config, do not patch.
Not always possible (physical switches cannot be “replaced”) but the mindset catches drift.
Tools in the IaC space
| Tool | Shape | Where it shines |
|---|---|---|
| Ansible | Imperative-ish declarative (tasks that are idempotent); SSH or API | Config of servers and network devices; agentless |
| Terraform | Fully declarative; providers for AWS/Azure/GCP/Cisco/etc. | Cloud resources, provider-rich ecosystem |
| Cisco NSO | Declarative, model-driven; speaks NETCONF/RESTCONF natively | Cross-vendor network service orchestration |
| Pulumi | Declarative, using real programming languages (Python/TS/Go) | Teams that prefer code over DSL |
| CloudFormation / ARM | AWS- / Azure-native declarative | Vendor-locked but tight integration |
Lifecycle
Developer writes/updates .tf or .yml file
│
▼
git commit + push
│
▼
CI pipeline runs:
- lint (yamllint, terraform fmt, ansible-lint)
- dry run (terraform plan, ansible-playbook --check)
│
▼
Human review on the PR
│
▼
CD pipeline applies (terraform apply, ansible-playbook)
│
▼
State recorded (terraform state, Ansible facts)
│
▼
Monitor + alert on drift
Common anti-patterns
- Config in Git but changes still made manually (“drift”).
- Secrets committed in plaintext.
- No PR review (“I will just push, it is small”).
- Everyone has prod access; no CI gating.
- No
terraform planbefore apply.
FAQ
Is Ansible IaC? Yes. Ansible is slightly imperative-flavoured (tasks run top to bottom) but each task is required to be idempotent, which gives most IaC benefits.
Is bash scripts IaC? Technically yes if stored in Git and idempotent. In practice bash scripts tend to drift from idempotent fast; prefer a real IaC tool.
What is GitOps? IaC + “Git is the sole source of truth”. A controller (ArgoCD, Flux) continuously reconciles live state to Git. See DevOps principles.
Do I need to pick one tool? Many teams use Terraform for cloud infrastructure and Ansible for inside-the-server config. They complement rather than compete.
