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

nwi*_*ler 134 ansible

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

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

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

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

这是这样的:

---
- directories:
  - foo
  - bar
  - baz
Run Code Online (Sandbox Code Playgroud)

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

Bru*_*e P 99

关于变量优先级的Ansible文档总结了这个niceley:

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

  • 额外的变量(命令行中的-e)总是赢
  • 然后是库存中定义的连接变量(ansible_ssh_user等)
  • 然后是"最重要的一切"(命令行开关,游戏中的变种,包括变量,角色变量等)
  • 然后是库存中定义的其余变量
  • 然后是关于系统发现的事实
  • 然后是"角色默认值",这是最"默认"并且优先于一切.

所以假设你有一个"tomcat"角色用于在一堆webhost上安装Tomcat,但是你需要在几台主机上使用不同版本的tomcat,需要它在其他情况下作为不同用户运行,等等.defaults/main.yml文件可能看起来如此这样的事情:

tomcat_version: 7.0.56
tomcat_user: tomcat
Run Code Online (Sandbox Code Playgroud)

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

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

  • 值得强调的是:**角色变量具有邪恶的优先级**.根据我的经验,他们比玩变量高,这真的很烦人. (37认同)
  • 谢谢,这是一个很好的页面 - 这就是我想要的.我将详细介绍"默认值"中的内容以及"vars"中的内容. (4认同)
  • 5 年后,但是......我倾向于这样看待它:角色默认值是我希望角色的用户在其变量中的某个地方覆盖的东西。角色变量,OTOH,允许我避免在任务中硬编码信息,但可能只会在测试时被覆盖,并由角色维护者更改。例如,初始管理员用户名将采用默认值,但依赖项版本将采用变量。 (2认同)

chi*_*org 33

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

在文章" 变量优先 - 在哪里放置你的角色变量 "中,作者给出了一个放置内容的例子vars:系统特定的常量不会发生太大变化.所以,你可以拥有vars/debian.ymlvars/centos.yml使用相同的变量名,但不同的价值观,并将其纳入条件.


onk*_*ows 9

IMHO it is impractical and not sensible that Ansible places such high priority on configuration in vars of roles. Configuration in vars/main.yml and defaults/main.yml should be low and probably the same priority.

Are there any real life examples of cases where we want this type of behavior?

There are examples that we dont' want this.

The point to make here is that configuration in defaults/main.yml cannot be dynamic. Configuration in vars/main.yml can. So for example you can include configuration for specific OS and version dynamically as shown in geerlingguy.postgresql

But because precedence is so strange and impractical in Ansible geerlingguy needs to introduce pseudo variables as can be seen in variables.yml

- name: Define postgresql_packages.
  set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined
Run Code Online (Sandbox Code Playgroud)

This is a concrete real life example that demonstrates that the precedence is impractical.

Another point to make here is that we want roles to be configurable. Roles can be external, managed by someone else. As a general rule you don't want configuration in roles to have high priority.

  • 这应该是评论,而不是答案。 (4认同)

小智 5

基本上,进入 \xe2\x80\x9crole defaults\xe2\x80\x9d (角色内的默认文件夹)的任何内容都是最具延展性且易于覆盖的。角色的 vars 目录中的任何内容都会覆盖命名空间中该变量的先前版本。这里要遵循的想法是,范围越明确,命令行 -e extra vars 总是获胜的优先级就越高。主机和/或清单变量可以胜过角色默认值,但不能像 vars 目录或 include_vars 任务那样显式包含。\n doc

\n