Ansible playbooks are the core components of Ansible. Playbooks are written in YAML format and describe a set of tasks that need to be executed on the managed systems. A playbook consists of one or more plays, and each play defines a set of tasks to be performed on a group of hosts. Tasks are the individual actions or commands that Ansible should execute, such as installing packages, copying files, or restarting services. Tasks call out to the programmed code units called modules.
The basic components of a playbook
Here’s the basic structure of an Ansible playbook:
---
- name: Example Playbook
hosts: target_hosts
tasks:
- name: Task 1
<module_name>: # appropriate Ansible module
<module_parameters>: <value>
- name: Task 2
<module_name>:
<module_parameters>: <value>
Let’s break it down:
name
: The name is a human-readable description of what the playbook does. It’s optional but recommended for clarity.hosts
: This section specifies the target hosts or groups of hosts where the tasks defined in the playbook will be executed. Hosts can be defined either as individual hostnames or IP addresses, or as groups defined in the Ansible inventory file. Patterns can be used here.tasks
: Tasks define the actions that Ansible should perform on the target hosts. Each task typically corresponds to a specific module, which carries out a particular programmed action on the target system. Tasks are executed sequentially, in the order they are defined in the playbook (from top to bottom). The modules are part of different collections.
These are the essential components of an Ansible playbook.
Additional playbook components
Additional playbook components can be:
vars
: Playbooks can include variable definitions that can be used throughout the playbook. Variables can be defined inline or in separate variable files, and they provide flexibility and reusability.become
: Indicates whether to execute tasks with escalated privileges (sudo
or another method).handlers
: Handlers are similar to tasks but are only executed if triggered by another task. They are typically used to restart services or perform other actions in response to changes made by tasks. Handlers are defined separately from tasks and referenced using thenotify
directive.roles
: Playbooks can organize tasks into reusable units called roles. Roles encapsulate all the necessary tasks, variables, and other files needed to perform a specific function or role within the infrastructure. They promote modularity, reusability, and maintainability of Ansible code.
Ansible playbooks allow you to define the desired state of your infrastructure and automate complex tasks across multiple servers.
Running Ansible playbooks
For the sake of simplicity let’s use the following inventory
file as reference for this section:
[deb]
192.168.1.91
192.168.1.92
[rpm]
192.168.1.93
The inventory file contains two groups (deb, rpm) and three hosts.
Your very first Ansible playbook file, let’s call it playbook.yaml
looks like this:
- name: My first Ansible play
hosts: all # Targets the "all" group
tasks:
- name: Checking availability with ping
ansible.builtin.ping:
The play targets the all
host group.
To run the playbook, you have to use the ansible-playbook
command. It takes similar arguments as the ansible
command which you used for Ad-Hoc commands. You can read more info about the command options and arguments using the --help
option.
Run the playbook with the ansible-playbook
command, use the -i
option for providing it an inventory file and use the playbook file as the last argument:
ansible-playbook -i inventory playbook.yaml
The output of an ansible-playbook
run will contain the following elements:
1: PLAY [My first Ansible play]
2: TASK [Gathering Facts]
3: 192.168.1.91: ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- The name of the play.
- Tasks running sequentially (there can be triggers, so called “handlers” here too).
- The “Play Recap” will show the results of the play.
A playbook file can contain multiple plays, both targeting different hosts or groups.
- name: My first Ansible play
hosts: all # Targets the "all" group
tasks:
- name: Checking availability with ping
ansible.builtin.ping:
- name: My second play
hosts: deb # Targets the "deb" group
tasks:
- name: Random command as root
ansible.builtin.command: 'uname'
become: true
The playbook above contains two plays, the “My first Ansible play” and the “My second play“. The first play targets the all
host group, the second one targets only the deb
group.
Targeting hosts and groups with the --limit
option
The playbook’s host
directive targets a set of managed hosts or groups from the inventory.
Using the ansible-playbook
command it will run on the hosts or groups from the hosts
directive.
It is possible to narrow down the targeted hosts or groups using the --limit
option of the ansible-playbook
command.
To check and validate the targeted hosts or groups of an Ansible playbook use the --list-hosts
option. This will NOT run the plays in the playbook, this only prints out the targeted systems.
ansible-playbook -i inventory playbook.yaml --list-hosts
playbook: playbook.yaml
play #1 (all): My first Ansible playbook TAGS: []
pattern: ['all']
hosts (3):
192.168.1.91
192.168.1.92
192.168.1.93
play #2 (deb): My second playbook TAGS: []
pattern: ['deb']
hosts (2):
192.168.1.91
192.168.1.92
Limiting the playbook run only for the rpm
group will work like this:
ansible-playbook -i inventory playbook.yaml --limit rpm --list-hosts
playbook: playbook.yaml
play #1 (all): My first Ansible playbook TAGS: []
pattern: ['all']
hosts (1):
192.168.1.93
play #2 (deb): My second playbook TAGS: []
pattern: ['deb']
hosts (0):
The first play targets the all
host group, the rpm
group is part of it so there is a targeted host.
The second play targets only the deb
group, there are no rpm
group member machines in it.
With some creativity you can create a useful combination of inventories, hosts and groups with it. My experience is that it is not worth it making the inventories overly complex.
It is a clever idea to plan in advance and to avoid mis-targeting hosts during playbook runs. Multiple small inventory files and playbooks work better than an over-complicated monster.
Summary
As you can see playbooks are the essential core parts of Ansible. They are the blueprints of different operations to be executed on hosts and groups.
Playbooks run tasks from top to bottom with the ansible-playbook
command. Tasks load Ansible modules to do the actual operations.
You can target less hosts from the hosts
directive of the playbook with the --limit
option.
This information is enough to get you started writing basic playbooks.
If you want to discuss the topic with other technology-minded people, join my Discord: https://discord.gg/YbSYGsQYES
Now we have an IRC channel as well: irc.libera.chat / #tomsitcafe