我可以从远程主机本身本地应用 Ansible 剧本,并且特殊变量已定义(并且大多数非空)。但是,当我在本地以远程主机为目标应用它时,它们都是空的。我希望从该远程机器的角度来看,在这两种情况下上下文应该是相同的。
具体来说,剧本有一个编写 BASH 脚本的 shell 任务。以下是其中的大部分内容:
echo "#!/bin/sh" > /usr/local/bin/ml_provision_info
echo >> /usr/local/bin/ml_provision_info
# Playbook info.
echo "echo 'Playbook Git revision: {{ ml_playbook_revision | default("<not provided>", true) }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'Playbook version (integer): {{ playbook_version }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'Playbook applied at: $(date)'" >> /usr/local/bin/ml_provision_info
echo "echo" >> /usr/local/bin/ml_provision_info
echo >> /usr/local/bin/ml_provision_info
# General Ansible context.
echo "echo 'VAR(ansible_dependent_role_names): {{ ansible_dependent_role_names | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'VAR(ansible_play_role_names): {{ ansible_play_role_names | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'VAR(ansible_role_names): {{ ansible_role_names | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'VAR(ansible_run_tags): {{ ansible_run_tags | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'VAR(ansible_skip_tags): {{ ansible_skip_tags | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo 'VAR(group_names): {{ group_names | default([]) | join(',') }}'" >> /usr/local/bin/ml_provision_info
echo "echo" >> /usr/local/bin/ml_provision_info
echo >> /usr/local/bin/ml_provision_info
当我们从本地运行剧本时,特殊变量具有预期值:
Playbook Git revision: 4967a0f8d249daa36b3a53e0d10d791502030a24
Playbook version (integer): 783
Playbook applied at: Wed Oct 23 01:39:44 UTC 2019
VAR(ansible_dependent_role_names):
VAR(ansible_play_role_names): resolvconf,jenkins_slave,git,git_tools,kraken_modules,slave_netrc,gcc5.4.1,ntp,docker,guardicore,yaegashi.blockinfile,swarmclient,zabbix_agent,specifics
VAR(ansible_role_names): kraken_modules,git,git_tools,ntp,zabbix_agent,guardicore,specifics,slave_netrc,swarmclient,resolvconf,gcc5.4.1,jenkins_slave,docker,yaegashi.blockinfile
VAR(ansible_run_tags): all
VAR(ansible_skip_tags):
VAR(group_names): ungrouped
然而,当我们从远程运行它时,大多数值都是不明确的:
Playbook Git revision: 4967a0f8d249daa36b3a53e0d10d791502030a24
Playbook version (integer): 783
Playbook applied at: Wed Oct 23 01:08:16 UTC 2019
VAR(ansible_dependent_role_names):
VAR(ansible_play_role_names):
VAR(ansible_role_names):
VAR(ansible_run_tags): all
VAR(ansible_skip_tags):
VAR(group_names): ungrouped
我错过了什么?
答案1
弄清楚 Ansible 中何时发生了变化并不总是那么容易。让我们试着找出 ansible_dependent_role_names 是何时添加的!
第一个选项
这通常是找出某些代码何时被更改的最佳方法,但它也适用于查找变量。主机变量由 lib/ansible/vars/hostvars.py 生成。
我们可以拉入 ansible repo 或使用 GitHub 进行 git blame。
https://github.com/ansible/ansible/blame/devel/lib/ansible/vars/hostvars.py
搜索 ansible_dependent_role_names 得到以下结果:
看着https://github.com/ansible/ansible/pull/46483它指出:
因此我们引入两个新的魔法变量,并重新定义一个:
- role_names 现在包含所有角色名称,包括依赖项的名称。检查 role_names 时最常见的用例是查看目标主机是否受特定角色的影响。将依赖项添加到此列表不会破坏这些用例,反而会使它们更准确。
- play_role_names 承担了前一个 role_names 的角色,仅列出按剧本明确列出的角色。如果需要查看角色是否明确配置,可以使用此列表
- dependent_role_names 列出了所有被包含的角色,因为它们是另一个角色的依赖项。这意味着它们可能包括也在 play_role_names 中定义的角色,因此检查 play_role_names 可以验证特定角色是否只是依赖项,或者既是依赖项又是明确要求的。
该提交于 2018 年 11 月添加到 devel,2.4 于 2018 年 9 月发布。
第二种选择
确保特定版本具有变量的更简单方法是使用 pip 和 virtualenv,这样你就可以轻松切换到旧版 Ansible 并使用 进行查看 ansible all -m setup
。请参阅https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#latest-releases-via-pip
第三种选择
看看更新日志!每个 Ansible 主要版本都有自己的更新日志,并且位置多年来一直在变化,但让我们来看看2.8 版本在 2.8.0 的发行说明中:
- 魔法变量 - 添加了一个新的 ansible_dependent_role_names 魔法变量来包含通过依赖项间接应用于主机的角色名称。
- 魔法变量 - 添加了新的 ansible_play_role_names 魔法变量来模拟 role_names 的旧功能。此变量仅列出直接应用于主机的角色名称,不包括通过依赖项添加的角色名称
- 魔法变量 - 添加了一个新的 ansible_role_names 魔法变量,以包含直接和间接(通过依赖项)应用于主机的角色名称。