Ansible - skip undefined variable in dict

久未见 提交于 2021-01-05 10:38:09

问题


I`m using ipa_user module to setup users. There is variable passsword which force new password. For some users (when var is not in dict) I would like to skip it in iteration, but it always fail.

This is snippet from my playbook. Ansible version is 2.7

task:

- name: adding ipa users
  ipa_user:
    name: "{{ item.value.login }}"
    state: "{{ item.value.state }}"
    givenname: "{{ item.value.givenname }}"
    sn: "{{ item.value.surname }}"
    mail: "{{ item.value.mail }}"
    telephonenumber: "{{ item.value.telephonenumber }}"
    title: "{{ item.value.title }}"
    password: "{{ item.value.password }}" <<- to be skipped if not found
    ipa_host: ipa.gdi.telekom.de
    ipa_user: admin
    ipa_pass: "{{ ipa_pass }}"
  with_dict: "{{ipausers}}"
  when: item.key in ipausers.keys()
  register: output_ipa_users

Log:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'password'\n\nThe error appears to have been in '/builds/gitlab/infra/user-management/roles/free-ipa/tasks/main.yml': line 13, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: adding ipa users\n  ^ here\n"}

Note: I tried it with:

with_dict: "{{ipausers|default({})}}"  
ignore_errors: yes

without success


回答1:


Not sure if it'll be much help to you now but for others than stumble on this post, I ended up with something like below for a similar problem. I'm using Ansible 2.7.8.

- name: Creating user accounts...
  user:
    name: "{{ item.name }}"
    state: "{{ item.state }}"
    comment: "{{ item.comment | default(omit) }}"
    group: "{{ item.groups is defined | ternary((item.groups|default([]))[0], omit) }}"
    groups: "{{ item.groups | default(omit) }}"
    password: "{{ item.password_hash | default(omit) }}"
    uid: "{{ item.uid | default(omit) }}"
  with_items: "{{ managed_users }}"

The solution is group: "{{ item.groups is defined | ternary((item.groups|default([]))[0], omit) }}"

If groups isn't in item then Ansible will omit the group part of this tasks but jinja2 will evaluate item.groups[0] anyway. So to allow for this we have to use item.groups|default([]) so jinja2 uses an empty list when groups isn't defined instead of throwing a 'dict object' has no attribute error. The omit part is similar to the default(omit) filter where Ansible simply omits the option from the task.

Lubo's problem is a little simpler so using just default(omit) filter should work. That said as password is required so the entire task should be skipped with a conditional.

- name: adding ipa users
  ipa_user:
    name: "{{ item.value.login }}"
    state: "{{ item.value.state }}"
    givenname: "{{ item.value.givenname }}"
    sn: "{{ item.value.surname }}"
    mail: "{{ item.value.mail }}"
    telephonenumber: "{{ item.value.telephonenumber }}"
    title: "{{ item.value.title }}"
    password: "{{ item.value.password | default(omit) }}" #<-- would be omitted
    ipa_host: ipa.gdi.telekom.de
    ipa_user: admin
    ipa_pass: "{{ ipa_pass }}"
  with_dict: "{{ipausers}}"
  when: item.key in ipausers.keys() and item.key.password is defined #<-- second check for when password is not defined.
  register: output_ipa_users



回答2:


If you want to completely skip the ipa_user module execution when password is not defined, check for its presence in your when clause:

when: item.value.password | default('') | length > 0

If you want to execute the ipa_user module without specifying a password for user if it does not exists, use the omit placeholder in your module params:

password: "{{ item.value.password | default(omit) }}"

Note: your current when clause can be removed. It will always return true as you are looping over a dict and later checking if the current key in the loop is part of that dict.




回答3:


There is a special omit variable to omit module parameters.

password: "{{ item.value.password|default(omit) }}"

To make a playbook or a role reusable it is a good idea to declare all parameters of a module in the task and default(omit) parameters that are not required.



来源:https://stackoverflow.com/questions/55824820/ansible-skip-undefined-variable-in-dict

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!