Reputation: 135
I'm trying to supply all task parameters using a dictionary in Ansible. Earlier, the args
module (now deprecated) was a handy way of doing this. Some tasks that I'm trying to put in a loop have fewer parameters than the rest, and since I don't want any variables to be exposed in my plays, I'm looking for a solution that closely matches the args
approach.
The dictionary variable (note: the last element doesn't have an 'opts' key/parameter):
lvm_vars:
- {vg: {{ lvm_names.data_vol_group }} , lv: {{ lvm_names.index_lv }} , size: 5G, opts: -i 3 -I 256}
- {vg: {{ lvm_names.data_vol_group }} , lv: {{ lvm_names.data_lv }} , size: 5G, opts: -i 3 -I 256}
- {vg: {{ lvm_names.data_vol_group }} , lv: {{ lvm_names.wal_lv }} , size: 5G, opts: -i 3 -I 256}
- {vg: {{ lvm_names.data_vol_group }} , lv: {{ lvm_names.tblspc_lv }} , size: 5G, opts: -i 3 -I 256}
- {vg: {{ lvm_names.backup_vol_group }} , lv: {{ lvm_names.backup_lv }} , size: 5G}
The args solution:
- name: Create LVs ({{ item.lv }})
lvol:
args: "{{ item }}"
with_items: "{{ lvm_vars }}"
What the final unrolled tasks should look like:
- name: Create LVs
lvol:
vg: {{ lvm_names.data_vol_group }}
lv: {{ lvm_names.index_lv }}
size: 5G
opts: -i 3 -I 256
- name: Create LVs
lvol:
vg: {{ lvm_names.data_vol_group }}
lv: {{ lvm_names.data_lv }}
size: 5G
opts: -i 3 -I 256
- name: Create LVs
lvol:
vg: {{ lvm_names.data_vol_group }}
lv: {{ lvm_names.wal_lv }}
size: 5G
opts: -i 3 -I 256
- name: Create tblspc LV
lvol:
vg: {{ lvm_names.data_vol_group }}
lv: {{ lvm_names.tblspc_lv }}
size: 5G
opts: -i 3 -I 256
- name: Create LVs
lvol:
vg: {{ lvm_names.backup_vol_group }}
lv: {{ lvm_names.backup_lv }}
size: 5G
I'm also okay with supplying only the parameter values from the dictionary, but this is problematic because the last item in my dictionary doesn't use the "opts" parameter. So if I try doing something like this:
- name: Create LVs ({{ item.lv }})
lvol:
vg: "{{ item.vg }}"
lv: "{{ item.lv }}"
size: "{{ item.size }}"
opts: "{{ item.opts }}"
with_items: "{{ lvm_vars }}"
I obviously get an error because 'item.opts' is undefined for the last item.
Upvotes: 1
Views: 563
Reputation: 39264
What you are looking for is the default
filter with the special value omit
.
By default Ansible requires values for all variables in a templated expression. However, you can make specific variables optional. For example, you might want to use a system default for some items and control the value for others. To make a variable optional, set the default value to the special variable
omit
Source: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#making-variables-optional
- name: Create LVs ({{ item.lv }})
lvol:
vg: "{{ item.vg }}"
lv: "{{ item.lv }}"
size: "{{ item.size }}"
opts: "{{ item.opts | default(omit) }}"
with_items: "{{ lvm_vars }}"
With this, if your item
dictionary does not contains the opts
key, the whole opts
key of lvol
will be removed out of the dictionary, so resulting in your last loop being:
- name: Create LVs (lvm_names.backup_lv)
lvol:
vg: lvm_names.backup_vol_group
lv: lvm_names.backup_lv
size: 5G
Upvotes: 2