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

Jinja2处理Ansible os_stack输出数据时遇变量错误求助

解决Ansible Jinja2模板的UndefinedVariable错误并生成期望的YAML格式

首先咱们来拆解你遇到的问题:

错误原因分析

你当前的模板代码存在两个关键问题,直接触发了AnsibleUndefinedVariable错误:

  1. 错误的循环对象:for group in outputs[0].description这行代码是在循环字符串"lb"的单个字符(也就是'l'和'b'),而不是遍历所有需要的分组名称(lb和web)。当后续代码尝试用单个字符去访问不存在的属性/索引时,自然会抛出错误。
  2. 误解数据结构的访问方式:outputs[0].output_value[group]完全不符合原始数据的结构——原始的outputs是一个平级列表,每个元素都是独立的键值对,并不是按分组嵌套的字典。

正确的Jinja2模板实现

我们需要先按description字段对outputs列表分组,再为每组内的IP条目添加递增的index,最后生成你期望的YAML结构。这里可以利用Ansible自带的groupby过滤器简化分组操作:

{%- set ip_specs = {} -%}
{%- for group_name, group_items in outputs | groupby('description') -%}
    {%- set net_list = [] -%}
    {%- for idx, item in group_items | enumerate(start=1) -%}
        {%- do net_list.append({
            'net_info': {'ip': item.output_value},
            'index': idx
        }) -%}
    {%- endfor %}
    {%- do ip_specs.update({group_name: net_list}) -%}
{%- endfor %}
{{ {'vm_list': ip_specs} | to_yaml }}

代码细节解释

  1. 分组处理:outputs | groupby('description')会自动把原始列表按description的值分成两组:('lb', [lb相关的两个条目])和('web', [web相关的三个条目])。
  2. 自动生成索引:用enumerate(start=1)来自动生成从1开始的递增索引,避免手动维护index列表的繁琐操作。
  3. 构造目标结构:把每个分组的结果整理到ip_specs字典中,最后通过to_yaml过滤器转换成标准的YAML格式输出。

测试输出

将你的原始outputs数据代入模板后,会生成完全符合你期望的结果:

vm_list:
  lb:
  - net_info: {ip: 10.1.1.11}
    index: 1
  - net_info: {ip: 10.1.1.12}
    index: 2
  web:
  - net_info: {ip: 10.1.1.13}
    index: 1
  - net_info: {ip: 10.1.1.14}
    index: 2
  - net_info: {ip: 10.1.1.15}
    index: 3

额外优化提示

如果需要让web组内的条目按output_key中的数字排序(比如让web_2排在web_3前面),可以在遍历分组前先对group_items排序:

{%- for idx, item in group_items | sort(attribute='output_key') | enumerate(start=1) -%}

这样web_1、web_2、web_3会按顺序排列,对应的index也会同步调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:35:07