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.
Related
I have a generic tasks, like update a DNS records based on my machine -> server
Which I use it in my playbooks with include_tasks like so:
- name: (include) Update DNS
include_tasks: task_update_dns.yml
I have many of these "generic tasks" simply acting as a "shared task" in many playbooks.
But in some cases, I just want to run one of these generic tasks on a server, but running the following gives the below error:
ansible-playbook playbooks/task_update_dns.yml --limit $myserver
# ERROR
ERROR! 'set_fact' is not a valid attribute for a Play
Simply because it's not a "playbook" they are just "tasks"
File: playbooks/task_update_dns.yml
---
- name: dig mydomain.com
set_fact:
my_hosts: '{{ lookup("dig", "mydomain.com").split(",") }}'
tags: always
- name: Set entries
blockinfile:
....
I know I can write a playbook, empty, that only "include" the task file, but I don't want to create a shallow playbook now for each task.
Is there a way to configure the task file in such way that I'll be able to run it for both include_tasks and as a "stand alone"/play command line ?
Have you tried to use custom tags for those tasks?
Create a playbook with all the tasks
---
- name: Update web servers
hosts: webservers
remote_user: root
tasks:
- name: dig mydomain.com
set_fact:
my_hosts: '{{ lookup("dig", "mydomain.com").split(",") }}'
tags: always
- name: Set entries
blockinfile:
tags:
- set_entries
- name: (include) Update DNS
include_tasks: task_update_dns_2.yml
tags:
- dns
...
when you need to run only that specific task, you just need to add the --tag parameter in the execution with the task name
ansible-playbook playbooks/task_update_dns.yml --limit $myserver --tag set_entries
I have some issues tagging tasks in roles.
I need to put some sql in sync mode, update some for patching with other hosts, and after etc
When i run my playbook i pass the tags different ways. I tried all sort of ways
Ans in the roles tasks i tag the tasks in the files with the tags i want to associate
When i use a main.yml, it tried to run all the tasks in the main regardless of the tagging, for the first host on the first line
When i dont use a main.yml or its empty the hosts tagging works but it does not run the playbook, only gather facts
here is my playbook:
---
- name: put sql in sync mode
hosts: v1sql02d
roles:
- role: winupdates
tags: [ sync ]
- name: update sql not on primary
hosts: v3sqlax01d, v3sql01d, v1sql03d
roles:
- role: winupdates
tags: [ updates ]
here is my main.yml
- name: run sql ag sync tasks
include: winagsync.yml tags=sync
- name: update sql on secondary
include: winupdates.yml tags=updates
here is my first task in tasks
win_shell: |
Set-ExecutionPolicy RemoteSigned
Powershell lines
tags:
- sync
and my winupdate one
win_updates:
state: searched
server_selection: default
register: update_count
debug: var=update_count
log_path: c:\ansible_win_updates.log
tags:
- updates
- name: Install Updates, Security and Critical
win_updates:
state: installed
server_selection: default
register: update_count
debug: var=update_count
log_path: c:\ansible_win_updates.log
reboot: yes
tags:
- updates
Please enlight me or help me
Thanks
Theoneakta
I would like to skip some of the plays based on a conditional value.
I could have a task at the beginning that would skip some of the other tasks when a condition is met.
I know I could always use set_fact and use this as a condition to run the other plays (roles and tasks) or evaluate the said condition directly in each play I want to skip.
However, since the plays already have a tagging system in place, is there something like set_tags in Ansible that I could leverage on to avoid having to add conditions all over my plays and bloat my already heavy playbook.
Something such as:
- name: skip terraform tasks if no file is provided
hosts: localhost
tasks:
set_tags:
- name: terraform
state: skip
when: terraform_files == ""
The two plays I'd like to skip:
- name: bootstrap a testing infrastructure
hosts: localhost
roles:
- role: terraform
state: present
tags:
- create_servers
- terraform
[...]
- name: flush the testing infrastructure
hosts: localhost
roles:
- role: terraform
state: absent
tags:
- destroy_servers
- terraform
If I understood correctly, the following should do the job:
- name: bootstrap a testing infrastructure
hosts: localhost
roles:
- role: terraform
state: present
when: terraform_files != ""
tags:
- create_servers
- terraform
[...]
- name: flush the testing infrastructure
hosts: localhost
roles:
- role: terraform
state: absent
when: terraform_files != ""
tags:
- destroy_servers
- terraform
This is basically the same as setting the when clause on every single tasks in the role. So each task will be inspected but skipped if the condition is false.
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 want to use the module mongodb_replication defined in greendayonfire.mongodb role.
I know I can use the module in my tasks after applying the role in the same play. But I don't want to apply the role (and execute all it's tasks). Is there any way to get to "include" the role without executing the tasks?
I want to have it like this
---
- hosts: mongodb-nodes
become: true
roles:
- base
- greendayonfire.mongodb
vars:
mongodb_package: mongodb-org
mongodb_version: "3.2"
mongodb_force_wait_for_port: true
mongodb_net_bindip: 0.0.0.0
mongodb_net_http_enabled: true
mongodb_replication_replset: "rs1"
mongodb_storage_prealloc: false
- hosts: mongodb-0
tasks:
- mongodb_replication: replica_set=rs1 host_name=item state=present
with_items:
- mongodb-0
- mongodb-1
- mongodb-2
where the second play is the one that runs the mongodb_replication module (only in the node mongodb-0). Right now it can't find the module.
I guess can I copy the module out of the role into my playbook but I will be cleaner if I could just import the module from the role (which I don't want to edit)
I found that it's possible to load the role without executing the task by using the when: false clause when referring to the role. This loads the vars, defaults, modules, etc.
- hosts: mongodb-0
roles:
- role: greendayonfire.mongodb
when: false
tasks:
- mongodb_replication: replica_set=rs1 host_name=item state=present
with_items:
- mongodb-0
- mongodb-1
- mongodb-2