如何使用Ansible为组变量配置属性优先级

如何使用Ansible为组变量配置属性优先级,ansible,ansible-facts,Ansible,Ansible Facts,我的Ansible角色中有一个文件vars/sonarqube.yml,其中包含内容 --- lvm_roles: sonarqube: size: '10g' path: '{{ sonar_home }}' lvm_roles: sonarqube: size: '20g' 以及一个包含内容的文件group\u vars/all/lvm.yml --- lvm_roles: sonarqube: size: '10g' path: '{

我的Ansible角色中有一个文件
vars/sonarqube.yml
,其中包含内容

---
lvm_roles:
  sonarqube:
    size: '10g'
    path: '{{ sonar_home }}'
lvm_roles:
  sonarqube:
    size: '20g'
以及一个包含内容的文件
group\u vars/all/lvm.yml

---
lvm_roles:
  sonarqube:
    size: '10g'
    path: '{{ sonar_home }}'
lvm_roles:
  sonarqube:
    size: '20g'
ansible.cfg
中,我有一行

hash_behaviour = merge
如果没有
merge
,结果事实将是

lvm_roles:
  sonarqube:
    size: '20g'
换句话说,我松开了
路径
var

使用
merge
时,结果为

lvm_roles:
  sonarqube:
    size: '10g'
    path: '/opt/sonarqube'
然而,我想要和期望的结果是

lvm_roles:
  sonarqube:
    size: '20g'
    path: '/opt/sonarqube'
因此,理想的行为是

  • Ansible合并变量
  • 组变量中的配置优先于我角色中的配置

  • 我可以在Ansible中配置此行为吗?怎么做

    在Ansible中无法配置优先级,您不能在角色中为
    组变量
    中的配置赋予高于
    变量
    目录中配置的优先级

    您需要的是Ansible不支持的条件默认变量。如这里和这里的示例所示

    这是Ansible作为IaC工具绝对缺乏的一个领域。例如,这是Chef非常常用的功能。Chef Apache cookbook中的一段代码演示了这种常见模式

    ....
    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”属性进行比较。厨师烹饪书中的配置具有较低的优先级,但您可以使用“覆盖”属性来提供非常高的优先级。然而,在烹饪书中使用“覆盖”属性是非常少见的。它们的实际用途非常有限。反之亦然,Ansible
    vars
    目录用于创建覆盖几乎所有其他配置的高优先级配置,实际用途非常有限

    如果您不同意,请分享我们绝对需要角色中高优先级配置的角色示例。例如,您可以共享一个指向Ansible角色的链接,以演示实际用途

    vars
    角色目录很有用,但不适合其预期用途。实际上,该目录用于存储条件配置。配置获得高优先级这一事实与其说是一个期望的或预期的结果,不如说是一个问题

    这一点可以通过角色来证明。在这个角色中,geerlingguy使用“伪变量”来解决Ansible没有条件默认值变量的问题

    例如,在变量
    \uuu postgresql\u data\u dir
    中引入。此变量具有较高的优先级

    __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 
    
    它没有实际用途,只是可以用来模拟有条件的默认var
    postgresql\u data\u dir
    ,如中所示

    如果可以配置优先级规则,这将是有意义的,因为Ansible角色中的
    vars
    目录由于其高优先级,通常实际用途有限。要实际使用
    vars
    目录技巧,需要使用
    postgresql\u data\u dir
    降低此目录中配置的优先级

    如果您不喜欢这种诡计,您可以选择使用中所述的变通方法
    set\u fact
    ,或中所述的不神圣内联编码

    建议Ansible社区将
    vars
    目录的预期用途从“覆盖”更改为“条件”配置。为角色中的配置提供高优先级是非常少见的要求。但是,条件配置非常常见

    问:“期望的行为是

    我可以在Ansible中配置此行为吗?

    A:不,不能换。“角色变量”(15)覆盖“组变量”(7)。使用“组变量”覆盖“角色默认值”(2)

    Q:“您需要的是Ansible不支持的条件默认变量。

    答:如果Ansible不支持条件缺省,那么就不可能为多个系统编写角色。可以创建条件默认值,例如

    #默认变量
    -名称:“os_vars_playbook_dir:vars from{{{playbook_dir}}/vars/defaults”
    包括变量:“{{item}”
    在第一个找到的情况下:
    -档案:
    -“{ansible_distribution}-{{ansible_distribution_release}.yml”
    -“{{ansible_distribution}}.yml”
    -“{{ansible_os_family}.yml”
    -“default.yml”
    -“defaults.yml”
    路径:“{{playbook_dir}}/vars/defaults”
    #自定义变量
    -名称:“os_vars_playbook_dir:vars from{{{playbook_dir}}/vars”
    包括变量:“{{item}”
    在第一个找到的情况下:
    -档案:
    -“{ansible_distribution}-{{ansible_distribution_release}.yml”
    -“{{ansible_distribution}}.yml”
    -“{{ansible_os_family}.yml”
    -“default.yml”
    -“defaults.yml”
    路径:“{{playbook_dir}}}/vars”
    
    (网址为)


    注释

  • 在播放设置发现主机上运行的系统后,可以包含特定于操作系统的变量

  • 角色的变量/默认值具有非常高的优先级“include_vars”(18)(因为1)。但是这个目录应该只包含系统变量。用户不希望在标准情况下更改这些变量

  • 如有必要,可以在vars/中自定义角色。vars/中的自定义配置文件将在角色更新后仍然有效,而vars/默认值可能会更新


  • 我建议您阅读以下内容:/角色中的变量比组变量具有更高的优先级,这很有趣。我想,在vars目录中给vars赋予这种优先级是没有意义的。角色中的变量应具有低优先级,因为您希望角色是可配置的。它没有意义是很容易说明的。最终得到的是“影子”变量,如角色默认值中的in变量,其优先级低于库存变量。角色变量中的变量的优先级高于清单变量。@onknowns作为p