我正在使用最新版本的 Ansible,并且尝试使用默认变量 inused role-oneon host one、 in role-two、used on host two,但我无法让它工作。
我在文档或 StackOverflow 上发现的任何内容都没有真正帮助。我不确定我做错了什么。理想情况下,我希望设置变量的值一次,并能够在我的剧本中的任何主机的另一个角色中使用它。
我已将其分解如下。
在我的清单中,我有一个名为 的主机组[test],其中有两个别名为one和 的主机two。
[test]
one ansible_host=10.0.1.10 ansible_connection=ssh ansible_user=centos ansible_ssh_private_key_file=<path_to_key>
two ansible_host=10.0.1.20 ansible_connection=ssh ansible_user=centos ansible_ssh_private_key_file=<path_to_key>
Run Code Online (Sandbox Code Playgroud)
我有一个剧本,其中包含每个主机的剧本,并且我提供了host和host 的hosts:值。"{{ host_group }}[0]"one"{{ host_group }}[1]"two
主机的戏剧one使用名为 的角色role-one,主机的戏剧two使用名为 的角色role-two。
[test]
one ansible_host=10.0.1.10 ansible_connection=ssh ansible_user=centos ansible_ssh_private_key_file=<path_to_key>
two ansible_host=10.0.1.20 ansible_connection=ssh ansible_user=centos ansible_ssh_private_key_file=<path_to_key>
Run Code Online (Sandbox Code Playgroud)
在role-one我设置了一个变量variable-one。
- name: Test Sharing Role Variables
hosts: "{{ host_group }}[0]"
roles:
- ../../ansible-roles/role-one
- name: Test Sharing Role Variables
hosts: "{{ host_group }}[1]"
roles:
- ../../ansible-roles/role-two
Run Code Online (Sandbox Code Playgroud)
variable_one我想在模板中使用 的值,role-two但我没有任何运气。我使用下面的任务来role-two测试并查看变量是否被“拾取”。
---
# defaults file for role-one
variable_one: Role One Variable
Run Code Online (Sandbox Code Playgroud)
当我运行剧本时,ansible-playbook test.yml --extra-vars "host_group=test"出现以下失败。
---
# tasks file for role-two
- debug:
msg: "{{ variable_one }}"
Run Code Online (Sandbox Code Playgroud)
lar*_*sks 11
角色中声明的变量的范围仅限于戏剧。role-one如果您想从in访问变量role-two,则它们都需要在同一个 play 中。例如,你可以写:
- name: Test Sharing Role Variables
hosts: "{{ host_group }}"
tasks:
- import_role:
name: role-one
when: inventory_hostname == "one"
- import_role:
name: role-two
when: inventory_hostname == "two"
Run Code Online (Sandbox Code Playgroud)
或者,您可以重组您的角色,以便可以将变量与您的操作分开导入。也就是说,拥有一个role_one_vars除了定义变量之外什么也不做的角色,然后您可以将其导入到 和role-one中role-two。也就是说,您将拥有类似以下的结构:
playbook.yml
hosts
roles/
role-one/
tasks/
main.yml
role-one-vars/
variables/
main.yml
role-two/
tasks/
main.yml
Run Code Online (Sandbox Code Playgroud)
看起来role-one/tasks/main.yml像:
- import_role:
name: role-one-vars
- debug:
msg: "in role-one: {{ variable_one }}"
Run Code Online (Sandbox Code Playgroud)
role-two/tasks/main.yml看起来像:
---
- import_role:
name: role-one-vars
- debug:
msg: "in role-two: {{ variable_one }}"
Run Code Online (Sandbox Code Playgroud)
看起来role-one-vars/vars/main.yml像:
---
variable_one: role one variable
Run Code Online (Sandbox Code Playgroud)
将所有这些放在一起,输出如下所示:
PLAY [Test Sharing Role Variables] *****************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [one]
TASK [role-one : debug] ****************************************************************************************************************************************************
ok: [one] => {
"msg": "in role-one: role one variable"
}
PLAY [Test Sharing Role Variables] *****************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [two]
TASK [role-two : debug] ****************************************************************************************************************************************************
ok: [two] => {
"msg": "in role-two: role one variable"
}
PLAY RECAP *****************************************************************************************************************************************************************
one : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
two : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run Code Online (Sandbox Code Playgroud)
问:“在具有多个主机的 Ansible playbook 中,从一个角色访问另一个角色中的变量”
答:简短的回答:使用set_fact并将变量放入hostvars中。
详细信息:给定角色
shell> cat roles/role-one/defaults/main.yml
variable_one: Role One Variable
shell> cat roles/role-one/tasks/main.yml
- debug:
var: variable_one
shell> cat roles/role-two/tasks/main.yml
- debug:
var: variable_one
Run Code Online (Sandbox Code Playgroud)
剧本
- hosts: one
roles:
- role-one
tasks:
- debug:
var: variable_one
- hosts: two
roles:
- role-two
- hosts: one
tasks:
- debug:
var: variable_one
Run Code Online (Sandbox Code Playgroud)
给出(删节)
PLAY [one] ************************************************
TASK [role-one : debug] ****
ok: [one] =>
variable_one: Role One Variable
TASK [debug] ****
ok: [one] =>
variable_one: Role One Variable
PLAY [two] ************************************************
TASK [role-two : debug] ****
ok: [two] =>
variable_one: VARIABLE IS NOT DEFINED!
PLAY [one] ************************************************
TASK [debug] ****
ok: [one] =>
variable_one: VARIABLE IS NOT DEFINED!
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,变量variable_one对于第一次运行的任务是可见的。但是,没有理由在第二场比赛中该变量对主机两人可见。该变量在第三次播放中对同一主机也不可见,因为它尚未存储在主机变量中,即“实例化”。下面的剧本
- hosts: one
roles:
- role-one
tasks:
- debug:
var: variable_one
- set_fact:
variable_one: "{{ variable_one }}"
- hosts: two
roles:
- role-two
- hosts: one
tasks:
- debug:
var: variable_one
Run Code Online (Sandbox Code Playgroud)
给出(删节)
PLAY [one] ************************************************
TASK [role-one : debug] ****
ok: [one] =>
variable_one: Role One Variable
TASK [debug] ****
ok: [one] =>
variable_one: Role One Variable
TASK [set_fact] ****
ok: [one]
PLAY [two] ************************************************
TASK [role-two : debug] ****
ok: [two] =>
variable_one: VARIABLE IS NOT DEFINED!
PLAY [one] ************************************************
TASK [debug] ****
ok: [one] =>
variable_one: Role One Variable
Run Code Online (Sandbox Code Playgroud)
现在,该变量对整个剧本中的主机可见,并且也可以对使用主机变量的其他主机可见。例如,下面的剧本
- hosts: one
roles:
- role-one
tasks:
- debug:
var: variable_one
- set_fact:
variable_one: "{{ variable_one }}"
- hosts: two
tasks:
- set_fact:
variable_one: "{{ hostvars.one.variable_one }}"
- include_role:
name: role-two
Run Code Online (Sandbox Code Playgroud)
给出(删节)
PLAY [one] ************************************************
TASK [role-one : debug] ****
ok: [one] =>
variable_one: Role One Variable
TASK [debug] ****
ok: [one] =>
variable_one: Role One Variable
TASK [set_fact] ****
ok: [one]
PLAY [two] ************************************************
TASK [set_fact] ****
ok: [two]
TASK [include_role : role-two] ****
TASK [role-two : debug] ****
ok: [two] =>
variable_one: Role One Variable
Run Code Online (Sandbox Code Playgroud)
上述设置的问题在于引用主机变量的主机是硬编码的。更好的方法是在所有主机的第一次播放中“实例化”变量。例如,为角色添加一个虚拟任务
shell> cat roles/role-one/tasks/noop.yml
- meta: noop
Run Code Online (Sandbox Code Playgroud)
然后,在第一个游戏中,包含所有主机,run_once导入角色,仅运行虚拟任务,并为所有主机“实例化”变量。例如
- hosts: all
tasks:
- import_role:
name: role-one
tasks_from: noop.yml
run_once: true
- set_fact:
variable_one: "{{ variable_one }}"
run_once: true
- hosts: two
roles:
- role-two
- hosts: one
roles:
- role-two
Run Code Online (Sandbox Code Playgroud)
给出(删节)
PLAY [all] ************************************************
TASK [set_fact] ****
ok: [one]
PLAY [two] ************************************************
TASK [role-two : debug] ****
ok: [two] =>
variable_one: Role One Variable
PLAY [one] ************************************************
TASK [role-two : debug] ****
ok: [one] =>
variable_one: Role One Variable
Run Code Online (Sandbox Code Playgroud)