Ansible循环中提取注册变量item.content及优化until判断的方法
核心问题根因
- 带循环的任务执行完成后,
register注册的变量顶层为全局汇总字典,所有单次循环的执行结果都存储在results子列表下,直接遍历status会遍历顶层字典的键值对,而非单次执行的结果对象,因此无法访问content字段,触发AnsibleUnsafeBytes object has no attribute 'content'报错。 - 原
until判断条件逻辑无效:status是单次uri请求返回的字典对象,直接对字典做字符串匹配search('Version')无法命中,判断逻辑一直未真正生效。
修正方案
1. 正确提取循环返回的content字段
遍历返回结果时,需定位到status.results子列表,每个列表元素就是单次循环执行的返回结果,可直接访问content字段。
修正后的内容提取任务:
- name: Print instance version content debug: msg: "Instance {{ item.item }}: {{ item.content.split('\n') }}" with_items: "{{ status.results }}" when: item.content is defined ignore_errors: yes
增加
when: item.content is defined判断,过滤掉请求失败的条目,避免因无content字段触发报错。
2. 修正until判断逻辑
将匹配条件精准指向content字段,每次重试时status都是当前单次uri请求的返回对象,直接判断status.content即可正确触发重试逻辑:
- name: "Verify started instance {{ item }}" uri: url: "http://localhost:808{{ item[-1] }}/url" method: GET return_content: yes register: status until: "status.content is search('Version')" retries: 3 delay: 60 ignore_errors: yes with_items: "{{ instances_running.stdout_lines }}" loop_control: label: "{{ item }}"
3. 将返回结果展示到任务名称中
注意:uri任务的名称是在任务启动执行前就完成渲染的,此时尚未发起HTTP请求,无法拿到返回的content内容,因此无法在uri任务本身的名称中嵌入返回值,只能在后续处理返回结果的任务中通过循环渲染任务名称。
可以单独创建展示任务,通过循环绑定变量的方式,将实例标识、返回的content内容嵌入任务名称,不需要额外通过debug的msg输出结果:
- name: "Instance {{ item.item }} version info: {{ item.content.split('\n')[0] }}" debug: var: item.content with_items: "{{ status.results | selectattr('content', 'defined') | list }}"
执行时任务输出会直接在标题行展示对应实例的版本信息。
额外说明
碰到的端口拼接报错(invalid literal for int() with base 10: '808l')是输入数据问题:instnull最后一个字符为小写字母l而非数字1,拼接后端口不合法,可在执行循环前增加端口格式校验步骤,避免脏数据导致请求失败。
内容的提问来源于stack exchange,提问作者syncerror
相关产品推荐
相关产品推荐

