Ansible-跳过字典中未定义的变量

时间:2019-04-24 07:45:06

标签: ansible

我正在使用ipa_user模块设置用户。有可变密码可以强制输入新密码。 对于某些用户(当var不在dict中时),我想在迭代中跳过它,但是它总是失败。

这是我的剧本的摘录。 Ansible版本是2.7

任务:

- 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

日志:

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"}

注意:我尝试过:

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

没有成功

3 个答案:

答案 0 :(得分:0)

有一个special omit variable可以省略模块参数。

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

要使剧本或角色可重复使用,最好在任务中声明模块的所有参数以及不需要的 default(omit)参数。

答案 1 :(得分:0)

如果在未定义密码的情况下要完全跳过ipa_user模块的执行,请检查when子句中是否存在该模块:

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

如果要执行ipa_user模块而不为用户指定密码(如果该密码不存在),请在模块参数中使用omit placeholder

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

注意:可以删除您当前的when子句。当您遍历字典并随后检查循环中的当前键是否是该字典的一部分时,它将始终返回true。

答案 2 :(得分:0)

不确定现在是否会对您有很大帮助,但对于其他人,除了偶然发现本文之外,我最终遇到类似问题,如下所示。我正在使用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 }}"

解决方法是 group: "{{ item.groups is defined | ternary((item.groups|default([]))[0], omit) }}"

如果groups不在item中,那么Ansible将忽略此任务的分组部分,但jinja2仍将评估item.groups[0]。因此,为此,我们必须使用item.groups|default([]),以便jinja2在未定义组时使用一个空列表,而不是抛出'dict object' has no attribute错误。省略部分类似于default(omit)过滤器,其中Ansible只是忽略了任务中的选项。

Lubo的问题要简单一些,因此仅使用default(omit)过滤器即可。话虽如此,但由于需要密码,因此应有条件地跳过整个任务。

- 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