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

但是加载变量的顺序是

  • 角色默认值
  • 库存变量
  • 库存组变量
  • 清单 host_vars
  • 剧本 group_vars
  • 剧本host_vars
  • 主机事实
  • 注册变量
  • 设置事实
  • 玩变量
  • 播放 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
4

1 回答 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') }}"
于 2016-03-12T06:49:14.247 回答