在使用循环时,如何访问Ansible事实的值?

在使用循环时,如何访问Ansible事实的值?,ansible,Ansible,这在我不使用循环时有效: --- - hosts: localhost tasks: - name: Get a cert from gRPC port get_certificate: host: "labrouter.abc.com" port: 50051 delegate_to: localhost run_once: true ignore_errors: yes

这在我不使用循环时有效:

---
- hosts: localhost
  tasks:
    - name: Get a cert from gRPC port
      get_certificate:
        host: "labrouter.abc.com"
        port: 50051
      delegate_to: localhost
      run_once: true
      ignore_errors: yes
      register: cert
    - name: Get Cert Data
      debug:
        msg: "Not_After: {{ cert.not_after }}"
输出:

TASK [Get Cert Data] ****************************************
ok: [localhost] => {
    "msg": "Not After: 20221210143235Z"
}
但是,当我尝试像这样通过主机循环时:

---
- hosts: localhost
  tasks:
    - name: Get a cert from gRPC port
      get_certificate:
        host: "{{ item }}"
        port: 50051
      delegate_to: localhost
      run_once: true
      ignore_errors: yes
      register: cert
      loop: "{{ groups['lab'] }}"
    - name: Get Cert Data
      debug:
        msg: "Not After: {{ cert.not_after }}"
我得到这个错误:

The error was: 'dict object' has no attribute 'not_after'
我的清单文件包含一个名为“lab”的组,其中有一个设备“labrouter.abc.com”与其关联


我希望能够向“实验室”组添加更多设备,并运行此剧本,以便获得每个设备的“not_after”值。我不知道如何访问循环中每个项目的“not_after”值。

停止循环,并让Ansible在主机上进行隐式循环:

---
- hosts: lab
  tasks:
    - name: Get a cert from gRPC port
      get_certificate:
        host: "{{ ansible_host }}"
        port: 50051
      delegate_to: localhost
      ignore_errors: yes
      register: cert

    - name: Get Cert Data
      debug:
        msg: "Not After: {{ cert.not_after }}"
(作为一般的“最佳实践”事项,如果您在主机上循环,可能有更好的方法,通过将播放的
hosts
值设置为这些主机,并让Ansible执行其隐式循环。)

引用:

在循环中使用
register
时,变量中的数据结构将包含
results
属性,该属性是模块所有响应的列表。这与使用不带循环的
寄存器时返回的数据结构不同

解决实际问题的最简单方法是循环查看
结果

-名称:获取证书数据
调试:
msg:“不在:{{item.Not_After}}
循环:“{cert.results}}”

虽然这是对您问题的直接回答,但如果最终目标是对
实验室
组中的每个目标采取行动,请查看并删除您的循环。

谢谢@Zeitounator,这确实给了我想要的答案。是否可以不打印整个“结果”列表,只打印调试消息?是的:我最初尝试过,但Ansible希望通过ssh连接到设备(路由器)以建立连接,目前不允许这样做。将
收集事实:否
添加到播放中。尝试过这样做,但Ansible仍尝试通过ssh连接到路由器。---主机:lab gather_事实:无任务:-名称:从gRPC端口获取证书获取证书:主机:“{ansible_host}}”端口:50051运行一次:true忽略错误:是注册:证书-名称:获取证书数据调试:msg:“不在之后:{{cert.Not_After}}”必须删除“委托给”因此Ansible不会尝试连接到localhost。您可以将
连接:local
放在播放中,并摆脱
委托给:localhost
。另外,请不要使用
run\u one:true
。您的建议确实帮助我在主机之间循环,但是,我看到了一些不好的输出。我假设它可能与模块本身有关。例如,当我在主机文件中放置一个可访问和不可访问的主机时,我从两个主机获得了良好的输出。但是,如果我只在主机文件中保留不可访问的主机,则会收到一个错误,指示该主机不可访问。