Skip to content

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 Jinja2 file available in a aristanetworks/ansible-avd repository.

Python code style

As AVD is an Ansible collection, we’re required to follow guidelines from the official 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’s 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’s 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

    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. This test also does a deep test and doesn’t require a test at an 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 values 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: August 10, 2022