Lesson 2 of 6

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

HostnameRoleManagement IPUsernamePassword
c9k-spineSpine/SW198.18.1.21developerLab@123
c9k-leaf1Leaf/SW198.18.1.31developerLab@123
c9k-leaf2Leaf/SW198.18.1.32developerLab@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 with terraform init and confirm "Terraform has been successfully initialized!"

  • Check 2: Terraform plans to add VLAN 511
    Verify with terraform plan showing "Plan: 1 to add, 0 to change, 0 to destroy."

  • Check 3: VLAN 511 appears in device running-config via RESTCONF JSON
    Verify with show running-config | format restconf -json and confirm VLAN 511 entry with name "Vlan511".

  • Check 4: terraform destroy removes VLAN 511
    Verify with terraform destroy completing and show running-config | format restconf -json showing vlan-list empty.


Common Mistakes

SymptomCauseFix
terraform init fails with provider not foundrequired_providers block incorrectly specified or network access blockedCheck required_providers block for correct source string; ensure your workstation can reach Terraform registry (or preinstall provider plugin)
terraform plan shows authentication errorIncorrect username/password or HTTPS certificates rejected by deviceVerify var.device_username and var.device_password values; confirm device accepts HTTPS + RESTCONF on management IP
terraform apply fails with RESTCONF 404/No modelRESTCONF not enabled or device model does not expose VLAN YANGConfirm device RESTCONF service is reachable and the IOS‑XE build supports the VLAN YANG model
VLAN not present after applyDevice had conflicting config or resource applied to different device URLConfirm 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.