Topics
This section explores how and when aggregate resources can be used within Ansible networking.
This document is part of a collection on networking. The complete list of guides can be found at :ref:`network guides <guide_networking>`.
Consider the case if you wanted to ensure a set of vlans are present on a switch. Although at a high level this sounds like a simple request, there in a slight nuance:
- If the vlans are to be in addition to the existing configuration, they are considered additive vlans.
- If the vlans are the only ones to exist, they are considered aggregate vlans.
.. versionadded:: 2.4
The aggregate:
option has been added in Ansible 2.4 and is available in certain modules. See the modules documentation to see if the feature is available.
Continuing our vlan example, the following task ensures that vlans 1
, 2
and 3
are in the states specified in the task, in addition to any existing vlans.
This task will not change any vlans already configured on the switch, apart from the ones specified in the task. Ansible will ensure that the vlans specified in the task exist with the name and state specified.
Bad
- name: configure vlans neighbor in addition to existing
net_vlan:
vlan_id: “{{ item.vlan_id }}”
name: “{{ item.name }}”
state: “{{ item.state | default(‘active’) }}”
with_items:
- { vlan_id: 1, name: default }
- { vlan_id: 2, name: mgmt }
- { vlan_id: 3, state: suspend }
The above task is executed 3 times (once per item
). This is very inefficient and will take a considerable amount of time to execute because a seperate connection is made to the network device for each item
.
Better format
The preceding example would be better written as follows:
- name: configure vlans
net_vlan:
aggregate:
- { vlan_id: 1, name: default }
- { vlan_id: 2, name: mgmt }
- { vlan_id: 3, state: suspend }
state: active
This task is very similar to the additive resource example above, with the following differences:
- The module (
net_vlan
) is executed only once, rather than n times as it doeswith_items
. - There is no way to to use
purge
onwith_items
. See the aggregate resources section for more information. - It is easier to write a cleaner task.
Consider the following example:
- name: configure vlans neighbor (delete others)
net_vlan:
aggregate:
- { vlan_id: 1, name: default }
- { vlan_id: 2, name: mgmt }
- { vlan_id: 3, state: suspend }
state: active
purge: true # Important
The state:
is "local overrides of global module values", see FIXMELINK: Local overrides of global module values.
- The
purge:
option (which defaults to no) ensures that only the specified entries are present. All other entries will be deleted.
Warning
Why does purge
default to no
?
To prevent accidental deletion, purge
is always set to no
. This requires that playbook writers explicitly add purge: true
to enable this to opt-in to potentially dangerious behaviour.
- Ansible to execute your "single source of truth" (execute here means we can talk to source of truth, e.g. CMS or external data source)
- Ansible is your "Source of Truth"
The additive format can be useful in a number of cases:
- When Ansible isn't executing your Single Source of truth; and therefore doesn't ...
- Allows you to start using Ansible to configure just one part of your network
- FIXME
When writing tasks using aggregate
you may find yourself repeating various settings within the aggregate dictionary. For example:
- name: Reserve mgmt vlans
net_vlan:
aggregate:
- { vlan_id: 4, name: reserved_vlan, state: active }
- { vlan_id: 5, name: mgmt, state: active }
- { vlan_id: 6, name: reserved_vlan , state: active}
name: reserved_vlan
state: active # override
In the above example we can see that state: active
is set for all vlans, and most have name: reserved_vlan
. We can simplify this to:
- name: Reserve mgmt vlans
net_vlan:
aggregate:
- { vlan_id: 4 }
- { vlan_id: 5, name: mgmt }
- { vlan_id: 6 }
name: reserved_vlan # override
state: active # override
Note that:
- Shorter task
- The special cases,
name: mgmt
, stand out a lot more, increasing readability - This can be very powerful when a module uses take a lot of options, most of which are common, such as
net_interfaces
ornxos_bgp_neighbor_af
FIXME: Become realy power on net_interfaces
, mtu, admin_state, description
The following need discussing further
- Should we warn if purge & not aggregate
- Do we want to add
required_if = [('purge', 'true', ['aggregate'])]
- Maybe no, as we may want to factory reset a all vlans
- Add tests for this
- Do we want to add
- Does the order matter for access controll list?
- Link to Aggreate declaritive intent
- Docs marker for "Reference ID"