Ansible 中的 jinja2 模板未正确评估嵌套字典变量

nested dictionary variable is not evaluated correctly with jinja2 template in Ansible

我在 yaml 文件和 jinja2 模板中有如下变量。

#consul_common.yml

preprod:
 config_token: "SomeTestToken"

#config.env.j2

service_config_token={{ config_token }}

剧本如下:

---
- hosts: all
  gather_facts: yes
  tasks:
    - include_vars: consul_common.yml
      
    - set_fact:
        config_token: "{{ (deploy_environment | lower) }}['config_token']"
    
    - debug:
        var: "{{ config_token }}"  
        

    - template: 
        src: config.env.j2
        dest:  /apps/account-service/config.env   

当我 运行 剧本传递额外的环境变量 deploy_environment=PREPROD 时,调试会给出正确的变量值,即“SomeTestToken” 但是当它在 jinja2 模板中模板化时,这就是我在 /apps/account-service/config.env

中得到的
service_config_token=preprod['consul_config_token']

我期待的内容是:service_config_token=SomeTestToken

尝试过 "{{ (deploy_environment | lower)['config_token'] }}",也没有用。

实际上 set_fact 设置的变量 config_token 包含字典引用 "config_token": "preprod['consul_config_token']",而不是值。

示例(注意缺少的 Jinja 定界符 {{ .. }}):

  - debug:
      var: config_token

此外,在您的 vars 文件 consul_common.yml 中,您正在设置 preprod['config_token']。而在你的 set_fact 中,你试图引用 preprod['consul_config_token'],理想情况下 不应该 给你 SomeTestToken.

的值

因此,在对上述问题进行更正后,下面的剧本应该可以完成工作:

  tasks:
  # include vars with a variable name, so that we can access the sub-dict "preprod"
  - include_vars:
      file: consul_common.yml
      name: consul_vars

  # I have used the shorter "deploy_env" variable
  - set_fact:
      config_token: "{{ consul_vars[deploy_env|lower]['config_token'] }}"

  - template:
      src: config.env.j2
      dest:  /apps/account-service/config.env

上面的剧本 运行 和 -e "deploy_env=PREPROD",将模板呈现为:

service_config_token=SomeTestToken