首页 文章

Ansible playbook只添加角色依赖变量

提问于
浏览
0

所有文件都是

# roles/a/defaults/main.yml
test: Role A

# roles/a/tasks/main.yml
- name: Things I dont want to run
  debug: msg="Not expected"


# hosts
host-1 host-1 ansible_connection=local test=Override


# test.yml
- hosts: all
  roles:
    - a # I only need the variable
  tasks:
    - name: action
      debug: var=test # Expected Override

我怎样才能做到这一点 ?

我想到了这个

roles/
    a-var # only include defaults variable definition
    a # depends on a-var
    b # depends on a-var, but do not run role a's task

有点麻烦,但我认为这可能是解决问题的唯一方法 .

为什么我想要这个是我不希望用户关心太多文件( group_vars,host_vars,extra_vars ),而且他们不知道ansible,我必须尽可能简单地部署我们的系统,他们唯一需要关心的是库存文件,像这样

host-1
host-2

[a]
host-1 port=1234

[b]
host-2 # use default port defined in role

[all:vars]
install_path=/opt # override the default path

但是加载变量的顺序是

  • 角色默认值

  • 库存变量

  • inventory group_vars

  • inventory host_vars

  • playbook group_vars

  • playbook host_vars

  • 主持人事实

  • 注册变种

  • set_facts

  • 玩变种

  • 播放vars_prompt

  • 播放vars_files

  • 角色并包含变量

  • 块变量(仅适用于块中的任务)

  • 任务变量(仅适用于任务)

  • 额外的变量(总是赢得优先权)

这对于这种组织很难,因为我无法做到这一点,var文件将击败库存配置 .

- host: b
  var_files:
    # I hope this is just default and not take over inventory config
    - roles/a/defaults/main.yml 
  tasks:
    - debug: var=install_path # become default not custom's

1 回答

  • 4

    我认为你的计划没有错 . 它确实很麻烦但会起作用 .

    另一个想法是使用一个条件:

    roles:
      - role: a
        when: False
    

    这不会执行角色 a 中的任何任务,但会评估其变量和默认值,以后可供其他角色使用 .

    这里的丑陋之处在于,Ansible会将条件传递给角色的每一项任务 . 它仍将在输出中显示为跳过的任务 .


    但只是为了确保您了解 default() 过滤器:

    您可以在模板或任务中执行以下操作:

    {{ port | default(42) }}
    

    因此,如果在库存文件中定义了端口,则将使用该端口 . 如果没有定义它将是42 .

    你甚至可以将它与 set_fact 任务结合起来 .

    - set_fact:
        port: "{{ port | default(42) }}"
    

    这是我认为是你的目标最干净的方法 .

    如果你有更多的变量,你需要一个默认值,你可以在一个任务中做到这一点:

    - set_fact:
        port: "{{ port | default(42) }}"
        install_path: "{{ install_path | default('/opt') }}"
    

相关问题