# Recursive variable templating

**URL:** <https://forum.ansible.com/t/recursive-variable-templating/7832>\
**Category:** Get Help\
**Created:** [August 13, 2024, 9:37pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832 "2024-08-13T21:37:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![yurnov](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/yurnov/32/3964_2.png) [@yurnov](https://forum.ansible.com/u/yurnov)\
**Post date:** [August 13, 2024, 9:37pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/1 "2024-08-13T21:37:31Z")

</div>

I have quite a huge inventory (actually, multiple inventory files) and some of the nodes have much more variables than others, default values is used for any missed variable, it works pretty fine if I have only one thread like “variable defined/not defined”, in that case I just can use filter plug-in default.

I.e. I have variable `timezone` that can be missed, I just can use `{{ timezone|default('UTC') }}`, and it works perfectly.

But I going to have a more complex scenario where the default value of the variable depends by some other parameter, like:  
`inventory/hosts`:

```auto
[servers]
localhost

[servers:vars]
timezone="Europe/Kyiv"
network="Lviv"

```

`inventory/group_vars/all`:

```auto
defaulttimezone: "{% if network == 'Athlone' %}Europe/Dublin{% else %}UTC{% endif %}"
desiredtimezone: "{{ timezone|default(defaulttimezone) }}"
timezone: "{{ desiredzone }}"

```

The idea here is that I should have `timezone` for all of my hosts, and for one region (network) I have one default value and for another - another. All of them can be overridden by `timezone` in the inventory of a particular host. Group vars have higher priority than inventory, so, here I should have the final variable.

Unfortunately, it doesn’t work in that way, please find below, test playbook (`playbooks/playbook.yaml`):

```auto
---
- hosts: localhost
  gather_facts: no
  tasks:
  - ansible.builtin.debug:
      var: timezone

```

and finally:

```auto
root@947fc5508048:/opt# ansible-playbook -i inventory/hosts playbooks/playbook.yaml 

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

TASK [ansible.builtin.debug] ********************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ desiredtimezone }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ timezone|default(defaulttimezone) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: recursive loop detected in template string: {{ timezone|default(defaulttimezone) }}. maximum recursion depth exceeded"}

PLAY RECAP **************************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0   

root@947fc5508048:/opt# 

```

It’s due to recursion doesn’t work. What solution can I have besides just using the different variable names in the inventory file? I prefer to keep `timezone` in inventory as is easy for humans to read, write, and understand.

It’s tested with `ansible-core==2.16.9`, but seems that 2.16.10 and 2.17.3 and current development version will end up with the same recursion error.

```auto
root@947fc5508048:/opt# ansible --version
ansible [core 2.16.9]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.12/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.12.4 (main, Jun 27 2024, 00:07:37) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.4
  libyaml = True
root@947fc5508048:/opt# 

```

Any suggestion?

---

<div class="post-metadata">

**Author:** ![mikemorency](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mikemorency/32/2672_2.png) [@mikemorency](https://forum.ansible.com/u/mikemorency)\
**Post date:** [August 14, 2024, 1:47pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/2 "2024-08-14T13:47:55Z")

</div>

You have a typo in your example i think. `timezone: "{{ desiredzone }}"` should be `timezone: "{{ desiredtimezone }}"` right?

Maybe obvious, but the recursion is happening because evaluating `timezone` means evaluation `desiredtimezone`, which means evaluating `timezone`…

You could try this:

```auto
#inventory/group_vars/all
defaulttimezone: "{% if network == 'Athlone' %}Europe/Dublin{% else %}UTC{% endif %}"

# playbook.yml
---
- hosts: localhost
  tasks:
    - name: Set TImezone
      set_fact:
        timezone: "{{ defaulttimezone }}"
      when: timezone is not defined

```

Alternatively:

```auto
#inventory/group_vars/all
network_to_timezone_map:
  Athlone: Europe/Dublin
  default: UTC

timezone: "{{ network_to_timezone_map[network] | default(network_to_timezone_map['default']) }}"

# playbook.yml
---
- hosts: localhost
  tasks:
    - debug:
        var: timezone

```

In both cases, `timezone` can be overridden with a command line var `ansible-playbook -e 'timezone=foo'`, in `host_vars`, or by settings a group\_var besides `all`

---

<div class="post-metadata">

**Author:** ![yurnov](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/yurnov/32/3964_2.png) [@yurnov](https://forum.ansible.com/u/yurnov)\
**Post date:** [August 14, 2024, 2:04pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/3 "2024-08-14T14:04:54Z")

</div>

> [@mikemorency](#):
>
> th cases, `timezone` can be overridden with a command line var `ansible-playbook -e 'timezone=foo'`, in `host_vars`, o

both will work, but it require a changes in playbooks (I have a huge old codebase), and it’s can’t be overridden by inventory file (inventory have lower priority than group vars)

---

<div class="post-metadata">

**Author:** ![mikemorency](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mikemorency/32/2672_2.png) [@mikemorency](https://forum.ansible.com/u/mikemorency)\
**Post date:** [August 14, 2024, 2:29pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/4 "2024-08-14T14:29:41Z")

</div>

hmmm ok. i do see i missed the stipulations in the original post, sorry about that. I dont think i see a solution without a change to the playook or variable names, hopefully someone else does

---

<div class="post-metadata">

**Author:** ![Denney-tech](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/denney-tech/32/1556_2.png) [@Denney-tech](https://forum.ansible.com/u/Denney-tech)\
**Post date:** [August 14, 2024, 2:36pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/5 "2024-08-14T14:36:26Z")

</div>

> [@yurnov](#):
>
> (inventory have lower priority than group vars)

So why not move the group vars from the inventory hosts file to… group vars?

`inventory/group_vars/all.yml`

```yaml
---
timezone: "{{ 'Europe/Dublin' if network == 'Athlone' else 'UTC' }}"

```

`inventory/group_vars/servers.yml`

```yaml
timezone: 'Europe/Kyiv'

```

`inventory/hosts`

```ini
[servers]
localhost

#[servers:vars]
#timezone="Europe/Kyiv"
#network="Lviv"

```

`playbook`

```yaml
---
- hosts: localhost
  gather_facts: no
  tasks:
  - ansible.builtin.debug:
      var: timezone

```

`output`

```auto
ansible-playbook -i ./inventory/hosts ./tmp.yml

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

TASK [ansible.builtin.debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "timezone": "Europe/Kyiv"
}

PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

```

Take advantage of variable precedence. If you place something in `inventory/host_vars/{{inventory_hostname}}.yml`, that will take precedence over the group vars (in case you have exceptions within any particular group).

---

<div class="post-metadata">

**Author:** ![jrglynn2](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@jrglynn2](https://forum.ansible.com/u/jrglynn2)\
**Post date:** [August 14, 2024, 2:45pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/6 "2024-08-14T14:45:48Z")

</div>

> [@yurnov](#):
>
> `timezone: "{{ desiredzone }}"`

to @mikemorency 's note - shouldn’t this be `timezone: "{{ desiredtimezone }}"`

---

<div class="post-metadata">

**Author:** ![shertel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/shertel/32/1241_2.png) [@shertel](https://forum.ansible.com/u/shertel)\
**Post date:** [August 14, 2024, 4:35pm UTC](https://forum.ansible.com/t/recursive-variable-templating/7832/7 "2024-08-14T16:35:40Z")

</div>

You can keep the same variable names (and remove the intermediate var desiredtimezone) by setting your default somewhere with less precedence than where you want to override it. In your example inventory, you are using inventory group vars (#3 [Using Variables — Ansible Community Documentation](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence)), so the only way to set the default timezone with less priority is using role defaults:

```auto
.
├── inventory
│ ├── hosts
│ │ [all]
│ │ h0
│ │ [servers]
│ │ h1
│ │ [servers:vars]
│ │ timezone="Europe/Kyiv"
│ │ network="Lviv"
├── roles
│ ├── default_vars
│ │ ├── defaults
│ │ │ ├── main.yml
│ │ │ │ defaulttimezone: "{% if network is defined and network == 'Athlone' %}Europe/Dublin{% else %}UTC{% endif %}"
│ │ │ │ timezone: "{{ defaulttimezone }}"
├── playbook.yml
│ ---
│ - hosts: h0,h1
│ gather_facts: no
│ roles:
│ - default_vars
│ tasks:
│ - ansible.builtin.debug:
│ var: timezone

```

You could also switch to using host vars in your inventory file (#8 in [Using Variables — Ansible Community Documentation](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence)), like this:

```auto
.
├── inventory
│ ├── group_vars
│ │ ├── all
│ │ │ defaulttimezone: "{% if network is defined and network == 'Athlone' %}Europe/Dublin{% else %}UTC{% endif %}"
│ │ │ timezone: "{{ defaulttimezone }}"
│ ├── hosts
│ │ [all]
│ │ h0
│ │ [servers]
│ │ h1 timezone="Europe/Kyiv" network="Lviv"
├── playbook.yml
│ ---
│ - hosts: h0,h1
│ gather_facts: no
│ tasks:
│ - ansible.builtin.debug:
│ var: timezone

```
