如何在Ansible中通过固定后缀匹配随机前缀键取值?
如何在Ansible中根据键的固定后缀提取vmvars的值
问题场景
传入Ansible的extra_vars格式如下:
{ "vmvars": { "v_ads1as_operating_system": "Linux", "v_mdjx2d_vm_name": "myvm123", "v_srsj4d_mount_point": "tmp" } }
其中vmvars的键前缀为v_<随机字符串>(不固定),但键的后缀(如_operating_system)固定且唯一。需要提取对应后缀键的值,但尝试多种json_query写法均失败,现寻求正确取值方法。
尝试过的错误写法
第一种:
--- - hosts: localhost tasks: - name: Get os_type from input set_fact: os_type: "{{ vmvars[item] | json_query(['*operating_system']) }}" loop: "{{ vmvars.keys() | list }}"
第二种:
- set_fact: os_type: "{{ vmvars[item] | json_query(vmvars['*operating_system']) }}"
第三种:
- set_fact: os_type: "{{ vmvars[item] | json_query([?contains(item,'operating_system')]) }}"
解决方法
方法1:使用Ansible原生过滤器(推荐)
无需依赖json_query,直接用Ansible内置过滤器处理:
--- - hosts: localhost tasks: - name: 提取操作系统类型 set_fact: os_type: "{{ vmvars | dict2items | selectattr('key', 'search', '_operating_system$') | map(attribute='value') | first }}" - name: 提取虚拟机名称 set_fact: vm_name: "{{ vmvars | dict2items | selectattr('key', 'search', '_vm_name$') | map(attribute='value') | first }}" - name: 提取挂载点 set_fact: mount_point: "{{ vmvars | dict2items | selectattr('key', 'search', '_mount_point$') | map(attribute='value') | first }}" - name: 打印结果 debug: msg: - "操作系统类型: {{ os_type }}" - "虚拟机名称: {{ vm_name }}" - "挂载点: {{ mount_point }}"
逻辑说明:
dict2items:将vmvars字典转换为[{key: "...", value: "..."}]格式的列表selectattr('key', 'search', '_operating_system$'):筛选键以指定后缀结尾的项($确保精准匹配后缀,避免前缀包含相同字符串的干扰)map(attribute='value'):提取筛选后项的value字段first:取结果列表的第一个元素(因后缀唯一,只会有一个匹配项)
方法2:使用json_query的正确写法
若必须使用json_query,可结合JMESPath语法实现:
--- - hosts: localhost tasks: - name: 用json_query提取操作系统类型 set_fact: os_type: "{{ vmvars | dict2items | json_query('[?ends_with(key, `_operating_system`)].value | [0]') }}" - name: 打印操作系统类型 debug: var: os_type
逻辑说明:
- 先通过
dict2items将字典转为键值对列表 - JMESPath表达式
[?ends_with(key,_operating_system)].value:筛选键以指定后缀结尾的项并提取其值 [0]:取第一个匹配结果(因后缀唯一)
错误写法的问题原因
- 错误地对单个值(
vmvars[item])使用json_query,该过滤器需作用在列表/字典这类可迭代结构上 - 误用不符合JMESPath语法的表达式(如
contains(item,'operating_system')),JMESPath中需使用ends_with等内置函数,且上下文逻辑错误
内容的提问来源于stack exchange,提问作者AniketGM
相关产品推荐
相关产品推荐

