Skip to content

Porting Guide for Ansible AVD 4.x.x

Major releases of AVD can contain breaking changes. The porting guide addresses how to update your inventory and playbooks to be compatible with new default behaviors and changed data models when upgrading from AVD 3.x versions.

Users of eos_designs do not have to consider the changes in eos_cli_config_gen, since those adaptions are built into eos_designs.

Common changes

Data model changes from “dict-of-dicts” to “list-of-dicts”

In AVD 4.0.0 and across both eos_designs and eos_cli_config_gen, all “dict-of-dicts” data models with user-defined keys have been changed to “list-of-dicts”.

As an example, ethernet_interfaces has been changed from:

ethernet_intefaces:
  Ethernet1:   # <-- User defined key
    <...>

to:

ethernet_interfaces:
  - name: Ethernet1:   # <-- "name" here is called the "primary_key" which must have a unique value across all list elements
    <...>

The old data models are still supported, but support will be removed in AVD 5.0.0.

In AVD 4.x inputs will be auto-converted as part of the new built-in schema-based type conversion, but the variable files will not be changed.

It is recommended to update the input data to the new data models at a convenient time after upgrading to AVD 4.x. AVD can be configured to error on type conversions, so by running the regular playbook with ansible-playbook playbook.yml -e avd_data_conversion_mode=error -e avd_data_validation_mode=error the play will be stopped, and errors will be produced for each conversion. This can be used as a list of data models to update.

$ ansible-playbook playbook.yml -e avd_data_conversion_mode=error
<...>
ERROR! [dc1-leaf2a]: 'Data Type Converted: connected_endpoints_keys from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: local_users from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: node_type_keys from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: servers from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: tenants from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: tenants.[0].vrfs from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: tenants.[0].vrfs.[0].svis from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: tenants.[0].vrfs.[1].svis from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: tenants.[0].l2vlans from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: spine.nodes from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: l3leaf.node_groups from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: l3leaf.node_groups.[0].nodes from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: l3leaf.node_groups.[1].nodes from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: l2leaf.node_groups from 'dict' to 'list'
ERROR! [dc1-leaf2a]: 'Data Type Converted: l2leaf.node_groups.[0].nodes from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: connected_endpoints_keys from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: local_users from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: node_type_keys from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: spine.nodes from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: l3leaf.node_groups from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: l3leaf.node_groups.[0].nodes from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: l3leaf.node_groups.[1].nodes from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: l2leaf.node_groups from 'dict' to 'list'
ERROR! [dc1-spine1]: 'Data Type Converted: l2leaf.node_groups.[0].nodes from 'dict' to 'list'
<...>

When the list is empty the variables have been updated correctly. Notice that errors may be emitted at different stages of the play, so let it run to the end.

Changes to role arista.avd.eos_designs

Network services variables

  • Rename evpn_rd_type to overlay_rd_type
  • Rename evpn_rt_type to overlay_rt_type
  • Rename vxlan_vlan_aware_bundles to evpn_vlan_aware_bundles

Fabric variables

The default value for p2p_uplinks_mtu has changed from 9000 to 9214.

To retain the AVD 3.x behavior, set p2p_uplinks_mtu to 9000:

p2p_uplinks_mtu: 9000

MLAG variables

mlag_peer_link_allowed_vlans no longer has a default value of “2-4094”. The new default does not enforce specific allowed VLANs.

To retain the AVD 3.x behavior, set mlag_peer_link_allowed_vlans to “2-4094”:

l3leaf:
  defaults:
    mlag_peer_link_allowed_vlans: "2-4094"

BGP variables

bgp_default_ipv4_unicast

A new key, bgp_default_ipv4_unicast: <bool> -> default false, was introduced to implement the best practice of disabling the default activation of the IPv4 unicast address-family.

To change the default behavior, set the key to true:

bgp_default_ipv4_unicast: true

Warning

Configuration under the <node_type_key>.defaults.bgp_defaults should be removed to avoid duplicate entries in the configuration.

Example:

l3leaf:
  defaults:
    bgp_defaults:
      # - no bgp default ipv4-unicast <--- remove this item to avoid duplicates

Note

This will now explicitly activate or deactivate bgp_default_ipv4_unicast in the EOS configuration.

bgp_update_wait_install

With AVD version 4.0.0, the default configuration generated by eos_designs have update wait-install configured under router_bgp and BGP VRF definitions for VRFs containing BGP peers.

To change the default behavior, update the following variable to false:

bgp_update_wait_install: false

bgp_peer_groups

The following keys under bgp_peer_groups have been replaced to avoid upper-case variables:

See the full data model in the documentation

bgp_peer_groups:
  IPv4_UNDERLAY_PEERS:
  MLAG_IPv4_UNDERLAY_PEER:
  EVPN_OVERLAY_PEERS:
bgp_peer_groups:
  ipv4_underlay_peers:
  mlag_ipv4_underlay_peer:
  evpn_overlay_peers:

ISIS underlay variables

isis_default_circuit_type

isis_default_circuit_type default changed from level-1-2 (EOS default) to level-2.

To keep the EOS default ISIS circuit-type set:

isis_default_circuit_type: "level-1-2"

Note

This will now print isis circuit-type level-1-2 in the EOS configuration matching the EOS default ISIS circuit-type.

L3 edge variables

l3_edge.p2p_links.[].qos_profile

l3_edge.p2p_links.[].qos_profile default changed from null to now leverage p2p_uplinks_qos_profile as its default value.

To retain the AVD 3.x behavior, set l3_edge.p2p_links.[].qos_profile to null:

l3_edge:
  p2p_links:
    - qos_profile: null

l3_edge.p2p_links.[].include_in_underlay_protocol

l3_edge.p2p_links.[].include_in_underlay_protocol default changed from false to true.

To retain the AVD 3.x behavior set l3_edge.p2p_links.[].include_in_underlay_protocol to false:

l3_edge:
  p2p_links:
    - include_in_underlay_protocol: false

l3_edge.p2p_links.[].isis_circuit_type

l3_edge.p2p_links.[].isis_circuit_type -> default changed from level-1-2 (EOS default) set by isis_default_circuit_type to level-2.

To retain the AVD 3.x behavior, set l3_edge.p2p_links.[].isis_circuit_type to level-1-2:

l3_edge:
  p2p_links:
    - isis_circuit_type: "level-1-2"

Note

This will now print isis circuit-type level-1-2 in the EOS configuration matching the EOS default isis circuit-type.

l3_edge.p2p_links.[].isis_hello_padding

l3_edge.p2p_links.[].isis_hello_padding default changed from false to true (EOS default).

No changes are required to variables since this matches to EOS default configuration.

Note

This will now print isis hello padding in the EOS configuration matching the EOS default.

l3_edge.p2p_links.[].ptp_enable

l3_edge.p2p_links.[].ptp_enable changed to l3_edge.p2p_links.[].ptp.enabled to create syntax consistency when configuring PTP:

l3_edge:
  p2p_links:
    ptp_enable: true
l3_edge:
  p2p_links:
    ptp:
      enabled: true

l3_edge.p2p_links.[].ptp.enabled requires the ptp.enabled: true to be set at the fabric level.

Set the following variable at the fabric level:

ptp:
  enabled: true

Core interfaces variables

core_interfaces.p2p_links.[].ptp_enable

core_interfaces.p2p_links.[].ptp_enable changed to core_interfaces.p2p_links.[].ptp.enabled to create syntax consistency when configuring PTP:

core_interfaces:
  p2p_links:
    ptp_enable: true
core_interfaces:
  p2p_links:
    ptp:
      enabled: true

core_interfaces.p2p_links.[].ptp.enabled requires the ptp.enabled: true to be set at the fabric level.

Set the following variable at the fabric level:

ptp:
  enabled: true

Connected endpoints

The connected_endpoints_key.[].adapters.[].server_ports has been removed and replaced with connected_endpoints_key.[].adapters.[].endpoint_ports in order to be generic across endpoint types.

<connected_endpoints_keys.key>:
  - name: <str>
    adapters:
      - server_ports:
<connected_endpoints_keys.key>:
  - name: <str>
    adapters:
      - endpoint_ports:

IP and IPv6 routing is no longer configured on pure L2 devices

For node types like l2leaf where underlay_router is set to false under node_type_keys, AVD versions below 4.0.0 still rendered ip routing, ip routing ipv6 interfaces, or ipv6 unicast-routing in the configuration. As of AVD version 4.0.0, these IP and IPv6 routing configurations are no longer configured for l2leaf or other node types with underlay_router: false.

To retain the AVD 3.x behavior, the inventory can be updated like this:

l2leaf:
  defaults:
    always_configure_ip_routing: true

BGP is no longer configured on irrelevant nodes

An example of an “irrelevant node” is a pure L3 Spine in L3LS running ISIS or OSPF in the underlay. As long as the spine is not set as route-server for any overlay BGP protocol, there is no need for router bgp <asn> to be configured on this device.

Example of default configuration previously generated but now removed:

router bgp 65000
  router-id 192.168.255.2
  maximum-paths 4 ecmp 4

To retain the AVD 3.x behavior, the inventory can be updated like this:

spine:
  defaults:
    structured_config:
      router_bgp:
        as: '65000'
        router_id: 192.168.255.2
        maximum_paths:
          paths: 4
          ecmp: 4

Per Arista best practice, all SVIs configured with ipv6 address virtual should also have ipv6 enable configured, to use link-local IPv6 addresses for NDv6 operations.

With AVD version 4.0.0, this best practice is now implemented by default.

Example input:

tenants:
  - name: mytenant
    <...>
    vrfs:
      - name: myvrf
        <...>
        svis:
          - id: 123
            <...>
            ipv6_address_virtuals:
              - 2001:db8:12::1/64

Now renders:

interface Vlan123
  <...>
  ipv6 enable                  ! <-- New command
  ipv6 address virtual 2001:db8:12::1/64

To retain the AVD 3.x behavior, the inventory can be updated like this:

tenants:
  - name: mytenant
    <...>
    vrfs:
      - name: myvrf
        <...>
        svis:
          - id: 123
            <...>
            ipv6_address_virtuals:
              - 2001:db8:12::1/64
            ipv6_enable: false # <--- Overriding the new default behavior

In-band management for L2 switches

With AVD version 4.0.0, some of the default values for in-band management are changing:

  • The SVI MTU was derived from p2p_uplinks_mtu with a default value of 9000. Now the SVI MTU defaults to 1500 and is configurable with inband_mgmt_mtu.
  • The SVI description was hardcoded to L2LEAF_INBAND_MGMT. The default SVI description is Inband Management and is configurable with inband_mgmt_description.
  • The VLAN name was hardcoded to L2LEAF_INBAND_MGMT. The default VLAN name is INBAND_MGMT and is configurable with inband_mgmt_vlan_name.

See the following example of modifying the values to retain the previous default behavior.

Previous default configuration:

vlan 4092
  name L2LEAF_INBAND_MGMT

interface Vlan4092
  description L2LEAF_INBAND_MGMT
  mtu 9000
  <...>

New default configuration:

vlan 4092
  name INBAND_MGMT

interface Vlan4092
  description Inband Management
  mtu 1500
  <...>

To retain the AVD 3.x behavior, the inventory can be updated like this:

l2leaf:
  defaults:
    inband_mgmt_mtu: 9000
    inband_mgmt_vlan_name: L2LEAF_INBAND_MGMT
    inband_mgmt_description: L2LEAF_INBAND_MGMT

l3leaf:
  defaults:
    inband_mgmt_mtu: 9000
    inband_mgmt_vlan_name: L2LEAF_INBAND_MGMT
    inband_mgmt_description: L2LEAF_INBAND_MGMT

Changes to role arista.avd.eos_cli_config_gen

The change has been incorporated into eos_designs, so action is only required when defining new interfaces with structured_config, custom_structured_configuration_, or when using eos_cli_config_gen directly.

With AVD 4.0.0, port-channel member interfaces defined under ethernet_interfaces will no longer ignore the type setting, which defaults to switched. Other switchport or IP related features are also no longer ignored.

This may be the intended behavior for interfaces with LACP fallback, which is the reason for this change.

Example input:

ethernet_interfaces:
  - name: Ethernet2
    channel_group:
      id: 2
      mode: active
    mode: access    # <--- These are just examples of "other configurations"
    vlans: 123      # <--- that were previously ignored.

Previous output:

interface Ethernet2
   channel-group 2 mode active

AVD version 4.x output:

interface Ethernet2
   switchport
   switchport mode access
   switchport access vlan 123
   channel-group 2 mode active

To retain the AVD 3.x configuration, the interface definition must be updated like this:

ethernet_interfaces:
  - name: Ethernet2
    type: port-channel-member
    channel_group:
      id: 2
      mode: active

hardware_counters.features

The hardware_counters.features model has been improved to allow more options.

hardware_counters:
  features:
    - ip: in
    - ip: out
    - vlan-interfaces: in
hardware_counters:
  features:
    - name: ip
      direction: out
    - name: ip
      direction: in
    - name: vlan-interfaces
      direction: in

See the full data model in the documentation

ip_name_servers

The name_server key has been deprecated in favor of ip_name_servers, more aligned with the EOS CLI.

See the full data model in the documentation

name_server:
  source:
    vrf: MGMT
  nodes:
    - 8.8.8.8
ip_name_servers:
  - ip_address: 8.8.8.8
    vrf: MGMT

ip_igmp_snooping

Disabling IGMP Snooping globally no longer blocks other IGMP snooping configuration.

Example input:

ip_igmp_snooping:
  globally_enabled: false
  vlans:
    - id: 10
      enabled: true
    - id: 20
      enabled: false
    - id: 30
      enabled: false

Previous output:

no ip igmp snooping

AVD version 4.x output:

no ip igmp snooping
ip igmp snooping vlan 10
no ip igmp snooping vlan 20
no ip igmp snooping vlan 30

While EOS accepts the extra configuration, IGMP snooping is still effectively disabled. To remove the extra configuration, update the inputs like this:

ip_igmp_snooping:
  globally_enabled: false

queue_monitor_length

To avoid ambiguous YAML data input, the data model for queue_monitor_length has been updated to require the enabled key.

queue_monitor_length:
  <...>
queue_monitor_length:
  enabled: true
  <...>

The change has been incorporated into eos_designs, so action is only required when defining structured_configuration directly.

vlan_interfaces.[].ip_attached_host_route_export

To avoid ambiguous YAML data input, the data model for vlan_interfaces.[].ip_attached_host_route_export has been updated to require the enabled.

vlan_interfaces:
  Vlan86:
    ip_address: 10.10.83.1/24
    ip_attached_host_route_export: {}
vlan_interfaces:
  - name: Vlan86
    ip_address: 10.10.83.1/24
    ip_attached_host_route_export:
      enabled: true

The change has been incorporated into eos_designs so action is only required when defining structured_configuration directly.

New data model for BGP VRF address-families

An improved data model for address family configuration under router_bgp.vrfs has been added, containing discrete models for the different address-families including subkeys for bgp additional-paths configuration options.

router_bgp:
  vrfs:
    - name: VRF001
      address_families:
        ipv4:
          bgp:
            additional_paths:
              - send any
          neighbors:
            10.2.3.4:
              activate: true
              route_map_out: RM-10.2.3.4-SET-NEXT-HOP-OUT
          networks:
            "100.64.0.0/10":
              route_map: RM-10.2.3.4
          peer_groups:
            TEST_PEER_GRP:
              activate: true
              next_hop:
                address_family_ipv6_originate: true
        ipv6:
          ...
router_bgp:
  peer_groups:
    - name: TEST_PEER_GRP
      activate: true
      next_hop:
        address_family_ipv6:
          enabled: true
          originate: true
  vrfs:
    - name: VRF001
      address_family_ipv4:
        bgp:
          additional_paths:
            send:
              any: true
        neighbors:
          - ip_address: 10.2.3.4
            activate: true
            route_map_out: RM-10.2.3.4-SET-NEXT-HOP-OUT
        networks:
          - prefix: 100.64.0.0/10
            route_map: RM-10.2.3.4
      address_family_ipv6:
        ...

Note

The change has been incorporated into eos_designs, no action is necessary to retain the same functionality. If using structured_config or custom_structured_configuration_ to enable this feature, it is recommended to migrate to using the new data model.

Replacement data model for next_hop.address_family_ipv6_originate under router_bgp.address_family_ipv4.peer_groups

The data model to turn on ipv4 routing over ipv6 next-hops has been replaced with a new extended one, the old data model has been deprecated and will be removed in AVD version 5.0.0.

An example of the old data model:

router_bgp:
  address_family_ipv4:
    peer_groups:
      - name: EXAMPLE
        next_hop:
          address_family_ipv6_originate: < bool >

An example of the new data model:

router_bgp:
  address_family_ipv4:
    peer_groups:
      - name: EXAMPLE
        next_hop:
          address_family_ipv6:
            enabled: < bool >
            originate: < bool >

Note

The change has been incorporated into eos_designs, no action is necessary to retain the same functionality. If using structured_config or custom_structured_configuration_ to enable this feature, it is recommended to migrate to using the new data model.

Sanitized configuration

Starting in AVD 4.0.0, the eos_cli_config_gen role replaces sensitive values in the device documentation by the string <removed> by default, similar to the output of show run sanitized on EOS.

To retain the 3.x behavior, the inventory can be updated like this:

eos_cli_config_gen_documentation:
  hide_passwords: false # default true

Changes to role arista.avd.eos_config_deploy_cvp

Inventory to CloudVision containers

In AVD 4.0.0, the role arista.avd.eos_config_deploy_cvp gets support for dynamic Ansible inventories. This means the CloudVision containers’ basis will no longer be the inventory.yml file. Instead, the role reads the loaded Ansible inventory. This inventory can be loaded from dynamic inventory plugins like Ansible Automation Platform, AWX, etc.

The new inventory parsing is stricter than the previous method, so all Ansible inventory groups must be laid out as a regular tree structure starting from the container_root.

The 3.x behavior can be retained by adding the variable avd_inventory_to_container_file: "{{ inventory_file }}" to the playbook task for arista.avd.eos_config_deploy_cvp like this example:

- name: Configuration deployment with CVP
  hosts: cv_servers
  connection: local
  gather_facts: false
  collections:
    - arista.avd
  tasks:
    - name: Provision CVP
      import_role:
        name: eos_config_deploy_cvp
      vars:
        container_root: 'DC1_FABRIC'
        configlets_prefix: 'AVD'
        state: present
        avd_inventory_to_container_file: "{{ inventory_file }}"  # <--- Retain old behavior from AVD v3.x.x

Supported group structure

In this example, the container_root is set to DC1_FABRIC. This means the container root and all groups below will be created as containers on CloudVision. Devices can be members of multiple group hierarchies like DC1_FABRIC and DC1_TENANT_NETWORKS as long as the other hierarchies are not below the group set as container_root.

---
all:
  children:
    DC1:
      children:
        DC1_FABRIC:
          children:
            DC1_SPINES:
              hosts:
                DC1-SPINE1:
                DC1-SPINE2:
            DC1_L3LEAFS:
              children:
                DC1_LEAF1:
                  hosts:
                    DC1-LEAF1A:
                    DC1-LEAF1B:
                DC1_LEAF2:
                  hosts:
                    DC1-LEAF2A:
                    DC1-LEAF2B:
        DC1_TENANTS_NETWORKS:  # <--- This group is under DC1, but it is NOT under DC1_FABRIC, so this inventory is supported
          children:
            DC1_L3LEAFS:

Unsupported group structure

---
all:
  children:
    DC1:
      children:
        DC1_FABRIC:
          children:
            DC1_SPINES:
              hosts:
                DC1-SPINE1:
                DC1-SPINE2:
            DC1_L3LEAFS:
              children:
                DC1_LEAF1:
                  hosts:
                    DC1-LEAF1A:
                    DC1-LEAF1B:
                DC1_LEAF2:
                  hosts:
                    DC1-LEAF2A:
                    DC1-LEAF2B:
            DC1_TENANTS_NETWORKS:  # <--- This group is under DC1_FABRIC, making DC1_L3LEAFS have two "parents",
              children:            #      so this inventory is *not* supported with the new inventory parser
                DC1_L3LEAFS:

Roles cvp_configlet_upload and eos_config_deploy_cvp default to cv_collection: v3

The roles arista.avd.cvp_configlet_upload and arista.avd.eos_config_deploy_cvp leverage modules from the arista.cvp collection to perform actions on the CloudVision Platform. These modules are currently available in v1 and v3 variants, but v1 modules have been deprecated. They will be removed from the arista.cvp collection in version 4.0.0.

With AVD version 4.0.0, the default cv_collection is set to v3.

The v3 modules are mostly compatible with the v1 modules, with a few known gaps:

  • v3 lacks support for hostnames with dots like leaf1.dc2.
  • The implementation of v3 in eos_config_deploy_cvp is missing support for the absent option.

v1 modules can still be used by setting cv_collection: v1, as long as the arista.cvp collection is not upgraded to 4.0.0 or above.