concatenate a value with another variable in default filter

I have the bellow Ansible inventory :

`
[web:children]
web-eu-west
web-us-east
[eu:vars]
dc=eu-west
[eu:children]
web-eu-west
[us:vars]
dc=us-east
[us:children]
web-us-east

`

The bellow is working fine in my playbook :
`
– hosts: “{{ hosts | default(‘web’) }}”

`

Unfortunately we have a case now where we need to combine the dc variable in the default filter , I’m trying the bellow two combinations with errors :

`

  • hosts: “{{ hosts | default('web-'dc) }}”
    `

ERROR! template error while templating string: expected token ‘,’, got ‘dc’. String: {{ hosts | default('web-'dc) }}

`

  • hosts: “{{ hosts | default(‘bid-’+ dc) }}”
    `

ERROR! the field ‘hosts’ has an invalid value, which appears to include a variable that is undefined. The error was: ‘dc’ is undefined

What is the right way to concatenate a value and a var using the default filter ?

Try this:

- hosts: "{{ hosts | default([ [ 'web-', dc ] | join ] ) }}"
or
- hosts: "{{ hosts | default([ 'web-', dc ] | join ) }}"

Not sure if you need two sets of square brackets.

Johannes

Your general approach is pretty much correct in your last example:

  • hosts: “{{ hosts | default(‘bid-’+ dc) }}”

Although jinja2 recommends using a ~ instead of + for string concatenation, although both will work.

However, the real problem is with your variable. You have created the dc variable in your inventory, which means that it is scoped to the hosts within that group. Because you are using the dc variable in your hosts declaration, no hosts have been targeted, and additionally, the dc variable is per host, not global.

As such, you cannot use the dc variable in a hosts declaration due to variable scoping, and the dc variable not being defined at that point.

The only real place to define a variable that can be used in the hosts declaration is via the command line via -e/–extra-vars

Got it Matt , that makes sense.

Thanks .