问题
Ansible 1.9.2 version.
Does Ansible supports variable expansion within a variable while evaluating it.
I have a task to download 3 zip files from Artifactory.
Instead of writing 3 separate tasks within the role, I used ansible's loop in the playbook. In Ansible role's default/main.yml, I have all the required variables defined/available to the role i.e. jmeterplugins_extras_artifactory_url and other (standard / webdriver) are visible to perf_tests role.
---
#- Download and install JMeterPlugins
# Use get_url when Ansible is 2.0+ is available on the machine (otherwise, we can't use get_url) thus, using wget.
- name: Download JMeterPlugins-*
command: wget {{ jmeterplugins_{{ item.plugin }}_artifactory_url }}
chdir="{{ common_download_dir }}"
creates="{{ common_download_dir }}/{{ jmeterplugins_{{ item.plugin }}_file }}"
with_items:
- { plugin: 'extras' }
- { plugin: 'standard' }
- { plugin: 'webdriver' }
But with the above code, I'm getting an error (as shown below):
15:58:57 TASK: [perf_tests | Download JMeterPlugins-*] *********************************
15:58:57 <jmeter01.super.fast.jenkins> ESTABLISH CONNECTION FOR USER: cmuser on PORT 22 TO jmeter01.super.fast.jenkins
15:58:57 fatal: [jmeter01.super.fast.jenkins] => Failed to template wget {{ jmeterplugins_{{ item.plugin }}_artifactory_url }} chdir="{{ common_download_dir }}" creates="{{ common_download_dir }}/{{ jmeterplugins_{{ item.plugin }}_file }}": template error while templating string: expected token 'variable_end', got '{'
15:58:57
15:58:57 FATAL: all hosts have already failed -- aborting
15:58:57
15:58:57 PLAY RECAP ********************************************************************
15:58:57 to retry, use: --limit @/home/cmuser/perf_tests.retry
15:58:57
15:58:57 jmeter01.super.fast.jenkins : ok=23 changed=6 unreachable=1 failed=0
Doesn't ansible supports variable expansion/evaluation if a variable contains another variable (especially when I'm using a loop).
I just dont want to expand my simple loop task into 3 different -name tasks for downloading zip files for jmeterplugins_extras, jmeterplugins_standard and jmeterplugins_webdriver separately. It seems like the error is related due to Jinja.
How can I use var's value giga in another variable i.e. if var contains giga, then I should get the value of variable "special_giga_variable" ({{special_{{ var }}_variable}})? where var was defined in defaults/main.yml as:
var: giga
回答1:
No it doesn't. But it doesn't mean that you have to expand it into 3 different tasks. What you can do is actually expand you "dictionary" to look similar to this:
with_items:
- {"url": "https://xxxxx", "file": "/tmp/xxxxx" }
- {"url": "https://yyyyy", "file": "/tmp/yyyyy" }
- {"url": "https://zzzzz", "file": "/tmp/zzzzz" }
Then in your task just call different parameters: {{ item.url }} and {{ item.file }}
Alternative Options:
Write your own filter that will expand your variable according to the value
{{ jmeterplugins_url | my_custom_filter(item.plugin) }}
Write a custom module, that will encapsulate all of the functionality of fetching url into the file based on your inputs
Write custom
lookup_plugin
that will iterate through your list of variables and produce correct result.Since you are using
command
module you can leveragebash
to concatenate your url, file in the same command ( this would probably be the messiest solution )
回答2:
It does.
You can use
set_fact:
variable: '{{ vars['my_' + variablename + '_variable'] }}'
the only downside of this approach so far is, it won't dynamically expand variables that get the value of another variable. an example:
roles/xxx/defaults/main.yml
:
var1: foo
var2: '{{ var1 }}'
This, unfortunately will not work when trying to use the resolved value in var2
. Hence,
- debug: msg='{{ vars["var2"] }}'
will output {{ var1 }}
instead of foo
.
Workaround:
In your vars declaration, instead of using var2: {{ var1 }}
, use var2: '{{ vars["var1"] }}'
. That way, it will work.
来源:https://stackoverflow.com/questions/32704247/ansible-variable-within-variable