如何在Ansible的hostvars字典层级中动态替换变量后缀?
Ansible动态访问hostvars嵌套字段方案
问题背景
我的hostvars中Web服务器的数据结构片段如下(结构固定):
{ "wordpress": { "config": { "port": 80, "ssl": { "port": 443 } } } }
我需要动态访问这类嵌套结构,无论是否启用SSL。直接访问的方式很简单,比如在Jinja循环中:
- debug: msg: "{{ hostvars[host].wordpress.config.port }}"
限制条件
- 数据必须保留在hostvars字典中,因为需要遍历主机
- 后缀路径不固定,除了
.wordpress.config.port,还可能是.openladap.whatever.anything.ldaps.port这类任意嵌套路径
需求
能否实现完全动态的后缀路径指定,类似C++中的成员指针?我尝试了以下代码但无法生效:
- hosts: lb1 vars: host: web1 suffix: '.wordpress.config.port' tasks: - debug: msg: "{{ hostvars[host] + suffix }}" - debug: msg: "{{ lookup('vars',hostvars[host] + suffix ) }}"
可行解决方案
方法1:使用json_query过滤器
json_query支持用字符串路径查询嵌套结构,完美匹配动态后缀需求:
- hosts: lb1 vars: host: web1 suffix: 'wordpress.config.port' # 注意去掉开头的点 tasks: - debug: msg: "{{ hostvars[host] | json_query(suffix) }}"
需要访问SSL端口时,只需把suffix改成'wordpress.config.ssl.port'即可。
方法2:拆分后缀为列表,遍历字典取值
把后缀按.拆分后,循环遍历字典键来获取目标值,原生Ansible即可实现,无需额外依赖:
- hosts: lb1 vars: host: web1 suffix: 'wordpress.config.port' tasks: - set_fact: target_value: "{{ hostvars[host] }}" - name: 遍历后缀路径获取值 set_fact: target_value: "{{ target_value[item] }}" loop: "{{ suffix.split('.') }}" - debug: msg: "{{ target_value }}"
方法3:使用Jinja2的resolve过滤器(Ansible 2.10+)
如果使用较新版本的Ansible,可借助resolve过滤器直接解析字符串形式的变量路径:
- hosts: lb1 vars: host: web1 suffix: '.wordpress.config.port' tasks: - debug: msg: "{{ hostvars[host].resolve(suffix.lstrip('.')) }}"
内容的提问来源于stack exchange,提问作者Marcus John
相关产品推荐
相关产品推荐

