Check multiple conditions in ansible when - ansible

I am giving a condition to my ansible task:
- hosts: "{{ env }}"
user: "{{ us1 }}"
gather_facts: no
tasks:
- name: Deploy Services on "{{ env }}"
shell: sh "{{ script_path }}/test.sh"
when: (package == "abc") and (env.startswith('PA_') or env.startswith('lon'))
I am running the above playbook, when the package=abc and env=PA_, its running. But when env=lon, it is giving error:
fatal: [lonxxx.abc.com]: FAILED! =>
{
"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'lonxxx'\n\nThe error appears to be in '/home/dbrun/dbRunPlaybooks/deploy_application.yml': line 25, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Deploy Services on \"{{ env }}"\"\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n with_items:\n - {{ foo }}\n\nShould be written as:\n\n with_items:\n - \"{{ foo }}\"\n"
}
I tried giving the when condition in below manner:
when: >
(package == "abc") and
(env.startswith('PA_')) or (env.startswith('lon'))
But giving the same error.
Please help.

Related

hashi_vault pass variable/argument into the lookup query

Do you know if I'm able to pass variable into the lookup query?
password: "{{ lookup('hashi_vault', 'secret=secret/data/my_secret:data')['{{ myvar }}']}}"
where myvar is set to mypass
vault kv put secret/my_secret mypass=abcd123
I'm getting the following error.
{"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute '{{myvar}}'\n\nThe error appears to be in '.../ansible/roles/joetests/tasks/main.yml': line 23, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}
I've tried different quotations but it doesn't seem to work
password: "{{ lookup('hashi_vault', 'secret=secret/data/my_secret:data')['"{{ myvar }}"']}}"
password: "{{ lookup('hashi_vault', 'secret=secret/data/my_secret:data')["'{{ myvar }}'"]}}"
If I use the following it returns the password successfully.
password: "{{ lookup('hashi_vault', 'secret=secret/data/my_secret:data')['mypass']}}"
I'm currently testing a very simple playbook
---
- debug:
msg:
- "{{ item }} => {{ password }}"
with_items:
- "{{ myvar }}"
where
myvar:
- user1
- user2
- user3
Every variable inside the curly braces ({{ }}) will be interpolated, so the trick here is to actually remove the quotes altogether. Try this instead:
password: "{{ lookup('hashi_vault', 'secret=secret/data/my_secret:data')[myvar] }}"

Ansible regex tomcat version

I'm struggling with an issue for some hours now, I want in tasks file to do an action only for a specific version of tomcat, exemple :
- name: Copy new context.xml(Manager App) for tomcat8 or 9
template:
src: templates/tomcat8-9/manager/context.xml
dest: /usr/share/tomcat/webapps/manager/META-INF/context.xml
owner: tomcat
group: tomcat
when: "{{ tomcat_ver }}" is match("^[8-9]")
If my tomcat_ver is 9.0.20 then it should match the pattern but I'm getting a strange error, I don't see where I'm missing any quote
fatal: [tomcatbis]: FAILED! => {"reason": "Syntax Error while loading YAML.\n did not find expected key\n\nThe error appears to be in '/projects/ansibles/roles/tomcat/tasks/tomcat-setup-Debian.yml': line 69, column 28, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n group: tomcat\n when: \"{{ tomcat_ver }}\" is match(\"^[8-9]\")\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n with_items:\n - {{ foo }}\n\nShould be written as:\n\n with_items:\n - \"{{ foo }}\"\n"}
Thanks for your help.
It should be like below:
---
- hosts: localhost
tasks:
- name: plat
debug:
msg: "Success"
when: '"{{ tomcat_ver }}" is match("^[8-9]")'
single quotes at the start and at the end
Use the version comparison test
when: tomcat_ver is version('8', '==') or
tomcat_ver is version('9', '==')
(not tested)

Syntax to pass dynamic variables to include_tasks along with with_item in Ansible playbook

Executing parent.yml which in turn calls child.yml playbook for execution with dynamic variables.
Variables from parent.yml aren`t interpolated inside child.yml playbook. Correct me if I am using correct syntax?
Parent.yml
- name: Main playbook to call MySQL backup
hosts: localhost
gather_facts: no
tasks:
- include_task: child.yml
vars:
var1: "{{ item.name }}"
var2: "{{ item.db_name }}"
with_items:
- { name: '10.10.10.01', db_name: 'prod1' }
- { name: '10.10.10.02', db_name: 'prod2' }
child.yml (Takes mysqldump from managed DB)
- name: MySQL dump
hosts: localhost
#gather_facts: no
#vars:
# v1: "{{ var1 }}"
# v2: "{{ var2 }}"
tasks:
- name: Executing the shell script
shell: 'mysqldump -h "{{ var1 }}" -u"ansi" -p"*****" "{{ var2 }}"| gzip > /tmp/mysql_dump/"{{ var2 }}"_`date +%Y%m%d-%H%M`.gz'
fatal: [127.0.0.1]: FAILED! => {"reason": "no action detected in task. This often indicates a misspelled module name, or incorrect module path.\n\nThe error appears to be in '/home/ansible/playbooks/DBpatch/Linux/child.yml': line 1, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: MySQL dump\n ^ here\n"}
include_task expects a list of tasks but you give it a complete playbook.
Child.yml should only contain what is currently below the line "tasks:".
See also https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_includes.html

Ansible: how to check if a variable is being loaded in a playbook?

I'm trying to write a playbook that will load vars from a group vars file then check if a variable exists
my playbook is like this:
---
- hosts: "{{ target }}"
roles:
- app
tasks:
- name: alert if variable does not exist
fail:
msg: "{{ item }} is not defined"
when: "{{ item }}" is not defined
with_items:
- country
- city
- street
...
My inventory file contains
[app]
ansible-slave1
ansible-slave2
[db]
ansible-db
[multi:children]
app
db
and I have the roles/app/vars/main.yml containing
country: "France"
city: "Paris"
What I was expecting is the playbook to output "street is not defined" but I have a syntax issue I can't resolve
[vagrant#ansible-master vagrant]$ ansible-playbook --inventory-file=ansible_master_hosts test_variables.yml --extra-vars "target=ansible-slave1" --syntax-check
ERROR! Syntax Error while loading YAML.
The error appears to have been in '/vagrant/test_variables.yml': line 10, column 24, but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
msg: "{{ item }} is not defined"
when: "{{ item }}" is not defined
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
I'd be happy with any hints.
Thanks
You have "" in invalid place of "when" statement. This should be like this:
msg: "{{ item }} is not defined"
when: "{{ item }} is not defined"
So the output will be:
failed: [hostname] (item=street) => {"changed": false, "item": "street", "msg": "street is not defined"}
there is on open issue conditional is defined fails to capture undefined var .
as a workaround I'd suggest to change the where condition to the following:
when: "{{ item }}" == ""

Ansible variable check in playbook

I have in the vars file the databases configured as the following:
project_dbs:
- { project_db_name: "project1", project_db_user: "user", tenon_db_password: "pass" }
- { project_db_name: "project2", project_db_user: "dev", tenon_db_password: "pass2"}
- { project_db_name: "project3", project_db_user: "{{datadog_mysql_username}}", project_db_password: "{{datadog_mysql_password}}" }
Now in a playbook I have a check:
- name: copy config.json template to server
tags: provision
template: src=config.json dest={{ project_root }}/config
when: item.project_db_name == "project2"
with_items: project_dbs
But the when check is failing. Any idea how to make that work?
The error message looks like this:
fatal: [test]: FAILED! => {"failed": true, "msg": "The conditional check 'item.projects_db_name == \"project2\"' failed. The error was: error while evaluating conditional (item.projects_db_name == \"project2\"): 'unicode object' has no attribute 'projects_db_name'\n\nThe error appears to have been in '/var/lib/jenkins/project/ansible/roles/project2/tasks/main.yml': line 28, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: copy config.json template to server\n ^ here\n"}
You use an outdated syntax called "bare variables" in with_items:
with_items: project_dbs
This way your item becomes a string object with the value of project_dbs and Ansible reports it doesn't have the attribute ("'unicode object' has no attribute 'projects_db_name'").
In Ansible 2.x you should quote variables in the following way:
with_items: "{{ project_dbs }}"
That said, your task makes no use of the values from the loop. The following will have the same effect:
- name: copy config.json template to server
tags: provision
template: src=config.json dest={{ project_root }}/config
Instead of using when you could just filter the list of project_dbs so it looks like this:
- name: "copy config.json template to server"
tags: provision
template: src=config.json dest={{ project_root }}/config
with_items: "{{ project_dbs | selectattr("project_db_name", "project2") }}"

Resources