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

Ansible中如何将嵌套字典内的主机名转换为对应IP地址

嵌套主机名字典转对应IP地址的Ansible实现

问题背景

现有如下嵌套结构的主机名字典变量:

vars:
    clusters:
        homelab:
            agents:
                - knode-01
                - knode-02
            servers:
                - kmaster-01
                - kmaster-02
                - kmaster-03
        remotelab:
            agents: []
            servers:
                - rmaster-01
                - rmaster-02
                - rmaster-03

同时inventory的hosts文件定义了主机对应的IP:

---
all:
  hosts:
    kmaster-01:
      ansible_host: 192.168.0.81
    kmaster-02:
      ansible_host: 192.168.0.82
    kmaster-03:
      ansible_host: 192.168.0.83
    knode-01:
      ansible_host: 192.168.0.91
    knode-02:
      ansible_host: 192.168.0.92
    rmaster-01:
      ansible_host: 192.168.1.81
    rmaster-02:
      ansible_host: 192.168.1.82
    rmaster-03:
      ansible_host: 192.168.1.83

需要将clusters中的主机名替换为对应的ansible_host值,生成如下目标结构:

cluster_ips:
    homelab:
        agents:
            - 192.168.0.91
            - 192.168.0.92
        servers:
            - 192.168.0.81
            - 192.168.0.82
            - 192.168.0.83
    remotelab:
        agents: []
        servers:
            - 192.168.1.81
            - 192.168.1.82
            - 192.168.1.83

实现方案

利用Ansible的Jinja2模板循环结合map('extract')过滤器,通过set_fact构建目标字典:

- name: 转换嵌套主机名为IP地址
  hosts: localhost
  gather_facts: no
  vars:
    clusters:
      homelab:
        agents:
          - knode-01
          - knode-02
        servers:
          - kmaster-01
          - kmaster-02
          - kmaster-03
      remotelab:
        agents: []
        servers:
          - rmaster-01
          - rmaster-02
          - rmaster-03
  tasks:
    - name: 构建cluster_ips字典
      set_fact:
        cluster_ips: >-
          {% set result = {} %}
          {% for cluster_name, groups in clusters.items() %}
            {% set cluster_data = {} %}
            {% for group_name, host_list in groups.items() %}
              {% set ip_list = host_list | map('extract', hostvars, 'ansible_host') | list %}
              {% do cluster_data.update({group_name: ip_list}) %}
            {% endfor %}
            {% do result.update({cluster_name: cluster_data}) %}
          {% endfor %}
          {{ result }}

    - name: 验证转换结果
      debug:
        var: cluster_ips

关键逻辑说明

  1. 层级遍历:通过两层Jinja2循环,依次遍历每个集群(homelab/remotelab)和集群内的主机组(agents/servers)。
  2. 主机名转IP:对每个主机组的列表,使用map('extract', hostvars, 'ansible_host')过滤器,从hostvars中提取对应主机的ansible_host值,再转为列表。
  3. 字典组装:通过do语句动态构建嵌套字典,最终将结果赋值给cluster_ips变量。

注意事项

  • 确保inventory中的主机已被正确加载,hostvars中能获取到对应主机的ansible_host变量。
  • 若主机组为空(如remotelab的agents),map过滤器会返回空列表,与目标结构一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:33:28