set_fact and "variable variables"

Hello,

I send this message to ansible-devel as I think it is an advanced subject that can lead to a devel discussion.

The following play currently works as expected (or at least as I expected :wink: :

  • hosts: localhost
    gather_facts: no
    vars:
    var1: var2

tasks:

  • name:
    set_fact: “{{ var1 }}=test”
  • name: debug
    debug: var=var2

It outputs “test”, meaning that the var1 variable has been expanded to var2 in the variable space.

Even though if this kind of feature can be very dangerous in the wrong hands, this can be helpful (and can help me solve an issue I have) to generate facts whose names depend on configurations that have been made in group_vars

In my case, I have several groups that define several lists of repositories to clone at specific revisions : HEAD, HEAD~1, …
I need to find a way, for each of these clones, to grab its git sha, and make it available to the rest of the playbook.

example of list (appid are uniques across all vars)
apps:

  • appid: app1
    repo: repo_url
    branch: HEAD

  • appid: app2
    repo: repo_url
    branch: HEAD~1

with the feature mentioned above, I could easily generate new facts:
app1_sha: ab324ccd…
app2_sha: a23324ce…

now my question is :

can I rely on the implementation and consider that this “variable variables” feature of set_fact is indeed a feature and will not disappear in future releases ?

Thank you
Jerome

That line is pre templated so it will continue to work, though ansible does not like to see such things when possible as they do defeat much of the desired aesthetic.

– Michael

I agree that “variable variables” is very bad for auditability.

Is there currently an elegant way to “extract” facts from a role in a non-colliding way ?

I know that with the syntax “register: O”, you can do something like

O = data that was registered in output during the invocation of the role R with params P1
O = data that was registered in output during the invocation of the role R with params P2

but I would need something like

O1 = data that was registered in output during the invocation of the role R with params P1
O2 = data that was registered in output during the invocation of the role R with params P2

is there a solution for this ? if not, do you see a need for this ?

If you’re talking about different hosts, they could be accessed via hostvars.

if the same role is being applied twice to the same hosts, I think you’re stuck with the above.