问题描述
有两个Ansible角色,一个角色名为foo
,另一个角色名为bar
。在bar
角色中,需要使用由foo
角色定义的变量{{ foo_path }}
,但不希望运行整个foo
角色。用户希望找到一种方式,能够加载来自不同角色的变量foo_path
,但不引入额外的运行开销。
解决方案
请注意以下操作可能受版本差异影响,务必做好备份。
方案1:将foo
角色的默认值加载到字典中并获取变量foo_path
- 首先,在
foo
角色的defaults/main.yml
中定义foo_path
的默认值。 - 在
bar
角色中的pb_bar.yml
中,使用include_vars
来加载foo
角色的默认值,并通过foo_defaults
字典获取foo_path
变量。 - 在
bar
角色中的任务中使用foo_path
变量。
以下是具体步骤:
1. 在foo
角色的defaults/main.yml
中定义foo_path
的默认值:
# roles/foo/defaults/main.yml
foo_path: /tmp/test.txt
- 在
bar
角色中的pb_bar.yml
中,使用include_vars
加载foo
角色的默认值,并通过foo_defaults
字典获取foo_path
变量:
# pb_bar.yml
- hosts: localhost
pre_tasks:
- include_vars:
file: roles/foo/defaults/main.yml
name: foo_defaults
- debug:
var: foo_defaults.foo_path
when: debug|d(false)|bool
- set_fact:
foo_path: "{{ foo_defaults.foo_path }}"
roles:
- bar
- 在
bar
角色中的任务中使用foo_path
变量:
# roles/bar/tasks/main.yml
- stat:
path: "{{ foo_path }}"
register: foo_path_st
- debug:
var: foo_path_st
when: debug|d(false)|bool
- assert:
that: foo_path_st.stat.exists
方案2:重新组织角色的任务结构
- 在
foo
角色中,将安装文件的任务与断言文件存在的任务分别放到不同的文件中。 - 在
bar
角色中使用include_role
加载foo
角色,并在其中选择需要执行的任务,以确保foo
角色的安装文件任务先于bar
角色执行。
以下是具体步骤:
1. 在foo
角色中,重新组织任务结构如下:
# roles/foo/tasks/assert_foo_path.yml
- stat:
path: "{{ foo_path }}"
register: foo_path_st
- debug:
var: foo_path_st
when: debug|d(false)|bool
- assert:
that: foo_path_st.stat.exists
# roles/foo/tasks/install_foo_path.yml
- file:
path: "{{ foo_path }}"
state: touch
# roles/foo/tasks/main.yml
- name: Install foo_path
include_tasks: install_foo_path.yml
- name: Assert foo_path
include_tasks: assert_foo_path.yml
- 在
bar
角色中,使用include_role
加载foo
角色,并选择需要执行的任务:
# roles/bar/tasks/main.yml
- name: Assert foo_path
include_role:
name: foo
tasks_from: assert_foo_path.yml
通过这两个方案,用户可以根据实际需求选择合适的方式来加载来自foo
角色的变量foo_path
,以满足角色间的依赖关系,同时避免引入额外的运行开销。
正文完