繁体   English   中英

是否可以使用 Ansible / Jinja2 展平列表列表?

[英]Is it possible to flatten a lists of lists with Ansible / Jinja2?

我的基本问题是,在创建一组 aws 服务器后,我想将它们配置为相互了解。

创建每个服务器后,它们的详细信息保存在注册的“服务器”变量中(如下所示)。 创建后我真正想要做的是运行这样的任务:

- name: Add servers details to all other servers
  lineinfile:
    dest: /path/to/configfile
    line: "servername={{ item.1.private_ip }}"
  delegate_to: "{{ item.0.public_dns_name }}"
  with_nested:
    - list_of_servers
    - list_of_servers

将列表两次提供给 'with_nested' 在这里是必不可少的。

获取列表列表很容易做到:

"{{ servers.results | map(attribute='tagged_instances') | list }}"

返回:

[ 
  [ { "private_ip": "ip1", "public_dns_name": "dns1" } , { ... }],
  [ { ... }, { ... } ]
]

但是你怎么把它变成:

[
  { "private_ip": "ip1", "public_dns_name": "dns1" },
  { ... },
  { ... }, 
  { ... }
]

'servers' 注册的 var 看起来像:

"servers": {
    "changed": true,
    "msg": "All items completed",
    "results": [
        {
            ...
            "tagged_instances": [
                {
                    ...
                    "private_ip": "ip1",
                    "public_dns_name": "dns1",
                    ...
                },
                {
                    ...
                    "private_ip": "ip2",
                    "public_dns_name": "dns2",
                    ...
                }
            ]
        },
        {
            ...
            "tagged_instances": [
                {
                    ...
                    "private_ip": "ip3",
                    "public_dns_name": "dn3",
                    ...
                },
                {
                    ...
                    "private_ip": "ip4",
                    "public_dns_name": "dns4",
                    ...
                }
            ]
        },
        ...
    ]
}

注意:我有一个非常丑陋的解决方案,它使用“with_flattened”和一个调试语句来创建一个新的注册变量“flattened_servers”,然后我再次映射它。 但我希望有一个更优雅的解决方案:)

Jinja2 带有一个内置的过滤器sum ,可以像这样使用:

{{ servers.results | sum(attribute='tagged_instances', start=[]) }}

有点晚了,但从 ansible 2.5 开始,您可以这样做:

 "{{ servers.results | map(attribute='tagged_instances') | list | flatten }}"

您可以进行列表理解以将其转换为字典列表。

例如:

- name: Convert
  shell: python -c "print [x for b in {{ servers }}['servers']['results'] for x in b['tagged_instances']]"
  register: my_list_of_dicts

假设{{ servers }}变量包含整个字典(不是 json)。

只是想列出“丑陋”的解决方法,因为 python 代码对我不起作用

  - debug: var=item
    with_flattened:
      - "{{ servers.results|map(attribute='tagged_instances')|list }}"
    register: servers_instances_tmp
    no_log: True

  - set_fact: servers_instances="{{ servers_instances_tmp.results|map(attribute='item')|list }}"

  - debug: var=servers_instances

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM