在具有多个主机的 Ansible playbook 中,从一个角色访问另一个角​​色中的变量

Jak*_*ice 9 ansible

我正在使用最新版本的 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-onerole-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)


Vla*_*tka 5

问:在具有多个主机的 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)