Variable resolution issue, bug or feature?

Hi,

I have a role that when it runs is only partially resolving variables.

Variable_A: defined in defaults - string

Variable_B: defined in defaults - hostvars reference to Variable_C that will be loaded through include_vars

Variable_C: defined in file and loaded through include_vars - string to reference Variable_A

The role task is to use Variable_B. When the role runs the task ends up being set to “{{ Variable _A }}” instead of the string like Ansible stopped resolving variables.

If I switch the role to use a Variable_A loaded through include_vars instead Ansible resolves the variable completely.

Is this expected or is it a bug?

Thanks,
Michael

Anyone? I’m going to file a bug next week if there is no other comment.

Hi,

I have a role that when it runs is only partially resolving variables.

Variable_A: defined in defaults - string
Variable_B: defined in defaults - hostvars reference to Variable_C that
will be loaded through include_vars
Variable_C: defined in file and loaded through include_vars - string to
reference Variable_A

The role task is to use Variable_B. When the role runs the task ends up
being set to "{{ Variable _A }}" instead of the string like Ansible stopped
resolving variables.

If I switch the role to use a Variable_A loaded through include_vars
instead Ansible resolves the variable completely.

Is this expected or is it a bug?

You should post at least the declaration of the variables. "Variable_A" and
"Variable_C" is clear. But what do you mean with "defined in defaults -
hostvar reference" ?

  "Variable_B: defined in defaults - hostvars reference to Variable_C"

It would be just guessing without complete, minimal, reproducible example.

Cheers,

  -vlado

git clone https://github.com/mooninite/ansible-test
cd ansible-test
ansible-playbook ./site.yml

Thanks,
Michael

It's neither a bug nor a feature. It's all by design, I think.

"include_vars" does not evaluate "Variable_C". This complies with "lazy
evaluation" when "Ansible evaluates any variables in playbook content at the
last possible second".
https://docs.ansible.com/ansible/latest/reference_appendices/glossary.html

    "hostvars.localhost": {
        "Variable_C": "{{ Variable_A }}",
    ...

The apparent problem comes from the difference how the module "debug"
evaluates the parameters "msg" and "var". The example below

    $ cat roles/test/tasks/main.yml
    - include_vars: test.yml
    - debug: msg="{{ hostvars[inventory_hostname].Variable_C }}"
    - debug: var="{{ hostvars[inventory_hostname].Variable_C }}"
    - debug: msg="{{ Variable_B }}"
    - debug: var="{{ Variable_B }}"

gives

    "msg": "{{ Variable_A }}"
    "{{ Variable_A }}": "a string"
    "msg": "{{ Variable_A }}"
    "{{ Variable_A }}": "a string"

Testing with the module "set_fact" shows that all is working as expected. The
example below

    - set_fact:
        my_list: "{{ my_list|default() +
                     [ Variable_B ] +
                     [ hostvars[inventory_hostname].Variable_C ] }}"
    - debug:
        var: my_list

gives

    "my_list": [
        "a string"
        "a string"
    ]

HTH. Cheers,

  -vlado

It's closed issue (locked and limited conversation to collaborators on Jul 25)
Hostvars of hostvars aren't evaluated #16351
https://github.com/ansible/ansible/issues/16351

- debug: msg="{{ hostvars[... its not recursively evaluating

HTH, Cheers,

  -vlado