Second ansible role not running in playbook - ansible

I am experimenting with using roles in a playbook. My simple playbook is as follows:
---
- name: Simple playbook
hosts: all
tasks:
- name: Role1
include_role:
name: role1
vars:
debugmode : true
- name: Role2
include_role:
name: role2
vars:
debugmode : true
I run the playbook with -vvv and I see all of my role1 tasks run. However, role2 tasks don't run, I just see this output (excerpt):
TASK [Role2] *********************************************************************************************************************************************************************************************************************************************************
task path: /myplaybook.yml:10
META: ran handlers
META: ran handlers
my my role2/tasks/main.yml file is:
- debug:
msg: "In create_vms role"

Although the cause of the problem is rather silly, I suspect this may help someone else.
The problem was that my file was accidentally named
role2/tasks/mail.yml
(not main.yml).
So ansible had no problem with this, it just ignored the file and did nothing. Seems like ansible should raise some kind of warning if no files are found in a role, so check for a typo :)

Related

Ansible - How to manage Large list of small tasks

I have written lots of small yaml task files for an ansible project.
Only few of these tasks files are being reused (say 30%).
I wonder how to manage this big list of tasks, should I convert all of them to roles, and call the playbook with roles:
Playbook as below (pls ignore the syntaxe), will be clear, But I do not like to have a role for each simple task.
- name: playbook with roles for each task
hosts: all
roles:
- small_task_1
- small_task_2
- small_task_3
- small_task_4
....
....
- small_task_20
I liked the idea of putting them 2-3 roles, and call the task with include_task (or import_task), but the problem is, to each call of a task, I have to add "import_role: , name: , tasks_from" EVEN THOUGH It's from the same role!
$ ansible-galaxy role list
$ /home/user1/.ansible/roles
roles_a, (unknown version)
roles_b, (unknown version)
in roles_a and roles_b, I may have around 10 yaml tasks for each
,,,
name: playbook with 2 roles
hosts: all
- name: small task 1
include_role:
name: role_a
tasks_from: small_task_1
- name: small task 2
include_role:
name: role_a
tasks_from: small_task_2
......
......
- name: small task 9
include_role:
name: role_a
tasks_from: small_task_9
- name: small task 10
include_role:
name: role_a
tasks_from: small_task_10
,,,
Above thing is not very handy...
I would like to group the tasks in a "role" (or any other ansible thing), and call the tasks from that group... something like :
,,,
name: playbook with 2 roles
hosts: all
- name: small tasks
include_role:
name: role_a
tasks_from: small_task_1
tasks_from: small_task_2
......
......
tasks_from: small_task_9
tasks_from: small_task_10
,,,
I've tried with block , but it does not shorten the playbook.
Can anyone guide me, please?
For your final example, you can just use a loop directive on your include_role task, like this:
- hosts: localhost
gather_facts: false
tasks:
- include_role:
name: role_a
tasks_from: "{{ item }}"
loop:
- small_task_1
- small_task_2
- small_task_3
- small_task_4

roles overides tasks in playbook

I have ansible playbook which look similar to the code below :
---
- hosts: localhost
connection: local
tasks:
- name: "Create custom fact directory
file:
path: "/etc/ansible/facts.d"
state: "directory"
- name: "Insert custom fact file"
copy:
src: custom_fact.fact
dest: /etc/ansible/facts.d/custom_fact.fact
mode: 0755
roles:
- role1
- role2
once i am running the playbook with ansible-playbook command
only the roles is running ,but the tasks is not getting ran
if i am remarking the roles from the playbook,the task gets ran
how can i make the task to run before the roles ?
Put the tasks in a section pre_tasks which are run before roles.
You may also find post_tasks useful which run tasks after roles.
Correct the indentation
- hosts: localhost
connection: local
tasks:
- name: "Create custom fact directory
file:
path: ...

Starting role from "tasks/alternate.yml" instead of "tasks/main.yml"

I have a large playbook that uses multiple roles to setup new servers. I'd like to re-use the playbook but for the decommission stage instead of calling into role_name/tasks/main.yml and having a lot of when: statements, I'd like to tell Ansible to call the role but start in role_name/tasks/decommission.yml.
As a first test I setup my main.yml file like this:
- name: "Provisioning new server"
block:
- name: "Include the provisioning steps."
include_tasks: provision.yml
when:
- not decom
- name: "DECOM - Unregister from Satellite server"
block:
- name: "DECOM - Include the deprovision steps."
include_tasks: decommission.yml
when:
- decom
But that's getting really ugly to maintain. Is this possible or am I overlooking an alternative way to setup the playbook?
Q: "Tell Ansible to call the role but start in role_name/tasks/decommission.yml"
A: Use include_role
- include_role:
name: role_name
tasks_from: decommission.yml
,or import_role
- import_role:
name: role_name
tasks_from: decommission.yml
See Re-using files and roles on what is the difference between including and importing a role.

Can I import a specific task from a role with dynamic name?

I have this role structure:
roles/
- a/
- tasks/
- main.yml
- k8s.yml
- templates/
- mytemplate.yml.j2
- b/
- tasks/
- main.yml
- k8s.yml
- templates/
- mytemplate.yml.j2
In my playbook I need to dynamically include a role, but running k8s.yml instead of main.yml. Something like this:
- roles:
- "{{ rolename }}/k8s.yml"
There's a include_role module that does exactly that:
- include_role:
name: "{{ rolename }}"
tasks_from: k8s
However this fails due to a bug that doesn't allow variables in the role name and will be fixed only on ansible 2.5 :(
Another approach would be to use include_tasks:
include_tasks: "roles/{{ rolename }}/tasks/k8s.yml"
The tasks are included and executed, but I get a failure message due to the fact that templates are not found (ansible tries to find the templates relative to the playbook dir, not the role dir):
TASK [Template processing] *********************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: /home/myuser/myproject/mytemplate.yml.j2
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find or access 'mytemplate.yml.j2'\nSearched in:\n\t/home/myuser/myproject/roles/a/tasks/templates/mytemplate.yml.j2\n\t/home/myuser/myproject/roles/a/tasks/mytemplate.yml.j2\n\t/home/myuser/myproject/templates/mytemplate.yml.j2\n\t/home/myuser/myproject/mytemplate.yml.j2"}
I even tried to overwrite the include_roles module with the patched version by adding it to myproject/library/, but I wasn't able to make it work.
Is there any way to accomplish this goal?
EDIT: The playbook works fine if the rolename variable is set on command line as an extra var, but it fails when it is set up with set_fact.
I was able to circumvent the bug by using hostvars:
- include_role:
name: "{{ hostvars[inventory_hostname]['rolename'] }}"
tasks_from: k8s
This way I can make it work until ansible 2.5 is released

Ansible: Skips "always" tags in roles

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.

Resources