summaryrefslogtreecommitdiffstats
path: root/docs/docsite/rst/playbook_guide/playbooks_tags.rst
blob: 4da0af02f4ab930a4288c52078ec38d89227502e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
.. _tags:

****
Tags
****

If you have a large playbook, it may be useful to run only specific parts of it instead of running the entire playbook. You can do this with Ansible tags. Using tags to execute or skip selected tasks is a two-step process:

   #. Add tags to your tasks, either individually or with tag inheritance from a block, play, role, or import.
   #. Select or skip tags when you run your playbook.

.. contents::
   :local:

Adding tags with the tags keyword
=================================

You can add tags to a single task or include. You can also add tags to multiple tasks by defining them at the level of a block, play, role, or import. The keyword ``tags`` addresses all these use cases. The ``tags`` keyword always defines tags and adds them to tasks; it does not select or skip tasks for execution. You can only select or skip tasks based on tags at the command line when you run a playbook. See :ref:`using_tags` for more details.

Adding tags to individual tasks
-------------------------------

At the simplest level, you can apply one or more tags to an individual task. You can add tags to tasks in playbooks, in task files, or within a role. Here is an example that tags two tasks with different tags:

.. code-block:: yaml

   tasks:
   - name: Install the servers
     ansible.builtin.yum:
       name:
       - httpd
       - memcached
       state: present
     tags:
     - packages
     - webservers

   - name: Configure the service
     ansible.builtin.template:
       src: templates/src.j2
       dest: /etc/foo.conf
     tags:
     - configuration

You can apply the same tag to more than one individual task. This example tags several tasks with the same tag, "ntp":

.. code-block:: yaml

   ---
   # file: roles/common/tasks/main.yml

   - name: Install ntp
     ansible.builtin.yum:
       name: ntp
       state: present
     tags: ntp

   - name: Configure ntp
     ansible.builtin.template:
       src: ntp.conf.j2
       dest: /etc/ntp.conf
     notify:
     - restart ntpd
     tags: ntp

   - name: Enable and run ntpd
     ansible.builtin.service:
       name: ntpd
       state: started
       enabled: true
     tags: ntp

   - name: Install NFS utils
     ansible.builtin.yum:
       name:
       - nfs-utils
       - nfs-util-lib
       state: present
     tags: filesharing

If you ran these four tasks in a playbook with ``--tags ntp``, Ansible would run the three tasks tagged ``ntp`` and skip the one task that does not have that tag.

.. _tags_on_includes:

Adding tags to includes
-----------------------

You can apply tags to dynamic includes in a playbook. As with tags on an individual task, tags on an ``include_*`` task apply only to the include itself, not to any tasks within the included file or role. If you add ``mytag`` to a dynamic include, then run that playbook with ``--tags mytag``, Ansible runs the include itself, runs any tasks within the included file or role tagged with ``mytag``, and skips any tasks within the included file or role without that tag. See :ref:`selective_reuse` for more details.

You add tags to includes the same way you add tags to any other task:

.. code-block:: yaml

   ---
   # file: roles/common/tasks/main.yml

   - name: Dynamic re-use of database tasks
     include_tasks: db.yml
     tags: db

You can add a tag only to the dynamic include of a role. In this example, the ``foo`` tag will `not` apply to tasks inside the ``bar`` role:

.. code-block:: yaml

   ---
   - hosts: webservers
     tasks:
       - name: Include the bar role
         include_role:
           name: bar
         tags:
           - foo

With plays, blocks, the ``role`` keyword, and static imports, Ansible applies tag inheritance, adding the tags you define to every task inside the play, block, role, or imported file. However, tag inheritance does *not* apply to dynamic re-use with ``include_role`` and ``include_tasks``. With dynamic re-use (includes), the tags you define apply only to the include itself. If you need tag inheritance, use a static import. If you cannot use an import because the rest of your playbook uses includes, see :ref:`apply_keyword` for ways to work around this behavior.

.. _tag_inheritance:

Tag inheritance: adding tags to multiple tasks
----------------------------------------------

If you want to apply the same tag or tags to multiple tasks without adding a ``tags`` line to every task, you can define the tags at the level of your play or block, or when you add a role or import a file. Ansible applies the tags down the dependency chain to all child tasks. With roles and imports, Ansible appends the tags set by the ``roles`` section or import to any tags set on individual tasks or blocks within the role or imported file. This is called tag inheritance. Tag inheritance is convenient, because you do not have to tag every task. However, the tags still apply to the tasks individually.

Adding tags to blocks
^^^^^^^^^^^^^^^^^^^^^

If you want to apply a tag to many, but not all, of the tasks in your play, use a :ref:`block <playbooks_blocks>` and define the tags at that level. For example, we could edit the NTP example shown above to use a block:

.. code-block:: yaml

   # myrole/tasks/main.yml
   - name: ntp tasks
     tags: ntp
     block:
     - name: Install ntp
       ansible.builtin.yum:
         name: ntp
         state: present

     - name: Configure ntp
       ansible.builtin.template:
         src: ntp.conf.j2
         dest: /etc/ntp.conf
       notify:
       - restart ntpd

     - name: Enable and run ntpd
       ansible.builtin.service:
         name: ntpd
         state: started
         enabled: true

   - name: Install NFS utils
     ansible.builtin.yum:
       name:
       - nfs-utils
       - nfs-util-lib
       state: present
     tags: filesharing

Adding tags to plays
^^^^^^^^^^^^^^^^^^^^

If all the tasks in a play should get the same tag, you can add the tag at the level of the play. For example, if you had a play with only the NTP tasks, you could tag the entire play:

.. code-block:: yaml

   - hosts: all
     tags: ntp
     tasks:
     - name: Install ntp
       ansible.builtin.yum:
         name: ntp
         state: present

     - name: Configure ntp
       ansible.builtin.template:
         src: ntp.conf.j2
         dest: /etc/ntp.conf
       notify:
       - restart ntpd

     - name: Enable and run ntpd
       ansible.builtin.service:
         name: ntpd
         state: started
         enabled: true

   - hosts: fileservers
     tags: filesharing
     tasks:
     ...

Adding tags to roles
^^^^^^^^^^^^^^^^^^^^

There are three ways to add tags to roles:

  #. Add the same tag or tags to all tasks in the role by setting tags under ``roles``. See examples in this section.
  #. Add the same tag or tags to all tasks in the role by setting tags on a static ``import_role`` in your playbook. See examples in :ref:`tags_on_imports`.
  #. Add a tag or tags to individual tasks or blocks within the role itself. This is the only approach that allows you to select or skip some tasks within the role. To select or skip tasks within the role, you must have tags set on individual tasks or blocks, use the dynamic ``include_role`` in your playbook, and add the same tag or tags to the include. When you use this approach, and then run your playbook with ``--tags foo``, Ansible runs the include itself plus any tasks in the role that also have the tag ``foo``. See :ref:`tags_on_includes` for details.

When you incorporate a role in your playbook statically with the ``roles`` keyword, Ansible adds any tags you define to all the tasks in the role. For example:

.. code-block:: yaml

   roles:
     - role: webserver
       vars:
         port: 5000
       tags: [ web, foo ]

or:

.. code-block:: yaml

   ---
   - hosts: webservers
     roles:
       - role: foo
         tags:
           - bar
           - baz
       # using YAML shorthand, this is equivalent to:
       # - { role: foo, tags: ["bar", "baz"] }

.. _tags_on_imports:

Adding tags to imports
^^^^^^^^^^^^^^^^^^^^^^

You can also apply a tag or tags to all the tasks imported by the static ``import_role`` and ``import_tasks`` statements:

.. code-block:: yaml

   ---
   - hosts: webservers
     tasks:
       - name: Import the foo role
         import_role:
           name: foo
         tags:
           - bar
           - baz

       - name: Import tasks from foo.yml
         import_tasks: foo.yml
         tags: [ web, foo ]

.. _apply_keyword:

Tag inheritance for includes: blocks and the ``apply`` keyword
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, Ansible does not apply :ref:`tag inheritance <tag_inheritance>` to dynamic re-use with ``include_role`` and ``include_tasks``. If you add tags to an include, they apply only to the include itself, not to any tasks in the included file or role. This allows you to execute selected tasks within a role or task file - see :ref:`selective_reuse` when you run your playbook.

If you want tag inheritance, you probably want to use imports. However, using both includes and imports in a single playbook can lead to difficult-to-diagnose bugs. For this reason, if your playbook uses ``include_*`` to re-use roles or tasks, and you need tag inheritance on one include, Ansible offers two workarounds. You can use the ``apply`` keyword:

.. code-block:: yaml

   - name: Apply the db tag to the include and to all tasks in db.yaml
     include_tasks:
       file: db.yml
       # adds 'db' tag to tasks within db.yml
       apply:
         tags: db
     # adds 'db' tag to this 'include_tasks' itself
     tags: db

Or you can use a block:

.. code-block:: yaml

     - block:
        - name: Include tasks from db.yml
          include_tasks: db.yml
       tags: db

.. _special_tags:

Special tags: always and never
==============================

Ansible reserves two tag names for special behavior: always and never. If you assign the ``always`` tag to a task or play, Ansible will always run that task or play, unless you specifically skip it (``--skip-tags always``).

For example:

.. code-block:: yaml

   tasks:
   - name: Print a message
     ansible.builtin.debug:
       msg: "Always runs"
     tags:
     - always

   - name: Print a message
     ansible.builtin.debug:
       msg: "runs when you use tag1"
     tags:
     - tag1

.. warning::
   * Fact gathering is tagged with 'always' by default. It is only skipped if
     you apply a tag and then use a different tag in ``--tags`` or the same
     tag in ``--skip-tags``.

.. warning::
   * The role argument specification validation task is tagged with 'always' by default. This validation
     will be skipped if you use ``--skip-tags always``.

.. versionadded:: 2.5

If you assign the ``never`` tag to a task or play, Ansible will skip that task or play unless you specifically request it (``--tags never``).

For example:

.. code-block:: yaml

   tasks:
     - name: Run the rarely-used debug task
       ansible.builtin.debug:
        msg: '{{ showmevar }}'
       tags: [ never, debug ]

The rarely-used debug task in the example above only runs when you specifically request the ``debug`` or ``never`` tags.

.. _using_tags:

Selecting or skipping tags when you run a playbook
==================================================

Once you have added tags to your tasks, includes, blocks, plays, roles, and imports, you can selectively execute or skip tasks based on their tags when you run :ref:`ansible-playbook`. Ansible runs or skips all tasks with tags that match the tags you pass at the command line. If you have added a tag at the block or play level, with ``roles``, or with an import, that tag applies to every task within the block, play, role, or imported role or file. If you have a role with lots of tags and you want to call subsets of the role at different times, either :ref:`use it with dynamic includes <selective_reuse>`, or split the role into multiple roles.

:ref:`ansible-playbook` offers five tag-related command-line options:

* ``--tags all`` - run all tasks, ignore tags (default behavior)
* ``--tags [tag1, tag2]`` - run only tasks with either the tag ``tag1`` or the tag ``tag2``
* ``--skip-tags [tag3, tag4]`` - run all tasks except those with either the tag ``tag3`` or the tag ``tag4``
* ``--tags tagged`` - run only tasks with at least one tag
* ``--tags untagged`` - run only tasks with no tags

For example, to run only tasks and blocks tagged ``configuration`` and ``packages`` in a very long playbook:

.. code-block:: bash

   ansible-playbook example.yml --tags "configuration,packages"

To run all tasks except those tagged ``packages``:

.. code-block:: bash

   ansible-playbook example.yml --skip-tags "packages"

Previewing the results of using tags
------------------------------------

When you run a role or playbook, you might not know or remember which tasks have which tags, or which tags exist at all. Ansible offers two command-line flags for :ref:`ansible-playbook` that help you manage tagged playbooks:

* ``--list-tags`` - generate a list of available tags
* ``--list-tasks`` - when used with ``--tags tagname`` or ``--skip-tags tagname``, generate a preview of tagged tasks

For example, if you do not know whether the tag for configuration tasks is ``config`` or ``conf`` in a playbook, role, or tasks file, you can display all available tags without running any tasks:

.. code-block:: bash

   ansible-playbook example.yml --list-tags

If you do not know which tasks have the tags ``configuration`` and ``packages``, you can pass those tags and add ``--list-tasks``. Ansible lists the tasks but does not execute any of them.

.. code-block:: bash

   ansible-playbook example.yml --tags "configuration,packages" --list-tasks

These command-line flags have one limitation: they cannot show tags or tasks within dynamically included files or roles. See :ref:`dynamic_vs_static` for more information on differences between static imports and dynamic includes.

.. _selective_reuse:

Selectively running tagged tasks in re-usable files
---------------------------------------------------

If you have a role or a tasks file with tags defined at the task or block level, you can selectively run or skip those tagged tasks in a playbook if you use a dynamic include instead of a static import. You must use the same tag on the included tasks and on the include statement itself. For example you might create a file with some tagged and some untagged tasks:

.. code-block:: yaml

   # mixed.yml
   tasks:
   - name: Run the task with no tags
     ansible.builtin.debug:
       msg: this task has no tags

   - name: Run the tagged task
     ansible.builtin.debug:
       msg: this task is tagged with mytag
     tags: mytag

   - block:
     - name: Run the first block task with mytag
       ...
     - name: Run the second block task with mytag
       ...
     tags:
     - mytag

And you might include the tasks file above in a playbook:

.. code-block:: yaml

   # myplaybook.yml
   - hosts: all
     tasks:
     - name: Run tasks from mixed.yml
       include_tasks:
         name: mixed.yml
       tags: mytag

When you run the playbook with ``ansible-playbook -i hosts myplaybook.yml --tags "mytag"``, Ansible skips the task with no tags, runs the tagged individual task, and runs the two tasks in the block.

Configuring tags globally
-------------------------

If you run or skip certain tags by default, you can use the :ref:`TAGS_RUN` and :ref:`TAGS_SKIP` options in Ansible configuration to set those defaults.

.. seealso::

   :ref:`playbooks_intro`
       An introduction to playbooks
   :ref:`playbooks_reuse_roles`
       Playbook organization by roles
   `User Mailing List <https://groups.google.com/group/ansible-devel>`_
       Have a question?  Stop by the google group!
   :ref:`communication_irc`
       How to join Ansible chat channels