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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:27:29