问题描述
在我的变量文件中,我需要定义一个列表变量,其项目具有相似的模式,并且还共享一些(冗余)信息.我想在循环中生成列表变量,而不是手动输入所有这些信息.
In my variable file, I need to define a list variable whose items are of similar pattern, and also share some (redundant) info. Instead of manually type all those info, I would like to generate the list variable in a loop.
例如,我有 100 台主机,主 IP 地址为 192.168.100.[1:100],每个主机都有一个额外的 IP 地址 10.0.1.[1:100].所有主 IP 使用相同的网关,比如 192.168.100.254,所有额外的 IP 使用另一个网关,比如 10.0.1.254.
e.g., I have 100 hosts, with primary ip address 192.168.100.[1:100], and each host has an extra ip addresses 10.0.1.[1:100]. All primary IPs use the same gateway, say 192.168.100.254, and all extra IPs use another gateway, say 10.0.1.254.
在一个任务中,我想遍历所有主机,对于每个主机,它的主IP、额外IP和网关都是必需的.我想在我的任务中使用with_items",所以我想要一个列表变量IP_ADDRS",其中每个项目都是一个像下面这样的字典:
In a task, I want to loop through all hosts, and for each host, it's primary ip, extra ip, and gateways are all needed. I want to use "with_items" in my task, so I want to have a list variable "IP_ADDRS", within which each item is a dict like below:
{ primary_ip: 192.168.100.x, primary_gw: 192.168.100.254, extra_ip: 10.0.1.x, extra_gw: 10.0.1.254}
代替手动定义 IP_ADDRS:
Instead of define IP_ADDRS manually:
IP_ADDRS:
- { primary_ip: 192.168.100.1, primary_gw: 192.168.100.254, extra_ip: 10.0.1.1, extra_gw: 10.0.1.254}
- { primary_ip: 192.168.100.2, primary_gw: 192.168.100.254, extra_ip: 10.0.1.2, extra_gw: 10.0.1.254}
- ...
我想以某种方式生成列表变量IP_ADDRS"...
I want to generate the list variable "IP_ADDRS" somehow...
我尝试了 jinja2 语句,如下所示:
I tried jinja2 statements, something like below:
IP_ADDRS: >
"{% for idx in range(1, 101) %}
- { primary_ip: 192.168.100.{{ idx }}, primary_gw: 192.168.100.254, extra_ip: 10.0.1.{{ idx }}, extra_gw: 10.0.1.254 }
"{% endfor %}"
当我使用调试模块打印 IP_ADDRS 时,它确实打印了列表中的所有项目,但是似乎 Ansible 并未将此变量视为列表,因此
When I print IP_ADDRS using debug module, it does literally print all items in the list, BUT it seems Ansible is not treat this variable as a LIST, thus
with_items: {{ IP_ADDRS }}
没有像我预期的那样工作.
does not work as I expected.
jinja2 语句有什么问题吗,或者有什么方法可以达到相同的结果?
Is there any thing wrong with the jinja2 statement, or is there a way to achieve the same result?
非常感谢,
/布鲁因
推荐答案
您可以定义对象的模板并在循环中使用它:
You may define template of your object and use it in loops:
---
- hosts: localhost
gather_facts: no
vars:
ip_template:
primary_ip: "192.168.100.{{ item }}"
primary_gw: "192.168.100.254"
extra_ip: "10.0.1.{{ item }}"
extra_gw: "10.0.1.254"
tasks:
# execute single task, no need in list
- debug:
msg: "{{ ip_template }}"
with_sequence: "start=1 count=5"
# construct list
- set_fact:
ip_list: "{{ (ip_list | default([])) + [ip_template] }}"
with_sequence: "start=1 count=5"
- debug:
msg: "{{ ip_list }}"
如果您仍然希望在变量中定义 ip_list
,则需要构建复杂的 Jinja2 语句以生成 JSON 格式而不是 YAML 格式的列表,正如您所尝试的那样.内部有两个对象的此类字符串的小示例:'[{"ip":"192.168.0.10","gw":"192.168.0.1"},{"ip":"192.168.0.20","gw":"192.168.0.1"}]'
If you still want to have ip_list
defined in your variables, you need to construct complex Jinja2 statement to generate list in JSON-format and not YAML, as you tried. Tiny example of such string with two objects inside: '[{"ip":"192.168.0.10","gw":"192.168.0.1"},{"ip":"192.168.0.20","gw":"192.168.0.1"}]'
这篇关于Ansible:在循环中生成变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!