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
关键逻辑说明
- 层级遍历:通过两层Jinja2循环,依次遍历每个集群(
homelab/remotelab)和集群内的主机组(agents/servers)。 - 主机名转IP:对每个主机组的列表,使用
map('extract', hostvars, 'ansible_host')过滤器,从hostvars中提取对应主机的ansible_host值,再转为列表。 - 字典组装:通过
do语句动态构建嵌套字典,最终将结果赋值给cluster_ips变量。
注意事项
- 确保inventory中的主机已被正确加载,
hostvars中能获取到对应主机的ansible_host变量。 - 若主机组为空(如
remotelab的agents),map过滤器会返回空列表,与目标结构一致。
内容的提问来源于stack exchange,提问作者Coyote
相关产品推荐
相关产品推荐

