从 Jinja2 模板为多个主机生成单个配置

Generate single configuration for multiple hosts from Jinja2 template

问题: 考虑到 Ansible 的性质,我有 2 个任务按预期顺序执行。据我了解,每个任务只能执行一个模块。

任务 1 - 从网络设备收集事实信息(序列号、版本等)。

任务 2 - 使用任务 1 中收集的信息渲染模板

理想结果: 由于我正在遍历大量网络设备,因此我的理想结果是一次选择一个设备,从中收集信息,然后呈现一个带有该信息的模板,接下来转到循环中的其他设备,依此类推。

方法: 我想保持相同的语法,在任务 1 中将事实保存在文件 (.json) 中,在任务 2 中,阅读JSON 文件并获取我感兴趣的变量。

有没有更好的方法呢? (可能不止一个)

我目前得到的内容不符合我的目的,因为当模板呈现时,它只包含有关最后一个设备的信息:

任务:roles/juniper.junos/tasks/main.yaml

- name: 1 - Gathering Facts
    junos_get_facts:
      host: "{{ inventory_hostname}}"
      user: ""
      passwd: ""
      savedir: "~/Ansible/Ouput/Facts"
    ignore_errors: True
    register: junos

- name: 2 - Creating the template
    template:
      src="~/Ansible/roles/juniper.junos/templates/template.j2"
      dest="~/Ansible/Ouput/Facts/Device_facts.yml"

模板:~/Ansible/roles/juniper.junos/templates/template.j2

{% for host in groups['OOB_AMS'] %}

   ANSIBLE NAME:                   {{ inventory_hostname}}

   HOSTNAME:               {{ junos.facts.hostname }}
   MODEL:                  {{ junos.facts.model }}
   SERIAL:                 {{ junos.facts.serialnumber }}
   VERSION:                {{ junos.facts.model }}
   UP TIME:                {{ junos.facts.RE0.up_time }}

{% endfor %}

理想输出:"~/Ansible/Ouput/Facts/Device_facts.yml"

   ANSIBLE NAME:                   DEVICE 1

   HOSTNAME:               DEVICE 1 HOSTNAME
   MODEL:                  DEVICE 1 MODEL
   SERIAL:                 DEVICE 1 SERIAL
   VERSION:                DEVICE 1 VERSION
   UP TIME:                DEVICE 1 UP TIME

   ANSIBLE NAME:                   DEVICE 2

   HOSTNAME:               DEVICE 2 HOSTNAME
   MODEL:                  DEVICE 2 MODEL
   SERIAL:                 DEVICE 2 SERIAL
   VERSION:                DEVICE 2 VERSION
   UP TIME:                DEVICE 2 UP TIME

   ANSIBLE NAME:                   DEVICE 3

   HOSTNAME:               DEVICE 3 HOSTNAME
   MODEL:                  DEVICE 3 MODEL
   SERIAL:                 DEVICE 3 SERIAL
   VERSION:                DEVICE 3 VERSION
   UP TIME:                DEVICE 3 UP TIME

你用 host 变量写了一个 for 循环,但一次都没用过。

将模板更改为:

{% for host in ansible_play_hosts %}

   ANSIBLE NAME:                   {{ hostvars[host].inventory_hostname}}

   HOSTNAME:               {{ hostvars[host].junos.facts.hostname }}
   MODEL:                  {{ hostvars[host].junos.facts.model }}
   SERIAL:                 {{ hostvars[host].junos.facts.serialnumber }}
   VERSION:                {{ hostvars[host].junos.facts.model }}
   UP TIME:                {{ hostvars[host].junos.facts.RE0.up_time }}

{% endfor %}

循环遍历 groups['OOB_AMS'] 还不错,但硬编码组名对于您的情况似乎没有必要。相反,您可以使用:ansible_play_hosts(2.2 版之前的play_hosts)。

另外,为了清晰起见,您可以将 run_once: true 添加到 template 任务中。这并不关键,因为模板在每次迭代中都会产生相同的输出,所以后面的运行无论如何都会跳过,但没有必要多次这样做。