Ansible角色依赖其他角色的变量

73次阅读
没有评论

问题描述

有两个Ansible角色,一个角色名为foo,另一个角色名为bar。在bar角色中,需要使用由foo角色定义的变量{{ foo_path }},但不希望运行整个foo角色。用户希望找到一种方式,能够加载来自不同角色的变量foo_path,但不引入额外的运行开销。

解决方案

请注意以下操作可能受版本差异影响,务必做好备份。

方案1:将foo角色的默认值加载到字典中并获取变量foo_path

  1. 首先,在foo角色的defaults/main.yml中定义foo_path的默认值。
  2. bar角色中的pb_bar.yml中,使用include_vars来加载foo角色的默认值,并通过foo_defaults字典获取foo_path变量。
  3. bar角色中的任务中使用foo_path变量。

以下是具体步骤:
1. 在foo角色的defaults/main.yml中定义foo_path的默认值:

# roles/foo/defaults/main.yml
foo_path: /tmp/test.txt
  1. 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
  1. 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:重新组织角色的任务结构

  1. foo角色中,将安装文件的任务与断言文件存在的任务分别放到不同的文件中。
  2. 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
  1. 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,以满足角色间的依赖关系,同时避免引入额外的运行开销。

正文完