问题描述
正在使用TestInfra编写mongo集群实例的测试脚本,并使用Molecule Ansible进行测试。他想要在所有实例之间共享变量。他创建了一个Python类,用于初始化和更新变量。每次运行molecule verify
时,每个测试都会在每个实例上运行,因此变量在单个实例上是独立的。
是否有可能在多个实例之间共享变量?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Ansible中,可以使用hostvars
字典来共享变量。根据Accessing information about other hosts with magic variables文档,hostvars
允许您访问另一个主机的变量,包括已收集的关于该主机的事实。您可以在playbook的任何位置访问主机变量。
以下是一个示例,演示如何使用hostvars
字典来共享变量:
- name: Example playbook
hosts: all
tasks:
- name: Print variable from another host
debug:
var: hostvars['test.example.com']['ansible_facts']['distribution']
在上面的示例中,我们使用hostvars
字典访问了名为test.example.com
的主机的ansible_facts
变量。您可以根据需要修改主机和变量的名称。
有关更多详细信息,请参阅Scoping variables和Caching facts文档。
方案2
如果禁用了“Fact Caching”,可以将所有hostvars
存储在文件中,以在Ansible playbooks之间共享信息。以下是一个示例模板,演示如何将所有主机的hostvars
存储在文件中:
$ cat my_hostvars.json.j2
my_hostvars_all:
{% for my_host in ansible_play_hosts_all %}
{{ my_host }}:
{{ hostvars[my_host]|to_nice_json }}
{% endfor %}
下面是一个示例playbook,演示如何将所有主机的hostvars
存储在文件中,并在下一个playbook中使用它:
- hosts: test_jails
tasks:
- set_fact:
test_var: "test_var_in_{{ inventory_hostname }}"
- template:
src: my_hostvars.json.j2
dest: "{{ inventory_dir }}/my_hostvars.json"
delegate_to: localhost
run_once: true
在上面的示例中,我们首先使用set_fact
任务设置了一个名为test_var
的变量。然后,使用template
任务将my_hostvars.json.j2
模板渲染为{{ inventory_dir }}/my_hostvars.json
文件,并将其委托给localhost(master)执行。
在下一个playbook中,我们可以使用include_vars
任务将存储在文件中的hostvars
包含进来,并将其存储在my_hostvars
变量中。然后,我们可以使用debug
任务打印出my_hostvars
变量的值。
- hosts: test_jails
tasks:
- include_vars: my_hostvars.json
- set_fact:
my_hostvars: "{{ my_hostvars_all[inventory_hostname] }}"
- debug:
var: my_hostvars.test_var
上述playbook将打印出每个主机的test_var
变量的值。
请注意,这只是一种共享变量的方法之一,您可以根据自己的需求进行调整和扩展。