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'] }}" }
Related
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
I would like to have dictionary defined in ansible like this
vhosts:
git_branch_1:
- { a: example.com, customer: a }
- { a: example.com, customer: b }
- { a: example.org, customer: a }
git_branch_2:
- { a: example.com, customer: x }
- { a: example.org, customer: y }
Some tasks I need to loop only over dict keys, this works fine
- name: "just debug"
debug: msg={{ item }}
with_items: "{{ vhosts.keys() }}"
But some tasks I would like to iterate over list from each key, and append the key as another property of dict, so I would like to combine/create new dict from this original dict, that will look like this:
combined_vhosts:
- { a: example.com, customer: a, branch: git_branch_1 }
- { a: example.com, customer: b, branch: git_branch_1 }
...
- { a: example.com, customer: x, branch: git_branch_2 }
And in some tasks I just need to get only the top level domain:
domains:
- example.com
- example.org
Is there a way, how can I achive this in ansible set_facts / jinja2 notation or do I have to write a custom plugin for ansible in python?
You can achieve this with set_fact:
---
- hosts: localhost
gather_facts: no
vars:
vhosts:
git_branch_1:
- { a: example.com, customer: a }
- { a: example.com, customer: b }
- { a: example.org, customer: a }
git_branch_2:
- { a: example.com, customer: x }
- { a: example.org, customer: y }
tasks:
- set_fact:
tmp_vhosts: "{{ item.value | map('combine',dict(branch=item.key)) | list }}"
with_dict: "{{ vhosts }}"
register: combined_vhosts
- set_fact:
combined_vhosts: "{{ combined_vhosts.results | map(attribute='ansible_facts.tmp_vhosts') | sum(start=[]) }}"
- debug:
msg: "{{ combined_vhosts }}"
More details about this trick with set_fact and with_ in this post.
To fetch all domains, you can use json_query('*[].a').
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.
top_level_main.yml
roles:
- { role: deploy_nds }
roles/deploy_nds/vars/main.yml
artifact_url: urlsomething
roles/deploy_nds/meta/main.yml
dependencies:
- {role: download_artifact, url: artifact_url }
roles/download_artifactory/tasks/main.yml
- name: download artifact from jfrog
get_url:
url: "{{ url }}"
dest: /var/tmp
I tried using variable name as "{{ artifact_url }}" but still it does not work as expect. Can someone please help?
I have explicitly included vars file of perticular role in playbook then it worked.
vars_files:
- roles/deploy_nds/vars/main.yml
roles:
- { role: deploy_nds }
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' ] }