Explicitely use role defaults

If you want to maintain the original role default regardless of overrides, be explicit about it so it makes sense to future you.

In your role/download/defaults/main.yml, do this:

---
# roles/download/defaults/main.yml
# Note: variables renamed so as to avoid the
#    "Variables names from within roles should use download_ as a prefix."
# message from `ansible_lint`.

download_local_release_dir_role_default: &dlrdrd /value/from/roles/download/defaults/main.yml
download_local_release_dir:              *dlrdrd

Then when hostvars[‘localhost’][‘download_local_release_dir’] is not defined, use download_local_release_dir_role_default, like so:

{{ hostvars['localhost']['download_local_release_dir']
   | default('download_local_release_dir_role_default') }}

The “&dlrdrd” defines a YAML node anchor, while “*dlrdrd” is a reference to that anchor. They only exist in the YAML parsing phase. I’m pretty sure Ansible itself will be oblivious to it, and that Ansible will see them as two variables which happen to have identical values. I only used the anchor and reference to be explicit about them being initialized with the same value. (And if you change the value, you don’t have to change it in two places.)

You could just as easily say

download_local_release_dir_role_default: /value/from/roles/download/defaults/main.yml
download_local_release_dir:              /value/from/roles/download/defaults/main.yml  # noqa yaml[colons]

or this:

download_local_release_dir_role_default: /value/from/roles/download/defaults/main.yml
download_local_release_dir: "{{ download_local_release_dir_role_default }}"

I find both of those alternatives aesthetically offensive, but they’ll both work. (Note that in the 2nd alternative, if someone changes the first variable elsewhere, they’ll also change the second – intentionally or not – because of lazy evaluation. That won’t be the case if you use the anchor/reference technique.)

3 Likes