Is it possible to import roles into an ansible playbook? - ansible

I have a bunch of playbooks where a big percentage of roles are common to all servers. So I'd like to do something like:
---
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- include: initial_setup.yml
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }
The initial_setup.yml would be something like:
- { role: role1, tags: ['role1' ] }
- { role: role2, tags: ['role2' ] }
Is it possible?

That's not possible as far as I know, but there is a simple workaround. You can create a role which will only have dependencies on other roles. To follow your example, you can create a role initial_setup, by creating a directory roles/initial_setup and in it create a directory meta with a file main.yml:
# roles/initial_setup/meta/main.yml
---
dependencies:
- { role: 'role1', tags: 'role1' }
- { role: 'role2', tags: 'role2' }
Now you can use initial_setup as any regular role:
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- { role: initial_setup, tags: ['initial_setup' ] }
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }

Related

How to put pause between ansible roles

Here is my playbook:
---
- hosts: "mms"
user: wladmin
roles:
- { role: App1 }
- { role: App2 }
- { role: App3 }
- { role: App4 }
I wish to put pause of 30 seconds between these ansible roles.
I tried the below but it give me syntax error:
roles:
- { role: App1 }
pause:
seconds: 30
- { role: App2 }
pause:
seconds: 30
- { role: App3 }
I also tried
roles:
- { role: App1 }
- pause:
seconds: 30
- { role: App2 }
- pause:
seconds: 30
- { role: App3 }
Can you please suggest?
pause isn't a role, so you can't include it in the roles section of your play. pause is a task. You have a couple of options:
Use import_role tasks instead of the roles section
For example:
- hosts: localhost
tasks:
- import_role:
name: App1
- pause:
seconds: 30
- import_role:
name: App2
- pause:
seconds: 30
- import_role:
name: App3
Create a "pause" role
Create a pause role. Put this in roles/pause/tasks/main.yml:
- name: pause
pause:
seconds: "{{ pause_seconds|default(30) }}"
And this in roles/pause/meta/main.yml:
allow_duplicates: true
Now you can write:
- hosts: localhost
roles:
- App1
- pause
- App2
- pause
- App3

Ansible conditionals on list variables passed into a role

I have following ansible code
- hosts: localhost
roles:
- { role: roleone }
- { role: roletwo, myvariable : ["var1","var2"] }
I need to set this list variable based on conditional.
Below is what I have tried, although it does not work:
- hosts: localhost
roles:
- { role: roleone }
- { role: roletwo, myvariable : ["foo1","foo2"], when: init=="true", myvariable : ["bar1","bar2"], when: init == "false" }
I was able to achieve this by using following code:
---
- hosts: all
roles:
- { role: roleone }
- { role: roletwo, myvariable: "{{ ['var1','var2'] if (init == "true") else ['bar1','bar2'] }}" }

Ansible - Use when condition in a playbook for roles

I am trying to add a when condition in my ansible-playbook. However, I am not able to figure out the exact syntax/method to do it because my roles are using additional parameters. Below mentioned is my playbook
---
- name: Deploying application code
hosts: uat-aegis
roles:
- { role: roles/send_slack, slack_message_text: "*`Started : Deploying code for {{ module_name }} on {{ inventory_hostname }}`*"}
- { role: roles/application_code_backup, backup_directory_name: "NAME", repo_directory: "/path/to/repo" }
- { role: roles/application_copy_config, repo_directory: "/path/to/repo"}
- { role: roles/application_git_pull, repo_url: "git#code.git", repo_directory: "/path/to/repo", branch_name: "BRANCH_NAME"}
- { role: roles/application_pm2_restart, process_name: "NAME" }
- { role: roles/send_slack, slack_message_text: "*`=== Completed : Deploying code for {{ module_name }} on {{ inventory_hostname }} ===`*"}
Here I need to execute roles/application_copy_config only when a certain variable value is true. This variable value is passed as --extra-vars while executing the ansible-playbook from Jenkins(Boolean value parameter in Execute Script). I have tried using the below piece of code but it does not work.
---
- name: Deploying application code
hosts: uat-aegis
roles:
- { role: roles/send_slack, slack_message_text: "*`Started : Deploying code for {{ module_name }} on {{ inventory_hostname }}`*"}
- { role: roles/application_code_backup, backup_directory_name: "NAME", repo_directory: "/path/to/repo" }
- { role: roles/application_copy_config
when: "copy_config=true", repo_directory: "/path/to/repo"}
- { role: roles/application_git_pull, repo_url: "git#code.git", repo_directory: "/path/to/repo", branch_name: "BRANCH_NAME"}
- { role: roles/application_pm2_restart, process_name: "NAME" }
- { role: roles/send_slack, slack_message_text: "*`=== Completed : Deploying code for {{ module_name }} on {{ inventory_hostname }} ===`*"}
ansible-playbook command is as follows
ansible-playbook plays/deploy_application/code.yml --extra-vars "module_name=$MODULE_NAME config_copy_path=$CURRENT_PATH/ env=$ENVIRONMENT copy_config=$COPY_CONFIG"
Please help me to use the when condition in the ansible-playbook. This is required becuase I need to execute the role: roles/application_copy_config only when the variable value is true. I have used this reference for adding when condition in the role
Was able to apply the when condition for boolean values using bool filter as mentioned below
---
- name: Deploying application code
hosts: uat-aegis
roles:
- { role: roles/send_slack, slack_message_text: "*`Started : Deploying code for {{ module_name }} on {{ inventory_hostname }}`*"}
- { role: roles/application_code_backup, backup_directory_name: "NAME", repo_directory: "/path/to/repo", when: var1 | bool }
- { role: roles/application_copy_config, repo_directory: "/path/to/repo"}
- { role: roles/application_git_pull, repo_url: "git#code.git", repo_directory: "/path/to/repo", branch_name: "BRANCH_NAME", when: var2 | bool}
- { role: roles/application_pm2_restart, process_name: "NAME", when: not var3 | bool }
- { role: roles/send_slack, slack_message_text: "*`=== Completed : Deploying code for {{ module_name }} on {{ inventory_hostname }} ===`*"}
Use the below code to check true and false
when: var1 | bool ----> true
when: not var2 | bool ----> false
You can specify conditionals with different style:
- name: Deploying application code
hosts: uat-aegis
roles:
- role: roles/application_code_backup
vars:
backup_directory_name: "NAME"
repo_directory: "/path/to/repo"
when: var1 | bool

Ansible: execute role only for some hosts

Let's say I have a single playbook with some roles for the installation of an appserver and I like to apply the same playbook on both production and testing servers.
Both production and testing servers have the same list of roles, with the exception of one, that only should be applied on production servers.
Is it possible to specify somehow that this role will only be applied to production servers using the same playbook?
For example, if the playbook is:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"] }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
and I have two inventories: one for production and one for testing.
When I run the playbook using the testing inventory, I don't want the role 'firewall' to be executed.
My idea is do something like setting a variable in the 'production' inventory and use something like 'if <var> is set, then execute role 'firewall'' ... I don't know if this is possible, and if it is, how to do it?
You can define a variable, for example production_environment, in your inventory files, assign true or false value and use a when conditional in the playbook:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"], when: production_environment }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
Or you can access inventory_file variable directly. For example if you use -i production:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"], when: inventory_file == "production" }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
Which way you go is an administrative decision. The second method uses less steps, but requires the inventory file name to be "hardcoded" in the playbook.
Why don't you just use inventory groups?
Make two inventories:
testing:
[application]
my-dev-server
production:
[application]
company-prod-server
[firewall]
company-prod-server
And change your playbook as follows:
---
- hosts: firewall
roles:
- { role: firewall, tags: ["firewall"] }
- hosts: application
roles:
- { role: mail, tags: ["mail"] }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
- { role: firewall, tags: ["firewall"], when: MyVar }
See Applying ‘when’ to roles and includes.

How do I call a role from within another role in Ansible?

My playbook runs a list of roles:
roles:
- common
- postgres
- nginx
- supervisord
- { role: deploy_app, app_name: myapp }
- { role: deploy_app, app_name: otherapp }
I have another role, celery, that I only want to run when the app named myapp is created using deploy_app. I was thinking I should pass a parameter into the role like this:
- { role: deploy_app, app_name: myapp, celery: yes }
Then within my deploy_app role, I would use a when conditional:
- name: create celery worker for application
<RUN ROLE HERE>
when: '{{ celery }}' == 'yes'
How can I conditionally run a role from within a task list?
I think ansible depenencies would help here. Just create a
/meta/main.yml inside your role with the following:
---
dependencies:
- { role: celery, tags: ["sometag"], when: "celery == 'yes'" }
I would suggest to not call from within a playbook and either use a condition in your entry books
- { role: celery, tags: ["sometag"], when: "celery == 'yes'" }
or simply convert it into a group of tasks in a file and do a conditional import
Hope that helps.

Resources