Skip to content

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

  1. Name: Description of what the task does
  2. Module: The Ansible module to use
  3. Parameters: Module-specific options
  4. Additional options:
  5. become: Privilege escalation
  6. when: Conditional execution
  7. tags: Task categorization
  8. 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