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 |
---|---|---|
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:
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.
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.