Network Automation with Ansible for Absolute Beginners

This lab builds significantly on the first two sessions and introduces two techniques that will appear in almost every real-world Ansible playbook you write – Jinja2 templating to dynamically generate values from inventory hostnames, and vars_files with loop to iterate over a structured YAML data file and apply configuration to multiple interfaces across multiple devices in a single playbook run.

The scenario is realistic and grounded. Your manager has tasked you with providing basic IPv4 addressing across all router interfaces in preparation for more advanced configurations in later labs. You have two sets of devices to work with – four edge routers numbered R1 through R4, and four named routers covering Manchester, London, Asia and America. Each group requires a slightly different approach which is exactly why this lab covers both.

The lab works through five tasks in sequence.

The first task is creating or reusing a host file that covers all routers across both groups. Rather than rebuilding from scratch, you carry forward the host file structure from the previous labs and merge the two device groups together. This is a practical habit worth building early – in real environments you are maintaining and extending inventory files rather than creating new ones for every job.

The second task is writing a playbook to configure loopback zero on each of the four edge routers using the addressing schema 100.100.100.x/32 where x matches the router number. This is where Jinja2 templating comes in. Because the edge routers are named R1, R2, R3 and R4 there is a numeric value embedded in the hostname that you can extract and use directly in the IP address. We use the inventory_hostname variable combined with a Python-style string slice to strip the leading R and pass just the numeric portion into the ip address command. This avoids hardcoding four separate tasks and is the foundation of how Ansible scales to large device counts.

The third task is writing a verification playbook using the cisco.ios.ios_command module to run show interface description and show ip interface brief including up across all edge routers simultaneously. We cover how to register output to a named variable and display it using the debug module with msg and stdout_lines. We also cover why variable naming matters when you have multiple tasks registering output in the same playbook – using the same variable name across tasks causes each subsequent task to overwrite the previous output, which is a common mistake when starting out.

The fourth task introduces vars_files and loop, which is where the real power of Ansible for network configuration becomes clear. Rather than hardcoding interface names, IP addresses, subnet masks and descriptions directly in the playbook, all of that data lives in a separate YAML file – router_interfaces.yaml – structured as a list of dictionaries with keys for interface name, description, IP and mask. The playbook references this file using vars_files and then loops through it using loop with item to apply each entry to the correct device. We cover the when condition using is defined to ensure the playbook only attempts to apply IP addresses to interfaces that have them defined in the data file, avoiding failures on interfaces intentionally left unconfigured.

The playbook also demonstrates a real error mid-lab – the loop directive was added to the second task but accidentally omitted from the first, causing the playbook to fail on the first run. We work through reading the error output, identifying the missing loop statement and correcting the indentation before re-running successfully. Seeing a real failure and the fix for it is more useful than a lab that works perfectly first time.

The fifth task re-runs the verification playbook, this time targeting all devices rather than just the edge routers, confirming that interface descriptions, IP addresses and no-shutdown states have been applied correctly across the entire topology. We finish by jumping onto the CLI of one of the routers and running a ping across the data plane to confirm end-to-end connectivity.

By the end of this lab you will understand how to use Jinja2 templating with inventory_hostname to generate dynamic values, how to separate configuration data from playbook logic using vars_files, how to iterate over structured YAML data using loop and item, how to use when conditions with is defined to handle optional data safely, and how to name registered output variables correctly when working with multi-task playbooks.

All host files, variable files and playbooks from this lab are available on the GitHub repo lab 3 linked in the course resources.

Lab 03: Ansible IP Address Configuration and Loopbacks
Scroll to top