如何在 Ansible (2.1.x)中的其他变量中重用变量而不会导致递归循环?
考虑这个roles/<role>/defaults/main.yml
文件:
---
liquibase:
version: "3.5.3"
download_file: "liquibase-{{liquibase.version}}-bin.tar.gz"
# I also tried this alternative with a similar result:
# download_file: "liquibase-{{liquibase[version]}}-bin.tar.gz
...
和此roles/<role>/tasks/main.yml
文件:
---
- name: Liquibase | Download
debug:
msg: "download_file: {{liquibase.download_file}}"
...
我希望变量liquibase.download_file
的值为liquibase-3.5.3-bin.tar.gz
但是当我使用此角色运行一个剧本时,我收到以下错误:
...
TASK [liquibase : Liquibase | Download] *******************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "...: recursive loop detected in template string: liquibase-{{liquibase.version}}-bin.tar.gz"}
...
显然我想下载Liquibase,我想让角色的用户决定使用哪个版本。我还希望能够完全覆盖下载位置(文件,URL等),例如,使用公司的FTP服务器或类似服务器。
答案 0 :(得分:4)
不支持在同一父dict中引用其他dict键。请参阅此issue。
您只能重构变量,以便在不同的变量树中生成version
和download_file
,例如:
liquibase_version: "3.5.3"
liquibase_download_file: "liquibase-{{liquibase_version}}-bin.tar.gz"
P.S。如果这是您的角色的默认设置,将liquibase_version
分隔为独立变量会更加明显。这样,用户只需重新定义liquibase_version
,liquibase_download_file
即可获得更改;如果是dict(如你的问题),你不能只覆盖一个密钥,用户必须使用version
和download_file
密钥设置完整的字典。
答案 1 :(得分:0)
当尝试将YAML结构的优雅与Jinja2的灵活性相结合时,我感到沮丧。由于不被支持,解决该问题的一种方法(我承认这有点不合时宜)是引入一个伪私有部分来帮助打破周期。首先,我们声明任何可能导致依赖的内容:
# Pseudo private KV pairs, used to work around recursion issues.
_liquibase_version: "3.5.3"
我们只需要声明将在字典中声明的任何内容,并形成另一个字典键的依赖项。接下来,我们可以根据需要声明字典,但在必要时使用“专用”键值对:
liquibase:
version: "{{_liquibase_version}}"
download_file: "liquibase-{{_liquibase_version}}-bin.tar.gz"
当然,_liquibase_version
不是真正的 ,而是充当助手,因此我们只需要定义一次值,但仍然可以引用{{ 1}}和{{liquibase.version}}
。