Ansible v2.2使用with_subelements报错,v1.7可正常运行
Ansible 2.2.1中条件检查
item未定义问题解决 问题背景
最近把Ansible从1.7升级到2.2.1后,原本正常运行的rsyslog配置任务突然报错了,提示条件检查ansible_fqdn == {{item.1}}失败,核心错误是'item' is undefined。下面是完整的错误信息、任务代码和变量定义,咱们一步步分析问题。
错误信息
TASK [base : Rsyslog yapilandiriliyor.] **************************************** fatal: [gkts.ahtapot]: FAILED! => {"failed": true, "msg": "The conditional check 'ansible_fqdn == {{item.1}}' failed. The error was: error while evaluating conditional (ansible_fqdn == {{item.1}}): 'item' is undefined The error appears to have been in '/etc/ansible/roles/base/tasks/rsyslog.yml': line 2, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: --- - name: Rsyslog yapilandiriliyor. ^ here "}
任务代码
- name: Rsyslog yapilandiriliyor. template: src: "{{ rsyslog['conf']['source'] }}" dest: "{{ rsyslog['conf']['destination'] }}" owner: "{{ rsyslog['conf']['owner'] }}" group: "{{ rsyslog['conf']['group'] }}" mode: "{{ rsyslog['conf']['mode'] }}" # when: "ansible_fqdn == item.1" when: "ansible_fqdn == {{item.1}}" with_subelements: - "{{ossimciks}}" - "{{clients}}" notify: - rsyslog servisini yeniden baslat sudo: yes tags: rsyslog
变量定义
ossimciks: server01: fqdn: "OSSIMCIK_FQDN" port: "20514" clients: - "LOG_KAYNAGI_FQDN" - "LOG_KAYNAGI_FQDN"
问题原因
这是Ansible版本升级后的语法规则变化导致的:
- 在Ansible 1.x中,
when条件里使用{{}}包裹变量是被允许的,但到了2.x版本,when语句本身就处于Jinja2的上下文环境中,不需要再用{{}}来引用变量。 - 当你写
when: "ansible_fqdn == {{item.1}}"时,Ansible会先尝试解析{{item.1}},但此时with_subelements还没开始迭代,item变量根本还没被定义,所以直接抛出了item is undefined的错误。 - 另外还有个潜在隐患:
with_subelements的第一个参数要求是列表类型,而你的ossimciks是字典类型。Ansible 1.x可能对这个做了兼容,但2.x版本对类型的要求更严格。
解决方案
第一步:修正when条件的语法
把when语句里的{{}}去掉,直接使用变量名:
when: ansible_fqdn == item.1
(也可以保留引号,但不需要再嵌套模板语法了)
第二步:修正ossimciks变量的结构(可选但建议)
把ossimciks从字典改成列表格式,符合with_subelements的官方要求:
ossimciks: - name: server01 fqdn: "OSSIMCIK_FQDN" port: "20514" clients: - "LOG_KAYNAGI_FQDN" - "LOG_KAYNAGI_FQDN"
同时把with_subelements改成:
with_subelements: - "{{ ossimciks }}" - clients
(这里第二个参数不需要用{{}},直接写键名即可)
做完这两步修改后,重新运行剧本应该就能正常执行了。
内容的提问来源于stack exchange,提问作者Alptugay
相关产品推荐
相关产品推荐

