在Ansible,在一个角色中,我有这样的vars文件:
vars/
app1.yml
app2.yml
Run Code Online (Sandbox Code Playgroud)
每个文件都包含特定于应用程序/网站的变量,如下所示:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
Run Code Online (Sandbox Code Playgroud)
理想情况下,如果没有预先知道哪些应用程序具有可变文件的任务,我最终会得到一个apps如下所示的数组:
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Run Code Online (Sandbox Code Playgroud)
即,它将文件中的变量合并为一个.
我知道我可以像这样加载所有变量文件:
- name: Load var files
with_fileglob:
- ../vars/*.yml
include_vars: '{{ item }}'
Run Code Online (Sandbox Code Playgroud)
但是,鉴于每个文件具有相同的变量名称,它将覆盖每个先前的变量集.我看不到加载变量并将它们放入apps数组的方法.
如果这是制作这样的东西的唯一方法,我愿意稍微重新排列.
你不能这样做.变量将始终覆盖具有相同名称的变量.你可以用这个确切的设置做的唯一事情是编写你自己的vars插件,它读取这些文件并将它们合并到一个数组中.
如果您愿意更改应用程序定义的结构,则可以使用哈希并设置您的hash_behavior=merge.在每个vars文件中,您将有一个定义,如:
apps:
app1:
git_repo: https://github.com/philgyford/app1.git
Run Code Online (Sandbox Code Playgroud)
apps:
app2:
git_repo: https://github.com/philgyford/app2.git
Run Code Online (Sandbox Code Playgroud)
当Ansible加载两个文件时,它会自动将它们合并到:
apps:
app1:
git_repo: https://github.com/philgyford/app1.git
app2:
git_repo: https://github.com/philgyford/app2.git</pre>
Run Code Online (Sandbox Code Playgroud)
但请注意,hash_behavior=merge从根本上改变了Ansible在全局范围内的默认行为.确保您的所有角色都没有此设置的问题.文件提到:
除非您认为绝对需要,否则我们通常建议您不要使用此设置
如果您仍然使用Ansible 1,则可以使用我的旧插件之一:include_vars_merged.基本上,这只会将行为添加hash_behavior=merge到单个任务中.
我还没有考虑将其迁移到Ansible 2,但目前看起来我不再需要它了.
小智 6
好吧,你不能直接构建一个数组,但是你可以用一个 dict 来实现同样的努力。
假设你想构造一个数组:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
Run Code Online (Sandbox Code Playgroud)
您可以将每个元素放在一个文件中,例如:
bob:
name: bob
age: 30
Run Code Online (Sandbox Code Playgroud)
alice:
name: alice
age: 35
Run Code Online (Sandbox Code Playgroud)
将这些文件放在同一个目录中(例如user),然后用于include_vars加载整个目录:
- name: Include vars
include_vars:
name: users
dir: user
Run Code Online (Sandbox Code Playgroud)
这会给你一个 dict users:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
Run Code Online (Sandbox Code Playgroud)
dict2items在ansible中使用过滤器,你得到你想要的数组
使用属性名称并将包含的变量放入字典中。根据您的需要调整词典名称。例如
- name: Load var files
include_vars:
file: "{{ item }}"
name: "incl_vars_{{ item|basename|splitext|first }}"
with_fileglob:
- vars/*.yml
Run Code Online (Sandbox Code Playgroud)
然后,使用查找插件varnames(2.8 版本中的新增功能),查找所有字典,并迭代列表。在循环中使用查找插件vars(2.5 版中的新增功能)并创建列表apps。例如
- set_fact:
apps: "{{ apps|default([]) + [lookup('vars', item)] }}"
loop: "{{ query('varnames', '^incl_vars_(.*)$') }}"
Run Code Online (Sandbox Code Playgroud)
给出
apps:
- git_repo: https://github.com/philgyford/app2.git
name: app2
- git_repo: https://github.com/philgyford/app1.git
name: app1
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以将列表转换为字典
- set_fact:
apps: "{{ dict(_keys|zip(apps)) }}"
vars:
_keys: "{{ apps|map(attribute='name')|list }}"
Run Code Online (Sandbox Code Playgroud)
给出
apps:
app1:
git_repo: https://github.com/philgyford/app1.git
name: app1
app2:
git_repo: https://github.com/philgyford/app2.git
name: app2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14667 次 |
| 最近记录: |