【问题标题】:Dynamic variable using hostvars within jinja2 loops在 jinja2 循环中使用主机变量的动态变量
【发布时间】:2021-09-01 18:43:08
【问题描述】:

如何使动态变量在 jinja2 循环中与主机变量一起使用?

有效:

{{ hostvars[inventory_hostname]['somevar_state'] }}

它也有效:

{{ hostvars[inventory_hostname].somevar_state }}

用于测试:

{{ hostvars[inventory_hostname]['' ~ 'somevar_state' ~ ''}}

但它不起作用:

如果 somevarlist 包含 'somevar' 值

{% for var in somevarlist %}
{{ hostvars[inventory_hostname][var + '_state'] }}
{% endfor %}

{{ hostvars[inventory_hostname]['' ~ var ~ '_state' ~ ''] }}

结果:

msg:任务包含一个带有未定义变量的选项...错误是:'ansible.vars.hostvars.HostVarsVars object' has no attribute 'somevar_state'...

【问题讨论】:

    标签: ansible jinja2


    【解决方案1】:

    我的事实“somevar_state”是动态设置的,并且是从每个主机中可能存在或不存在的另一个事实派生而来的。在这种情况下,我们需要在打印之前检查每个主机上是否定义了变量,否则会失败。感谢 Vladimir 通过调试示例帮助我理解问题。

    - name: add lines to file
      blockinfile:
        path: myoutfile
        block: |
          {% for host in ansible_play_batch %}
          {% for sname in myservices %}
          {% set service = sname | lower ~ '_state' %}
          {% if hostvars[host][service] is defined and hostvars[host][service] %}
          {{ host }}: {{ service }}: {{ hostvars[host][service] }}
          {% endif %}
          {% endfor %}
          {% endfor %}
      delegate_to: localhost
    

    【讨论】:

      【解决方案2】:

      使用Assignments。例如

          - set_fact:
              somevar_state: expected value
          - debug:
              msg: |
                {% set x = var ~ '_state' %}
                {{ hostvars[inventory_hostname][x] }}
            vars:
              var: somevar
      

      给予

        msg: |-
          expected value
      

      问:模板在循环中使用列表。

      答:例如

      - hosts: localhost
        vars:
          somevarlist: [var1, var2, var3]
        tasks:
          - set_fact:
              var1_state: expected value 1
              var2_state: expected value 2
              var3_state: expected value 3
          - debug:
              msg: |
                {% for var in somevarlist %}
                {% set x = var ~ '_state' %}
                {{ hostvars[inventory_hostname][x] }}
                {% endfor %}
      

      给予

        msg: |-
          expected value 1
          expected value 2
          expected value 3
      

      【讨论】:

      • 谢谢,但是当模板在循环中使用列表时会出现问题。例如:{% for var in somevarlist %}{% set x = var ~ '_state' %}{{ hostvars[inventory_hostname][x] }}{% endfor %}
      • 不客气。不要将代码放入 cmets。相反,edit 你的问题并提出minimal reproducible example。请参阅How do comments work? 和“cmets 有什么用,什么时候不应该发表评论?”特别是。
      猜你喜欢
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多