如何使用Ansible

时间:2019-09-24 09:52:07

标签: ansible ansible-facts

我在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'

所以理想的行为是

  1. Ansible合并vars
  2. group_vars中的
  3. config优先于我的角色中的config。

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

2 个答案:

答案 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"


笔记

  1. 特定于OS的变量可以在播放设置发现正在运行的系统后包含。

  2. 角色的vars / defaults具有很高的优先级“ include_vars” (18)(因为1)。但是此目录仅应包含系统变量,以使用户在标准情况下不希望更改。

  3. 如有必要,可以在vars /中自定义角色。 vars /中的自定义配置文件将在角色更新后保留下来,而vars / defaults可能会更新。

  4. 为什么要有人将其硬接线?

为方便起见,该代码位于GitHub