Skip to content

Code Style

AVD Coding style

This page provides a list of guidelines to apply when developing the Jinja2 template in the AVD context. These rules apply for either creation or update of any J2 file available in aristanetworks/ansible-avd repository.

Python code style

As AVD is an Ansible collection, we are required to follow guidelines from ansible documentation for all Python code.

YAML Syntax guidelines

SYNTAX-1 - Use variable in Jinja
  • Description

A single space shall be added between Jinja2 curly brackets and a variable’s name

  • Example
{{ ethernet_interface }}
SYNTAX-2 - Filter syntax
  • Description

When variables are used in combination with a filter, | shall be enclosed by space

  • Example
{{ my_value | to_json }}
SYNTAX-3 - Indentation for statement blocks
  • Description

Nested jinja code block shall follow the next rules:

  • All J2 statements must be enclosed by 1 space
  • All J2 statements must be indented by 4 more spaces within the jinja delimiter
  • To close a control, the end tag must have the same indentation level as the opening tag
  • Indentation must be 4 spaces and NOT tabulation
  • Example
{# Initial block indentation #}
{% if my_variable is arista.avd.defined %}

{# Nested block indentation #}
{% for ethernet_interface in ethernet_interfaces %}
{%     if ethernet_interface.name is arista.avd.defined %}
{%         set result = ethernet_interface.name %}
{# ..... output truncated ..... #}
{%     endif %}
{% endfor %}
SYNTAX-4 - Expand list on a single line
  • Description

Instead of doing a for loop on a single line, the join filter should be leveraged as much as possible

  • Example
{{ ciphers | join(", ") }}
SYNTAX-5 - Test if a variable in a list

Description

To test if a variable is part of a list, the in operator should be used as much as possible to avoid long if/elif/else block.

Example

{% if underlay_routing_protocol is arista.avd.defined and underlay_routing_protocol in ['isis', 'ospf'] %}
SYNTAX-6 - Render long CLI
  • Description

When a long CLI with multiple options needs to be built, use pure J2 logic and then print

  • Example
{% for ip_helper in vlan_interfaces[vlan_interface].ip_helpers | arista.avd.natural_sort %}
{%     set ip_helper_cli = "ip helper-address " ~ ip_helper %}
{%     if vlan_interfaces[vlan_interface].ip_helpers[ip_helper].vrf is arista.avd.defined %}
{%         set ip_helper_cli = ip_helper_cli ~ " vrf " ~ vlan_interfaces[vlan_interface].ip_helpers[ip_helper].vrf %}
{%     endif %}
{%     if vlan_interfaces[vlan_interface].ip_helpers[ip_helper].source_interface is arista.avd.defined %}
{%         set ip_helper_cli = ip_helper_cli ~ " source-interface " ~ vlan_interfaces[vlan_interface].ip_helpers[ip_helper].source_interface %}
{%     endif %}
   {{ ip_helper_cli }}
{% endfor %}

YAML Variable definition

VAR-1 - Variable name case
  • Description

All variables shall use lower case

  • Example
{{ variable }}
VAR-2 - Variable name format
  • Description

If a variable is multi-words, underscore _ shall be used as a separator.

  • Example
{{ my_variable_name }}
VAR-3 - Iterable Variables
  • Description

For an iterable variable, the plural form shall be used

  • Example
{{ ethernet_interfaces }}
VAR-4 - Variables in a For Loop
  • Description

For variables in a for loop, the singular form shall be used

  • Example
{{ ethernet_interfaces[ethernet_interface] }}
VAR-5 - Variables concatenation

Description

Tilde ~ should be used for string concatenation as it automatically converts variables to a string.

Example

{% set ip_helper_cli = ip_helper_cli ~ " source-interface " ~ vlan_interfaces[vlan_interface].ip_helpers[ip_helper].source_interface %}
VAR-6 - Variable type comparison

Description

To test the type of a variable, it is recommended to use is/is not keywords

Example

{# Test if variable is string #}
{% if ethernet_interface is string %}

{# Test if variable is not a string #}
{% if ethernet_interface is not string %}
VAR-7 - Variable content comparison

Description

To test the content of a variable, it is recommended to use ==/!= keywords

Example

{# Test if variable is equal to 'Ethernet1' #}
{% if ethernet_interface == 'Ethernet1' %}

{# Test if variable is not equal to 'Ethernet1' #}
{% if ethernet_interface != 'Ethernet1' %}

Info

Also PLUGIN-2 can do a test if the variable is defined and has a specific value

VAR-8 - String comparison

Description

All strings should be compared based on lowercase format.

Example

{% if underlay_routing_protocol is arista.avd.defined and underlay_routing_protocol | lower in ['isis', 'ospf'] %}

AVD Plugins usage

Plugins documentation is available here

PLUGIN-1 - Test if a variable exists
  • Description

All tests to check if a variable is defined shall be done with arista.avd.defined. Test also does a deep test and does not require to do test at upper level.

  • Example
{# Simple test #}
{% if ethernet_interfaces is arista.avd.defined %}

{# Deep test #}
{% if router_bgp.vrfs[vrf].rd is arista.avd.defined %}
PLUGIN-2 - Test if variable exists with a given value
  • Description

To test if a variable is defined and has a specific value, the test arista.avd.defined shall be used

  • Example
{% if vlan.name is arista.avd.defined('test') %}
PLUGIN-3 - Default value
  • Description

If a default value must be used, the arista.avd.default plugin shall be used instead of a if/else block. The plugin can be used to fallback to different value(s) until one of them is defined and valid

  • Example
{# Simple default test with one default value #}
{{ vlan.name | arista.avd.default('test_vlan') }}

{# Default test with a list of default options #}
{{ vlan.name | arista.avd.default(default.vlan.name, 'test_vlan') }}

Last update: May 5, 2022
Back to top