Ansible Network Resource Modules: Declarative Config - 夜莺博客

Ansible Network Resource Modules: Declarative Config

Old-style network automation sent a list of CLI commands and hoped for the best. Resource modules take the opposite approach: you describe the intended state of one resource — VLANs, interfaces, L2 or L3 configuration — and the module reads the device, computes the difference, and applies only that. The practical payoff is idempotence: run the same playbook twice and the second run reports no changes. This article covers the model, the state parameter that causes most surprises, and the workflow for adopting resource modules on a live network.

The resource module model

Each module manages exactly one resource type for one platform: arista.eos.eos_vlans, cisco.ios.ios_interfaces, cisco.iosxr.iosxr_l3_interfaces, and so on. Every module shares the same five states and the same fact-gathering counterpart.

Element Purpose
state: gathered Read the device and return structured data — no changes
state: rendered Produce the platform configuration for the supplied data, without touching the device
state: parsed Convert an existing configuration blob into structured data
state: merged Add or update only the given attributes, leaving everything else alone
state: replaced Make the listed resources match exactly — removes attributes not specified
state: overridden Make the entire resource section match — deletes resources not listed at all

The distinction between merged, replaced and overridden is where deployments break. merged is safe and additive; replaced will strip attributes you omitted; overridden will delete every VLAN, interface or prefix that is not in your task. Many teams standardise on merged for routine changes and use the stronger states only for a deliberate "this device must look exactly like this" build.

Start by gathering facts

- name: Collect current VLAN state
  hosts: access_switches
  gather_facts: false
  tasks:
    - name: Gather VLAN facts
      arista.eos.eos_facts:
        gather_subset:
          - config
      register: facts

    - name: Show structured VLANs
      ansible.builtin.debug:
        msg: "{{ facts.ansible_facts.ansible_network_resources.vlans }}"

Gathering first gives you a real baseline and, more importantly, the exact schema the module expects. Hand-written YAML that ignores the schema produces errors that read like punctuation problems rather than data-model problems.

Applying state with merge and replace

- name: Configure VLANs
  arista.eos.eos_vlans:
    config:
      - vlan_id: 10
        name: ten
      - vlan_id: 20
        name: twenty
        state: suspend
    state: merged

- name: Exactly this VLAN set, nothing else
  arista.eos.eos_vlans:
    config:
      - vlan_id: 40
        name: forty
    state: overridden

Note the module-level state: merged alongside the per-VLAN state: suspend: the first controls operation, the second describes the VLAN's administrative state on the device. Confusing the two is a common source of "why did my VLAN get suspended" tickets.

Idempotent verification

- name: Re-apply and assert no changes
  arista.eos.eos_vlans:
    config: "{{ intended_vlans }}"
    state: merged
  register: result

- name: Fail if the device is not converged
  ansible.builtin.assert:
    that: not result.changed
    fail_msg: "Configuration drift detected on {{ inventory_hostname }}"

That assertion is the point of the whole approach: a playbook that reports changed on a re-run means either somebody changed the device by hand or your intended state is incomplete. Run it on a schedule to detect drift, and run it after incident remediation to prove the device returned to the documented state.

Adoption path for a live network

  1. Run the fact-gathering module against a representative device from each platform and model.
  2. Save the structured output as the starting point for your intended state — do not type it from memory.
  3. Start with read-only tasks in check mode (--check --diff) to see what the module would change. Diversions between expectation and reality usually reveal that your source of truth is stale.
  4. Roll out merged operations first for additive changes, on one device, in one maintenance window.
  5. Only then consider overridden, and only for devices you own end to end.

Two operational notes. Resource modules require a persistent connection (network_cli or httpapi) and an inventory that describes each device's platform, so keep credentials in an encrypted vault rather than in the playbook. And keep the older command-based approach for the gaps: some features and some platforms have no resource module yet, and a mixed toolbox is normal — the wrapper patterns in Netmiko network automation cover those cases. When you are ready to run playbooks as a service rather than from a laptop, the structure in AWX job templates and workflows adds the audit trail and access control that change management will ask for, and pairing every run with the collection described in network configuration backup with Oxidized means you always have a rollback point.

原文链接:https://docs.ansible.com/projects/ansible/2.10/collections/arista/eos/eos_vlans_module.html