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

如何在Ansible中合并拥有共同键的嵌套字典?

在Ansible中合并嵌套字典的相同条目属性

当然可以实现!这种把敏感配置(比如VPN共享密钥)和普通配置分开存储,甚至将敏感部分用Vault加密的需求非常常见,Ansible内置的combine过滤器就能完美解决你的问题。

具体实现步骤

假设你已经将配置分别放在两个文件中:

  • vpns.yml:存储普通VPN配置(未加密)
  • vpn_credentials.yml:存储Vault加密的共享密钥

1. 编写Playbook实现合并

在你的playbook中,先加载这两个变量文件,然后使用combine过滤器并加上recursive=True参数来递归合并嵌套字典:

- name: 合并VPN配置与加密的共享密钥
  hosts: localhost
  vars_files:
    - vpns.yml
    - vpn_credentials.yml
  tasks:
    - name: 生成合并后的完整VPN字典
      set_fact:
        merged_vpns: "{{ vpns | combine(vpn_credentials, recursive=True) }}"
    
    - name: 验证合并结果(仅用于测试)
      debug:
        var: merged_vpns

2. 关键参数说明

  • combine:Ansible用于合并字典的核心过滤器,默认情况下会用右侧字典的键覆盖左侧同名键
  • recursive=True:开启递归合并模式,针对嵌套字典,当外层键(比如example、example2)相同时,会将内层的键值对(比如vpn_shared_key)合并到一起,而非直接替换整个内层字典——这正是你需要的行为

3. Vault加密文件的使用

因为vpn_credentials.yml是加密状态,你只需要:

  1. 用ansible-vault encrypt vpn_credentials.yml加密该文件
  2. 运行playbook时加上--ask-vault-pass(交互式输入Vault密码),或者指定密码文件--vault-password-file=your_vault_pass_file,Ansible会自动解密加载变量,完全不影响合并逻辑

合并后的结果

执行上述playbook后,merged_vpns变量就会生成你期望的结构:

merged_vpns:
  example:
    vpn_connection_name: "example"
    vpn_client_public_ip: "xxx.xxx.xxx.xxx"
    vpn_shared_key: "somekey"
  example2:
    vpn_connection_name: "example2"
    vpn_client_public_ip: "xxx.xxx.xxx.xxx"
    vpn_shared_key: "someotherkey"

如果遇到内层键冲突的情况(比如两个字典有同名的内层键且值不同),combine会默认用右侧字典(vpn_credentials)的值覆盖左侧,但在你的场景中应该不会出现这种情况,因为两边的配置是互补的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:32:40