Skip to content

Code Style

AVD Coding style

This page provides a list of guidelines to apply when developing Jinja2 template in 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 next rules:

  • All J2 statements must be enclosed by 1 space
  • All J2 statements must be indented by 4 more spaces within jinja delimiter
  • To close a control, end tag must have same indentation level
  • Indentation are 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 single line
  • Description

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

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

Description

To test if a variable is part of a list, 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 ['ibgp', 'isis', 'ospf'] %}
SYNTAX-6 - Render long CLI
  • Description

When a long CLI with multiple options needs to be built, use a 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 variable is multi-words, underscore _ shall be used as a separator.

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

For 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 ~ symbol should be used for string concatenation as it automatically converts variables to a string.

Example

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

Description

To test 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 content of a variable, it is recommended to use ==/!= keywords

Example

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

{# Test if variable is not a string #}
{% if ethernet_interface != 'Ethernet1' %}

Info

Also PLUGIN-2 can do test if variable is defined and has 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 ['ibgp', 'isis', 'ospf'] %}

AVD Plugins usage

Plugins documentation is available here

PLUGIN-1 - Test if a variable exists
  • Description

All tests to check if 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 arita.avd.defined %}

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

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

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

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

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

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

Last update: June 7, 2021