I noticed that since the new ansible with security patched is released, many our roles and playbooks are broken. For example, our role depends on this, it is also broken
https://github.com/Ansibles/generic-users/blob/master/tasks/main.yml#L3-L5
since it uses if else statements to generate optional arguments like gid. In the latest version of Ansible, it adds new arguments, so it fails to pass security check, an error like
A variable inserted a new parameter into the module args. Be sure to quote variables if they contain equal signs (for example: "{{var}}").
is raised.
I tried to modify the way arguments are passed by leveraging default filter
`
- name: generic-users | Make sure all groups are present
group: >
name=“{{ item.name }}”
system=“{{ item.system|default(‘no’) }}”
gid=“{{ item.gid|default(None) }}”
state=present
with_items: genericusers_groups
`
For argument “system”, there is a value “no” I can use as a default value, no problem at all. But for “gid”, I tried to feed it with “default(None)”, the value will be rendered as string first anyway, so that would be gid=None, ValueError be raised. As a result, unavoidable, I need to pass a valid value to gid.
I saw some discuss in this issue report: https://github.com/ansible/ansible/issues/8233
I understand that for security reason, if-else statements in playbook are not welcomed, but the problem is without if-else statements, I have no idea how to omit arguments without “do not set anything for this” value. The problem is a little bit like Python’s not set default value, we usually create an object stands for not_set value like this
`
NOT_SET = object()
def foobar(value=NOT_SET):
pass
`
But in ansible, I didn’t see anything like that. Or did I miss something? I think it would be helpful if there is some kind of special filter like
`
- name: generic-users | Make sure all groups are present
group: >
name=“{{ item.name }}”
system=“{{ item.system|default(‘no’) }}”
gid=“{{ item.gid|default_omit) }}”
state=present
with_items: genericusers_groups
`
The default_omit filter here omits “gid” argument if it is not defined. Just an idea. However, since modifying context in a jinja2 template would be difficult to implement, I think maybe it’s better to encourage YAML style arguments like this:
`
- name: generic-users | Make sure all groups are present
group:
name: “{{ item.name }}”
system: “{{ item.system|default(‘no’) }}”
gid: “{{ item.gid|default_omit) }}”
state=present
with_items: genericusers_groups
`
And for the default_omit, maybe it can return a random nonce generated by system (so that attacker cannot inject this value to remove argument), like this
omit_place_holder_8843d7f92416211de9ebb963ff4ce28125932878
And when ansible sees this value for a argument, it simply remove the key from arguments instead of passing it down to module.
But anyway, these are just some thinkings, the more important thing is, I would like to know, at this moment, how can I solve that “gid” cannot be omit issue? Is there any workaround? There are so many modules there, if you give an argument there, it means you want to change that thing, and there is no not_set value.