Ansible Task Control
Introduction
Task control in Ansible allows you to manage the execution flow of tasks within a playbook. This can include task retries, conditionals, and even handling failures gracefully. In this tutorial, we will cover various methods to control tasks in Ansible.
Conditionals
Conditionals in Ansible allow you to execute tasks based on certain conditions. This is done using the when
statement, which is a Jinja2 expression.
- name: Install Apache on Debian
apt:
name: apache2
state: present
when: ansible_os_family == "Debian"
In this example, the task will only run if the ansible_os_family
fact equals "Debian".
Loops
Loops allow you to iterate over a list of items and perform the same task for each item. Ansible provides the loop
keyword for this purpose.
- name: Install multiple packages
apt:
name: "{{ item }}"
state: present
loop:
- git
- curl
- vim
Here, the task will install the packages git
, curl
, and vim
.
Handlers
Handlers are special tasks that are triggered by other tasks. They are typically used to restart services after configuration files have been changed.
- name: Copy Apache config file
copy:
src: /srv/httpd.conf
dest: /etc/httpd/conf/httpd.conf
notify:
- Restart Apache
handlers:
- name: Restart Apache
service:
name: httpd
state: restarted
In this example, the handler "Restart Apache" will be triggered if the task "Copy Apache config file" changes the configuration file.
Task Delegation
Delegation allows you to run a task on a different host than the one being managed. This is done using the delegate_to
keyword.
- name: Check disk space on web servers
command: df -h
delegate_to: web01.example.com
Here, the task will run the df -h
command on web01.example.com
, regardless of which host is being managed by the playbook.
Retries
Retries allow you to attempt a task multiple times before failing. This is useful for tasks that may temporarily fail and succeed upon retrying.
- name: Ensure service is running
service:
name: myservice
state: started
retries: 5
delay: 10
until: result is succeeded
register: result
This example will attempt to start the service myservice
up to 5 times, with a 10-second delay between each attempt.
Ignoring Errors
In some cases, you may want to ignore errors for specific tasks. This can be achieved using the ignore_errors
keyword.
- name: Attempt to stop a non-existent service
service:
name: nonexistent_service
state: stopped
ignore_errors: yes
In this example, the task will not cause the playbook to fail, even if the service does not exist.
Asynchronous Tasks
Asynchronous tasks allow you to run long-running operations in the background and check for their completion later. This is useful for tasks that may take a significant amount of time to complete.
- name: Long running database migration
command: /usr/bin/migrate-database
async: 3600
poll: 0
register: migration_job
- name: Wait for database migration to complete
async_status:
jid: "{{ migration_job.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
delay: 60
This example runs a database migration script asynchronously and checks for its completion every 60 seconds, up to 30 times.
Conclusion
Task control in Ansible provides a powerful set of tools to manage the execution flow of tasks in your playbooks. By using conditionals, loops, handlers, delegation, retries, error handling, and asynchronous tasks, you can create robust automation scripts that handle a variety of scenarios.