Yaml

Except for ansible.cfg which is an .ini file, all ansible files are in yaml, so let's spent some time on YAML.

At the end of inventories chapter we showed how to use yaml to define list and maps variables.

In this chapter we'll go a bit further.

Goals

  • what's yaml
  • parsing and dumping yaml with python
  • strings: quotes and multi-line

See also


In [ ]:
cd /notebooks/exercise-08/

What's yaml?


In [ ]:
import yaml

txt = """
{ "yaml": 'is', 'a superset': 'of json'}
"""
ret = yaml.load(txt)
print(ret)

In [ ]:
# Yoda loves dictionaries ;)
print(yaml.dump(ret))

In [ ]:
# Customized dumper
print(yaml.dump(ret, default_flow_style=False))

In [ ]:
txt = """
# Yaml comments starts with hash
you: {'can':'use', 'brace':'syntax'}
"""

ret = yaml.load(txt)
print(yaml.dump(ret))

In [ ]:
print(yaml.dump(ret, default_flow_style=False))

In [ ]:
# Yaml can describe list..
print(yaml.load("""
- tasks:
  - contains 
  - a
  - list
  - of
  - modules
"""))

In [ ]:
# .. and maps / dicts
print(yaml.load("""
- tasks:
  - name: "this dict has two keys: name and debug"
    debug: msg="Welcome to Rimini!"
"""))

Quoting

Yaml rocks respect to json at managing texts, but watch out:

  • colon : is a special character for yaml: it denotes key names
  • single { are special charactes too: yaml is a subset of json

Moreover, as we're using Ansible

  • ansible expands moustaches {{ content }} as variable

In [ ]:
print(yaml.load("""
this_works: http://no-spaces-after-colon:8080
"""))

In [ ]:
print(yaml.load("""this_no: spaces: after colon"""))

In [ ]:
# Quoting is important!
print(yaml.load("""
that: "works: though"
"""))

In [ ]:
# This is fine 
print(yaml.load("""
this_is: fine={{in_yaml}} but
"""))

# but with ansible you should
print(yaml.load("""
always: quote="{{moustaches}}"
"""))

Long texts

Long texts are easy and clean as long as you use > and | instead of quoting .


In [ ]:
text = """

one_line: "Rimini is also tied with the great cinema, since it is representative of Federico Fellini's world of fantasy."

trimmed_one_line: >-
  Rimini is also tied with the great cinema,
  since it is representative of Federico Fellini's
  world of fantasy.

always_one_line: >
  Rimini is also tied with the great cinema,
  since it is representative of Federico Fellini's
  world of fantasy.
  
"""
ret = yaml.load(text)

assert ret['one_line'] == ret['trimmed_one_line'] == ret['always_one_line']

Or write a multi_line string with proper carets


In [ ]:
text = """

multi: "Rimini, or the ancient Ariminum, 
is an art heritage city with over 22 centuries of history.

In 268 B.C., the Roman Senate sent six thousand settlers 
who founded the city that was meant to be strategically central 
and to develop to this day."

# Comments are ignored from parser.

preserves: |
  Rimini, or the ancient Ariminum, 
  is an art heritage city with over 22 centuries of history. 
  
  In 268 B.C., the Roman Senate nsent six thousand settlers 
  who founded the city that was meant to be strategically central 
  and to develop to this day.

trims: |-
  Rimini, or the ancient Ariminum, 
  is an art heritage city with over 22 centuries of history. 
  
  In 268 B.C., the Roman Senate nsent six thousand settlers 
  who founded the city that was meant to be strategically central 
  and to develop to this day.


"""

ret = yaml.load(text)
print(yaml.dump(ret, default_flow_style=False))

Exercise

Use the cell below to find the differences between trims and preserve_caret.


In [ ]:
# exercise 
preserves = ret['preserves']
trims = ret['trims']

Yaml and Ansible recap

Yaml

  • all files are yaml but inventories (for now) and ansible.cfg
  • prefer > and | over quote hell
  • ALWAYS QUOTE :

Ansible

  • QUOTE with_items
  • DON'T QUOTE when
  • use ansible-lint
  • Moustaches are special ansible characters: to verbatim print them, you shoud:

    • open an expansion section
    • write the "{{" string in it

    • eg: {{ "{{" }} whatever {{ "}}" }}

Exercise

Can you find a shorter way to express

{{ "{{" }} ansible_hostname  {{ "}}" }}

Try it with the debug module


In [ ]:


In [ ]:


In [ ]: