Question:
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.
1 2 3 4 5 6 7 8 9 10 11 12 |
--- #- 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):
1 2 3 4 5 6 7 8 9 10 11 |
15:58:57 TASK: [perf_tests | Download JMeterPlugins-*] ********************************* 15:58:57 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
Answer:
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:
1 2 3 4 5 |
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 )