hiera.yaml
---
:hierarchy:
- node/%{host_fqdn}
- site_config/%{host_site_name}
- site_config/perf_%{host_performance_class}
- site_config/%{host_type}_v%{host_type_version}
- site/%{host_site_name}
- environments/%{site_environment}
- types/%{host_type}_v%{host_type_version}
- hosts
- sites
- users
- common
# options are native, deep, deeper
:merge_behavior: deeper
我们目前有此层次结构配置。因此,配置按以下顺序合并:common.yaml>users.yaml>sites.yaml>hosts.yaml>1types/xxx_vxxx.yaml>等。对于变量顶部层次结构,只有当该文件存在时,它才会被覆盖。
例如:common.yaml
server:
instance_type: m3.medium
site_config/mysite.yaml
server:
instance_type: m4.large
因此,对于所有其他站点,实例类型将为m3.medium,但仅对于mysite,实例类型为m4.large.
我如何在Ansible中实现同样的目标?
我认为@Xiong在Ansible中使用变量是正确的
您可以设置灵活的库存,vars优先级从常规到特定。
但如果有帮助的话,你可以试试这个片段:
---
- hosts: loc-test
tasks:
- include_vars: hiera/{{ item }}
with_items:
- common.yml
- "node/{{ ansible_fqdn }}/users.yml"
- "node/{{ ansible_fqdn }}/sites.yml"
- "node/{{ ansible_fqdn }}/types/{{ host_type }}_v{{ host_type_version }}.yml"
failed_when: false
- debug: var=server
这将尝试从结构与您的问题类似的文件中加载变量
不存在的文件将被忽略(因为failed_when: false
(
文件按此列表的顺序(从上到下(加载,覆盖以前的值。
Gotchas:
必须定义列表中使用的所有变量(例如,本例中的
host_type
不能在common.yml
中定义(,因为要迭代的项目列表是在执行整个循环之前模板化的(有关解决方法,请参阅更新(。默认情况下,Ansible覆盖(替换(dicts,我猜您的用例期望合并行为。这可以通过hash_behavior设置来实现,但这对于Ansible剧本来说是不寻常的。
p.S.您可以通过将with_items
更改为with_first_found
来更改从上到下的合并行为,并反转列表(从特定到常规(。在这种情况下,Ansible将从找到的第一个文件加载变量。
更新:在文件路径中使用以前包含的变量。
您可以将循环拆分为多个任务,因此Ansible将在模板化下一个文件的包含路径之前评估每个任务的结果
制作hiera_inc.yml
:
- include_vars: hiera/common.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/users.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/sites.yml
failed_when: false
- include_vars: hiera/node/{{ ansible_fqdn }}/types/{{ host_type | default('none') }}_v{{ host_type_version | default('none') }}.yml
failed_when: false
在你的主要战术手册中:
- include: hiera_inc.yml
这看起来有点笨拙,但通过这种方式,您可以在common.yaml
中定义host_type
,并且它将在下一个任务的路径模板中得到尊重。
使用Ansible 2.2,可以将include_vars
包含到命名变量(而不是全局主机空间(中,因此您可以将_vars包含到hiera_facts
中,并使用combine
过滤器将它们合并,而不会改变全局哈希行为。
我不熟悉Puppet,所以这可能不是一个直接的映射。但我理解你的问题是"如何在一个共享位置使用值,但在不同的服务器上覆盖它们的定义?"。在Ansible中,您可以使用变量来执行此操作。
您可以直接在库存中定义变量。您可以在特定于主机和组的文件中定义变量。您可以在剧本级别定义变量。您可以在角色级别定义变量。见鬼,您甚至可以使用命令行开关定义变量。
在所有这些地方之间,您应该能够定义覆盖以适应您的情况。您可能需要查看有关如何决定在哪里定义变量的文档部分,以了解更多信息。
它似乎比Hiera更基本,但有人创建了一个具有类似语法的基本ansible查找插件
https://github.com/sailthru/ansible-oss/tree/master/tools/echelon