Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Ansible playbook tasks in order of tags

I want to run tasks in ansible playbook in order of tags given in --tags

My ansible playbook

---
- hosts: all
  remote_user: root
  vars:
    file_path: '{{filename}}'
  tasks:
    - name: Delete user
      user:
        name: "{{username}}"
        state: absent
        remove: yes
      tags:
        - delete_user

    - name: Create user
      user: 
        name: "{{username}}"
        shell: /bin/bash
        groups: "{{groupname}}"
        password: "{{ password |password_hash('sha512') }}"
      tags:
        - create_user

    - name: Add ssh key
      authorized_key:
        user: "{{username}}"
        key: "{{lookup('file', 'file_path')}}"
        exclusive: yes
      tags:
        - add_ssh_key

Run Ansible

ansible-playbook createuser.yml --extra-vars "username=hello password=helloworld groupname=something filename=/path/to/filename" --tags=create_user,add_ssh_key,delete_user

Expected Output

TASK: [Create user] *********************************************************** 
changed: [ip address]

TASK: [Add ssh key] *********************************************************** 
changed: [ip address]

TASK: [Delete user] *********************************************************** 
ok: [ip address]

Output Comes

TASK: [Delete user] *********************************************************** 
ok: [ip address]

TASK: [Create user] *********************************************************** 
changed: [ip address]

TASK: [Add ssh key] *********************************************************** 
changed: [ip address]

Order of tags given

create_user,add_ssh_key,delete_user

But Executed in order

delete_user,create_user,add_ssh_key,

like image 504
iammehrabalam Avatar asked Dec 29 '15 09:12

iammehrabalam


People also ask

What are Ansible playbook tags and how to use them?

Basically, the instruct Ansible to execute (or not to execute) specific tasks within the playbook file. Usually, tasks that are skipped have been carried out and hence there is no need to carry them out once again. This way, tags avoid repetition and optimize playbook execution time. They are handy when you want to run certain tasks on demand.

How to select or skip tasks within a role in Ansible?

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.

What is--list-tasks in Ansible?

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. These command-line flags have one limitation: they cannot show tags or tasks within dynamically included files or roles.

What does--tags never do in Ansible?

New in version 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 ). The rarely-used debug task in the example above only runs when you specifically request the debug or never tags.


2 Answers

That's not what tags are for and there is no way to do that within Ansible. Tasks always are execute in the order they have been defined in the tasks file(s) and/or in order roles have been added to a playbook/play.

If you want to target specific tasks in order you could call the playbook multiple times with a single tag applied.

ansible-playbook ... --tags=create_user
ansible-playbook ... --tags=add_ssh_key
ansible-playbook ... --tags=delete_user

You could write a simple bash script to automate that. (That's what one usually ends up with anyway when you have a more complex setup and have to deal with multiple tags)

like image 55
udondan Avatar answered Oct 24 '22 05:10

udondan


Generally, all tasks are executed in the order they are in the playbook if no tags are given. I think because your tags cover all tasks in the playbook, they are just executed in the order as they would without any tags. So, a solution could be to rearrange the tasks in the playbook.

Example playbook:

  - hosts: localhost

    tasks:
      - name: Third task
        shell:
        tags: "third"

      - name: Second task
        shell:
        tags: "second"

      - name: First task
        shell:
        tags: "first"

First run:

ansible-playbook -c 'local' test.yml --tags=first,second,third --list-tasks

Output:

playbook: test.yml

play #1 (localhost): localhost        TAGS: []
  tasks:
    Third task        TAGS: [third]
    Second task       TAGS: [second]
    First task        TAGS: [first]

Second run:

ansible-playbook -c 'local' test.yml --tags=third,first,second --list-tasks

Output(didn't change):

playbook: test.yml

play #1 (localhost): localhost        TAGS: []
  tasks:
    Third task        TAGS: [third]
    Second task       TAGS: [second]
    First task        TAGS: [first]

Now let's rearrange tasks in the playbook:

- hosts: localhost

  tasks:
    - name: First task
      shell:
      tags: "first"

    - name: Second task
      shell:
      tags: "second"

    - name: Third task
      shell:
      tags: "third"

Final run:

ansible-playbook -c 'local' test.yml --tags=third,first,second --list-tasks

Output (proper order):

playbook: test.yml

play #1 (localhost): localhost        TAGS: []
  tasks:
    First task        TAGS: [first]
    Second task       TAGS: [second]
    Third task        TAGS: [third]
like image 29
lumaks Avatar answered Oct 24 '22 05:10

lumaks