我对Ansible行为有点困惑:看起来,当我请求一个键的值时,它会计算字典中的所有值。
这是我的案子。我有一本有两个键的字典:dev和prod。每个密钥的值都是通过一个特定的Jinja2表达式来定义的,该表达式涉及使用AWS解密。大致看上去如下:
mydict:
dev: '{{ "dev-ciphertext" | kms_decrypt }}'
prod: '{{ "prod-ciphertext" | kms_decrypt }}'kms_decrypt是一个自定义过滤器,用于解密密文。由于dev和prod环境是分开的,并且剧本在只对其中一个环境有效的加密上下文中运行,所以一次只能计算一个表达式。尝试从另一个键检索值将失败。
假设剧本运行在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"}我意识到有很多方法可以解决这个问题,但是谁能解释为什么当只查询一个键时,整个字典值会得到评估呢?这对我来说似乎没有意义--至少从性能的角度来看是这样的。
发布于 2019-05-16 05:59:07
jinja模板在所有情况下都会呈现--没有“懒惰的Jinja”这样的东西,只有通过when:或类似的守卫来执行懒惰的任务。
因此,如果您还没有将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'] }}"https://stackoverflow.com/questions/56157605
复制相似问题