Skip to main content

YAML teoría y ejemplos + ejercicios resueltos

Introducción

Guía de lectura sobre YAML:

  1. YAML Syntax - Ansible Docs
  2. YAML - Wikipedia
  3. YAMLLint - YAML Syntax Checker

Teoría y ejemplos

For Ansible, nearly every YAML file starts with a list. Each item in the list is a list of key/value pairs, commonly called a “hash” or a “dictionary”.

All YAML files (regardless of their association with Ansible or not) can optionally begin with --- and end with .... This is part of the YAML format and indicates the start and end of a document.

---
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
...

A dictionary is represented in a simple key: value form (the colon must be followed by a space):

# An employee record
martin:
  name: Martin D'vloper
  job: Developer
  skill: Elite

More complicated data structures are possible, such as lists of dictionaries, dictionaries whose values are lists or a mix of both:

# Employee records
- martin:
    name: Martin D'vloper
    job: Developer
    skills:
      - python
      - perl
      - pascal
- tabitha:
    name: Tabitha Bitumen
    job: Developer
    skills:
      - lisp
      - fortran
      - erlang

Dictionaries and lists can also be represented in an abbreviated form if you really want to. These are called “Flow collections”:

---
martin: {name: Martin D'vloper, job: Developer, skill: Elite}
fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']

Ansible doesn’t really use these too much, but you can also specify a boolean value (true/false) in several forms. Use lowercase ‘true’ or ‘false’ for boolean values in dictionaries if you want to be compatible with default yamllint options:

create_key: true
needs_agent: false
knows_oop: True
likes_emacs: TRUE
uses_cvs: false

Values can span multiple lines using | or >. Spanning multiple lines using a “Literal Block Scalar” | will include the newlines and any trailing spaces. Using a “Folded Block Scalar” > will fold newlines to spaces; it’s used to make what would otherwise be a very long line easier to read and edit. In either case the indentation will be ignored. Examples are:

include_newlines: |
            exactly as you see
            will appear these three
            lines of poetry

fold_newlines: >
            this is really a
            single line of text
            despite appearances

While in the above > example all newlines are folded into spaces, there are two ways to enforce a newline to be kept:

fold_some_newlines: >
    a
    b

    c
    d
      e
    f

Alternatively, it can be enforced by including newline \n characters (this is exactly the same as the above):

fold_same_newlines: "a b\nc d\n  e\nf\n"

Let’s combine what we learned so far in an arbitrary YAML example. This really has nothing to do with Ansible, but will give you a feel for the format:

---
# An employee record
name: Martin D'vloper
job: Developer
skill: Elite
employed: True
foods:
  - Apple
  - Orange
  - Strawberry
  - Mango
languages:
  perl: Elite
  python: Elite
  pascal: Lame
education: |
  4 GCSEs
  3 A-Levels
  BSc in the Internet of Things

While you can put just about anything into an unquoted scalar, there are some exceptions. A colon followed by a space (or newline) ": " is an indicator for a mapping. A space followed by the pound sign " #" starts a comment. Because of this, the following is going to result in a YAML syntax error:

foo: somebody said I should put a colon here: so I did
windows_drive: c:
foo: "an escaped \' single quote"

…but this will work:

windows_path: c:\windows
foo: 'somebody said I should put a colon here: so I did'
windows_drive: 'c:'
foo: "somebody said I should put a colon here: so I did"
windows_drive: "c:"

The difference between single quotes and double quotes is that in double quotes you can use escapes:

foo: "a \t TAB and a \n NEWLINE"

Further, Ansible uses “{{ var }}” for variables. If your value starts with a quote the entire value must be quoted, not just part of it. If a value after a colon starts with a “{”, YAML will think it is a dictionary, so you must quote it, like so:

foo: "{{ variable }}"
foo: "{{ variable }}/additional/string/literal"
foo2: "{{ variable }}\\backslashes\\are\\also\\special\\characters"
foo3: "even if it's just a string literal it must all be quoted"

Ejercicios

  1. Given a dictionary with the property property1 and value value1. Add an additional property property2 and value value2.

    property1: value1

    Solución:

    property1: value1
    property2: value2
  2. Given a dictionary with the property name and value apple. Add additional properties to the dictionary.

    Key/Property Value
    name apple
    color red
    weight 90g

    name: apple

    Solución:

    name: apple
    color: red
    weight: 90g
  3. A dictionary employee is given. Add the remaining properties to it using information from the table below.

    Key/Property Value
    name john
    gender male
    age 24

    employee:
        name: john

    Solución:

    employee:
        name: john
        gender: male
        age: 24
  4. Now try adding the address information. Note the address is a dictionary

    Key/Property Value
    name john
    gender male
    age 24
    address
    Key/Property Value
    city edison
    state new jersey
    country united states

    employee:
        name: john
        gender: male
        age: 24

    Solución:

    employee:
        name: john
        gender: male
        age: 24
        address:
            city: edison
            state: 'new jersey'
            country: 'united states'
  5. We would like to add additional details for each item, such as color, weight etc. We have updated the first one for you. Similarly modify the remaining items to match the below data.

    Fruit Color Weight
    apple red 100g
    apple red 90g
    mango yellow 150g

    -
        name: apple
        color: red
        weight: 100g
    - apple
    - mango
    

    Solución:

    -
        name: apple
        color: red
        weight: 100g
    -
        name: apple
        color: red
        weight: 90g
    -
        name: mango
        color: yellow
        weight: 150g
    
  6. We would like to record information about multiple employees. Convert the dictionary employee to an array employees.

    employee:
        name: john
        gender: male
        age: 24

    Solución:

    employees:
        -
            name: john
            gender: male
            age: 24
  7. Add an additional employee to the list using the below information.

    Key/Property Value
    name sarah
    gender female
    age 28
    employees:
        -
            name: john
            gender: male
            age: 24

    Solución:

    employees:
        -
            name: john
            gender: male
            age: 24
        -
            name: sarah
            gender: female
            age: 28
  8. Now try adding the pay information. Remember while address is a dictionary, payslips is an array of month and amount

    Key/Property Value
    name john
    gender male
    age 24
    address ...
    payslips
    # month amount
    1 june 1400
    2 july 2400
    3 august 3400
    employee:
        name: john
        gender: male
        age: 24
        address:
            city: edison
            state: 'new jersey'
            country: 'united states'

    Solución:

    employee:
        name: john
        gender: male
        age: 24
        address:
            city: edison
            state: 'new jersey'
            country: 'united states'
        payslips:
            -
                month: june
                amount: 1400
            -
                month: july
                amount: 2400
            -
                month: august
                amount: 3400