除非设置为默认值,否则 Ansible 变量未定义

除非设置为默认值,否则 Ansible 变量未定义

我正在尝试向现有的 git 存储库添加一个新变量,其中包含大量使用角色的 Ansible 文件。因此,无论在哪里foo引用,下面

vars_files:
   - vars/aws.yml
   - vars/aws-credentials.yml

我添加了新行

   - vars/rpm-repo.yml

我已经创建了vars/rpm-repo.yml以下内容:

---
yum_rpm_dir: https://example.com/repo/noarch

根据给出的命令,这是有效的 YAML这个答案用于检查文件是否是有效的 YAML。

我已经roles/foo/tasks/main.yml更改了一项yum任务来安装它:

name: "{{ yum_rpm_dir }}/rest-api-{{ rest_api_version }}-1.noarch.rpm"

(此明确 URL 的目的是为了解决我们的 RPM 存储库中的一个错误。)

但我明白:

fatal: [1.2.3.4]: FAILED! => {"failed": true, "msg": "'yum_rpm_dir' is undefined"}

所以我想,显然我还没有理解变量如何与 Ansible 中的角色交互的复杂性,所以我将它添加为默认值,这肯定会起作用。

roles/foo/defaults/main.yml因此我也将上面的文件复制了到。

这可行,但这只是一种 hack。将其设为变量的全部意义在于,它的值可以被多个角色使用,而无需复制和粘贴。

总结:如何在 Ansible 中正确设置变量以便角色可以获取它?

答案1

您没有指定ansible正在使用的版本,并且从 1.x 到 2.x 有重要的变化。

来自在线文档,答案是

如何在 Ansible 中正确设置变量以便角色可以获取它?

将会:

在 1.x 中,优先级如下(最后列出的变量优先):

  • “角色默认值”,它失去了所有角色的优先级,并且最容易被覆盖
  • inventory 中定义的变量
  • 关于系统发现的事实
  • “其他大多数内容”(命令行开关、正在运行的变量、包含的变量、角色变量等)
  • 连接变量(ansible_user 等)
  • 额外变量(命令行中的 -e)总是获胜

在 2.x 中,优先顺序更加具体(最后列出的变量优先):

  • 角色默认值(每个角色中的任务将看到自己角色的默认值。在角色之外定义的任务将看到最后一个角色的默认值)
  • 库存变量(库存文件中定义或由动态库存提供的变量)
  • 库存组变量
  • 库存主机变量
  • 剧本 group_vars
  • 剧本 host_vars
  • 主办方事实
  • 玩变量
  • 播放 vars_prompt
  • 播放 vars_files
  • 注册变量
  • 设置事实
  • 角色并包含变量
  • 块变量(仅适用于块中的任务)
  • 任务变量(仅适用于任务)
  • 额外变量(始终优先)

针对您的特定用例的答案要求您提供文件在目录结构中的位置var(因为无法从提供的数据中推断出)。根据这些文件的放置位置,它们具有不同的优先级。

我个人更喜欢将数据分组group_vars(检查最佳实践文档中提供了首选布局),这样我就可以将数据分配给主机组,主要是因为这通常直接映射到角色。

答案2

问题很简单,我错过了一个foo使用该角色的文件。

引用看起来foo不像这样:

 roles:
    - foo

但像这样:

 roles:
     - { role: foo, rest_api_version: "{{ blah_version }}" }

所以我忽略了它。一旦我在对 foo 角色的“调用”之前添加对 vars 文件的相同引用,它就可以在没有默认文件的情况下工作。

相关内容