I am using the below task in my play book and trying to set condition using "when" to trigger the task.
the blow one is working
ansible-playbook vdomqury.yml -e adom=In-Adom-01 -e FGT=FGVM04TM19001830 -e vdom= -vvv
if i remove var vdom playbook stopped
ansible-playbook vdomqury.yml -e adom=In-Adom-01 -e FGT=FGVM04TM19001830 -vvv
tasks:
- name: USE CUSTOM TYPE TO QUERY AVAILABLE SCRIPTS
f_query:
adom: "{{ adom }}"
object: "custom"
custom_endpoint: "/pm/config/adom/{{ adom }}/_package/status/{{ FGT }}/{{ vdom }}"
register: results
tags: ADDLAG
when: vdom != ""
- name: USE CUSTOM TYPE TO QUERY AVAILABLE SCRIPTS
f_query:
adom: "{{ adom }}"
object: "custom"
custom_endpoint: "/pm/config/adom/{{ adom }}/_package/status/{{ FGT }}"
register: results
tags: ADDLAG
when: vdom == "" or vdom is not defined
Change the conditions to
when: vdom|default("")|length > 0
respectively
when: vdom|default("")|length == 0
You should check if vdom is defined before making a comparison on it, otherwise the interpreter will unsuccessfully try to fetch its value. This should work (can't check right now): when: vdom is defined and vdom != "".
Related
I'm having hard time trying to figure it out what I'm doing wrong with my Ansible playbook.
I've got a bunch of tasks, which define or not some variables according to context, depending of the result, some task will be ignored or not.
For this specific case, I check if a VlanID already exists, if it doesn't then I create one, and retrieve the new VlanID from the result.
Here is the playbook :
---
#Tasks for portGroup_add
- name: Get all portgroups in dvswitch vDS
community.vmware.vmware_dvs_portgroup_find:
hostname: "{{ vcenter_server }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
dvswitch: "{{ vcenter_dvSwitch }}"
validate_certs: False
register: portGroup_infos
when: (OLD_VLANID is not defined) or (OLD_VLANID|length < 1)
#Get last VLAN ID for HDS client, and set VLANID + 1
- name: get portGroup_infos
set_fact:
VLANID: "{{ item.vlan_id }}"
with_items: "{{ portGroup_infos.dvs_portgroups}}"
when:
- (portGroup_infos is defined) and (portGroup_infos|length > 0)
- item.name | regex_search("\(HDS :\s*")
While everything is working pretty well for most of the tasks, this one fires the following error :
The conditional check 'item.name | regex_search("\(HDS :\s*")' failed.
The error was: error while evaluating conditional (item.name | regex_search("\(HDS :\s*")): 'item' is undefined
Which is pretty obvious, because the dict portGroup_infos, is not defined.
In order to get the new VlanID, I'm using a "when" conditionnal , which check if in the item, the value "(HDS :" , is present.
But I don't want the task to launch if the portGroup_infos variable defined above is not set, I though I'd should use nested "when", but can't succeed.
Ansible version : 2.10.7
python version : 3.7.3
Thank you for your help.
Put both tasks into a block, e.g.
- block:
- name: Get all portgroups in dvswitch vDS
...
- name: get portGroup_infos
...
when: OLD_VLANID|default('')|length == 0
Is it possible to use the skip_reason as condition to another task?
Here is the task:
- name: PSP Validation
script: roles/OS_minor_upgrade/files/PSP_validation.sh
ignore_errors: true.
register: PSP_VAL
when: >
not 'VMware' in HWMODEL.stdout
Which output:
TASK [OS_minor_upgrade : PSP Postwork] ******************************************************************************************************************************************************
task path: /home/ansible/linuxpatching_OS_Upgrade/roles/OS_minor_upgrade/tasks/upgrade.yml:264
skipping: [server123] => {
"changed": false,
"skip_reason": "Conditional result was False"
}
Now I want to use the above as condition to execute another task, I tried with the task below but it seem like it is not working.
- name: OSupgrade done
shell: echo {{ inventory_hostname }} "OS Upgrade Done" > OUTGOING-OSUPGRADE-PATCHCOMPLETION/inventory_{{ inventory_hostname }}_{{ '%y%m%d%H%M%S' | strftime }}_Offlineoutput
delegate_to: localhost
when: >
fs_check.rc == 0 and val_etrust.rc == 0 and 'PSP Installation is successfully completed' in PSP_VAL.stdout or 'Conditional result was False' in PSP_VAL.skip_reason
How can this be achieved?
Technically, you can use 'skip_reason' as any other variable, but I STRONGLY suggest you not to.
The reason is that person, reading your code (you, 1 week later) would be in a total loss over such decision.
If you have important information about your host, you can use set_fact module to update your host information. Further tasks can use this to make decisions.
- name: Update vmware info
set_fact:
vmware_flag: ('VMware' in HWMODEL.stdout)
- name: PSP Validation
script: roles/OS_minor_upgrade/files/PSP_validation.sh
failed_when: false
register: PSP_VAL
when: not vmware_flag
- name: OSupgrade done
delegate_to: localhost
copy:
dest: OUTGOING-OSUPGRADE-PATCHCOMPLETION/inventory_{{ inventory_hostname }}_{{ '%y%m%d%H%M%S' | strftime }}_Offlineoutput
content: '{{ inventory_hostname }} "OS Upgrade Done"'
when: (some other conditions) or vmware_flag
There are specific ansible tests to verify the registered result of a task
In your specific case:
when: <...all other conditions...> or PSP_VAL is skipped
How do we check for a registered variable if only one of the two conditions turns out to be true having the same registered variable?
Below is my playbook that executes only one of the two shell modules.
- name: Check file
shell: cat /tmp/front.txt
register: myresult
when: Layer == 'front'
- name: Check file
shell: cat /tmp/back.txt
register: myresult
when: Layer == 'back'
- debug:
msg: data was read from back.txt and print whatever
when: Layer == 'back' and myresult.rc != 0
- debug:
msg: data was read from front.txt and print whatever
when: Layer == 'front' and myresult.rc != 0
Run the above playbook as
ansible-playbook test.yml -e Layer="front"
I do get error that says myresult does not have an attribute rc. What is the best way to print debug one statements based on the condition met?
I tried myresult is changed but that too does not help. Can you please suggest.
Use ignore_errors: true and change the task order. Try as below.
- name: Check file
shell: cat /tmp/front.txt
register: myresult
when: Layer == 'front'
- debug:
msg: data was read from front.txt and print whatever
when: not myresult.rc
ignore_errors: true
- name: Check file
shell: cat /tmp/back.txt
register: myresult
when: Layer == 'back'
- debug:
msg: data was read from back.txt and print whatever
when: not myresult.rc
ignore_errors: true
We need to go through this structure
Zone spec
https://gist.github.com/git001/9230f041aaa34d22ec82eb17d444550c
I was able to run the following snipplet but now I'm stucked at the error checking.
playbook
--
- hosts: all
gather_facts: no
vars_files:
- "../doc/application-zone-spec.yml"
roles:
- { role: ingress_add, customers: "{{ application_zone_spec }}" }
role
- name: check if router exists
shell: "oc get dc -n default {{ customers.zone_name }}-{{ item.type }}"
with_items: "{{ customers.ingress }}"
ignore_errors: True
register: check_router
- name: Print ingress hostnames
debug: var=check_router
- name: create new router
shell: "echo 'I will create a router'"
with_items: "{{ customers.ingress }}"
when: check_router.rc == 1
Output of a ansible run
https://gist.github.com/git001/dab97d7d12a53edfcf2a69647ad543b7
The problem is that I need to go through the ingress items and I need to map the error of the differnt types from the "check_router" register.
It would be nice to make something like.
Pseudo code.
Iterate through the "customers.ingress"
check in "check_router" if the rc is ! 0
execute command.
We use.
ansible-playbook --version
ansible-playbook 2.1.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
You can replace the second loop with:
- name: create new router
shell: "echo 'I will create a router with type {{ item.item }}'"
with_items: "{{ check_router.results }}"
when: item.rc == 1
This will iterate over every step of check_route loop and you can access original items via item.item.
I want to conditionally define a variable in an Ansible playbook like this:
my_var: "{{ 'foo' if my_condition}}"
I would like the variable to remain undefined if the condition does not resolve to true.
Ansible gives the following error if I try to execute the code:
fatal: [foo.local] => {'msg': 'AnsibleUndefinedVariable: One or more undefined
variables: the inline if-expression on line 1 evaluated
to false and no else section was defined.', 'failed': True}
Why is this an error anyway?
The complete case looks like this:
{role: foo, my_var: "foo"}
If my_var is defined, the role does something special. In some cases, I don't want the role to do this. I could use when: condition, but then I would have to copy the whole role block. I could also use an extra bool variable, but I would like a solution without having to change the "interface" to the role.
Any ideas?
You could use something like this:
my_var: "{{ 'foo' if my_condition else '' }}"
The 'else' will happen if condition not match, and in this case will set a empty value for the variable. I think this is a short, readable and elegant solution.
This code may help you to define a variable with condition.
- hosts: node1
gather_facts: yes
tasks:
- name: Check File
shell: ls -ld /etc/postfix/post-install
register: result
ignore_errors: yes
- name: Define Variable
set_fact:
exists: "{{ result.stdout }}"
when: result|success
- name: Display Variable
debug: msg="{{ exists }}"
ignore_errors: yes
So here the exists will display only if the condition is true.
My example, after https://stackoverflow.com/a/43403229/5025060:
vars:
sudoGroup: "{{ 'sudo' if ansible_distribution == 'Ubuntu' else 'wheel' }}"
Because of the different sudo conventions used by Ubuntu versus other platforms, here I am telling Ansible to set a variable named sudoGroup to sudo if the platform is Ubuntu, otherwise set it to wheel.
Later in my playbook, I combine the variable with Ansible's user module to add either sudo or wheel to an account's secondary groups depending on the OS Ansible is running on:
- name: Add or update bob account
user:
name: bob
uid: 3205
groups: "{{ sudoGroup }}"
append: yes
NOTES:
Double quotes around the {{ variable }} are required in the user: groups: definition above.
Once I define sudoGroup as above in my playbook's global vars: section, Ansible configures it at run time (based on ansible_distribution) for each target I define in my hosts: section.
I believe you're after the default(omit) filter. (Reference).
As per the example, mode will behave like it wasn't set at all for the first two items in the loop.
- name: touch files with an optional mode
file:
dest: "{{item.path}}"
state: touch
mode: "{{item.mode|default(omit)}}"
loop:
- path: /tmp/foo
- path: /tmp/bar
- path: /tmp/baz
mode: "0444"
This can be set as with bool:
- name: Conditional (true and false)
set_fact:
my_boolean_set_to_be: "{{ 'true' if my_var == 'foo' else 'false' }}"
- name: Display Variable
debug: msg="{{ my_boolean_set_to_be }}"
This can be set as for more conditionals like 'if-ifelse-else' statements:
- name: Conditional for 'my_var' (2 options and one default)
set_fact:
my_var_set_to_be: "{{ 'breakfast' if my_var == 'morning' else 'lunch' if my_var == 'afternoon' else 'dinner' }}"
- name: Display Variable
debug: msg="{{ my_var_set_to_be }}"