You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从多主机的Ansible注册变量ec2_eni生成指定格式字典?

问题

我通过条件筛选(include_tasks)给Play中的部分主机执行以下任务,为其添加两个辅助私有IP:

- name: Add two secondary private IPs to WSFC hosts 
  amazon.aws.ec2_eni:
    eni_id: '{{ hostvars[inventory_hostname].network_interfaces[0].network_interface_id }}'
    secondary_private_ip_address_count: 2
    subnet_id: '{{ hostvars[inventory_hostname].network_interfaces[0].subnet_id }}'
  delegate_to: localhost
  register: ec2_eni

我需要以最高效的方式,从注册的ec2_eni变量生成如下格式的字典,按主机分类存储新增的两个IP:

some_dict:
  - hostname: host1
    ip1: ###.###.###.###
    ip2: ###.###.###.###
  - hostname: host2
    ip1: ###.###.###.###
    ip2: ###.###.###.###

ec2_eni的返回结构示例如下:

{
    "interface": {
        "id": "eni-999",
        "subnet_id": "subnet-999",
        "vpc_id": "vpc-999",
        "description": "Primary IPv4 interface for EC2 instance",
        "owner_id": "999",
        "status": "in-use",
        "mac_address": "00:00:00:00:00:00",
        "private_ip_address": "192.168.0.1",
        "source_dest_check": true,
        "groups": {
            "sg-999": "security-group"
        },
        "private_ip_addresses": [
            {
                "private_ip_address": "192.168.0.1",
                "primary_address": true
            },
            {
                "private_ip_address": "192.168.0.2",
                "primary_address": false
            },
            {
                "private_ip_address": "192.168.0.3",
                "primary_address": false
            }
        ]
    }
}
解决方案

可以通过set_fact结合Jinja2过滤器和循环,一次性生成目标字典,无需额外循环任务,实现高效处理:

- name: Generate target IP dictionary grouped by host
  set_fact:
    some_dict: >-
      {%- set ip_list = [] -%}
      {%- for host in ansible_play_hosts -%}
          {%- set secondary_ips = hostvars[host].ec2_eni.interface.private_ip_addresses 
                                   | selectattr('primary_address', 'equalto', false) 
                                   | map(attribute='private_ip_address') 
                                   | list -%}
          {%- if secondary_ips | length >= 2 -%}
              {%- set _ = ip_list.append({
                  'hostname': host,
                  'ip1': secondary_ips[0],
                  'ip2': secondary_ips[1]
              }) -%}
          {%- endif -%}
      {%- endfor -%}
      {{ ip_list }}
  delegate_to: localhost

说明

  • ansible_play_hosts:包含当前Play中所有符合条件的主机(即执行过添加IP任务的主机)
  • selectattr('primary_address', 'equalto', false):过滤出所有非主IP的条目
  • map(attribute='private_ip_address'):提取条目中的IP字符串,转换为列表
  • 最后将每个主机的信息组装为指定格式的字典,加入结果列表

内容的提问来源于stack exchange,提问作者Kimmel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:30:42