Objective 6.6
Recognize the capabilities of configuration management mechanisms such as Ansible and Terraform
What configuration management means
A configuration management tool is software that takes a description of how devices should be configured and makes reality match that description, across many devices at once. The description lives in text files that can be stored in a version-control system such as Git, which is where the phrase infrastructure as code (IaC) comes from: the network’s configuration is treated like software source code, with history, reviews, and rollback.
Two vocabulary pairs come up constantly:
- Push versus pull. In a push model, a central server connects to the devices and sends them their configuration. In a pull model, a small program (an agent) installed on each device periodically contacts the server and asks “what should I look like?”, then applies any changes itself.
- Agent-based versus agentless. Agent-based tools require that agent software be installed on every managed device. Agentless tools need nothing installed on the device; they use protocols the device already supports, such as SSH or an API. Agentless is far better suited to network devices, because you generally cannot install third-party software on a switch.
A third idea, procedural versus declarative, distinguishes tools that say how (run these steps in this order) from tools that say what (here is the end state; you figure out the steps). Ansible playbooks are largely procedural in structure (a list of tasks), although many of its modules behave declaratively. Terraform is fully declarative.
Ansible
Ansible is an open-source automation tool, now owned by Red Hat, written in Python. It is by far the most common configuration management tool used with Cisco network devices, and the exam expects you to know its defining characteristics.
| Ansible characteristic | Detail |
|---|---|
| Agentless | Nothing is installed on the managed devices |
| Transport | SSH to network devices (also NETCONF, RESTCONF, or HTTPS APIs through specific modules) |
| Model | Push: the Ansible control node connects out to the devices |
| Language | Written in Python; the files you write are YAML |
| Control node | Any Linux/macOS machine with Python and Ansible installed; no dedicated server required |
| Idempotent | Most modules check the current state and only make a change if one is needed |
Ansible’s main file types:
| File | Purpose |
|---|---|
| Inventory | A list of the devices to manage, usually grouped (e.g., [switches], [routers]), with connection details; in INI or YAML format |
| Playbook | A YAML file containing one or more plays; each play targets a group of hosts and lists tasks to run in order |
| Task | One action, executed by calling a module with parameters |
| Module | A reusable unit of code that does one job, such as cisco.ios.ios_config (send config lines) or cisco.ios.ios_command (run show commands) |
| Role | A packaged, reusable collection of tasks, templates, and variables |
| Template | A Jinja2 text file with variables that Ansible fills in to generate configuration |
| Variables / facts | Values you define, plus facts Ansible discovers from devices |
A tiny inventory file:
[switches]
sw1 ansible_host=10.1.1.11
sw2 ansible_host=10.1.1.12
[switches:vars]
ansible_network_os=cisco.ios.ios
ansible_connection=ansible.netcommon.network_cli
ansible_user=admin
A tiny playbook that configures NTP and a syslog server on every switch in the group:
---
- name: Standardize NTP and syslog on access switches
hosts: switches
gather_facts: false
tasks:
- name: Configure NTP server
cisco.ios.ios_config:
lines:
- ntp server 10.1.1.100
- name: Configure syslog destination
cisco.ios.ios_config:
lines:
- logging host 10.1.1.200
- logging trap informational
- name: Save the running configuration
cisco.ios.ios_config:
save_when: modified
You run it with ansible-playbook -i inventory.ini ntp-syslog.yml. Ansible connects to each host over SSH, checks whether the lines already exist, adds any that are missing, and reports ok (no change needed) or changed for each task. Running it a second time reports ok everywhere, which is idempotency in action.
Terraform
Terraform, made by HashiCorp, is primarily an infrastructure provisioning tool rather than a device-configuration tool. It is used to create and manage resources in cloud platforms (AWS, Azure, Google Cloud), virtualization systems (VMware), and controller-based network products (Cisco ACI, Catalyst Center, Meraki, SD-WAN, Intersight, and others). Its defining characteristics:
| Terraform characteristic | Detail |
|---|---|
| Declarative | You describe the desired end state; Terraform calculates what must change |
| Language | HCL (HashiCorp Configuration Language); JSON is also accepted |
| Providers | Plugins that know how to talk to a specific platform’s API (AWS, ACI, Meraki, and hundreds more) |
| State file | terraform.tfstate records what Terraform has created and maps your code to real resources; it is the source of truth for the next run |
| Agentless | Talks to platform APIs (usually REST) over HTTPS; nothing installed on targets |
| Model | Push, from wherever Terraform runs |
| Idempotent | Applying the same code twice makes no changes the second time |
| Infrastructure as code | Code is stored in Git; changes are reviewed like software |
The Terraform workflow has three main commands:
terraform initdownloads the providers referenced in the code.terraform plancompares the code with the state file and the real platform and prints exactly what it would create, change, or destroy, without doing it.terraform applyexecutes the plan (after asking for confirmation).terraform destroyremoves everything the code created.
A tiny example that creates a network in a Meraki organization:
terraform {
required_providers {
meraki = {
source = "cisco-open/meraki"
}
}
}
provider "meraki" {
meraki_dashboard_api_key = var.api_key
}
resource "meraki_networks" "branch12" {
organization_id = "123456"
name = "Branch-12"
product_types = ["switch", "wireless"]
time_zone = "America/Chicago"
}
The words in this example illustrate HCL syntax: a provider block, a resource block with a type and a local name, and key = value arguments (note the equals sign, unlike YAML’s colon).
Ansible versus Terraform
| Aspect | Ansible | Terraform |
|---|---|---|
| Primary purpose | Configuration management and task automation on existing devices | Provisioning and lifecycle of infrastructure and controller objects |
| Style | Procedural playbook (ordered tasks), modules mostly idempotent | Fully declarative |
| Language of files | YAML (playbooks), INI/YAML (inventory), Jinja2 (templates) | HCL |
| Written in | Python | Go |
| Device connection | SSH (or APIs) | Provider plugins calling APIs |
| Agent | Agentless | Agentless |
| Push/pull | Push | Push |
| Tracks state? | No state file; checks the device each run | Yes, terraform.tfstate |
| Preview changes | --check mode (dry run) |
terraform plan |
| Typical Cisco use | Pushing CLI configuration to IOS/IOS-XE/NX-OS devices | Managing ACI, Meraki, Catalyst Center, SD-WAN, cloud |
In practice the two are often combined: Terraform builds the virtual machines, cloud networks, or controller objects, and Ansible then configures the operating systems and devices inside them.
Puppet and Chef (brief mention)
Older CCNA versions named Puppet and Chef; the v1.1 blueprint says “such as Ansible and Terraform,” so recognize the others at a high level.
| Tool | Agent? | Model | Language | Key files |
|---|---|---|---|---|
| Puppet | Agent-based (agentless possible via a proxy) | Pull: agents check in with the Puppet master, by default every 30 minutes | Written in Ruby; files use Puppet’s own declarative DSL | Manifest (desired state), modules, resource catalog |
| Chef | Agent-based (chef-client) | Pull: clients check in with the Chef server | Written in Ruby; files use a Ruby-based DSL | Recipes grouped into cookbooks, run-list |
| Ansible | Agentless | Push | Python; YAML files | Playbook, inventory, modules, roles |
| Terraform | Agentless | Push | Go; HCL files | Configuration files, providers, state file |