1. Tags¶
Running specific parts of a playbook, role or taskfile is what tags are all about. Their purpose is to filter tasks based on a tag and then execute them. Take the playbook below for example,
---
# /tmp/playbook.yml
- hosts: all
tasks:
- name: Install emacs
package:
name: emacs-nox
state: installed
tags: good
- name: Place emacs config file
copy:
src: .emacs
dest: {{ ansible_env.HOME }}
tags: evil
- name: Install vim
package:
name: vim
state: present
tags: evil
- name: Install nano
package:
name: nano
state: installed
you could install emacs by running:
ansible-playbook /tmp/playbook.yml --tags good
ansible-playbook /tmp/playbook.yml --skip-tags evil
The former can be understood as “only run tasks tagged as good”, hence tasks one and two will be the only ones to be executed. The latter, on the other hand, means “run every task not tagged as evil”, therefore tasks one, two AND four will be executed.
1.1. Inheritance¶
Tags only affect tasks; this means tagging a task, role or playbook import will only serve the purpose of tagging all tasks within it.
Warning
include statements DO NOT tag tasks within them. Multi-tagging only applies to dynamic includes, such as import statements.
---
# Tasks within taskfile_1.yml will not be tagged,
# but the include will.
- include_tasks: taskfile_1.yml
tags: tag_1
# Tasks within taskfile_2 will be tagged, as well
# as the import statement itself.
- import_tasks: taskfile_2.yml
tags: tag_2
Think of it as multi-tagging, where declaring one tag automatically tags a set of tasks. For example, the playbook below
---
- hosts: all
roles:
- role: apache
vars:
ssl_port: 443
tags:
- web
- container
will tag all tasks within the role apache.
1.2. Special tags¶
Tag | Meaning | Explicit |
---|---|---|
always | always run a task; can be skipped using –skip-tags always. | yes |
never | never run a task, unless explicitly told to do so. | yes |
tagged | run tagged tasks only | no |
untagged | run untagged tasks only | no |
all | run all tasks (DEFAULT) | no |
1.3. Example¶
Consider a provisioned cluster with 501 nodes (1 master, 500 slaves), where ansible’s average running time is 25 to 30 minutes.
Suppose you are given the task
of automating the creation of the folder /scratch-local
and its
subdirectories, so that each node has a directory per scientist, named after
the convention /scratch-local/<username>
.
In order to accomplish the task,
you intend to read the usernames from the datacenter’s FreeIpa manager
and later use them to create the appropriate directories under
/scratch-local/
:
#/tmp/scratch_local.yml
---
- name: Get users from FreeIpa
shell: ipa user-find --raw --pkey-only | awk '/uid:/{print $2}'
register: get_users
- name: Create dirs
file:
path: "/scratch-local/{{ item }}"
state: directory
owner: "{{ item }}"
loop: "{{ get_users.stdout_lines }}"
Running the above taskfile will ensure all scientists have their own folder in the specified path. You quickly realize, however, that it will take 25 to 30 minutes for the changes to be applied and upon the creation of new user accounts at worst 30 minutes * N° of new users (if they are not created within ansible’s run interval). So, you decide to tag the tasks:
#/tmp/playbook.yml
---
- hosts: computes
tasks:
- import_tasks: scratch_local.yml
tags: scratch
Finally, you tell your boss incorporating your code to the git repo holding
ansible data and running the command ansible-playbook --tags scratch <playbook>
will do the job without further delay.