Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ansible字典:所有值的隐式计算?_Ansible_Jinja2 - Fatal编程技术网

Ansible字典:所有值的隐式计算?

Ansible字典:所有值的隐式计算?,ansible,jinja2,Ansible,Jinja2,我对Ansible行为有点困惑:看起来当我请求一个键的值时,它会计算字典中的所有值 这是我的箱子。我有一本有两个键的字典:dev和prod。每个密钥的值都是通过特定的Jinja2表达式定义的,该表达式涉及使用AWS KMS进行解密。大致上是这样的: mydict: dev: '{{ "dev-ciphertext" | kms_decrypt }}' prod: '{{ "prod-ciphertext" | kms_decrypt }}' kms\u decrypt是一个自定义筛选器

我对Ansible行为有点困惑:看起来当我请求一个键的值时,它会计算字典中的所有值

这是我的箱子。我有一本有两个键的字典:
dev
prod
。每个密钥的值都是通过特定的Jinja2表达式定义的,该表达式涉及使用AWS KMS进行解密。大致上是这样的:

mydict:
  dev: '{{ "dev-ciphertext" | kms_decrypt }}'
  prod: '{{ "prod-ciphertext" | kms_decrypt }}'
kms\u decrypt
是一个自定义筛选器,用于解密密文。由于
dev
prod
环境是分开的,并且playbook在仅对其中一个环境有效的加密上下文中运行,一次只能计算一个表达式。尝试从另一个键检索值将失败

假设剧本在
dev
环境中运行,当我评估
mydict['dev']
时,我希望它返回解密的
dev-ciphertext
。然而,事实上,我得到的是
prod ciphertext
解密失败,因为加密上下文不匹配

我可以用一个简单的例子来说明同样的行为。我没有重新创建解密机制,而是通过一个未定义的变量定义了一个字典值:

- hosts: localhost
  become: no
  vars:
    dev_value: '123'
    mydict:
     dev: '{{ dev_value }}'
     prod: '{{ prod_value }}'
  tasks:
    - debug:
        msg: "{{ mydict['dev'] }}"
尽管从未明确查询过
mydict['prod']
,但我仍然收到一个错误,表明无法对其进行评估:

TASK [debug] *********************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'prod_value' is undefined\n\nThe error appears to have been in 'ansible/test.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - debug:\n      ^ here\n"}

我意识到有很多方法可以解决这个问题,但是有人能解释为什么当只查询一个键时,整个字典值都会被计算吗?至少从性能的角度来看,这对我来说似乎没有意义。

Jinja模板在任何情况下都是呈现的——没有“懒惰的Jinja”这样的东西,只有通过
的懒惰任务,当:
或类似的保护

因此,如果您的代码中没有
my_dict[“dev”]
这样的名称,那么我建议您使用合理的名称,如
my_env
或其他名称,并且只声明一个对活动环境有意义的值:

- hosts: localhost
  become: no
  vars:
    dev_value: '123'
  tasks:
  - set_fact:
      my_env: '{{ "prod-ciphertext" | kms_decrypt }}'
    when: some_environment_variable == "prod"
  - set_fact:
      my_env: '{{ "dev-ciphertext" | kms_decrypt }}'
    when: some_environment_variable == "dev"
否则,您可以保护表达式(为了清楚起见,始终将被计算),以在不适用时返回默认值:

- hosts: localhost
  become: no
  vars:
    dev_value: '123'
    my_dict:
      prod: '{{ ("prod-ciphertext" | kms_decrypt)
               if the_magic_env == "prod" else {} }}'
      dev: '{{ ("dev-ciphertext" | kms_decrypt)
               if the_magic_env == "dev" else {} }}'
  tasks:
    - debug:
        msg: "{{ mydict['dev'] }}"

感谢您的详细解释和建议的解决方法!