ansible yaml

‘Playbooks Are YAML’
—Bas Meijer, Lorin Hochstein, Rene Moser, “Ansible: Up and Running”

Core Idea

Playbooks are YAML, so master the grammar: lists and dictionaries, block strings, when to quote, and anchors for reuse, plus Ansible’s own string idioms.

  • Core structures: lists and dictionaries, with Ansible’s practice of quoting strings.
  • Multi-line strings: literal, folded, and the chomping and indentation indicators.
  • Ansible-specific: pure YAML instead of string arguments, quoting rules, and YAML anchors with aliases.

You don’t need to quote YAML strings. Even if there are spaces, you don’t need to quote them.In some scenarios in Ansible, you will need to quote strings. It is a good practice just to quote all strings.

List

Indent list items and delimit them with hyphens. Lists have a name followed by a colon, as follows:

shows:
   - My Fair Lady
   - Oklahoma
   - The Pirates of Penzance

Inline list

shows: [ My Fair Lady , Oklahoma , The Pirates of Penzance ]

Dictionaries

he YAML specification calls them mappings, but we call them dictionaries here to be consistent with the Ansible documentation

address: 
	street: Main Street 
	appt: 742 
	city: Logan 
	state: Ohio

Inline Dictionaries

address: { street: Main Street, appt: '742', city: Logan, state: Ohio}

Multi-line Strings

You can format multi-line strings with YAML by combining a block style indicator (| or >), a block chomping indicator (+ or –), and even an indentation indicator (1 to 9).

# Block style | (literal): Preserves newlines and spacing
literal_example: |
  This is line 1
  This is line 2
  This is line 3 with preserved line breaks.
 
# Block style > (folded): Collapses newlines into spaces
folded_example: >
  This is line 1
  This is line 2
  This is line 3, but newlines are folded into spaces.
 
# Block chomping indicator + (keep): Retains trailing newlines
keep_trailing_example: |+
  This is line 1
  This is line 2
 
# Block chomping indicator - (strip): Removes all trailing newlines
strip_trailing_example: |-
  This is line 1
  This is line 2
  
# Indentation indicator (1 to 9): Specifies indentation levels
indented_example: >
  This is line 1
    This is line 2 (indented by 2 spaces)
      This is line 3 (indented by 4 spaces)

The greater-than sign (>) immediately following the command: module directive tells YAML “automatically quote the next set of indented lines as one long string, with each line separated by a space”.

Pure YAML Instead of String Arguments

Lorin likes this style:

- name: Ensure nginx is installed
  package: name=nginx update_cache=true

Bas prefers pure-YAML style, because that can be parsed for correctness by yamllint:

 - name: Ensure nginx is installed
   package:
     name: nginx
     update_cache: true

Quoting in Ansible Strings

If you reference a variable right after specifying the module, the YAML parser will misinterpret the variable reference as the beginning of an inline dictionary. Consider the following example:

- name: Perform some task
  command: {{ myapp }} -a foo

Ansible will try to parse the first part of {{ myapp }} -a foo as a dictionary instead of a string, and will return an error. In this case, you must quote the arguments:

- name: Perform some task
  command: "{{ myapp }} -a foo"

A similar problem arises if your argument contains a colon. For example:

- name: Show a debug message
  debug:
    msg: The debug module will print a message: neat, eh?

The colon in the msg argument trips up the YAML parser. To get around this, you need to quote the entire msg string. Single and double quotes are both correct; Bas prefers to use double quotes when the string has variables:

- name: Show a debug message
  debug:
    msg: "The debug module will print a message: neat, eh?"

This will make the YAML parser happy. Ansible supports alternating single and double quotes, so you can do this:

- name: Show escaped quotes
  debug:
    msg: '"The module will print escaped quotes: neat, eh?"'
 
- name: Show quoted quotes
  debug:
    msg: "'The module will print quoted quotes: neat, eh?'""

This yields the expected output:

TASK [Show escaped quotes] *****************************************************
ok: [localhost] ==> {
    "msg": "\"The module will print escaped quotes: neat, eh?\""
}
TASK [Show quoted quotes] ******************************************************
ok: [localhost] ==> {
    "msg": "'The module will print quoted quotes: neat, eh?'"
}

YAML Anchors (&) and Aliases (*)

list - How to merge YAML arrays? - Stack Overflow
Don’t Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files | by King Chung Huang | Medium

YAML provides anchors (&) and aliases (*) to reuse parts of a configuration, reducing duplication and improving maintainability.

  • Anchor (&name) → Defines a reusable block.
  • Alias (*name) → References an existing anchor.
# Repetitive Code
 
server1:
  name: web-server
  image: nginx
  ports:
    - "80:80"
 
server2:
  name: web-server
  image: nginx
  ports:
    - "80:80"
# DRY Code
 
server-config: &common-config
  image: nginx
  ports:
    - "80:80"
 
server1:
  <<: *common-config
  name: web-server-1
 
server2:
  <<: *common-config
  name: web-server-2
  image: apache # Overriding the image for server2
# Using Anchors in Lists
 
ports: &default-ports
  - "80:80"
  - "443:443"
 
server1:
  image: nginx
  ports: *default-ports
# You can combine multiple anchors for greater flexibility.
 
base-config: &base
  image: nginx
  restart: always
 
logging-config: &logging
  logging:
    driver: "json-file"
    options:
      max-size: "10m"
 
server:
  <<: [*base, *logging]
  name: web-server