spoovy
spoovy

Reputation: 343

How to create a 'null' default in Ansible

I want 'lucy' to follow the user module creators' default behaviour which is to create and use a group matching the user name 'lucy'. However for 'frank' I want the primary group to be an existing one; gid 1003. So my hash looks like this:

lucy:
  comment: dog
frank:
  comment: cat
  group: 1003

And my task looks like this:

- name: Set up local unix user accounts
  user:
    name: "{{ item.key }}"
    comment: "{{ item.value.comment }}"
    group: "{{ item.value.group | default(undef) }}"
  loop: "{{ users|dict2items }}"

This doesn't work, as undef is not recognised. Nor is anything else I can think of. 'null', 'None' etc. all fail. '' creates an empty string which is not right either. I can't find out how to do it. Any ideas?

Upvotes: 11

Views: 27872

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68254

default(omit) is what you are looking for. For example,

- name: Set up local Unix user accounts
  user:
    name: "{{ item.key }}"
    comment: "{{ item.value.comment }}"
    group: "{{ item.value.group | default(omit) }}"
  loop: "{{ users|dict2items }}"

Comments

Comment by Lucas Basquerotto: "... omit only works correctly when used directly in a module, it won't work in a set_fact ..."

A: You're wrong. For example, default(omit) works both in set_fact and in the module. The first item in the list defaults to false with the result "VARIABLE IS NOT DEFINED!". The second item defaults to omit. Omitted parameter get_checksum defaults to true with the checksum in the results

shell> cat pb.yml
- hosts: localhost
  tasks:
    - set_fact:
        test:
          - "{{ gchk|default(false) }}"
          - "{{ gchk|default(omit) }}"
    - stat:
        path: /etc/passwd
        get_checksum: "{{ item }}"
      loop: "{{ test }}"
      register: result
    - debug:
        var: item.stat.checksum
      loop: "{{ result.results }}"

gives

shell> ansible-playbook pb.yml | grep item.stat.checksum
  item.stat.checksum: VARIABLE IS NOT DEFINED!
  item.stat.checksum: 7c73e9f589ca1f0a1372aa4cd6944feec459c4a8

In addition to this, default(omit) works as expected also in some expressions. For example

    - debug:
        msg: "{{ {'a': item}|combine({'b': true}) }}"
      loop: "{{ test }}"

gives

  msg:
    a: false
    b: true

  msg:
    b: true

See the results without default values

shell> ansible-playbook pb.yml -e "gchk={{ true|bool }}"

It does not work when passing vars to a module (a template in my case ...). When using omit, the template gets the value of the placeholder instead.

A: Of course, it doesn't work in this use case. For example,

shell> cat pb.yml
- hosts: localhost
  tasks:
    - debug:
        msg: |
          {{ var1 }}
          {{ var2 }}
      vars:
        var1: "{{ foo }}"
        var2: "{{ bar|default(omit) }}"

gives

shell> ansible-playbook pb.yml -e foo=123
  ...
  msg: |-
    123
    __omit_place_holder__73431d735cecaedbd9c4386e2ebc77ded8eaee51

The goal is to omit a parameter in a module. The question says: I can think of. 'null', 'None' etc. all fail. '' creates an empty string which is not right either. I can't find out how to do it. Any ideas? This is not your use case. The title is misleading, perhaps? Set the default to None if you want to use null. Perhaps, this will do what you want.

      vars:
        var1: "{{ foo }}"
        var2: "{{ bar|default(None) }}"

Upvotes: 29

Related Questions