如何定义一个 Ansible 变量,其值是同一映射结构中的另一个变量?
为了允许变量的合理命名空间,我定义了这样的映射结构,其中一些值依赖于同一结构中的其他变量:
acme:
directory:
hostname: "acme-staging-v02.api.letsencrypt.org"
letsencrypt:
config_dir: "/etc/letsencrypt"
keys_dir: "{{ letsencrypt.config_dir }}/keys"
csrs_dir: "{{ letsencrypt.config_dir }}/csr"
certs_dir: "{{ letsencrypt.config_dir }}/certs"
accounts_dir: "{{ letsencrypt.config_dir }}/accounts"
csr_file: "{{ letsencrypt.csrs_dir }}/{{ site_domain }}.csr"
account_key_file: "{{ letsencrypt.csrs_dir }}/{{ acme.directory.hostname }}"
email_address: "certificate-reminders@{{ site_domain }}"
这失败了,因为 Ansible 无法解析在同一数据结构中引用其他值的值:
在模板字符串中检测到递归循环:{{letsencrypt.config_dir }}/keys
所以我认为查找vars
将允许推迟该解决方案:
acme:
directory:
hostname: "acme-staging-v02.api.letsencrypt.org"
letsencrypt:
config_dir: "/etc/letsencrypt"
keys_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/keys"
csrs_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/csr"
certs_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/certs"
accounts_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/accounts"
csr_file: "{{ lookup('vars', 'letsencrypt.csrs_dir') }}/{{ site_domain }}.csr"
account_key_file: >-
{{ lookup('vars', 'letsencrypt.csrs_dir') }}/{{ acme.directory.hostname }}
email_address: "certificate-reminders@{{ site_domain }}"
这失败了,因为 Ansible 正在尝试立即解决该查找:
未找到具有此名称的变量:letsencrypt.config_dir
当然我可以把它们分开,所以它们是单独的变量。但是,这违背了我将强相关变量全部分组在同一个命名空间中的目的。
那么什么将允许我定义数据结构,以便某些值可以依赖于同一结构中的其他变量?
(感谢@michael-hampton 提供了这个答案。)
如Ansible 问题#8603中所述,配置解析器正在读取变量值并立即尝试呈现它在定义变量时遇到的模板。当模板引用尚未完全定义的变量时,这会导致解析失败。
'rquelibari'的评论给出了很好的分析:
并详细解释这是如何发生的。
'cmpunches'随后的评论直接说明了所需的解决方案:
因此,直到 Ansible 中的 YAML 解析器被更正以将变量值读取为纯文本而不尝试立即渲染模板(因此推迟渲染直到所有变量都被定义),值中的这种交叉引用还不能在 Ansible 变量中完成.