如何设置特定于 Ansible 层的库存变量?
How to set an Ansible tier-specific inventory variable?
是否可以创建一个 Ansible 清单变量,该变量与清单主机或组无关,但剧本所在的服务器层 运行?我有一个使用 APT 安装 libffi-dev 包的 Ansible 角色,但我可能想在每个服务器层上安装该包的不同版本。为此,我创建了一个变量 "libffi-dev_ver"。我还有与我的每个等级相对应的清单文件 "development"、"staging" 和 "production"。
我的角色的主要任务(从我的主要 site.yml 剧本调用)检查版本变量在 运行 角色之前是否存在:
# roles/misc_libs/tasks/main.yml
- include: check_vars.yml tags=misc_libs
- include: misc_libs.yml tags=misc_libs
check_vars.yml 检查以确保包版本变量存在:
# roles/misc_libs_tasks/check_vars.yml
- name: check that required role variables are set
fail: msg="{{ item }} is not defined"
when: not {{ item }}
with_items:
- libffi-dev_ver
misc_libs 角色实际使用该变量来安装包:
# roles/misc_libs/tasks/misc_libs.yml
- name: install libffi-dev
apt: >
pkg=libffi-dev={{ libffi-dev_ver }}
update_cache=yes
cache_valid_time=3600
become: True
我的开发清单文件如下所示:
# development
[webservers]
web01.example.com ansible_ssh_host=<ip_address>
[dev:children]
webservers
[webservers:vars]
libffi-dev_ver="3.1-2+b2"
当我运行这个命令时:
ansible-playbook -i development site.yml -l webservers
我收到这个 Ansible 错误:
fatal: [web01.example.com] => error while evaluating conditional: not libffi-dev_ver
在 Ansible 中像这样声明包版本控制变量的正确方法是什么?该变量的值取决于服务器层,这向我表明它进入了清单文件,因为清单文件是特定于服务器层的。但是所有清单变量似乎都必须与主机或组相关联。我已经做到了,但角色仍然看不到变量。我可以向检测服务器层的角色添加一个任务,并使用 "when" 条件来相应地设置变量,但该解决方案看起来很难看,因为如果你在一个角色中安装多个包,你需要三个条件对于每个包版本变量。我查看了 Ansible 文档并阅读了许多关于设置多层 playbook 的博客文章,但我没有看到这种特殊情况得到解决。像这样声明层特定变量的正确方法是什么?
我不明白你想要完成什么。为什么是:
# roles/misc_libs/tasks/misc_libs.yml
- name: install libffi-dev
apt: >
pkg=libffi-dev={{ libffi-dev_ver }}
update_cache=yes
cache_valid_time=3600
become: True
when: libffi-dev_ver is defined
不够?
问题是我声明的变量 'libffi-dev_ver' 实际上是一个必须遵守 Python 2.x 命名规则的 Jinja2 identifier。根据这些规则,“-”(破折号)是无效字符。将其更改为“_”(下划线)后,我不再收到错误。
此外,check_vars.yml剧本实际上是不必要的。有一个 Ansible 配置变量 error_on_undefined_vars 会导致包含未定义变量的步骤失败。由于默认情况下为真,因此我不需要 运行 check_vars.yml,因为所有变量都已被检查。
声明特定于服务器层的变量的一个地方似乎在 group_vars 目录中的一个文件中,该文件与清单文件中以该层命名的组同名。所以在我的例子中,我的 'development' 清单文件包含一个 'dev' 子组。该组包含我要安装 libffi-dev 包的 Web 服务器。因此,我创建了一个文件 'group_vars/dev' 并在该文件中声明了一个名为 'libffi_dev_ver' 的变量,我可以在我的 misc_libs.yml 剧本中引用它。
是否可以创建一个 Ansible 清单变量,该变量与清单主机或组无关,但剧本所在的服务器层 运行?我有一个使用 APT 安装 libffi-dev 包的 Ansible 角色,但我可能想在每个服务器层上安装该包的不同版本。为此,我创建了一个变量 "libffi-dev_ver"。我还有与我的每个等级相对应的清单文件 "development"、"staging" 和 "production"。
我的角色的主要任务(从我的主要 site.yml 剧本调用)检查版本变量在 运行 角色之前是否存在:
# roles/misc_libs/tasks/main.yml
- include: check_vars.yml tags=misc_libs
- include: misc_libs.yml tags=misc_libs
check_vars.yml 检查以确保包版本变量存在:
# roles/misc_libs_tasks/check_vars.yml
- name: check that required role variables are set
fail: msg="{{ item }} is not defined"
when: not {{ item }}
with_items:
- libffi-dev_ver
misc_libs 角色实际使用该变量来安装包:
# roles/misc_libs/tasks/misc_libs.yml
- name: install libffi-dev
apt: >
pkg=libffi-dev={{ libffi-dev_ver }}
update_cache=yes
cache_valid_time=3600
become: True
我的开发清单文件如下所示:
# development
[webservers]
web01.example.com ansible_ssh_host=<ip_address>
[dev:children]
webservers
[webservers:vars]
libffi-dev_ver="3.1-2+b2"
当我运行这个命令时:
ansible-playbook -i development site.yml -l webservers
我收到这个 Ansible 错误:
fatal: [web01.example.com] => error while evaluating conditional: not libffi-dev_ver
在 Ansible 中像这样声明包版本控制变量的正确方法是什么?该变量的值取决于服务器层,这向我表明它进入了清单文件,因为清单文件是特定于服务器层的。但是所有清单变量似乎都必须与主机或组相关联。我已经做到了,但角色仍然看不到变量。我可以向检测服务器层的角色添加一个任务,并使用 "when" 条件来相应地设置变量,但该解决方案看起来很难看,因为如果你在一个角色中安装多个包,你需要三个条件对于每个包版本变量。我查看了 Ansible 文档并阅读了许多关于设置多层 playbook 的博客文章,但我没有看到这种特殊情况得到解决。像这样声明层特定变量的正确方法是什么?
我不明白你想要完成什么。为什么是:
# roles/misc_libs/tasks/misc_libs.yml
- name: install libffi-dev
apt: >
pkg=libffi-dev={{ libffi-dev_ver }}
update_cache=yes
cache_valid_time=3600
become: True
when: libffi-dev_ver is defined
不够?
问题是我声明的变量 'libffi-dev_ver' 实际上是一个必须遵守 Python 2.x 命名规则的 Jinja2 identifier。根据这些规则,“-”(破折号)是无效字符。将其更改为“_”(下划线)后,我不再收到错误。
此外,check_vars.yml剧本实际上是不必要的。有一个 Ansible 配置变量 error_on_undefined_vars 会导致包含未定义变量的步骤失败。由于默认情况下为真,因此我不需要 运行 check_vars.yml,因为所有变量都已被检查。
声明特定于服务器层的变量的一个地方似乎在 group_vars 目录中的一个文件中,该文件与清单文件中以该层命名的组同名。所以在我的例子中,我的 'development' 清单文件包含一个 'dev' 子组。该组包含我要安装 libffi-dev 包的 Web 服务器。因此,我创建了一个文件 'group_vars/dev' 并在该文件中声明了一个名为 'libffi_dev_ver' 的变量,我可以在我的 misc_libs.yml 剧本中引用它。