I would like to know if it's possible with Ansible to test 2 values in a when
condition that are changed in the loop.
disksizefromjson
is a variable that I extracted from a json file (and this value is being correctly changed when I remove the when
condition).
item['Size']
is the variable that I extracted from a previous task with a powershell command.
---
- name: get disk info on windows vm
ansible.windows.win_powershell:
script: |
Get-ciminstance win32_volume -Filter DriveType=3 | where-object{$_.Label -notlike "*Reserved*" -and $_.SystemVolume -ne $true} | Select-Object Name, Label, FileSystem, BlockSize, @{'Name'='Size'; 'Expression'={[math]::Ceiling($_.Capacity / 1GB)}}, @{'Name'='Freespace'; 'Expression'={[math]::Ceiling($_.Freespace / 1GB)}}, @{'Name'='Free'; 'Expression'={[math]::Ceiling(($_.Freespace * 100)/$_.Capacity)}} | Sort-Object Name
register: diskNewVm
- name: test disk size
set_fact:
disksizefromjson: "{{ diskinfosfromjson | from_json | selectattr('Name', 'equalto', item['Name']) | map(attribute='Size') | first | default(10) }}"
when: item['Size'] > disksizefromjson
loop: "{{ diskNewVm.output }}"
This results in the following error:
The conditional check 'item['Size'] > disksizefromjson' failed. The error was: error while evaluating conditional (item['Size'] > disksizefromjson): 'disksizefromjson' is undefined
When I remove the when
condition, disksizefromjson
is defined well...
So, is it possible to have 2 variables in when condition?
So, is it possible to have 2 variables in when condition?
Sure, you can use any number of variables there. But the error that Ansible gives you is absolutely expected because during the first iteration of your loop the disksizefromjson
variable (by the way, Ansible is Python-based, so it's recommended to use the snake case notation) doesn't exist yet.
If you know a safe default value for your case, you can simply define it using the default
filter (note I used a trimmed multiline YAML string without newline preservation for a better readability of a long chain of Jinja2 filters):
- name: test disk size
set_fact:
disksizefromjson: >-
{{
diskinfosfromjson
| from_json
| selectattr('Name', 'equalto', item['Name'])
| map(attribute='Size')
| first
| default(10)
}}
when: item['Size'] > disksizefromjson | default(10)
loop: "{{ diskNewVm.output }}"
Speaking of which, it seems like you tried to do that because you used a | default(10)
inside the variable definition itself. There is another problem with your template: the default
filter, as any other, doesn't work exactly as a try-catch construct, it refers to the previous value. So, in your case, it will only work if the first
item of your map(attribute='Size')
is undefined.