Creating Ansible Playbooks
1. Understanding Playbook Structure
| Component | Description | Example |
|---|---|---|
| playbook | YAML file containing one or more plays | site.yml |
| play | One or more tasks to execute on a set of hosts | - hosts: webservers |
| hosts | Target hosts for the play | hosts: web |
| tasks | List of tasks to run on the hosts | tasks: |
| name | Descriptive name for a task | name: "Install Apache" |
| action/module | Module to execute on the target host | action: apt name=apache2 state=present |
Example: Basic Playbook Structure
---
- name: "Deploy web application"
hosts: webservers
tasks:
- name: "Install Apache"
apt:
name: apache2
state: present
2. Defining Plays
| Property | Description | Example |
|---|---|---|
| name | Human-readable description of the play | "Install and configure Nginx" |
| hosts | Inventory groups or hosts to target | "web_servers" |
| become | Run tasks with elevated privileges (sudo) | true |
| vars | Variables scoped to this play | {"nginx_version": "1.21.6"} |
| tasks | List of tasks to execute | [{name: "Install Nginx", apt: name: nginx}] |
Example: Basic Play Definition
---
- name: Install and configure Nginx
hosts: web_servers
become: true
vars:
nginx_version: "1.21.6"
tasks:
- name: Update package cache
apt:
update_cache: yes
- name: Install Nginx
apt:
name: nginx
state: present
3. Specifying Target Hosts
| Host Specification | Description | Example |
|---|---|---|
| inventory | File or directory containing host definitions | ansible-playbook site.yml -i inventory.ini |
| hosts | Target hosts or groups in playbook | hosts: webservers |
| groups | Logical collections of hosts | webservers: hosts: [web1, web2] |
Example: Hosts and Groups
---
- name: Configure web servers
hosts: webservers
vars:
http_port: 80
tasks:
- name: Ensure Apache is installed
apt:
name: apache2
state: present
Example: Using Inventory File
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[databases]
db1 ansible_host=192.168.1.20
4. Setting Remote User
| Property | Description | Default |
|---|---|---|
| remote_user | User to execute the task as on the remote host | ansible_user (if set) or current user |
| become | Switch to a different user using privilege escalation | false |
| become_user | User to become when using privilege escalation | root |
Example: Setting remote user for a task
- name: Run command as specific user
command: whoami
remote_user: deploy
Example: Using become to switch user
- name: Install package with root privileges
apt:
name: nginx
state: present
become: yes
become_user: root
5. Enabling Privilege Escalation
| Option | Values | Description |
|---|---|---|
| become | true |
Enable privilege escalation for the task |
| become_method | sudo, su, doas, pbrun |
Method used to escalate privileges |
| become_user | root, www-data |
User to escalate to |
| become_flags | -H, -S |
Flags passed to the become method |
Example: Using become to run as root
- name: Install package with root privileges
apt:
name: nginx
state: present
become: true
become_user: root
Note: Privilege escalation requires proper configuration in
ansible.cfg or sudo permissions on the target host.
6. Configuring Become Method
| Option | Values | Description |
|---|---|---|
| become | true / false |
Enable or disable privilege escalation |
| become_method | sudo / su / pfexec / doas / pbrun / runas |
Privilege escalation method to use |
| become_user | root / www-data |
User to become when executing the task |
| become_flags | -H / -S |
Flags to pass to the become method (e.g., -H for home directory) |
Example: Using become with sudo
- name: Install a package with root privileges
apt:
name: nginx
state: present
become: true
become_method: sudo
become_user: root
Note: The
become functionality requires that the target host has the appropriate privilege escalation tools installed (e.g., sudo).
7. Defining Tasks
| Property | Description | Example |
|---|---|---|
| name | Human-readable description of the task | name: "Install Apache" |
| action | Module to execute (e.g., yum, copy) |
action: yum name=httpd state=installed |
| when | Conditional expression to control task execution | when: ansible_os_family == "RedHat" |
| loop | Repeat task for each item in a list | loop: [ "httpd", "mod_ssl" ] |
| register | Store output of a task for later use | register: result |
Example: Conditional Task Execution
- name: Configure firewall for RedHat
firewalld:
service: http
permanent: true
state: enabled
when: ansible_os_family == "RedHat"
Example: Looping Over a List
- name: Create directories
file:
path: /var/www/{{ item }}
state: directory
loop:
- html
- css
- js
8. Setting Gather Facts
| Option | Values | Description |
|---|---|---|
| gather_facts | true | false |
Controls whether to gather facts about the target host. Defaults to true. |
Example: Disabling Fact Gathering
- name: Example playbook without facts
hosts: all
gather_facts: false
tasks:
- name: Print a message
debug:
msg: "No facts gathered"
Note: Disabling
gather_facts can speed up playbook execution when facts are not needed.
9. Using Proper YAML Syntax
| Element | Description | Example |
|---|---|---|
| Indentation | Use 2 spaces for indentation; no tabs | |
| Keys and Values | Use colon followed by a space for key-value pairs | name: Install nginx |
| Lists | Use dash and space for list items | |
| Multiline Strings | Use | for literal blocks or > for folded blocks |
|
| Comments | Start with # |
# This is a comment |
Example: Basic Playbook Structure
# Define the playbook
---
- name: Example Playbook
hosts: all
vars:
app_port: 8080
tasks:
- name: Ensure nginx is installed
apt:
name: nginx
state: present
Note: YAML is sensitive to whitespace and requires consistent indentation. Misaligned indentation can cause parsing errors in Ansible.
10. Validating Playbook Syntax
| Option | Values | Notes |
|---|---|---|
| --syntax-check | true |
Validates playbook syntax without executing |
| --check | false |
Simulates execution without making changes |
| --list-hosts | false |
Lists matching hosts without running playbook |
Note: The
--syntax-check option is essential before running playbooks in production environments to prevent execution errors due to malformed YAML or invalid module parameters.