70

I need to create new variable from contents of other variables. Currently I'm using something like this:

- command: echo "{{ var1 }}-{{ var2 }}-{{ var3 }}"
  register: newvar

The problem is:

  • Usage of {{ var1 }}...{{ varN }} brings too long strings and very ugly code.
  • Usage of {{ newvar.stdout }} a bit better but confusing.
  • Usage of set_fact module caches fact between runs. It isn't appropriate for me.

Is there any other solution?

3 Answers 3

73

Since strings are lists of characters in Python, we can concatenate strings the same way we concatenate lists (with the + sign):

{{ var1 + '-' + var2 + '-' + var3 }}

If you want to pipe the resulting string to some filter, make sure you enclose the bits in parentheses:

e.g. To concatenate our 3 vars, and get a sha512 hash:

{{ (var1 + var2 + var3) | hash('sha512') }}

Note: this works on Ansible 2.3. I haven't tested it on earlier versions.

Sign up to request clarification or add additional context in comments.

1 Comment

While correct, the much safer operator for concatenating strings in Jinja is actually the tilde (~) operator.
48

Good question. But I think there is no good answer which fits your criteria. The best I can think of is to use an extra vars file.

A task like this:

- include_vars: concat.yml

And in concat.yml you have your definition:

newvar: "{{ var1 }}-{{ var2 }}-{{ var3 }}"

Comments

32

As simple as joining lists in python itself.

ansible -m debug -a msg="{{ '-'.join(('list', 'joined', 'together')) }}" localhost

localhost | SUCCESS => {
  "msg": "list-joined-together" }

Works the same way using variables:

ansible -m debug -a msg="{{ '-'.join((var1, var2, var3)) }}" localhost

3 Comments

Just an aside. Why does ansible -m debug -a msg="title {{ '-'.join((var1, var2, var3)) }}" localhost not work?
@orodbhen not 100% sure but it feels like some weird arg parsing issue - try: ansible -m debug -a "msg='{{ var1 }} title {{ var1 }} {{ \"-\".join((var1, var2, var3)) }}'" localhost -e var1=test -e var2=foo -e var3=bar
Interestingly enough, this also works: ansible -m debug -a "msg='{{ var1 }} title {{ var1 }} {{ '-'.join((var1, var2, var3)) }}'" localhost -e var1=test -e var2=foo -e var3=bar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.