First, the essential ideas
- Ansible control node and inventory
- The control node runs Ansible. Inventory identifies authorized targets and their connection variables. Agentless means a persistent Ansible agent is not installed on the managed router; network access and credentials are still required.
- Module, collection and playbook
- A module performs a defined task. A collection packages related modules and plugins. A playbook describes ordered tasks for selected hosts, commonly in YAML, a structured text format sensitive to indentation.
- Idempotence
- An idempotent configuration operation aims to leave the same intended state after repeated application. Not every command or module is idempotent, and a changed flag alone does not prove desired network behavior.
- Infrastructure as code
- Infrastructure as code, IaC, represents intended infrastructure in versioned definitions that can be reviewed and processed by tools. It is a management approach, not a guarantee that changes are correct.
- Terraform provider and state
- A provider connects Terraform to a platform's API. State maps declared resource identities to managed objects and stores relevant attributes. State is operationally important and may contain sensitive information.
- Plan, apply and drift
- A plan proposes changes based on configuration, state and refreshed observations. Apply performs approved actions. Drift is a difference between expected or recorded state and what exists outside the tool's intended workflow.
- Rollback boundary
- Reverting a definition or state file is not a time machine. Destructive changes may need backups or compensating actions, and a second apply may not recreate lost data or sessions.
Automation starts with a target and a permitted operation. In this exercise the target is one lab router and the operation is show ip interface brief. The inventory, connection method and module make that scope visible before any command is sent.
See the idea
Ansible targets one router and returns evidence
Inventory chooses the target; the module sends a bounded read command and returns evidence to the control node.
Review the target scope
The inline inventory contains only 192.0.2.58. Confirm that scope before the password prompt or any device command.
What this model leaves out: This is the scoped Ansible management path, not user traffic or Terraform provisioning. The inventory record is a logical input, not a network device.
Full visual explanation and references
The one-host inventory selects R58. The Ubuntu Ansible control node connects by SSH to R58 and receives its show-command output.
This is the scoped Ansible management path, not user traffic or Terraform provisioning. The inventory record is a logical input, not a network device.
- Review the target scope
The inline inventory contains only 192.0.2.58. Confirm that scope before the password prompt or any device command.
www.cisco.com - Execute the read command
The control node uses network_cli over SSH and ios_command to request show ip interface brief from R58.
developer.cisco.com - Verify returned identity
Compare actual returned output with R58's console. A task status alone cannot prove that the intended router was queried.
www.cisco.com
One idea at a time
Start with something familiar.
Read the Ansible invocation from left to right: inventory address, target pattern, connection plugin, username, password prompt, operating-system variable, module and module arguments. The trailing comma means an inline host list rather than a filename.
Why learn this?
The same command can be safe against one disposable router and unsafe against a broad production inventory. Target selection and module capability matter as much as the command text. Review them before entering a password.
An everyday comparison
A technician has a work order naming one cabinet and a checklist of permitted inspections. A separate construction plan describes resources to build and a ledger tracks which resources belong to that project.
What happens in a network
Ansible inventory and tasks resemble the scoped work order. Terraform declarations and state resemble the plan and resource ledger. The comparison helps separate executing tasks from reconciling managed resources.
Where the comparison stopsNeither tool is limited to this analogy: Ansible can use declarative resource modules, and Terraform providers can manage many kinds of configuration. Their real contracts and state behavior decide what is safe.
Follow one worked example
- Verify the exact target before automation.
Ubuntu ens3 at 192.0.2.10 connects only to R58 GigabitEthernet1 at 192.0.2.58. SSH is established and its host key is recorded in this isolated lab.
Why: Automation should not be the first unexplained connection to an unknown device.
- Run a read command using the network module.
cisco.ios.ios_command returns show ip interface brief output over network_cli. It is not the Linux shell module and does not enter IOS configuration mode.
Why: A platform-aware module speaks the device's CLI and returns structured task results.
- Repair one bad inventory address.
The same invocation targets unused .59 and should fail to connect. Restoring .58 and rerunning must recover the original output.
Why: A bounded inventory error teaches target diagnosis without altering router configuration.
Your first small task
Read a hypothetical plan marked + for create, ~ for in-place update and -/+ for replacement. Explain which action needs special concern if the resource holds data, and whether a plan alone performs the change.
Show a hint
Version history of configuration and backups of operational data solve different recovery problems.
Check the expected result
Replacement can destroy and recreate a resource, risking data or service continuity. A plan proposes actions; it does not itself apply them.
Pause and explain it in your own words
Can reverting a Terraform state file safely undo an infrastructure deletion?
Show a hint
Distinguish the ledger from the objects it describes.
Show the explanation
No. State is not the infrastructure and restoring an older state can misrepresent reality. Recovery requires reconciling actual resources, approved configuration and backups or compensating actions under a controlled procedure.
Short answer
What should you understand today?
Ansible runs tasks against an explicit inventory using suitable modules and connections. Terraform compares declared infrastructure with state and provider observations to plan changes. Both require scoped access, review and verification. This lesson executes only read-command instructions through Ansible; Terraform provisioning is explained without any cloud apply.
Before you begin
Learning targets
- Review IOS modes, SSH, IPv4 local-subnet addressing and JSON command arguments.
- Use GNS3 2.2 with an entitled CSR1000v IOS XE 17.3 router and Ubuntu 24.04 control VM.
- Preinstall ansible-core 2.19.x, cisco.ios 11.6.0, compatible ansible.netcommon 8.x and Paramiko 3.x; record actual versions before isolation.
- Identify Ansible control node, inventory, connection plugin, collection and module.
- Execute a scoped IOS show command through Ansible and compare returned output with the device console.
- Fault one inventory address, restore the original target and verify the same command again.
- Explain Terraform providers, plan/apply, state, drift, sensitive data and rollback limits separately.
Words you will meet
Open a word when you need its meaning. You do not need to memorize the whole list before reading.
Ansible control node and inventory
The control node runs Ansible. Inventory identifies authorized targets and their connection variables. Agentless means a persistent Ansible agent is not installed on the managed router; network access and credentials are still required.
Module, collection and playbook
A module performs a defined task. A collection packages related modules and plugins. A playbook describes ordered tasks for selected hosts, commonly in YAML, a structured text format sensitive to indentation.
Idempotence
An idempotent configuration operation aims to leave the same intended state after repeated application. Not every command or module is idempotent, and a changed flag alone does not prove desired network behavior.
Infrastructure as code
Infrastructure as code, IaC, represents intended infrastructure in versioned definitions that can be reviewed and processed by tools. It is a management approach, not a guarantee that changes are correct.
Terraform provider and state
A provider connects Terraform to a platform's API. State maps declared resource identities to managed objects and stores relevant attributes. State is operationally important and may contain sensitive information.
Plan, apply and drift
A plan proposes changes based on configuration, state and refreshed observations. Apply performs approved actions. Drift is a difference between expected or recorded state and what exists outside the tool's intended workflow.
Rollback boundary
Reverting a definition or state file is not a time machine. Destructive changes may need backups or compensating actions, and a second apply may not recreate lost data or sessions.
Choose a management approach and an owner
Device-based management works directly with each device. Cloud-based management hosts management services at a provider; the packet path need not traverse that service. Controller-based management coordinates a domain. Automation-based management runs repeatable tasks, while IaC makes intended infrastructure reviewable as definitions. These approaches can coexist. Assign configuration ownership so a manual edit, controller and pipeline do not continually overwrite each other.
- This extends Day 55's management-approach comparison for announced v2.0 5.3.
- Hosting location alone does not specify the user's forwarding path.
Understand the Ansible execution chain
The control node reads inventory and variables, chooses a connection plugin and invokes a module. For IOS show commands, cisco.ios.ios_command with ansible.netcommon.network_cli communicates over SSH. It does not install a persistent agent on the router and does not support configuration-mode commands. Configuration modules such as ios_config have different behavior and require separate review. A playbook packages tasks for repeatable use rather than making them inherently safe.
- Inspect inventory and variables before credential entry.
- Read-only task success is not permission to run an unreviewed write module.
Verify results instead of trusting task color
Ansible results include status and module-returned fields. Read the actual stdout content and compare it with the router console. A successful task can collect the wrong device's output if the inventory is wrong. An unreachable result usually concerns connection or authentication; a failed command may instead involve syntax or privilege. Avoid blindly retrying writes or broadening credentials to make a task green.
- Never paste passwords into an inventory example or command-line variable.
- Keep host-key checking enabled and investigate unexpected key changes.
Terraform plans resources through providers
Terraform uses declared resources, provider capabilities and state to determine proposed actions. A provider is the platform-specific integration, not a universal Cisco CLI driver. Review initialization sources and pinned versions before use. A plan may show create, update, destroy or replacement. Apply carries out the approved plan, but APIs can fail partway through, and a plan can become stale as the environment changes.
- A plan is reviewable evidence of proposed actions, not proof those actions succeeded.
- Ansible and Terraform have overlapping capabilities; avoid a rigid configure-versus-provision slogan.
Protect state and plan for imperfect recovery
State maps resource identities and can retain sensitive attributes. Protect it with appropriate access controls, backup and a backend that supports the required collaboration and locking. Marking an output sensitive can hide display without removing every secret from state. Drift can arise when another actor changes the platform. Reverting a Git commit changes definitions, while a later plan may propose new actions rather than restore history exactly.
- A state backup is not a backup of every managed resource's data.
- Check-mode or plan support is useful but is not a complete transactional rollback guarantee.
Match the practical to the exam and available rights
The chapter recognizes Ansible and Terraform capabilities for v1.1 6.6. It adds executable Ansible command instructions for announced v2.0 5.5 and IaC/management instruction for part of 5.3. Runtime execution is for the learner to observe; authoring did not contact a router. The current v1.1 applies through 2 February 2027 and v2.0 starts on 3 February.
- Do not replace the required Ansible practical with a claim that reading a playbook is execution.
- No paid API, public sandbox password or production target is used.
Real-world walkthrough
The correct module reads the wrong inventory target
In a fictional operations workflow, an engineer copies a known read-only task but selects the wrong inventory. The task itself is harmless, yet its output is attributed to the intended router and used to justify a change. The risk comes from incorrect evidence identity, not only from write permissions.
- Verify the approved host list and the exact address passed to the control node before running the task.
- Confirm the SSH host identity and compare device-reported name, release and interface address with the console.
- Treat a connection failure as a scoped target problem instead of widening the inventory or disabling host-key checking.
- Restore the correct one-host target and repeat the original read command.
- Attach the real output to the correct device record and keep Terraform plans or unrelated changes outside this task.
Guided GNS3 lab
Run one IOS command through Ansible
Prepare an isolated SSH target, execute show ip interface brief through a platform-aware Ansible module, fault one inventory address and recover. Terraform is not executed, and no runtime result is fabricated.
Addressing plan
| Device | Interface | Address | Purpose |
|---|---|---|---|
| Control | ens3 | 192.0.2.10/24; no gateway | Single Ansible control endpoint. |
| R58 | GigabitEthernet1 | 192.0.2.58/24; SSH TCP 22 | Only authorized managed target. |
| No device | None | 192.0.2.59 unused | Deliberate inventory fault; no scan or additional target. |
Set up the lab
- Verify Cisco image entitlement and save a stopped-project fresh baseline. Keep direct router and VM consoles open.
- Preinstall the documented Ansible components before disconnecting the lab; do not use this procedure to upgrade a shared control host.
- Confirm the Ubuntu adapter is ens3; map consistently if your imported VM differs. No other interface may connect to an external network.
- The literal password below is disposable lab-only data. Never reuse it outside this disconnected project; Ansible prompts rather than embedding it in the invocation.
- For the first SSH connection in this two-node isolated lab, confirm the direct cable and freshly created R58 identity, record the offered fingerprint and accept it once. Production requires independently verified host keys, not this limited trust-on-first-use setup.
Address and identify the router
In GNS3, right-click R58 and choose Console before typing. Use only the fresh disposable node. Set a hostname and local domain for SSH key generation, then configure the one control-facing interface.
enable
show version
configure terminal
hostname R58
ip domain name lab.invalid
interface GigabitEthernet1
ip address 192.0.2.58 255.255.255.0
no shutdown
endWhat each command means
enable- Enter privileged EXEC on this authorized lab device; stop if access is not authorized.
show version- Record the actual image and release.
configure terminal- Enter global configuration from privileged EXEC; changes affect the active configuration.
hostname R58- Set the lab identity used in prompts and key naming.
ip domain name lab.invalid- Set a reserved lab domain for key generation.
interface GigabitEthernet1- Select the sole control-VM link.
ip address 192.0.2.58 255.255.255.0- Set the authorized management address.
no shutdown- Enable the isolated link.
end- Return to privileged EXEC without saving or undoing the accepted changes.
- What you should see
- Expect R58 identity and the planned interface address; record actual state.
- Why this step matters
- Target identity and addressing must be known before introducing automation.
Enable lab-only SSH access
In GNS3, right-click R58 and choose Console before typing. Configure a disposable local login and SSH version 2. Privilege 15 is confined to this fresh isolated teaching node; production automation needs a separately designed least-privilege role.
configure terminal
username learner privilege 15 secret D58-Only-ChangeMe
crypto key generate rsa modulus 2048
ip ssh version 2
line vty 0 4
login local
transport input ssh
end
show ip sshWhat each command means
configure terminal- Enter global configuration from privileged EXEC; changes affect the active configuration.
username learner privilege 15 secret D58-Only-ChangeMe- Create the disposable lab-only account; never reuse this published example secret.
crypto key generate rsa modulus 2048- Generate R58's fresh RSA host key on this empty lab node.
ip ssh version 2- Require SSH version 2.
line vty 0 4- Select the lab remote-access lines.
login local- Authenticate these lines against the local account database.
transport input ssh- Allow SSH rather than Telnet on these lines.
end- Return to privileged EXEC without saving or undoing the accepted changes.
show ip ssh- Check the SSH service state and version.
- What you should see
- Expect SSH enabled with the intended version; stop on any command rejection.
- Why this step matters
- The target must support authenticated remote access before a network automation module can use it.
Address the control VM and inspect tools
In GNS3 open the Control VM console and Terminal. Confirm ens3 is the sole lab adapter, add its address and inspect the already-installed tooling. Do not fetch packages during this disconnected exercise.
ip -brief address
sudo ip address add 192.0.2.10/24 dev ens3
sudo ip link set ens3 up
ansible --version
ansible-galaxy collection list
python3 -c 'import paramiko; print(paramiko.__version__)'What each command means
ip -brief address- Identify the actual adapter and ensure the planned address is unused.
sudo ip address add 192.0.2.10/24 dev ens3- Assign the temporary control address on the isolated interface.
sudo ip link set ens3 up- Enable that interface.
ansible --version- Record Ansible and Python details.
ansible-galaxy collection list- Verify cisco.ios and ansible.netcommon are installed at the planned compatible versions.
python3 -c 'import paramiko; print(paramiko.__version__)'- Confirm the selected Paramiko SSH transport is installed.
- What you should see
- Expect the planned local address and required components; missing dependencies are a stop condition.
- Why this step matters
- Tool and connection requirements are explicit so unsupported environments cannot masquerade as executed automation.
Establish the SSH identity baseline
In the Control VM console Terminal, connect only to R58. Apply the isolated first-use fingerprint procedure from setup, enter the disposable password interactively, and run the shown IOS read command after login.
ssh learner@192.0.2.58
show ip interface brief
exitWhat each command means
ssh learner@192.0.2.58- Open SSH to the one authorized target and record its host identity.
show ip interface brief- At the R58 SSH prompt, record the target's address and interface state.
exit- Leave the router SSH session and return to the Control shell.
- What you should see
- Expect the R58 prompt and 192.0.2.58 on GigabitEthernet1, then the local shell.
- Why this step matters
- A known SSH identity and console comparison anchor the later automated output.
Execute the bounded Ansible read
In the Control VM console Terminal at the Linux shell, read the full one-host invocation before running it. Enter the password only when prompted. It uses network_cli and ios_command, not a generic shell module.
ansible -i '192.0.2.58,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'What each command means
ansible -i '192.0.2.58,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'- Use a one-host inline inventory, SSH password prompt, IOS network plugin, bounded connection/command timeouts and a single read command.
- What you should see
- Expect a task result containing actual show output; compare GigabitEthernet1 and .58 with the console baseline.
- Why this step matters
- The automation result is useful only when its device identity and returned content match the intended target.
Introduce a single inventory fault
In the Control VM console Terminal, run the same read invocation with only the inventory changed to unused .59. This two-node project has no device at that address; do not expand it into a scan.
ansible -i '192.0.2.59,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'What each command means
ansible -i '192.0.2.59,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'- Change only the target address to the documented unused lab address; connection should fail within the configured bounded attempts.
- What you should see
- Expect a connection or unreachable error, not router output. Record the actual classification and timing.
- Why this step matters
- The fault tests target selection without changing device state or relaxing authentication.
Restore the target and independently retest
In the Control VM console Terminal, restore .58 and repeat the original invocation. Then open R58's GNS3 console and compare show ip interface brief manually before reporting recovery.
ansible -i '192.0.2.58,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'What each command means
ansible -i '192.0.2.58,' all -c ansible.netcommon.network_cli -u learner -k -e ansible_network_os=cisco.ios.ios -e ansible_network_cli_ssh_type=paramiko -e ansible_connect_timeout=5 -e ansible_command_timeout=10 -m cisco.ios.ios_command -a '{"commands":["show ip interface brief"]}'- Restore the exact authorized one-host inventory and repeat the same read command.
- What you should see
- Expect the original target output again; require the independent R58 console comparison.
- Why this step matters
- Restoring inventory text is not enough; returned evidence must again correspond to the intended router.
Close the isolated exercise
In the Control VM console Terminal, preserve redacted observations, remove only its temporary lab address and the specific disposable host-key entry. Stop both nodes and restore the saved fresh project baseline to remove lab-only SSH credentials and keys.
sudo ip address del 192.0.2.10/24 dev ens3
ssh-keygen -R 192.0.2.58What each command means
sudo ip address del 192.0.2.10/24 dev ens3- Remove only the temporary address added by this exercise.
ssh-keygen -R 192.0.2.58- Remove only the known_hosts entry for this disposable router address after the exercise.
- What you should see
- Expect the temporary host setup removed. Stopping and restoring the saved project baseline removes the router's lab-only state.
- Why this step matters
- The cleanup scope is explicit; no shared inventory, Terraform state or production configuration is touched.
Verify
- Record actual Ansible, collection, Paramiko and IOS XE versions and the direct cable mapping.
- Confirm the SSH identity and preserve a direct-console baseline for the one target.
- Read returned Ansible stdout and match the exact interface address; do not rely only on task status.
- Capture the .59 connection fault, restore .58 and require both automated and direct-console retests.
- Keep Terraform labeled conceptual and all router runtime labeled unmeasured during authoring.
Troubleshoot
- If the host key changes unexpectedly, stop and verify the target; do not disable host-key checking globally.
- If the module is missing, verify the preinstalled collection and interpreter environment before reconnecting anything externally.
- If authentication fails, check the lab username, interactive password and SSH configuration via console; do not broaden the inventory.
- If show output is returned from an unexpected identity, stop even if the task is successful; correct the target and repeat verification.
GNS3 does not provide Cisco images. A license or entitlement must permit the image in the selected environment; do not share or redistribute image files. Cisco Modeling Labs is an official alternative. Its supplied Cisco reference images are licensed for use within CML, not automatically for export to GNS3. An unlicensed learner must use the explicitly labeled paper alternative, not report simulated Cisco execution.
- Remove only the control VM's temporary address and disposable known_hosts entry.
- Restore the stopped fresh-project baseline to remove the published lab-only account and generated keys.
- Retain redacted evidence, never distribute Cisco images, and do not create or modify Terraform state.
Practice set
Answer before you reveal
01What does the trailing inventory comma mean?
Here it contains one address. A broader inventory would change the task's reach even if the command stayed unchanged.
02Why use ios_command instead of a shell module?
A router CLI is not a normal Linux shell, and configuration-mode commands need a different appropriate module.
03Does agentless mean credential-free?
It means a persistent Ansible agent is not installed on the managed router; SSH identity and permissions still matter.
04What does Terraform state track?
It is important operational data, can contain secrets, and is not a substitute for the resources themselves.
05Does a plan apply infrastructure changes?
The environment can change afterward, and execution can fail; actual outcomes require separate verification.
06Why is reverting a definition not guaranteed rollback?
A later apply reconciles current reality under provider behavior; it cannot necessarily recover lost operational data.
Knowledge check
Quiz: prove the reasoning
Keep these
Technical takeaways
- Scope inventory before choosing modules or entering credentials.
- Use platform-aware modules and inspect returned content.
- Agentless access still needs authentication and host identity.
- Terraform plan, state and infrastructure are distinct objects.
- Idempotence and check modes are not automatic rollback.
- Versioned definitions require independent behavioral verification.
