Ansible Playbook YAML Basics
Learn the YAML you need for Ansible playbooks, including key-value pairs, lists, nested mappings and indentation, with the common mistakes that break a playbook.
Every playbook you write is a YAML file. Ansible itself is forgiving about many things, but YAML is not: one wrong space and the whole playbook fails to load. Fifteen minutes spent on YAML now saves hours of confusing errors later.
YAML is a format for writing structured data in plain text. People read it easily, and programs parse it easily. Files use the .yml or .yaml extension. Ansible accepts both. We use .yml in this course, like the lecture.
You can practise in any editor. VS Code with the Red Hat YAML extension highlights indentation errors as you type.
Start and end markers
---
# your data goes here
...--- marks the start of a YAML document and ... marks the end. Neither is compulsory. Most Ansible playbooks start with --- and leave out .... Both forms are correct.
Key-value pairs (a mapping)
The simplest YAML is a list of keys and values separated by a colon and a space:
---
id: 1
name: Rohan
city: Bengaluru
...A few rules:
- There must be a space after the colon.
name:Rohanis not a key-value pair - A space before the colon (
name : Rohan, as typed in the lecture) is allowed, but the usual style isname: Rohan - Do not end lines with commas. YAML is not JSON. In
name: Rohan,the comma becomes part of the value, so the name is literallyRohan,, andid: 1,turns the number 1 into the text1, - Strings usually need no quotes. Add quotes when a value contains a
:followed by a space, starts with{,*or@, or when you wantyes,noor0644treated as text
Lists
When a key has more than one value, write each value on its own line, indented, starting with a hyphen and a space:
---
id: 1
name: Rohan
city: Bengaluru
hobbies:
- cricket
- music
- chess
...hobbies is now a list (an array) of three items. The same thing can be written on one line in flow style, which you will sometimes see in Ansible:
hobbies: [cricket, music, chess]Nesting and indentation
Data often has a hierarchy. An employee belongs to Telusko, and the employee has an id, a name and an address. The address itself has a city and a state. In YAML, you show "belongs to" by indenting:
---
telusko:
employee:
id: 1
name: Harsh
address:
city: Udaipur
state: Rajasthan
...Read it from the left:
teluskois the top-level keyemployeeis indented two spaces, so it is a child ofteluskoid,nameandaddressare at the same level, so they are siblings, all children ofemployeecityandstateare children ofaddress
You never repeat the parent. Lining up name exactly under id is enough to say "this is also part of employee".
Spaces, never tabs
YAML does not allow tab characters for indentation. Use spaces only, and stay consistent. Two spaces per level is the convention in Ansible. Most editors can convert the Tab key into spaces for .yml files.
Lists of mappings: the shape of every playbook
Ansible playbooks combine both ideas: a list where each item is a mapping. Look at this shape carefully, because every playbook in the rest of the course follows it:
---
- name: First play
hosts: webservers
tasks:
- name: First task
ansible.builtin.ping:
- name: Second task
ansible.builtin.ping:| Line | YAML meaning | Ansible meaning |
|---|---|---|
- name: First play | First item of the top-level list, a mapping | A play |
hosts: webservers | Another key in the same mapping (lined up with name) | Which inventory hosts the play runs on |
tasks: | A key whose value is a list | The list of tasks in this play |
- name: First task | First item of the tasks list | A task |
ansible.builtin.ping: | A key with an empty value | The module the task runs |
The hyphen starts a new list item, and every key of that item lines up with the first key after the hyphen. You will write your first real playbook with exactly this structure in the next lesson.
Common YAML mistakes in playbooks
| Mistake | What happens | Fix |
|---|---|---|
| Tab used for indentation | found character '\t' that cannot start any token | Replace tabs with spaces |
hosts: indented more or less than name: | did not find expected key or the key is attached to the wrong parent | Line up sibling keys exactly |
Missing space after colon (hosts:all) | The line is read as plain text instead of a key, and YAML fails with could not find expected ':' | Write hosts: all |
Value starts with {{ without quotes | Syntax Error while loading YAML, because YAML reads { as the start of a dictionary. Ansible usually adds a hint about missing quotes | Quote it: "{{ var }}" (covered in the variables lesson) |
mode: 0644 without quotes | YAML reads it as a number instead of text, and the permissions can come out wrong (the official docs warn about this) | Write mode: "0644" |
Check a YAML file quickly
On the control node you can let Python parse any YAML file. No output means the syntax is valid:
python3 -c 'import yaml, sys; yaml.safe_load(open(sys.argv[1]))' sample2.ymlFor playbooks, ansible-playbook --syntax-check does a better job, as you will see next.
Try It Yourself
- Write
sample1.ymlwith your own details and a list of three hobbies. Validate it with the Python one-liner. - Add a
citieskey with a list of three cities (hometown, current city, a city you travel to). - Extend
sample2.ymlwith a second employee. Hint: turnemployeeinto a list of mappings. - Break the file on purpose: replace two spaces with a tab, then add a comma at the end of a line. Read the error each time.
Official references
Written By: Shramik Masti
How is this guide?
Last updated on
Ansible Adhoc commands
Run one-off Ansible commands from the control node without writing a playbook, target all hosts or a single group, and read the SUCCESS and CHANGED output.
Ansible First Playbook
Write and run your first Ansible playbook that pings every managed node, understand the hosts, variables and tasks sections, check syntax and read the PLAY RECAP.
