Issue with 'forwarding' variable values

I have a tasks file with a TASK like this

- set_fact:
    new_pgport: "{{ databaseport|default(next_port) }}"
    new_pginstance: "{{ instanzname }}"
    new_pgdata: "{{ postgres_data_root }}/{{ new_pginstance }}"
    ...

a playbook executes this further down inside a role and is called with

ansible-playbook pg_instance_add.yml -e '{"databaseport":"5448" , "instanzname":"bitbucketp"}'

and fails complaining that new_pginstance wouldn’t have a value assigned to it.

for troubleshooting I add a debug right before that set_fact

- debug:
    msg: "instanzname = {{ instanzname }}, port = {{ databaseport }}"

… witch displays both (instanzname & databaseport) values correctly.

I can work around this by adding -e '{"new_pginstance":"bitbucketp"}' to the execution command (so I have this twice in the call, which seems not as it should be

I would rather understand why the assining of the value for instanzname into new_pg_instance obviousely does not work as expected.

Any hints what I am doing wrong?


a little more detail on the error message:
"An unhandled exception occurred while templating '{{ instanzname }}'. Error was a <class 'ansible.errors.AnsibleError'>"

Your error is cut off before any of the useful information that it contains, like the actual error message.

Your issue is that you cannot reference a variable before it exists, and new_pginstance is being created by this task so it does not exist when the task arguments are evaluated (this would have been noted in the error message that you received.)

One way to fix this is to set it as a var instead of using set_fact (vars can be used at the play, role, block, or task level), for example:

- vars:
    new_pgport: "{{ databaseport|default(next_port) }}"
    new_pginstance: "{{ instanzname }}"
    new_pgdata: "{{ postgres_data_root }}/{{ new_pginstance }}"
  block:
    - name: An actual task
      debug:
        msg: Hello {{ new_pgdata }}

The other alternative is to use multiple set_fact tasks, so that the variable exists when you reference it:

- set_fact:
    new_pginstance: "{{ instanzname }}"

- set_fact:
    new_pgport: "{{ databaseport|default(next_port) }}"
    new_pgdata: "{{ postgres_data_root }}/{{ new_pginstance }}"
3 Likes