Ansible,如何访问从文件导入的变量?

Ansible, how to access variables which were imported from a file?

我在剧本中生成了一个 yml 文件 (cert_expiring.yml),它包含一个字典,其中包含 SSL 证书即将过期的服务器的 ID 和服务器名称。

例如:cert_expiring.yml

myDict:
    705:node1.corp.com
    670:node2.corp.com
    1163:node3.corp.com
    715:node4.corp.com

我有一个正在读取此文件并将其存储在名为“expired_certs”的变量中的游戏:

- name: Store file contents into variable
      include_vars:
        file: cert_expiring.yml
        name: expired_certs

“expired_certs”的内容如下所示:

{
    "msg": {
        "changed": true,
        "msg": "All items completed",
        "results": [{
            "ansible_loop_var": "item",
            "backup": "",
            "changed": true,
            "diff": [{
                    "after": "",
                    "after_header": "./cert_expiring.txt (content)",
                    "before": "",
                    "before_header": "./cert_expiring.txt (content)"
                },
                {
                    "after_header": "./cert_expiring.txt (file attributes)",
                    "before_header": "./cert_expiring.txt (file attributes)"
                }
            ],
            "failed": false,
            "invocation": {
                "module_args": {
                    "attributes": null,
                    "backrefs": false,
                    "backup": false,
                    "content": null,
                    "create": true,
                    "delimiter": null,
                    "dest": "./cert_expiring.txt",
                    "directory_mode": null,
                    "firstmatch": false,
                    "follow": false,
                    "force": null,
                    "group": null,
                    "insertafter": null,
                    "insertbefore": null,
                    "line": "    705:node1.corp.com",
                    "mode": null,
                    "owner": null,
                    "path": "./cert_expiring.txt",
                    "regexp": null,
                    "remote_src": null,
                    "selevel": null,
                    "serole": null,
                    "setype": null,
                    "seuser": null,
                    "src": null,
                    "state": "present",
                    "unsafe_writes": null,
                    "validate": null
                }
            },
            "item": {
                "cn": "node1.corp.com",
                "expires": "2020-11-05T15:20:18+00:00",
                "id": 705,
                "serial": "1111"
            },
            "msg": "line added"
        }]
    }
}

我正在尝试按照相同的过程 从嵌套的 json 中引用“cn”、“expires”、“id”和“serial”,但不确定为什么不工作。

这是我访问这些元素的游戏:

- name: Print expired_certs variable contents
      debug:
        msg: "{{ expired_certs | json_query('results.item[*].{expires: expires, cn: cn, serial: serial, id: id}') }}"

输出:

ok: [localhost] => {
    "msg": ""
}

另外,试过这个:

msg: "{{ expired_certs | json_query('results.[*].{expires: item.expires, cn: item.cn, serial: item.serial, id: itme.id}') }}"

输出:

ok: [localhost] => {
    "msg": {
        "cn": null,
        "expires": null,
        "id": null,
        "serial": null
    }
}

需要帮助了解如何访问嵌套元素。

查看您的 JSON,键 results 是一个列表,而不是字典:

{
  "results": [{
    "changed": true,
    "...cut": "for brevity"
  }]
}

在JSON中,方括号表示数组(或list讲Ansible语言)

item 是字典,不是列表:

{
  "item": {
    "cn": "node1.corp.com",
    "expires": "2020-11-05T15:20:18+00:00",
    "id": 705,
    "serial": "1111"
  }
}

在JSON中,大括号表示对象(或字典来使用Ansible语言)

所以,您的 wildcard expression 只是按错了键。

应该是:

results[*].item

与你的实际情况相反:

results.item[*]

而且,因为 item 键已经只包含您需要的信息,所以您不需要付出额外的努力并重做一个对象。你可以留在 results[*].item.

结束于:

- name: Print expired_certs variable contents
  debug:
    msg: "{{ expired_certs | json_query('results[*].item') }}"