Ansible字典:所有值的隐式计算?
我对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是一个自定义筛选器
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'] }}"
感谢您的详细解释和建议的解决方法!