Ansible 2.8 角色 - 使用 vars/main 目录

Ansible 2.8 Roles - using the vars/main directory

我正在尝试将我的 Ansible 角色变量拆分为多个文件 - 根据 ,应该可以创建一个 vars/main 目录,并且该目录中的所有 .yml 文件应该被自动加载。

然而,这似乎并没有发生在我的情况下。

我的目录结构:

vars
└── main
    ├── gce_settings.yml
    ├── vsphere_settings.yml
    └── vsphere_zone.yml

然而,当我尝试使用 vsphere_settings.yml 中定义的变量时,Ansible 抱怨该变量未定义: {"msg": "The task includes an option with an undefined variable. The error was: 'vsphere_user' is undefined

如果我将变量声明移动到 vars/main.yml,一切都会按预期进行。但是,当然,我更愿意将我的变量分成多个文件。

我无法在官方 Ansible 文档中找到对此 "feature" 的任何引用,我不知道如何解决它。谁能指出我正确的方向?

我的ansible版本: ansible 2.8.5 在 Ubuntu 16.04

在你问之前:是的,我确实确保 main.yml 在尝试加载时不存在 vars/main/*.yml...

TL;DR 版本:这是 ansible 中的一个错误,由 vars/main 中存在空的 .yml 文件引起。已经有一个 PR。看 here

实际结果(如评论中所述)实际上取决于文件的处理顺序(默认情况下,我的 Ansible 似乎按字母顺序处理它们 - 但这可能取决于版本或底层OS):

  • 如果先处理空文件,您会收到一条错误消息:ERROR! failed to combine variables, expected dicts but got a 'NoneType' and a 'AnsibleMapping'
  • 如果空文件是在其他文件之后处理的,没有错误信息,但是到此为止设置的所有变量都被销毁了

更多细节:因为我不知道如何在 Ansible 本身中解决这个问题,我转到代码并开始添加 print 语句以查看发生了什么。

在我的例子中,我在 vars/main 目录中有一些空的 .yml 文件(我计划稍后填充的文件。好吧......当代码遇到这样一个空文件时看起来, 它会破坏它到目前为止构建的整个字典。

要么我遗漏了一些非常重要的东西,要么这是一个错误...重现步骤:

  • 创建角色
  • 创建 vars/main 目录,并在其中填充一些 .yml 文件
  • 添加一个空的 .yml 文件(命名以便在其他文件之后处理)
  • 尝试打印第一个文件中的变量
    ansible# tree roles 
    roles
    +-- test
        +-- tasks
        ¦   +-- main.yml
        +-- vars
            +-- main
                +-- correct_vars.yml

    4 directories, 2 files

    ansible# cat roles/test/vars/main/correct_vars.yml  myname: bogd

    ansible# ansible-playbook -i inventory.yml test.yml 
    ... 
    ok: [localhost] => {
        "myname": "bogd" } 
    ...

    ansible# echo > roles/test/vars/main/emptyfile.yml

    ansible# ansible-playbook -i inventory.yml test.yml 
    ... ok: [localhost] => {
        "myname": "VARIABLE IS NOT DEFINED!" } 
    ...

稍后编辑:是的,这是一个错误...参见 here

下面的例子

$ cat play.yml 
- hosts: localhost
  roles:
    - role1

$ cat roles/role1/tasks/main.yml 
- debug:
    var: var1

$ cat roles/role1/vars/main/var1.yml 
var1: test_var1

给予

"var1": "test_var1"