First Steps
This guide walks you through configuring a Cisco IOS-XE device using Network as Code — starting from a single YAML file and a one-line Terraform module, then progressively introducing the IOS-XE-specific constructs that make it easy to scale to multi-device deployments.
Prerequisites:
- Terraform 1.9.0 or later
- Your preferred text editor / IDE (such as Visual Studio Code)
- IOS-XE device reachable from your workstation
-
Enable NETCONF on Devices
Section titled “Enable NETCONF on Devices”NETCONF must be enabled on each IOS-XE device before Terraform can communicate with it. Connect to each device and run:
config tnetconf-yangendEnsure the device management IP is reachable from the machine running Terraform.
-
Set Environment Variables
Section titled “Set Environment Variables”The IOS-XE provider authenticates using environment variables. Set the following in your terminal:
Terminal window export IOSXE_USERNAME=adminexport IOSXE_PASSWORD=password -
Create Your First Data File
Section titled “Create Your First Data File”In a new project directory, create a file named
inventory.nac.yamlwith the following content. Replace thehostwith your device’s management address:iosxe:devices:- name: SWITCH1host: 10.1.1.1configuration:system:hostname: SWITCH1mtu: 9198This file describes the desired state of a single device. The
configurationblock uses the same structure as the IOS-XE CLI, so you can describe any setting you would normally configure via the command line. -
Create the Terraform Configuration
Section titled “Create the Terraform Configuration”In the same directory, create a file named
main.tf:module "iosxe" {source = "netascode/nac-iosxe/iosxe"version = "0.1.0"yaml_files = ["inventory.nac.yaml"]}This is the only Terraform configuration required. The
nac-iosxemodule reads the YAML file and maps its contents to the underlying IOS-XE provider resources automatically. -
Initialize Terraform
Section titled “Initialize Terraform”Run the following command to download the provider and module:
Terminal window terraform init -
Apply the Configuration
Section titled “Apply the Configuration”Preview and apply your changes:
Terminal window terraform applyReview the plan and type
yesto confirm. Terraform pushes the configuration to the device via NETCONF.
Congratulations! You have configured your first IOS-XE device using Network as Code. The sections below show how to extend this foundation to multi-device deployments using global configuration, device groups, templates, and interface groups.
Going Further
Section titled “Going Further”Global Configuration
Section titled “Global Configuration”When managing multiple devices, it is common to have settings that apply to all of them — such as NTP servers or syslog destinations. Rather than repeating these in every device block, you can define them once under the global key.
Add a second device and move shared configuration to global:
iosxe: global: configuration: ntp: servers: - ip: 10.0.0.10
devices: - name: SWITCH1 host: 10.1.1.1 configuration: system: hostname: SWITCH1 mtu: 9198
- name: SWITCH2 host: 10.1.1.2 configuration: system: hostname: SWITCH2 mtu: 9198The IOS-XE module merges configuration at three levels — global → device group → device — with more specific levels taking precedence. NTP is now applied to both devices without duplication.
Device Groups
Section titled “Device Groups”Device groups let you apply a shared configuration block to a set of devices. This is useful for anything that is common to a role (e.g., all access switches share the same spanning-tree settings).
Add a device_groups section and reference the group from each device:
iosxe: global: configuration: ntp: servers: - ip: 10.0.0.10
device_groups: - name: SWITCHES configuration: spanning_tree: mode: rapid-pvst
devices: - name: SWITCH1 host: 10.1.1.1 device_groups: - SWITCHES configuration: system: hostname: SWITCH1 mtu: 9198
- name: SWITCH2 host: 10.1.1.2 device_groups: - SWITCHES configuration: system: hostname: SWITCH2 mtu: 9198Both devices now inherit the spanning_tree setting from the SWITCHES group. A device can belong to multiple groups, and each group is merged in order before the device-level configuration is applied.
Templates
Section titled “Templates”Templates allow you to define reusable configuration blocks that are rendered per device using variable substitution. This avoids writing nearly-identical YAML blocks for each device when only a few values differ.
The simplest template type is model — defined inline in your YAML. Add a loopback template that uses a per-device variable:
First, register the template in your YAML (you can add this to inventory.nac.yaml or a separate file):
iosxe: templates: - name: LOOPBACK type: model configuration: interfaces: loopbacks: - id: 0 ipv4: address: ${lo0_ip} address_mask: 255.255.255.255Then assign the template and provide the variable on each device:
iosxe: device_groups: - name: SWITCHES templates: - LOOPBACK configuration: spanning_tree: mode: rapid-pvst
devices: - name: SWITCH1 host: 10.1.1.1 device_groups: - SWITCHES variables: lo0_ip: 10.0.0.1
- name: SWITCH2 host: 10.1.1.2 device_groups: - SWITCHES variables: lo0_ip: 10.0.0.2When Terraform runs, the LOOPBACK template is rendered once per device, substituting ${lo0_ip} with the value from each device’s variables block. SWITCH1 gets 10.0.0.1 and SWITCH2 gets 10.0.0.2 as their loopback address.
Interface Groups
Section titled “Interface Groups”Interface groups define a named set of interface configuration that can be reused across multiple interfaces or devices. They are especially useful for enforcing consistent settings on a class of interface — for example, all loopbacks should have the same MTU and shutdown state.
Add an interface group and reference it from the loopback template:
iosxe: interface_groups: - name: LOOPBACK_INTERFACE configuration: mtu: 1500 shutdown: false
templates: - name: LOOPBACK type: model configuration: interfaces: loopbacks: - id: 0 interface_groups: [LOOPBACK_INTERFACE] ipv4: address: ${lo0_ip} address_mask: 255.255.255.255The interface_groups key on an interface is a list, so a single interface can inherit from multiple groups. Group configuration is merged before any inline interface configuration is applied.
You now have the full building blocks of a Network as Code IOS-XE deployment. Explore the IOS-XE Data Models section for the complete list of configurable attributes, and the VXLAN example repository for a production-scale reference implementation.