Ansible角色中的defaults和vars有什么区别?


151

创建新的Ansible角色时,模板会同时创建vars和一个defaults带有空main.yml文件的目录。在定义角色时,我可以将变量定义放在任何一个中,并且它们将在我的任务中可用。

将定义放入defaults和之间有什么区别vars?应该进入defaults什么,应该进入vars什么?将两者用于同一数据是否有意义?

我知道两者之间的优先级/优先级有所不同,但是我想了解应该去哪里。

假设我的角色将在目标系统上创建目录列表。我想提供要创建的默认目录的列表,但想允许用户在使用角色时覆盖它们。

如下所示:

---
- directories:
  - foo
  - bar
  - baz

从执行的角度来看,我可以将其放置在defaults/main.yml或中vars/main.yml,这没有任何区别-但是应该去哪里?

Answers:


113

有关变量优先级的Ansible文档总结了此niceley:

如果在不同的位置定义了多个同名变量,则它们将以一定顺序获胜,即:

  • 多余的变量(在命令行中用-e)总是赢
  • 然后是清单中定义的连接变量(ansible_ssh_user等)
  • 然后出现“大多数其他内容”(命令行开关,正在使用的var,包含的var,角色的var等)
  • 然后是库存中定义的其余变量
  • 然后出现有关系统的事实
  • 然后是“角色默认值”,这是最“默认值”,并且优先于所有内容。

因此,假设您有一个“ tomcat”角色,可用于在一系列Web主机上安装Tomcat,但是您需要在几个主机上安装不同版本的tomcat,在其他情况下,它需要以不同的用户身份运行,等等。该defaults/main.yml文件可能看起来像这样的东西:

tomcat_version: 7.0.56
tomcat_user: tomcat

由于这些只是默认值,这意味着如果没有在所讨论的主机的其他任何地方定义这些变量,则将使用它们。您可以通过Extra-vars,清单文件中的事实等覆盖这些变量,以为这些变量指定不同的值。

编辑:请注意,上面的列表适用于Ansible1.x。在Ansible 2.x中,该列表已扩展。与往常一样,Ansible文档提供了2.x变量优先级的详细说明。


4
谢谢,这是一个很棒的页面-那就是我想要的。我将详细介绍要放入的内容defaults以及接下来要放的内容vars
nwinkler

42
值得强调的是:角色var具有邪恶的高优先级。以我的经验,它们比玩变种高,这真令人讨厌。
tedder42

5年后,但是...我倾向于这样看:角色默认值是我期望角色用户在其var中某个地方覆盖的东西。角色变量OTOH允许我避免对任务中的信息进行硬编码,但可能仅被测试覆盖,并由角色维护者进行更改。例如,默认的初始admin用户名是vars,而依赖项版本则是vars。
ntwrkguru

41

定义的角色变量var具有很高的优先级-只能通过在命令行,特定任务或块中传递它们来覆盖它们。因此,几乎所有变量都应在中定义defaults

在“ 变量优先级-角色变量的放置位置 ”一文中,作者提供了一个示例,说明vars:不变的系统特定常量。因此,您可以拥有vars/debian.ymlvars/centos.yml具有相同的变量名但具有不同的值,并有条件地包括它们。


3

基本上,任何涉及“角色默认值”(角色内的默认值文件夹)的东西都是最易延展的,并且很容易被覆盖。角色的vars目录中的所有内容都会覆盖名称空间中该变量的先前版本。这里要遵循的想法是,范围越明确,在命令行中的优先级就越高-e总是赢得额外的var。主机变量和/或清单变量可以取代角色默认值,但不能像vars目录或include_vars任务那样显式包含。 doc


2

恕我直言,Ansible将如此高的优先级放在角色变量中的配置上是不切实际且不明智的。在配置和应低,可能是相同的优先级。vars/main.ymldefaults/main.yml

在我们想要这种行为的案例中,有没有现实生活中的例子?

有一些我们不想要的例子。

这里要说明的是,配置defaults/main.yml不能是动态的。vars/main.yml可以配置。因此,例如,您可以动态包含特定操作系统和版本的配置,如geerlingguy.postgresql中所示。

但是因为优先级在Ansible中是如此奇怪且不切实际,所以geerlingguy需要引入伪变量,如在variables.yml中所见。

- name: Define postgresql_packages.
  set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined

这是一个具体的现实生活示例,证明了优先级是不切实际的。

在此要说明的另一点是,我们希望角色是可配置的。角色可以是外部角色,也可以由其他人管理。通常,您不希望角色中的配置具有高优先级。


这应该是评论,而不是答案。
ntwrkguru

-4

变量和默认值是并行的。这是一个例子

-name: install package
 yum: name=xyz{{package_version}} state=present

在默认文件中,您将具有以下内容:

package_version: 123

ansible会做的是,它将取值package_version并将其放在包名称旁边,这样它将在某处显示为:

-name: install package
 yum: name=xyz123 state=present

这样,它将安装xyz123而不安装xyz123.4或在xyz的大型存储库中进行安装。

最后它会做 yum install -y xyz123

因此,基本上,默认值是存在的值,如果您没有为变量设置特定的值,则会导致空格无法保持为空。


不能投票,因为它不能解决问题。显然defaults,当没有vars定义时使用,但是答案没有解释,为什么要定义一个或另一个值,这就是OP要求的。比较下面的解释。
Thomas Hirsch '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.