本文介绍了Ansible:在循环中生成变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的变量文件中,我需要定义一个列表变量,其项目具有相似的模式,并且还共享一些(冗余)信息.我想在循环中生成列表变量,而不是手动输入所有这些信息.

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:在循环中生成变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 03:03