Tasks and Handlers
Overview
Understanding how to write effective tasks and handlers in Ansible playbooks.
Task Structure
Basic Task Format
- name: Install nginx
apt:
name: nginx
state: present
become: true
tags:
- nginx
- installation
Task Components
- Name: Description of what the task does
- Module: The Ansible module to use
- Parameters: Module-specific options
- Additional options:
- become: Privilege escalation
- when: Conditional execution
- tags: Task categorization
- register: Store task output
Task Types
Command Execution
# Simple command
- name: Check disk space
command: df -h
register: disk_space
# Shell commands with pipes
- name: Find large files
shell: |
find /var/log -type f -size +100M | sort -n
args:
executable: /bin/bash
File Operations
- name: Create directory
file:
path: /app/data
state: directory
mode: '0755'
owner: app_user
group: app_group
- name: Copy configuration
copy:
src: files/app.conf
dest: /etc/app/app.conf
backup: yes
Package Management
- name: Ensure required packages
package:
name:
- nginx
- postgresql
- redis-server
state: present
Task Control
Loops
# Simple loop
- name: Create users
user:
name: "{{ item }}"
state: present
loop:
- john
- jane
- bob
# Loop with dictionary
- name: Configure virtual hosts
template:
src: "vhost.conf.j2"
dest: "/etc/nginx/sites-available/{{ item.domain }}"
loop: "{{ virtual_hosts }}"
loop_control:
label: "{{ item.domain }}"
Conditionals
- name: Start service
service:
name: nginx
state: started
when: ansible_facts['os_family'] == "Debian"
- name: Check multiple conditions
debug:
msg: "All conditions met"
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_version is version('20.04', '>=')
Handlers
Basic Handler Structure
handlers:
- name: Restart nginx
service:
name: nginx
state: restarted
- name: Reload nginx
service:
name: nginx
state: reloaded
tasks:
- name: Update nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- Reload nginx
Handler Ordering
handlers:
- name: Restart database
service:
name: postgresql
state: restarted
listen: "restart services"
- name: Restart web server
service:
name: nginx
state: restarted
listen: "restart services"
tasks:
- name: Update configuration
template:
src: app.conf.j2
dest: /etc/app/app.conf
notify: "restart services"
Error Handling
Blocks
- name: Handle deployment
block:
- name: Deploy application
deploy_helper:
path: "{{ app_path }}"
- name: Configure application
template:
src: app.conf.j2
dest: /etc/app/app.conf
rescue:
- name: Rollback deployment
deploy_helper:
path: "{{ app_path }}"
state: clean
always:
- name: Cleanup temp files
file:
path: /tmp/deployment
state: absent
Failure Handling
- name: Attempt risky operation
command: /bin/risky_command
register: command_result
ignore_errors: true
- name: Handle failure
debug:
msg: "Command failed: {{ command_result.stderr }}"
when: command_result.rc != 0
Performance Optimization
Async Tasks
- name: Long-running operation
command: /usr/bin/long_operation
async: 3600
poll: 0
register: async_result
- name: Check operation status
async_status:
jid: "{{ async_result.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
delay: 60
Best Practices
Task Naming
# Good naming
- name: Ensure nginx is installed and running
apt:
name: nginx
state: present
# Bad naming
- name: nginx
apt:
name: nginx
state: present
Task Organization
# Group related tasks
- name: Database setup
block:
- name: Install database
package:
name: postgresql
state: present
- name: Configure database
template:
src: postgresql.conf.j2
dest: /etc/postgresql/postgresql.conf
- name: Start database
service:
name: postgresql
state: started
enabled: yes