Master Ansible Playbooks: From Basics to Advanced Variable Management
This guide explains what an Ansible playbook is, its YAML syntax, how to write tasks, use inventory limits, manage variables through extra‑vars, vars files, host/group vars, custom facts, control flow with when/changed_when/failed_when, delegate tasks, prompt users, apply tags, and handle errors with blocks and rescue/always sections.
What is an Ansible Playbook?
Fundamentally, a playbook is similar to a shell script: it strings together commands (tasks) with optional conditionals, but unlike a shell script it can run on multiple hosts simultaneously, requiring you to specify the target hosts.
Playbook Syntax
Playbooks use YAML. A file starts with three dashes ( ---) and uses indentation to define blocks. A minimal example from the official documentation looks like this:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.confIndentation works like Python to delimit code blocks.
Simple Example: Check MySQL Status
---
- hosts: all
remote_user: root
gather_facts: no
tasks:
- name: check the mysql status
service: name=mysqld state=runningRunning the playbook with ansible-playbook test.yml produces output showing each host’s result.
Limiting Execution to Specific Hosts
Use the --limit option to run a playbook only on a subset of hosts defined in the inventory:
[root@test2 playbook]# ansible-playbook test.yml --limit dbserversListing Hosts in a Playbook
[root@test2 playbook]# ansible-playbook test.yml --list-hostsOther useful command‑line options include: --inventory=path – specify an inventory file (default /etc/ansible/hosts). -v, -vvv, -vvvv – increase verbosity. --extra-vars=vars – define variables on the command line. --forks – set the number of parallel processes (default 5). --connection=type – choose the remote connection method (default ssh). --check – run in dry‑run mode; tasks are evaluated but not executed.
Handlers
Handlers let you trigger actions (e.g., service restarts) only when a task reports a change. Define them with a handlers: section and invoke them via notify:
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apacheKey points:
Handlers run only if the notifying task actually executes.
They run once at the end of each play unless you use meta: flush_handlers.
If a play fails before reaching a handler, you can force execution with --force-handlers.
Variables
Variables can be supplied in several ways:
Extra vars on the command line: ansible-playbook test.yml --extra-vars "test_var=test".
vars block inside the playbook:
---
- hosts: all
remote_user: root
gather_facts: no
vars:
test_var: Hello World
tasks:
- name: test playbook variables
command: echo {{ test_var }}vars_files to include an external YAML file.
---
- hosts: all
remote_user: root
gather_facts: no
vars_files:
- vars.yml
tasks:
- name: test playbook variables
command: echo {{ test_var }}The vars.yml file simply contains the variable definitions.
Inventory variables can be defined per host or per group directly in the /etc/ansible/hosts file, e.g., 10.0.102.212 test_var=212.
For larger inventories, use host_vars/ and group_vars/ directories. Each file is named after a host or group and contains YAML variable definitions.
# Example host_vars/10.0.102.162
---
test_var: 162Group variables apply to all hosts in the group:
# group_vars/all
---
test_group_var: from groupUsing Hostvars and Built‑in Facts
You can access any host’s variables with hostvars['host1']['admin_user']. Common built‑in facts include groups, group_names, inventory_hostname, inventory_hostname_short, and play_hosts.
Registered Variables
Use register to capture a task’s result (stdout, stderr, changed, delta) for later use:
- name: test the register variables
shell: uptime
register: results
- name: print the register result
debug: msg="{{ results.stdout }}"Control Flow
when statements let tasks run only when a condition is true, e.g., stopping MySQL on a specific IP:
- name: shut down the db server
service: name=mysqld state=stopped
when: ansible_eth0.ipv4.address == "10.0.102.162"Additional conditional keywords are changed_when and failed_when.
Task Delegation
Use delegate_to to run a task on a different host than the one currently being processed, or local_action to run it on the control machine:
- name: stop the db server
service: name=mysqld state=stopped
delegate_to: 10.0.102.162
- name: create a local test file
local_action: shell touch test1111Waiting for Services
Use the wait_for module to pause execution until a port becomes reachable:
- name: wait for webserver to start
local_action:
module: wait_for
host: webserver1
port: 80
delay: 10
timeout: 300
state: startedInteractive Prompts
The vars_prompt keyword asks the user for input at runtime:
---
- hosts: all
remote_user: root
vars_prompt:
- name: share_user
prompt: "what is your network username?"
private: no
- name: share_pass
prompt: "what is your network password"
private: noCollected values can be referenced later with {{ share_user }} and {{ share_pass }}.
Tags
Tags let you run or skip specific tasks or roles. Define them with a tags: list on a play, role, or task, then invoke with --tags or --skip-tags on the command line.
Blocks, Rescue, and Always
Blocks group related tasks and allow error handling:
- block:
- name: risky command
script: monitoring-connect.sh
rescue:
- debug: msg="There was an error in the block"
always:
- debug: msg="This always executes"If any task inside the block fails, the rescue section runs; the always section runs regardless of success or failure.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
