web-dev-qa-db-fra.com

ansible - variable dans la variable

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

14
Arun Sangal

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:

  1. Écrivez votre propre filtre qui développera votre variable en fonction de la valeur {{ jmeterplugins_url | my_custom_filter(item.plugin) }}

  2. É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

  3. Écrivez un lookup_plugin Personnalisé qui parcourra votre liste de variables et produira un résultat correct.

  4. 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)

5
Vor

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.

Solution de contournement:

Dans votre déclaration vars, au lieu d'utiliser var2: {{ var1 }}, utilisation var2: '{{ vars["var1"] }}'. De cette façon, cela fonctionnera.

18
karolyi