I'm searching for a way to always run a role, regardless of --tags args.
Here is a simple playbook:
- hosts: all
roles:
- { role: role1, tags: always },
- { role: role2, tags: tag1 },
- { role: role3, tags: tag2 }
I would like only role1 and role2 to run when I launch the following filter (instead of only role2):
ansible-playbook -i hosts deploy.yml --tags tag1
I though it was the default behavior with the special always tag (see http://docs.ansible.com/ansible/playbooks_tags.html#special-tags)
I'm playing with Ansible 1.8.4.
Most probably your Ansible version is the problem.
The always tag was introduced with this pull request, which was merged into the devel branch on February 25. According to the releases, the next released version after that date was Ansible 1.9.0-1.
Related
I have 3 tasks that will get the version from the database and I have 3 roles inside these roles few tasks have a dependency on the version.
I can't use a variable here because the value is dynamic and I cant set facts because I should be able to run individual roles and only a few tasks from each role with tags.
My Example below.
Role1:-
Tasks I need to run multiple times(example):-
- name: get version
block:
- command: "mongo get_version.js"
register: op
- name: filter version number from output
shell: "echo {{ present_version.stdout }}| grep 'version'"
register: present_version
tags: role1_db_tag
- name: do something
- name: do something when a version is something
when: present_version == "something"
tags: role1_db_tag
Role2:
- name: get version
block:
- command: "mongo get_version.js"
register: op
- name: filter version number from output
shell: "echo {{ present_version.stdout }}| grep 'version'"
register: present_version
tags: role2_db_tag
- name: do some other things
- name: do something else when a version is something
when: present_version == "something"
tags: role2_db_tag
Now I am running the get version tasks 3 times in each role now.
Is there any way like handlers just to mention some name for these repetitive tasks and call when required?
Expecting:-
Role2:
- name: fetch version
function: get_version
register: present_version
tags: role1_db_tag
- name: do something else when a version is something
when: present_version == "something"
tags: role2_db_tag
PS: Is there a better way than include_* or import_*.
As you have already surmised, the way you would typically handle this is by moving the get version task into a separate role, and then including that in the dependent roles using e.g. import_role:
- import_role:
name: get_version
If you have a number of small shared tasks, you can create a "library" role with multiple task files:
- import_role:
name: library
tasks_from: get_version
See "Using Roles" for a discussion of include_role vs import_role.
You can get similar behavior by adding a dependency to your role
instead. E.g., in Role1, create a file meta/main.yml with the
following content:
dependencies:
- get_version
This will automatically run the get_version role before role1 any
time you run role1.
See "Using Role Dependencies" for more information.
I need to run some roles in concurrent mode in Ansible.
I run ansible via:
ansible-playbook install_full.yml --tags "10_clean_up,20_pull_images,30_install_postgres_11,40_install_jboss-eap-7.0" --extra-vars "ansible_user=user ansible_password=password"
The playbook install_full.yml looks like:
- hosts: localhost
vars_files:
- "vars/build.yml"
roles:
- { role: 10_clean_up, tags: 10_clean_up }
- { role: 20_pull_images, tags: 20_pull_images }
- { role: 30_install_postgres_11, tags: 30_install_postgres_11 }
- { role: 40_install_jboss-eap-7.0, tags: 40_install_jboss-eap-7.0 }
30 and 40 role can be run in the same time (to save some time), is it possible to run couple of roles in parallel, not like now - by order list ?
Thanks on advance!
It is not possible at this time and many have asked for that feature. From the ansible project : https://github.com/ansible/ansible/issues/19083.
FYI it is possible to use async on tasks, but it is not possible to use it on roles.
You'd need strategy: free for the set of roles you want to run at the same time. Check this out:
https://medium.com/#ibrahimgunduz34/parallel-playbook-execution-in-ansible-30799ccda4e0
I have the following includes in a old role by a colleague.
---
- name: deploy
include: deploy.yml
when: deploy is defined and deploy == 'True'
- name: undeploy
include: undeploy.yml
when: undeploy is defined and undeploy == 'True'
- name: database-migrate
include: database-migrate.yml
when: db is defined and db == 'True'
However, irrespective of how I include the role Ansible is automatically processing each include. I can verify this by using the --list-tasks option.
For example in my playbook I have the following
roles:
- { role: vip-notification-services-app, deploy: 'True', tags: ['deploy']}
I running with version 2.1.1.0 (upgraded a few weeks back). This role was executing fine before the upgrade.
Therefore I'm wondering if this style of includes in a role no longer allowed or there is some different syntax I need to use.
The --list-tasks option it does not evaluate the when conditional for its results.
That is, if you have a playbook.yml:
---
- hosts: localhost
connection: local
tasks:
- debug:
when: false
ansible-playbook playbook.yml --list-tasks will display:
playbook: test.yml
play #1 (localhost): localhost TAGS: []
tasks:
debug TAGS: []
although the debug task would never run (the result will not change if you change the condition to with: true).
As Konstantin Suvorov noticed, include always includes all tasks and then applies when conditional to each task. Thus in --list-tasks result you will always see all tasks. They won't however be executed in a real run.
I have a playbook which calls multiple roles I have written. This playbook has each role tagged so than I can call them separately or run the entire procedure from start to end. Within the roles additional tags may be provided to break up the works within those as well. Some of the role tasks are tagged with "always" because I want them to execute whenever the role is ran, regardless of any role specific tags.
The problem I am running into is that these "always" tags execute whether the role specific tag is called or not. If I don't call the tag for a role, I don't want to role to execute at all, including any "always" tasks specific to that role.
Example:
# Playbook
- hosts: localhost
roles:
- role: roleA
tags: do_roleA
- role: roleB
tags: do_roleB
# Role A:
- name: Always do this when doing role A
debug: msg="test"
tags: always
- name: Task1
debug: msg="task1"
tags: do_task1
- name: Task2
debug: msg="task2"
tags: do_task2
Example call:
ansibile-playbook my-playbook.yml --tags "do_roleB"
But this causes the debug in Role A to occur as well.
Some requirements I have:
Can not skip "always" as roleB may have some tasks that require it.
Do not want to change the tag from always and add a list of tags for every sub task. i.e. [do_task1,do_task2] as the number of tags would become large and easy to forget to add one.
Basically I am looking for a way to tell Ansible, if I call a "playbook tag" execute only roles from the playbook where the tag matches; do not execute any of the tasks in roles that do not match, even if they are tagged with "always". But if I call a "role tag" execute all the tasks in that role which either have tags of "always" or the tag I called.
Does Ansible have a feature like this? If it helps I am using Ansible 2.0.1.0
Keep in mind that applying tag do_roleA to a role adds do_roleA tag to every task in that role.
So your example role actually becomes:
# Role A:
- name: Always do this when doing role A
debug: msg="test"
tags:
- always
- do_roleA
- name: Task1
debug: msg="task1"
tags:
- do_task1
- do_roleA
- name: Task2
debug: msg="task2"
tags:
- do_task2
- do_roleA
You can remove always tag from that task, so after tagging a role with do_roleA it will be the only tag for that task.
So calling playbook with -t do_roleB will not execute that task.
For anybody who might land on this page having the same issue -- the solution is to use untagged:
playbook.yaml
- name: Preparing gateway node
hosts: "{{ hosts }}"
serial: 1
remote_user: root
any_errors_fatal: true
tasks:
- include_role:
name: my-role
tags: [ untagged, install, config, my-role-enable-service ]
my-role/tasks/main.yaml
- name: Task 1
debug:
msg: "Run when tags: untagged and config"
tags: [ untagged, config ]
- name: Task 2
debug:
msg: "Run when tags: untagged and install"
tags: [ untagged, install ]
- name: Task 3
debug:
msg: "Run when tags: my-role-enable-service"
tags: [ untagged, my-role-enable-service ]
When you run:
ansible-playbook playbook.yaml -- runs all tasks
ansible-playbook playbook.yaml --tags config -- runs only Task 1
ansible-playbook playbook.yaml --tags install -- runs only Task 2
ansible-playbook playbook.yaml --tags my-role-enable-service -- runs only Task 3
This quickly becomes handy when you have all-in-one roles that does installation or building from source in conjunction with configuration.
You can simply use --tags config after the installation steps have completed to speed-up your playbook instead of having to wait for things to build from sources every time.
I have a very simple ansible configuration:
- name: Prepare and intsall RethinkDB on available machines
hosts: all
roles:
- { role: rethinkdb, tags: ["install"] }
And a corresponding vagrant config:
universe.vm.provision "ansible" do |a|
a.playbook = "configuration.yml"
a.groups = {
"primary" => ["rmaster"],
"secondary" => ["rsecondary"]
}
end
The problem is if i call vagrant provision ansible runs rethinkdb role ignoring specified in configuration.yml file install tag. Though it works if i put it into vagrant as a.tags = "install", but it won't work if i have a sequence of ansible tasks to run with different tags, so i'd like to specify them from ansible playbook.
As far as I know, it's not possible for a playbook to define the role tags that will be run by the role. What tags: ["install"] does is to assign the install tag to the tasks from the rethinkdb role ("you may wish to assign tags to the roles you specify").
If your install, configure, launch, etc. tags are run in sequence, then you should be able to dispatch them to different (possibly dependent) roles. If not, then your only other solution is to run individual tasks using not tags but variable values.
E.g:
in roles/rethinkdb/tasks/main.yml:
- name: my_task
when: run_rethinkdb_install
in playbook.yml:
- name: Prepare and intsall RethinkDB on available machines
hosts: all
vars:
run_rethinkdb_install: True
roles:
- { role: rethinkdb, tags: ["install"] }