Precedence is not configurable in Ansible, you cannot give configuration in group_vars
a higher precedence than configuration in the vars
directory in a role.
What you want are conditional default vars which Ansible does not support . As shown for example here Set Ansible role defaults conditionally and here use conditionals in vars ansible.
This is an area where Ansible is definitely lacking as an IaC tool. It is for example a very commonly used feature with Chef. Snippet from attributes/default.rb from the Chef Apache cookbook demonstrates this common pattern
....
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'
Configuration in the vars
directory can be compared to "override" attributes in Chef. Configuration in a Chef cookbook has a low precedence but you can use "override" attributes to give a very high precedence. The use of "override" attributes in cookbooks is however very uncommon. They are of very limited practical use. Vice versa the Ansible vars
directory for its intended use of creating high precedence configuration that overrides almost all other configuration, is of very limited practical use.
If you disagree please share examples of roles where we absolutely need high precedence configuration in a role. You can for example share a link to a Ansible role that demonstrates practical use.
The vars
role directory is useful but not for its intended use. In practice the directory is used to store conditional configuration. The fact that configuration gets a high precedence is a more a problem than a desired or intended result.
This is demonstrated by the geerlingguy.posttgresql role. In this role geerlingguy uses "pseudo variables" to work around the fact that Ansible does not have conditional defaults vars.
For example in vars/Debian-7.yml a variable __postgresql_data_dir
is introduced. This variable gets a high precedence.
__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main"
It is of no practical use other than that it can be used to mimic a conditional default var postgresql_data_dir
as show in tasks/variables.yml
- name: Define postgresql_data_dir.
set_fact:
postgresql_data_dir: "{{ __postgresql_data_dir }}"
when: postgresql_data_dir is not defined
It would make sense if precedence rules could be configured because the vars
directory in a Ansible role is typically of limited practical use because of its high precedence. To make practical use of the vars
directory trickery is needed as demonstrated by the postgresql_data_dir
in the geerlingguy.posttgresql role to lower precedence of configuration in this directory.
If you don't like this trickery you can alternatively use workaround set_fact
as described in Set Ansible role defaults conditionally or unholy inline coding as described in use conditionals in vars ansible.
The Ansible community would be well advised to change the intended use of the vars
directory from "override" to "conditional" configuration. Giving high precedence to configuration in a role is very uncommon requirement. Conditional configuration is however very very common.