Skip to content

Welcome to YAML

What is YAML?

YAML is what's officially referred to as a data serialization language. While that sounds complex, data serialization is the process of converting objects within a data model into a byte stream for the purpose of storing or transferring it. Breaking this down, we know when trying to automate configuration management or deployment, we need to specify what we want to configure, that is, what our desired end-state configuration should look like. ( intent based networking )

An important note is about why we are talking about and using YAML in the first place. As mentioned in the beginning, YAML is a data serialization language, however, it is not the only one. Some other common, data serialization languages are XML, JSON, and CSV. The reason we are particular towards YAML is that not only are there libraries available in most programming languages, but also because as the following table shows, it is very human readable.

XML JSON YAML
<ntp>
  <local_interface>
    <name>Management1</name>
    <vrf>mgmt</vrf>
  </local_interface>
  <servers>
    <name>time-a-g.nist.gov</name>
    <preferred>true</preferred>
    <vrf>mgmt</vrf>
  </servers>
  <servers>
    <name>utcnist.colorado.edu</name>
    <vrf>mgmt</vrf>
  </servers>
</ntp>
{
  "ntp": {
    "local_interface": {
      "name": "Management1",
      "vrf": "mgmt"
    },
    "servers": [
      {
        "name": "time-a-g.nist.gov",
        "preferred": true,
        "vrf": "mgmt"
      },
      {
        "name": "utcnist.colorado.edu",
        "vrf": "mgmt"
      }
    ]
  }
}
---
ntp:
  local_interface:
    name: Management1
    vrf: mgmt
  servers:
    - name: time-a-g.nist.gov
      preferred: true
      vrf: mgmt
    - name: utcnist.colorado.edu
      vrf: mgmt

Common YAML Syntax

Now that we know the idea of what YAML is and what it's used for, we can cover the various constructs within a YAML file, and how to use those expressions to create files that are useful to us as engineers trying to manage configurations.

Comments

Comments are an important part of any documentation or configuration you are doing. When creating or modifying any network configurations, while you may not realize it, you are commenting on something important. When configuring an interface, you may add a description, such as the name of a downstream device or server it's connected to. Or, if it's a provider handoff, you may add the NOC telephone number and the circuit ID. If you are configuring BGP peers, you may add a description to each peer so it's clear what the neighbor is.

In YAML, you can enter comments anywhere you'd like, and ideally, where it makes sense to help explain what your data model is representing. Comments in YAML are represented with the pound symbol (as shown below).

---
# This is my YAML vars file for global configuration settings.
some config:  here

# Management Interface Configuration
mgmt_gateway: 192.168.0.1
mgmt_interface: Management0
Tip

✍ In VS Code, you can auto-comment any text you want by selecting the text and pressing windows Ctrl + / or mac Cmd + /.

Mappings

The first and basic YAML construct is a mapping, which comprises what is technically called a scalar. This will probably be the only time you ever hear or reference the word scalar.

---
# These are some examples of scalars

integer: 10
boolean: true
string: "Welcome to the Automation Workshop"

In normal day-to-day use, you will see scalars referred to as key-value pair mappings, or just mappings for short. A mapping is the data label (key), followed by its value, separated by a : colon.

Here are some network configuration specific mappings:

---
# Network Config Mappings

mgmt_interface: Management1
mgmt_interface_vrf: MGMT

Boolean

Another type of mapping in YAML is booleans. Booleans are true or false values assigned to their data labels. While the actual true or false does not have to be in a certain case, if you want the value to be compatible with lint options, you should use all lowercase.

Here are some network configuration boolean mappings.

---
# Network Config Mappings

evpn_gateway:
        evpn_l2:
          enabled: true

mlag: false

Lists

Lists, sometimes called sequences, are similar to arrays in development. A list has a top-level label, or what I like to refer to as a key, representing the list's elements (The key nomenclature will come in handy when thinking through loops in Jinja templates). In a standard list, you will have singular entries below the top-level label.

Here are some examples of lists:

---
# Some lists of BGP specific configurations

bgp-peers:
    - 192.168.103.1
    - 192.168.103.3
    - 192.168.103.5

bgp_defaults:
    - 'distance bgp 20 200 200'
    - 'neighbor default send-community'

Dictionary

While we just covered lists, which allow you to specify an item that falls inline below a parent label or key, what happens when you want to include more specific attributes to that parent label, or if you want to introduce more details such as key-value pair mappings to your list? In that occasion, what is used, and what you will see regularly in just about every network variables file, is a dictionary. As previously described, a dictionary is a list of key-value mappings.

Here is an example of a dictionary:

---
l3spine:
  defaults:
    spanning_tree_mode: rapid-pvst
    spanning_tree_priority: 4096
    mlag_interfaces: [Ethernet53, Ethernet54]

Nested Data Structures

One of the double-edged parts of YAML is that it can be quite complex. This is good because it is very flexible for building our data model, but it also means the model can get out of control. YAML syntax is hierarchical, and at the same time, just about every construct we covered before this can be nested within each other. Let's take a look at some nested data structures that illustrate this.

In this first example we will have a nested dictionary:

Reminder

✍ Indentation is key.

---
# local users

local_users:
  admin:
    privilege: 15
    role: network-admin
    sha512_password: encrypted_pass
  noc:
    privilege: 1
    role: network-operator
    sha512_password: encrypted_pass

The following example will show another network device specific nested data structure which mixes dictionaries and lists in different places:

---
ntp:
  local_interface:
    name: Management1
    vrf: MGMT
  servers:
    - name: 0.north-america.pool.ntp.org
      preferred: true
      vrf: MGMT
    - name: 1.north-america.pool.ntp.org
      vrf: MGMT
    - name: 2.north-america.pool.ntp.org
      vrf: MGMT

svis:
  10:
    name: 'DATA'
    ip_virtual_router_addresses:
      - 10.10.10.1
    mtu: 9214
    nodes:
      SW-CORE-A:
        ip_address: 10.10.10.2/23
      SW-CORE-B:
        ip_address: 10.10.10.3/23

Now that we have covered the most common YAML constructs, lets get into the lab and build some of our own data models we can use to render device configurations.

Onto the YAML Lab

Continue to the YAML Lab