所有文件都是
# 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 回答
我认为你的计划没有错 . 它确实很麻烦但会起作用 .
另一个想法是使用一个条件:
这不会执行角色
a
中的任何任务,但会评估其变量和默认值,以后可供其他角色使用 .这里的丑陋之处在于,Ansible会将条件传递给角色的每一项任务 . 它仍将在输出中显示为跳过的任务 .
但只是为了确保您了解
default()
过滤器:您可以在模板或任务中执行以下操作:
因此,如果在库存文件中定义了端口,则将使用该端口 . 如果没有定义它将是42 .
你甚至可以将它与
set_fact
任务结合起来 .这是我认为是你的目标最干净的方法 .
如果你有更多的变量,你需要一个默认值,你可以在一个任务中做到这一点: