Version Ansible 1.9.2.
Ansible prend-il en charge l'expansion des variables au sein d'une variable lors de son évaluation.
J'ai la tâche de télécharger 3 fichiers Zip depuis Artifactory.
Au lieu d'écrire 3 tâches distinctes dans le rôle, j'ai utilisé la boucle de ansible dans le playbook. Dans default/main.yml du rôle Ansible, j'ai toutes les variables requises définies/disponibles pour le rôle, c'est-à-dire que jmeterplugins_extras_artifactory_url et autres (standard/webdriver) sont visibles par perf_tests rôle.
---
#- 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' }
Mais avec le code ci-dessus, j'obtiens une erreur (comme indiqué ci-dessous):
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
Ne prend pas en charge ansible expansion/évaluation de variable si une variable contient une autre variable (en particulier lorsque j'utilise une boucle).
Je ne veux tout simplement pas étendre ma tâche de boucle simple en 3 tâches de nom différent pour télécharger des fichiers Zip pour jmeterplugins_extras, jmeterplugins_standard et jmeterplugins_webdriver séparément. Il semble que l'erreur soit liée à Jinja.
Comment puis-je utiliser la valeur de var giga dans une autre variable, c'est-à-dire si var contient giga, alors je devrait obtenir la valeur de la variable "special_giga_variable" ( {{special _ {{var}} _ variable}} )? où var a été défini dans defaults/main.yml comme:
var: giga
Non, ce n'est pas le cas. Mais cela ne signifie pas que vous devez l'étendre en 3 tâches différentes. Ce que vous pouvez faire, c'est développer votre "dictionnaire" pour qu'il ressemble à ceci:
with_items:
- {"url": "https://xxxxx", "file": "/tmp/xxxxx" }
- {"url": "https://yyyyy", "file": "/tmp/yyyyy" }
- {"url": "https://zzzzz", "file": "/tmp/zzzzz" }
Ensuite, dans votre tâche, appelez simplement différents paramètres: {{ item.url }} and {{ item.file }}
Options alternatives:
Écrivez votre propre filtre qui développera votre variable en fonction de la valeur {{ jmeterplugins_url | my_custom_filter(item.plugin) }}
Écrivez un module personnalisé, qui encapsulera toutes les fonctionnalités de récupération d'url dans le fichier en fonction de vos entrées
Écrivez un lookup_plugin
Personnalisé qui parcourra votre liste de variables et produira un résultat correct.
Puisque vous utilisez le module command
, vous pouvez utiliser bash
pour concaténer votre URL, fichier dans la même commande (ce serait probablement la solution la plus compliquée)
Cela fait.
Vous pouvez utiliser
set_fact:
variable: '{{ vars['my_' + variablename + '_variable'] }}'
le seul inconvénient de cette approche à ce jour est qu'elle ne développera pas dynamiquement les variables qui obtiennent la valeur d'une autre variable. un exemple:
roles/xxx/defaults/main.yml
:
var1: foo
var2: '{{ var1 }}'
Cela ne fonctionnera malheureusement pas lorsque vous essayez d'utiliser la valeur résolue dans var2
. Par conséquent,
- debug: msg='{{ vars["var2"] }}'
affichera {{ var1 }}
au lieu de foo
.
Dans votre déclaration vars, au lieu d'utiliser var2: {{ var1 }}
, utilisation var2: '{{ vars["var1"] }}'
. De cette façon, cela fonctionnera.