Chapter 7: Managing Complex Plays and Playbooks
Ansible complex playbooks cheat sheet
The chapter on one page: the pattern syntax in one place, the difference between importing and including, and flashcards for quick revision.
The chapter in six sentences
- A host pattern selects hosts from the inventory by name: a host, a group, a wildcard, or a comma-separated list of those.
&keeps only hosts that are also in a group and!removes hosts; whatever the order, plain terms are added first, then intersections, then exclusions.--limitnarrows the hosts of every play for one run, and--list-hostsshows the result without running anything.import_playbookcombines whole playbooks; task files hold a plain list of tasks that many plays can reuse.import_tasksis static: the file is read when the playbook is parsed.include_tasksis dynamic: the file is read when the task runs.- Pass
vars:to an import or include so that one task file can do different work each time it is used.
Cheat sheet
Patterns
hosts: all # everything
hosts: web # a group (and its children)
hosts: web,db # union
hosts: 'web,&production' # in web AND in production
hosts: 'web,!staging' # web except staging
hosts: '*.lab.example.com' # wildcard: host and group names
hosts: '~server[ab]\.' # regular expression
hosts: 'web[0]' # first host of web; [-1] last; [0:1] first twoCommand line
ansible 'web,!staging' --list-hosts # test a pattern
ansible-navigator run -m stdout site.yml --list-hosts # hosts of each play
ansible-navigator run -m stdout site.yml --list-tasks # tasks (imports expanded)
ansible-navigator run -m stdout site.yml --limit canary
ansible-navigator run -m stdout site.yml --limit 'all,!canary'Playbooks
# site.yml: top level only
- name: Web tier
ansible.builtin.import_playbook: web.yml
- name: Database tier
ansible.builtin.import_playbook: db.ymlTask files
# tasks/install.yml: a list of tasks, nothing else
- name: Packages are installed
ansible.builtin.dnf:
name: "{{ packages }}"
state: presenttasks:
- name: Packages # static
ansible.builtin.import_tasks: tasks/install.yml
vars:
packages: [httpd, firewalld]
- name: Firewall services # dynamic, once per item
ansible.builtin.include_tasks: tasks/firewall.yml
loop: [http, https]
- name: TLS # dynamic, loaded only if true
ansible.builtin.include_tasks: tasks/tls.yml
when: enable_tls | boolimport_tasks | include_tasks | |
|---|---|---|
| Read | At parse time | At run time |
when | Applied to each task inside | Decides once whether to load the file |
loop | Error | Yes |
| File name from facts | No | Yes |
--list-tasks, --start-at-task | See inside | See only the include |
- What are host patterns matched against?
- The host and group **names in the inventory**. Nothing is resolved through DNS.
- Pattern for "in web AND in production"?
- `'web,&production'`
- Pattern for "all except the db group"?
- `'all,!db'`
- In what order are pattern terms applied?
- Plain terms are added, then `&` intersections, then `!` exclusions, whatever order they are written in.
- What does `--limit` do to a play's `hosts`?
- Narrows it: the play runs on hosts matching **both**. It never adds hosts.
- How do you preview the hosts of each play?
- `ansible-navigator run -m stdout site.yml --list-hosts`
- What happens when a pattern term matches nothing?
- A warning, "Could not match supplied host pattern", and the run continues.
- Where does `import_playbook` go?
- At the **top level** of a playbook, in place of a play.
- What is in a task file?
- A YAML **list of tasks** only: no `hosts`, no `tasks:` keyword.
- Static or dynamic: `import_tasks`?
- **Static**: read at parse time. `include_tasks` is dynamic: read when the task runs.
- Which one can take a `loop`?
- `include_tasks`. A loop on `import_tasks` is an error.
- How does `when` behave on `import_tasks`?
- It is copied to **every task** in the file, and each one tests it.