我在Ansible角色vars/sonarqube.yml
中有一个包含内容的文件
---
lvm_roles:
sonarqube:
size: '10g'
path: '{{ sonar_home }}'
还有一个包含内容的文件group_vars/all/lvm.yml
lvm_roles:
sonarqube:
size: '20g'
在ansible.cfg
中,有一行
hash_behaviour = merge
如果没有merge
,结果将是
lvm_roles:
sonarqube:
size: '20g'
换句话说,我失去了path
变体。
使用merge
的结果是
lvm_roles:
sonarqube:
size: '10g'
path: '/opt/sonarqube'
但是我想要和期望的结果是
lvm_roles:
sonarqube:
size: '20g'
path: '/opt/sonarqube'
所以理想的行为是
group_vars
中的我可以在Ansible中配置此行为吗?怎么样?
答案 0 :(得分:0)
在Ansible中无法配置优先级,因此,在角色中,group_vars
中的配置不能赋予比vars
目录中的配置更高的优先级。
您想要的是Ansible不支持的条件默认变量。如此处Set Ansible role defaults conditionally和此处use conditionals in vars ansible所示。
这是Ansible作为IaC工具绝对缺乏的领域。例如,它是Chef的一个非常常用的功能。厨师Apache食谱的attributes/default.rb的片段演示了这种常见模式
....
case node['platform_family']
when 'rhel', 'fedora', 'amazon'
if node['platform'] == 'amazon'
default['apache']['package'] = 'httpd24'
default['apache']['devel_package'] = 'httpd24-devel'
else
default['apache']['package'] = 'httpd'
default['apache']['devel_package'] = 'httpd-devel'
end
default['apache']['service_name'] = 'httpd'
default['apache']['perl_pkg'] = 'perl'
default['apache']['apachectl'] = '/usr/sbin/apachectl'
default['apache']['dir'] = '/etc/httpd'
default['apache']['log_dir'] = '/var/log/httpd'
在vars
目录中的配置可以与Chef中的“ override”属性进行比较。 Chef食谱中的配置优先级较低,但是您可以使用“ override”属性来赋予很高的优先级。但是,在食谱中使用“覆盖”属性非常少见。它们的实际用途非常有限。相反,用于其预期用途的Ansible vars
目录用于创建优先级高的配置,该配置优先于几乎所有其他配置,在实际应用中非常有限。
如果您不同意,请分享一些角色示例,在这些示例中,我们绝对需要对角色进行高优先级配置。例如,您可以共享一个指向Ansible角色的链接,以证明其实际用法。
vars
角色目录很有用,但没有预期的用途。实际上,该目录用于存储条件配置。配置获得较高优先级的事实比预期或预期结果要成问题。
geerlingguy.posttgresql角色证明了这一点。 geerlingguy在此角色中使用“伪变量”来解决Ansible没有条件默认变量vars的事实。
例如,在vars/Debian-7.yml中引入了变量__postgresql_data_dir
。此变量具有较高的优先级。
__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main"
除了可以用来模拟条件默认变量postgresql_data_dir
(如tasks/variables.yml中所示)外,它没有任何实际用途
- name: Define postgresql_data_dir.
set_fact:
postgresql_data_dir: "{{ __postgresql_data_dir }}"
when: postgresql_data_dir is not defined
如果可以配置优先级规则,这是有道理的,因为Ansible角色中的vars
目录由于其较高的优先级而通常在实际使用中受到限制。要切实利用vars
目录,就需要进行欺骗,如geerlingguy.posttgresql角色中的postgresql_data_dir
所示,以降低此目录中的配置优先级。
如果您不喜欢这种技巧,则可以选择使用Set Ansible role defaults conditionally中所述的解决方法set_fact
或使用use conditionals in vars ansible中所描述的邪恶的内联编码。
我们最好建议Ansible社区将vars
目录的预期用途从“覆盖”配置更改为“条件”配置。要求角色中的配置具有较高优先级是非常不常见的要求。但是,条件配置非常普遍。
答案 1 :(得分:0)
Q:“所需的行为是
1) Ansible merges vars
2) config in group_vars takes precedence to config in my role.
我可以在Ansible中配置此行为吗?
A:否。precedence无法更改。 “角色变量” (15)覆盖“ group_vars” (7)。使用“ group_vars” 覆盖“角色默认设置”(2)。
Q:您想要的是Ansible不支持的条件默认变量。
A:如果Ansible不支持条件默认值,则不可能为多个系统编写角色。可以创建条件默认值。下面是一个例子
# Defaults variables
- name: "al_include_os_vars_playbook_dir: Vars from {{ playbook_dir }}/vars/defaults"
include_vars: "{{ item }}"
with_first_found:
- files:
- "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
- "defaults.yml"
paths: "{{ playbook_dir }}/vars/defaults"
# Custom variables
- name: "al_include_os_vars_playbook_dir: Vars from {{ playbook_dir }}/vars"
include_vars: "{{ item }}"
with_first_found:
- files:
- "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
- "defaults.yml"
paths: "{{ playbook_dir }}/vars"
特定于OS的变量可以在播放设置发现正在运行的系统后包含。
角色的vars / defaults具有很高的优先级“ include_vars” (18)(因为1)。但是此目录仅应包含系统变量,以使用户在标准情况下不希望更改。
如有必要,可以在vars /中自定义角色。 vars /中的自定义配置文件将在角色更新后保留下来,而vars / defaults可能会更新。
为什么要有人将其硬接线?
为方便起见,该代码位于GitHub