Stelios
Stelios

Reputation: 1102

Pass variable within dictionary using other dictionary value

How does one assign a value containing a variable to a dictionary key, when it is using another dictionary value as a parameter.

Example

---
- name: Test vars
  hosts: ['localhost']
  vars:
    foo:
      a: "foo a value"
      b: "{{ a }}"
  tasks:
  - name: Fix owneship and permission issue with sudoers file
    debug:
      msg: Print {{ foo.b }}

I have tried the following:

vars:
  foo:
    a: " foo a value"
    b: "{{ foo.a }}"
vars:
  foo:
    a: " foo a value"
    b: "{{ foo['a'] }}"
vars:
  foo:
    a: " foo a value"
    b: "{{ a }}"

None of the above work.

Upvotes: 1

Views: 976

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39079

You can fulfil this requirement using YAML only, via a couple node anchor / alias node.

In YAML syntax, you can add an anchor before a value, then you can reference it via an alias node.

An anchor is denoted by the & indicator:

some_key: &anchor_name value

While an alias is denoted by the * indicator:

some_other_key: *anchor_name

So, given the task:

- debug:
    var: foo.b
  vars:
    foo:
      a: &foo_a "foo a value"
      b: *foo_a

This yields the expected:

ok: [localhost] => 
  foo.b: foo a value

But, indeed, it is just an anchor and alias, you won't be able to compose a value from a literal plus a variable or compose based on multiple variables, e.g. if you want

####
# Please note that this is a counterexample and won't work
####

mydict:
  foo: "example {{ mydict.bar }}"
  bar: 123

or

####
# Please note that this is a counterexample and won't work
####

mydict:
  foo: "{{ mydict.bar }}{{ mydict.baz }}"
  bar: 123
  baz: 456

You are left with no option, as this is something Ansible does not plan to allow:

This is expected and not something that we plan on changing. You cannot create a self referential variable.

Quoted from sivel, maintainer of Ansible, on their issue tracker

Upvotes: 2

Related Questions