ansible-переменная внутри переменной

версия Ansible 1.9.2.

поддерживает ли Ansible расширение переменной внутри переменной при ее оценке.

у меня есть задача загрузить 3 zip-файла из Artifactory.

вместо написания 3 отдельных задач в роли я использовал цикл ansible в playbook. В роли Ansible по умолчанию / main.yml, у меня есть все необходимые переменные, определенные / доступные для роли, т. е. jmeterplugins_extras_artifactory_url и другие (standard / webdriver) видимый perf_tests роль.

---
#- 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' }   

но с вышеуказанным кодом я получаю ошибку (как показано ниже):

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   

не Ansible поддерживает расширение/оценку переменных, если переменная содержит другую переменную (особенно когда я использую цикл).

Я просто не хочу расширять свою простую задачу цикла на 3 задачи с разными именами для загрузки zip-файлов для jmeterplugins_extras, jmeterplugins_standard и jmeterplugins_webdriver отдельно. Похоже, что ошибка связана с Jinja.

Как я могу использовать значение var гига в другой переменной, т. е. если var содержит гига, тогда я должен получить значение переменной "special_giga_variable" ({{special_{{ var }}_variable}})? где var был определен в defaults / main.yml as:

var: giga

2 ответов


нет, это не так. Но это не означает, что вам нужно расширить его на 3 разных задачи. То, что вы можете сделать, это на самом деле расширить "словарь", чтобы выглядеть так:

with_items:
 - {"url": "https://xxxxx", "file": "/tmp/xxxxx" }
 - {"url": "https://yyyyy", "file": "/tmp/yyyyy" }
 - {"url": "https://zzzzz", "file": "/tmp/zzzzz" }

тогда в вашей задаче просто назовите разные параметры:{{ item.url }} and {{ item.file }}

Альтернативные Варианты:

  1. напишите свой собственный фильтр, который расширит вашу переменную в соответствии со значением {{ jmeterplugins_url | my_custom_filter(item.plugin) }}

  2. написать специальный модуль, который будет инкапсулировать все функциональные возможности извлечения url-адреса в файл на основе ваших входных данных

  3. пишем на заказ lookup_plugin это будет перебирать ваш список переменных и производить правильный результат.

  4. если вы используете command модуль, вы можете использовать bash чтобы объединить Ваш url-адрес, файл в той же команде (это, вероятно, было бы самым грязным решением )


это делает.

можно использовать

set_fact:
  variable: '{{ vars['my_' + variablename + '_variable'] }}'

единственным недостатком этого подхода до сих пор является то, что он не будет динамически расширять переменные, которые получают значение другой переменной. пример:

roles/xxx/defaults/main.yml:

var1: foo
var2: '{{ var1 }}'

это, к сожалению, не будет работать при попытке использовать разрешенное значение в var2. Следовательно,

- debug: msg='{{ vars["var2"] }}'

выводит {{ var1 }} вместо foo.

решение:

в ваших vars объявление, вместо использования var2: {{ var1 }} используйте var2: '{{ vars["var1"] }}'. Так это сработает.