Learning the YAML syntax

In this section, you will learn how to write a YAML file with the correct syntax and best practices and tips for running a playbook on multiple remote machines. Ansible uses YAML because it is easier for humans to read and write than other common data formats, such as XML or JSON. There are no commas, curly braces, or tags to worry about, and the enforced indentation in the code ensures that it is tidy and easy on the eye. In addition, there are libraries available in most programming languages for working with YAML.

This reflects one of the core goals of Ansible—to produce easy-to-read (and write) code that described the target state of a given host. Ansible playbooks are (ideally) supposed to be self-documenting, as documentation is often an afterthought in busy technology environments—so, what better way to document than through the automation system responsible for deploying code?

Before we dive into YAML structure, a word on the files themselves. Files written in YAML can optionally begin with --- (as seen in the example playbook in the previous section) and end with .... This applies to all files in YAML, regardless of whether it is employed by Ansible or another system, and indicates that the file is in the YAML language. You will find that most examples of Ansible playbooks (as well as roles and other associated YAML files) start with --- but do not end with ...—the header is sufficient to clearly denote that the file uses the YAML format.

Let's explore the YAML language through the example playbook we created in the preceding section:

  1. Lists are an important construct in the YAML language—in fact, although it might not be obvious, the tasks: block of the playbook is actually a YAML list. A list in YAML lists all of its items at the same indentation level, with each line starting with -. For example, we updated the httpd package from the preceding playbook using the following code:
  - name: Update the latest of an Apache Web Server
yum:
name: httpd
state: latest

However, we could have specified a list of packages to be upgraded as follows:

  - name: Update the latest of an Apache Web Server
yum:
name:
- httpd
- mod_ssl
state: latest

Now, rather than passing a single value to the name: key, we pass a YAML-formatted list containing the names of two packages to be updated.

  1. Dictionaries are another important concept in YAML—they are represented by a key: value format, as we have already extensively seen, but all of the items in the dictionary are indented by one more level. This is easiest explained by an example, so consider the following code from our example playbook:
    service:
name: httpd
state: restarted

In this example (from handler), the service definition is actually a dictionary and both the name and state keys are indented with two more spaces than the service key. This higher level of indentation means that the name and state keys are associated with the service key, therefore, in this case, telling the service module which service to operate on (httpd) and what to do with it (restart it).

Already, we have observed in these two examples that you can produce quite complicated data structures by mixing lists and dictionaries. 

  1. As you become more advanced at playbook design (we will see examples of this later on in this book), you may very well start to produce quite complicated variable structures that you will put into their own separate files to keep your playbook code readable. The following is an example of a variables file that provides the details of two employees of a company:
---
employees:
- name: daniel
fullname: Daniel Oh
role: DevOps Evangelist
level: Expert
skills:
- Kubernetes
- Microservices
- Ansible
- Linux Container
- name: michael
fullname: Michael Smiths
role: Enterprise Architect
level: Advanced
skills:
- Cloud
- Middleware
- Windows
- Storage

In this example, you can see that we have a dictionary containing the details of each employee. The employees themselves are list items (you can spot this because the lines start with -) and equally, the employee skills are denoted as list items. You will notice the fullname, role, level, and skills keys are at the same indentation level as name but do not feature - before them. This tells you that they are in the dictionary with the list item itself, and so they represent the details of the employee. 

  1. YAML is very literal when it comes to parsing the language and a new line always represents a new line of code. What if you actually need to add a block of text (for example, to a variable)? In this case, you can use a literal block scalar, |, to write multiple lines and YAML will faithfully preserve the new lines, carriage returns, and all the whitespace that follows each line (note, however, that the indentation at the beginning of each line is part of the YAML syntax):
Specialty: |
Agile methodology
Cloud-native app development practices
Advanced enterprise DevOps practices

So, if we were to get Ansible to print the preceding contents to the screen, it would display as follows (note that the preceding two spaces have gone—they were interpreted correctly as part of the YAML language and not printed):

Agile methodology
Cloud-native app development practices
Advanced enterprise DevOps practices

Similar to the preceding is the folded block scalar, >, which does the same as the literal block scalar but does not preserve line endings. This is useful for very long strings that you want to print on a single line, but also want to wrap across multiple lines in your code for the purpose of readability. Take the following variation on our example:

Specialty: >
Agile methodology
Cloud-native app development practices
Advanced enterprise DevOps practices

Now, if we were to print this, we would see the following:

Agile methodologyCloud-native app development practicesAdvanced enterprise DevOps practices

We could add trailing spaces to the preceding example to stop the words from running into each other, but I have not done this here as I wanted to provide you with an easy-to-interpret example.

As you review playbooks, variable files, and so on, you will see these structures used over and over again. Although simple in definition, they are very important—a missed level of indentation or a missing - instance at the start of a list item can cause your entire playbook to fail to run. As we discovered, you can put all of these various constructs together. One additional example is provided in the following code block of a variables file for you to consider, which shows the various examples we have covered all in one place:

---
servers:
- frontend
- backend
- database
- cache
employees:
- name: daniel
fullname: Daniel Oh
role: DevOps Evangelist
level: Expert
skills:
- Kubernetes
- Microservices
- Ansible
- Linux Container
- name: michael
fullname: Michael Smiths
role: Enterprise Architect
level: Advanced
skills:
- Cloud
- Middleware
- Windows
- Storage
Speciality: |
Agile methodology
Cloud-native app development practices
Advanced enterprise DevOps practices

You can also express both dictionaries and lists in an abbreviated form, known as flow collections. The following example shows exactly the same data structure as our original employees variable file:

---
employees: [{"fullname": "Daniel Oh","level": "Expert","name": "daniel","role": "DevOps Evangelist","skills": ["Kubernetes","Microservices","Ansible","Linux Container"]},{"fullname": "Michael Smiths","level": "Advanced","name": "michael","role": "Enterprise Architect","skills":["Cloud","Middleware","Windows","Storage"]}]

Although this displays exactly the same data structure, you can see how difficult it is to read with the naked eye. Flow collections are not used extensively in YAML and I would not recommend you to make use of them yourself, but it is important to understand them in case you come across them. You will also notice that although we've started talking about variables in YAML, we haven't expressed any variable types. YAML tries to make assumptions about variable types based on the data they contain, so if you want assign 1.0 to a variable, YAML will assume it is a floating-point number. If you need to express it as a string (perhaps because it is a version number), you need to put quotation marks around it, which causes the YAML parser to interpret it as a string instead, such as in the following example:

version: "2.0"

This completes our look at the YAML language syntax. Now that's complete, in the next section, let's take a look at ways that you can organize your automation code to keep it manageable and tidy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.61.119