Ansible角色中默认值和变量之间的区别是什么?

时间:2015-03-18 16:31:30

标签: ansible

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

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

我知道两者之间的优先级/优先级存在差异,但我想了解应该去哪里。

让我们说我的角色会在目标系统上创建一个目录列表。我想提供一个要创建的默认目录列表,但是希望允许用户在使用该角色时覆盖它们。

以下是这样的:

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

我可以将其放入defaults/main.ymlvars/main.yml,从执行的角度来看,它不会有任何区别 - 但它应该去哪里?

5 个答案:

答案 0 :(得分:86)

variable precedence上的Ansible文档总结了这个不错的文章:

  

如果在不同的地方定义了多个同名变量,他们会以某种顺序获胜,即:

     
      
  • 额外的变量(命令行中的-e)总是胜利
  •   
  • 然后是库存中定义的连接变量(ansible_ssh_user等)
  •   
  • 然后“大多数其他”(命令行开关,游戏中的变种,包括变量,角色变量等)
  •   
  • 然后是库存中定义的其余变量
  •   
  • 然后发现了关于系统的事实
  •   
  • 然后是“角色默认值”,这是最“默认”并且优先于所有内容。
  •   

假设你有一个“tomcat”角色用于在一堆webhost上安装Tomcat,但是你需要在几台主机上使用不同版本的tomcat,需要在其他情况下以不同的用户身份运行,等等。 defaults/main.yml文件可能如下所示:

tomcat_version: 7.0.56
tomcat_user: tomcat

由于这些只是默认值,这意味着如果这些变量没有在相关主机的任何其他位置定义,则会使用它们。您可以通过额外变量,库存文件中的事实等覆盖这些变量,以指定这些变量的不同值。

编辑:请注意,以上列表适用于Ansible 1.x.在Ansible 2.x中,列表已经扩展。与往常一样,Ansible Documentation提供了2.x的变量优先级的详细描述。

答案 1 :(得分:25)

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

在文章“Variable Precedence - Where To Put Your Role Vars”中,作者给出了vars中放置内容的一个示例:系统特定的常量不会发生太大变化。因此,vars/debian.ymlvars/centos.yml可以使用相同的变量名但不同的值,并有条件地包含它们。

答案 2 :(得分:3)

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

答案 3 :(得分:1)

恕我直言,将Ansible在角色 vars 中放在如此高的优先级上是不切实际且不明智的。 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

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

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

答案 4 :(得分:-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

所以基本上默认值是存在的值,如果没有为变量设置特定值,则导致该空间不能保持为空。