#87490·ansible

Alternative to the global `vars` dictionnary as a "null namespace" for vars

Author: VannTenCreated Sep 4, 2026Updated Sep 11, 2026
Labelswaiting_on_contributorfeature

Summary

I'm trying to define a variable which should resolve correctly independently of delegation context, and has a different defaults depending on host context. By correctly, I mean that for a normal task on host A, the variable should be hostvars[A]['my-var'] (or the role default) and on a delegated task to B (from A), the variable should be hostvars['B']['my-var'] (or the role defaults) (The defaults also depend on host variables.)

I'm currently using vars for this and I'm looking for an alternative to access the global var namespace in a programmatic way.

This is my current implementation:

yaml
# my_role/vars/main.yml
# resolve variables across delegation
#
# this should point to the correct bin_dir in all contexts,

_var_ns: "{{ hostvars[ansible_delegated_vars.keys()[0]] if ansible_delegated_vars is defined else vars }}"
delegated_bin_dir: "{{ _var_ns['bin_dir'] | d(default_bin_dir) }}"
# the default filter is only useful in the delegation case and when bin_dir is not explicitely set in inventory for the delegated to host.

# Reused for bin_dir, but needs to be a separate variable to allow
# inventory override without mangling delegated_bin_dir
default_bin_dir: "{{(
      '/usr/local/bin'
      if _var_ns['ansible_facts']['os_family'] != 'Flatcar'
      else '/opt/bin'
    )
    if _var_ns['ansible_facts']['user_id'] == (_var_ns['ansible_become_user'] | d('root'))
    else
      (_var_ns['ansible_facts']['env'].HOME + '/.local/bin')
}}"

# my_role/defaults/main.yml
bin_dir: {{ default_bin_dir }} # this one is supposed to be overriden (if necessary) in inventory.

Unfortunately, vars is deprecated and set for removal.

Alternatives:

  • the lookup plugin vars only resolves top level variable, so AFAIU it's not suitable for this..
  • ansible.utils.get_path would work if if's var parameters was nullable, but that's not the case.
  • inlining _var_ns into every usage site (and using the target variable directly). This works but is not very practical or DRY.
  • custom lookup plugin. I'm not sure if they do have access to the necessary data though. => probably the solution we'll try once vars is removed.
  • using set_fact before to materialize defaults into hostvars -> but set_fact for big inventories has a certain overhead.

Issue Type

Feature Idea

Component Name

vars

Additional Information

See above for the example.

The context of this is Kubespray (Kubernetes installer) where a number of tasks are delegated, and needs to use the delegated host context for several things (file location, etc).

Code of Conduct

  • I agree to follow the Ansible Code of Conduct