ansible - 变量中的变量

ansible - variable within variable

Ansible 1.9.2 版本。

Ansible 是否支持在评估变量时在变量内进行变量扩展。

我有一个任务要从 Artifactory 下载 3 个 zip 文件。

我没有在角色中编写 3 个单独的任务,而是在剧本中使用了 ansible 的循环。在 Ansible 角色的 default/main.yml 中,我拥有该角色所需的所有变量 defined/available,即 jmeterplugins_extras_artifactory_url 和其他(标准/网络驱动程序)对 [=30= 可见]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 不支持变量 expansion/evaluation。

我只是不想将我的简单循环任务扩展为 3 个不同的 -name 任务,分别为 jmeterplugins_extras、jmeterplugins_standard 和 jmeterplugins_webdriver 下载 zip 文件。看来错误与 Jinja 有关。

如何在另一个变量中使用 var 的值 giga 即如果 var 包含 giga ,那么我应该得到变量 "special_giga_variable" ({{special_{{ var }}_variable}}) 的值?其中 var 在 defaults/main.yml 中定义为:

变量:千兆

不,不是。但这并不意味着您必须将其扩展为 3 个不同的任务。你可以做的实际上是扩展你 "dictionary" 看起来像这样:

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. 扩展变量
  3. 编写一个自定义模块,它将根据您的输入将获取 url 的所有功能封装到文件中

  4. 编写自定义 lookup_plugin,它将遍历您的变量列表并产生正确的结果。

  5. 由于您使用的是 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"] }}'。这样就可以了。