Ansible not overriding default vars

Asked by At

I have the following variables defined in role/defaults/main.yml:

jvm_heap_size_max: 1024
jvm_heap_size_min: "{{ (jvm_heap_size_max * 0.5)|int|abs }}"

My group_vars folder looks like this:

├── group_vars
│   ├── all
│   ├── group
│   │   ├── vars
│   │   └── vault

And I have the following variable in inventories/test/group_vars/group/vars:

jvm_heap_size_max: 512
jvm_heap_size_min: 1024

My expected output is:

jvm_heap_size_max: 512
jvm_heap_size_min: 1024

But what I'm getting is this:

jvm_heap_size_max: 1024
jvm_heap_size_min: 1024

How come? I'm using Ansible 2.7.7

2 Answers

0
Francis On Best Solutions

I forgot to mention that I'm targeting the same host in my example above. Apparently, this behavior is documented:

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#how-variables-are-merged

By default variables are merged/flattened to the specific host before a play is run. This keeps Ansible focused on the Host and Task, so groups don’t really survive outside of inventory and host matching. By default, Ansible overwrites variables including the ones defined for a group and/or host (see the hash_merge setting to change this) .

2
Thomas Hirsch On

This should work as you described.

I set up a minimal example, and verified that group_vars do have higher precedence than role defaults, as is written in the documentation.

As your example does not include the actual name of the group, and the respective folder names, I assume that is where the error lies.

Also, when I verified this, my group_vars were in the file group_vars/all.yml in the root directory of my project, I am not familiar with the other pattern.

Quick example using localhost and group_vars/all.yml:

roles/testrole/defaults/main.yml

---
jvm_heap_size_max: 1024
jvm_heap_size_min: "{{ (jvm_heap_size_max * 0.5)|int|abs }}"

roles/testrole/tasks/main.yml

---
- debug:
    var: jvm_heap_size_min

- debug:
    var: jvm_heap_size_max

group_vars/all.yml

---
jvm_heap_size_max: 2048

testplay.yml

- hosts: localhost
  roles:
    - testrole

Invocation & output:

➜  ansible-playbook testplay.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [localhost] *************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [testrole : debug] ******************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "jvm_heap_size_min": "1024"
}

TASK [testrole : debug] ******************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "jvm_heap_size_max": 2048
}

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0