Cisco IOS-XE Provider
Objective
In this lesson you will learn how to use the Cisco IOS‑XE Terraform provider to manage device configuration declaratively. We will create a Terraform provider configuration, declare an iosxe_vlan resource to provision VLAN 511 on an IOS‑XE switch, read that VLAN back with a data resource, and finally remove the configuration with terraform destroy. This matters in production because Terraform provides a stateful, idempotent way to manage large numbers of devices: it checks the current device state via RESTCONF before making changes and can reliably remove or reconcile configuration across many devices.
Real‑world scenario: an enterprise is rolling out a standardized VLAN and needs to create the same VLAN on dozens of IOS‑XE switches. Using the IOS‑XE Terraform provider lets automation engineers declare the desired VLAN once and have Terraform ensure it is present (or removed) on each target device.
Quick Recap
Refer to the topology used in Lesson 1. No additional devices are required for this lesson — we will operate against the same management addresses.
ASCII Topology (management network — VLAN1):
[ c9k-spine ]---VLAN1 mgmt---[ c9k-leaf1 ]
IP: 198.18.1.21 IP: 198.18.1.31
user: developer user: developer
pass: Lab@123 pass: Lab@123
[ c9k-spine ]---VLAN1 mgmt---[ c9k-leaf2 ]
IP: 198.18.1.21 IP: 198.18.1.32
user: developer user: developer
pass: Lab@123 pass: Lab@123
Device Table
| Hostname | Role | Management IP | Username | Password |
|---|---|---|---|---|
| c9k-spine | Spine/SW | 198.18.1.21 | developer | Lab@123 |
| c9k-leaf1 | Leaf/SW | 198.18.1.31 | developer | Lab@123 |
| c9k-leaf2 | Leaf/SW | 198.18.1.32 | developer | Lab@123 |
Key Concepts (theory before hands‑on)
-
RESTCONF protocol & JSON payloads
Terraform’s Cisco IOS‑XE provider uses RESTCONF to talk to IOS‑XE. RESTCONF is an HTTP/HTTPS‑based API that carries YANG model data encoded as JSON (or XML). When Terraform creates or updates a resource it issues RESTCONF calls (HTTP methods such as GET, PATCH, POST as appropriate) containing JSON payloads to the device’s RESTCONF endpoint. -
Provider + Resource model (declarative, stateful)
Terraform operates by declaring providers and resources in HCL. The provider knows how to translate resource declarations into RESTCONF calls for the device. Terraform stores state locally (or remotely) and compares desired state vs. actual device state before applying changes — preventing blind overwrites. -
Idempotence & Execution Plan
terraform plan shows what Terraform will change. If the device already matches the declared resource, Terraform will perform no operation. This makes repeated runs safe — Terraform only acts when it detects drift. -
CLI -> Model mapping
Many IOS‑XE CLI constructs have corresponding YANG models exposed via RESTCONF. When you declare a VLAN resource in Terraform the provider translates that declaration into the correct RESTCONF payload to configure the VLAN on the device’s running configuration. -
Practical care: authentication and RESTCONF availability
RESTCONF must be reachable and credentials must be valid. In production, RESTCONF access is typically restricted to a management network and often secured with certificates or AAA; for labs we use username/password over HTTPS.
Tip: Think of Terraform as a librarian who keeps an exact copy of the inventory (state) and only adds or removes books (resources) to match the master list.
Step-by-step configuration
Step 1: Create the Terraform provider configuration
What we are doing: We declare the iosxe provider and set connection parameters (username, password, host URL). This tells Terraform which plugin to use and where to send RESTCONF requests. Using variables keeps credentials out of source files and allows reuse across devices.
terraform {
required_providers {
iosxe = {
source = "CiscoDevNet/iosxe"
version = ">=0.5.0"
}
}
}
provider "iosxe" {
username = var.device_username
password = var.device_password
url = var.host_url
}
What just happened: The terraform block instructs Terraform to load the iosxe provider plugin. The provider block supplies the runtime connection parameters. The provider will use RESTCONF over HTTPS to contact the device at var.host_url with the supplied credentials.
Real-world note: In production you will commonly use a remote state backend and secrets manager for credentials (avoid plaintext terraform.tfvars on disk).
Verify:
terraform init
Initializing provider plugins...
- Finding hashicorp/local versions matching "..."
- Installing provider "CiscoDevNet/iosxe"...
Terraform has been successfully initialized!
Explanation of verification: terraform init downloads and initializes the iosxe provider plugin. If the provider fails to initialize, Terraform cannot translate resources into device API calls.
Step 2: Declare the VLAN resource (desired state)
What we are doing: We declare an iosxe_vlan resource for VLAN 511 with the name "Vlan511" and ensure it is not shutdown. This is the desired configuration we want present on the device.
resource "iosxe_vlan" "example" {
vlan_id = 511
name = "Vlan511"
shutdown = false
}
What just happened: This HCL block defines a managed resource named iosxe_vlan.example. When applied, the iosxe provider will translate this into RESTCONF calls to create VLAN 511 and set its name and admin state on the targeted IOS‑XE device.
Real-world note: Using a VLAN numeric ID that is consistent across the fabric reduces mistakes during provisioning and troubleshooting.
Verify:
terraform plan
Refreshing Terraform state in-memory prior to plan...
data.iosxe_vlan.example: Refreshing state...
An execution plan has been generated and is shown below.
Plan: 1 to add, 0 to change, 0 to destroy.
+ resource "iosxe_vlan" "example" {
+ id = (known after apply)
+ name = "Vlan511"
+ shutdown = false
+ vlan_id = 511
}
Explanation of verification: terraform plan shows Terraform will add one resource (the VLAN). It also indicates what attributes will be created. If plan reports no changes, the device already matches the desired state.
Step 3: Apply the configuration to the device
What we are doing: We instruct Terraform to apply the planned change and create VLAN 511 on the device via RESTCONF.
terraform apply -auto-approve
awsome: Applying... (note: provider will execute RESTCONF calls)
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
What just happened: Terraform called the iosxe provider which performed RESTCONF transactions (likely HTTP POST or PATCH against the device’s VLAN YANG model) to create VLAN 511 and set its properties. Terraform then updated its local state to record that the resource exists on the device.
Real-world note: Apply is an irreversible convenience in production only when you are confident of the plan — most teams review output before applying.
Verify on the device (show running-config in RESTCONF JSON form):
show running-config | format restconf -json
{
"Cisco-IOS-XE-native:native": {
"vlan": {
"vlan-list": [
{
"id": 511,
"name": "Vlan511",
"state": "active"
}
]
}
}
}
Explanation of verification: The device’s running configuration formatted for RESTCONF/JSON shows VLAN 511 with name "Vlan511" and state active. This confirms the RESTCONF write succeeded and IOS‑XE is reflecting the configuration.
Step 4: Read back the VLAN with a data resource
What we are doing: We add a Terraform data source that queries the device for VLAN 511. Data resources allow Terraform to read live device state without asserting changes.
data "iosxe_vlan" "example" {
vlan_id = 511
}
What just happened: The data block instructs the iosxe provider to fetch VLAN 511 attributes from the device and make those values available within Terraform (for outputs or for use in other resources). This proves you can both write and read configuration via the provider.
Real-world note: Data resources are useful when you need to reference existing device attributes in a larger orchestration or templating workflow.
Verify:
terraform plan
Refreshing Terraform state in-memory prior to plan...
data.iosxe_vlan.example: Refreshing state...
No changes. Infrastructure is up-to-date.
Plan: 0 to add, 0 to change, 0 to destroy.
Explanation of verification: A plan that reports no changes confirms the data read succeeded and the declared resource is already present. If the data source cannot find the VLAN, Terraform will report an error during refresh.
Step 5: Remove the VLAN with terraform destroy
What we are doing: We remove the managed VLAN by destroying Terraform-managed resources, demonstrating clean teardown and the stateful delete behavior.
terraform destroy -auto-approve
Destroy complete! Resources: 1 destroyed.
What just happened: Terraform issued RESTCONF delete (or equivalent) calls to remove VLAN 511 from the device and updated its state to reflect the resource no longer exists. This demonstrates the ability to cleanly remove configuration managed by Terraform.
Real-world note: Destroy is powerful — in production you typically perform targeted deletes or remove resources from version control rather than issuing blanket destroy commands.
Verify on the device:
show running-config | format restconf -json
{
"Cisco-IOS-XE-native:native": {
"vlan": {
"vlan-list": []
}
}
}
Explanation of verification: The JSON shows an empty vlan-list, indicating VLAN 511 was removed from running-config.
Verification Checklist
-
Check 1: Provider initializes successfully
Verify withterraform initand confirm "Terraform has been successfully initialized!" -
Check 2: Terraform plans to add VLAN 511
Verify withterraform planshowing "Plan: 1 to add, 0 to change, 0 to destroy." -
Check 3: VLAN 511 appears in device running-config via RESTCONF JSON
Verify withshow running-config | format restconf -jsonand confirm VLAN 511 entry with name "Vlan511". -
Check 4: terraform destroy removes VLAN 511
Verify withterraform destroycompleting andshow running-config | format restconf -jsonshowing vlan-list empty.
Common Mistakes
| Symptom | Cause | Fix |
|---|---|---|
| terraform init fails with provider not found | required_providers block incorrectly specified or network access blocked | Check required_providers block for correct source string; ensure your workstation can reach Terraform registry (or preinstall provider plugin) |
| terraform plan shows authentication error | Incorrect username/password or HTTPS certificates rejected by device | Verify var.device_username and var.device_password values; confirm device accepts HTTPS + RESTCONF on management IP |
| terraform apply fails with RESTCONF 404/No model | RESTCONF not enabled or device model does not expose VLAN YANG | Confirm device RESTCONF service is reachable and the IOS‑XE build supports the VLAN YANG model |
| VLAN not present after apply | Device had conflicting config or resource applied to different device URL | Confirm provider url points to the intended device (var.host_url) and check device running-config with `show running-config |
Key Takeaways
- Terraform’s IOS‑XE provider uses RESTCONF with JSON to translate resource declarations into device configuration; it is stateful and idempotent — Terraform will only change what differs from the desired state.
- A provider block tells Terraform how to connect to the device (username, password, URL). Keep credentials secure and use remote state for production.
- Use terraform plan to validate changes, terraform apply to make them, and terraform destroy to remove managed resources cleanly.
- Data resources let you query device state without making changes; they’re useful for building dependent resources or validating existing configuration.
Final thought: In production networks, using the IOS‑XE Terraform provider reduces manual CLI drift and makes large-scale, repeatable configuration changes predictable and auditable — critical for consistent campus or data centre provisioning.