来自站点 yaml 或模板的 Ansible 剧本循环?

Ansible playbook loop from site yaml or template?

我正在尝试使用我的 Ansible 剧本来调用站点 YAML 引用来创建一个文件名,该文件名可以为多个开关递增。我究竟做错了什么?我相信剧本是从主机 YAML 中提取的?

格式:<switch>-<site>-<floor><stackid>.txt

例如:有两个开关:

host_vars/host.yaml

project_name: test
device_name: swi
site_abbrev: lon
device_type: switch
switch_stacks:
- id: 01
  installation_floor: 1
- id: 02
  installation_floor: 2

templates/switch-template.j2

{% for stack in switch_stacks %}
set system host-name {{ device_name }}-{{ site_abbrev }}-{{ stack.installation_floor }}{{ stack.id }}
{% endfor %}

问题所在的剧本,如何获取主机名以便为 2 个交换机中的每一个正确创建?

我的剧本:

- name: Create Folder Structure
  hosts: junos
  gather_facts: false

  tasks:
    - name: Create Site Specific Folder
      file:
        path: /home/usr/complete_config/{{ project_name }}
        state: directory
        mode: 0755

    - name: Set Destination Directory & Filename for Switch Configurations
      set_fact:
        dest_dir: /home/usr/complete_config/{{ project_name }}
        full_device_name: "{{ device_name|lower }}-{{ site_abbrev|lower }}-{{ switch_stacks.installation_floor }}{{ switch_stacks.id }}.txt"
      when: device_type == 'switch'

Ansible 错误,运行:

ansible-playbook playbooks/site-playbook.yaml
TASK [Set Destination Directory & Filename for Switch Configurations] **************************************************
fatal: [site-switch]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'installation_floor'\n\nThe error appears to be in '/home/usr/playbooks/switch-playbook.yaml': line 19, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - name: Set Destination Directory & Filename for Switch Configurations\n      ^ here\n"}

因此,您确实需要 loop 才能设置此事实,否则,您将尝试访问列表中的 installation_floor,而这是不可能的。

您还将面临 switch_stacks 中项目的 id 的问题,因为 01 是一个整数,最终将显示为 1,简单地说.所以你要么需要将它们声明为字符串,要么用 format filter.

填充它们

所以,你完成了这个任务:

- set_fact:
    full_device_name: >-
      {{ 
        full_device_name 
        | default([]) 
        + [
          device_name | lower ~ '-' ~ 
          site_abbrev | lower ~ '-' ~ 
          item.installation_floor  ~  
          "%02d" | format(item.id) ~ '.txt'
        ]
      }}
  loop: "{{ switch_stacks }}"
  when: device_type == 'switch'

这将创建一个列表:

full_device_name:
  - swi-lon-101.txt
  - swi-lon-202.txt

鉴于剧本:

- hosts: localhost
  gather_facts: false

  tasks:
    - set_fact:
        full_device_name: >-
          {{ 
            full_device_name 
            | default([]) 
            + [
              device_name | lower ~ '-' ~ 
              site_abbrev | lower ~ '-' ~ 
              item.installation_floor  ~  
              "%02d" | format(item.id) ~ '.txt'
            ]
          }}
      loop: "{{ switch_stacks }}"
      when: device_type == 'switch'
      vars:
        device_name: swi
        site_abbrev: lon
        device_type: switch
        switch_stacks:
          - id: 01
            installation_floor: 1
          - id: 02
            installation_floor: 2

    - debug: 
        var: full_device_name

这产生:

TASK [set_fact] ************************************************************
ok: [localhost] => (item={'id': 1, 'installation_floor': 1})
ok: [localhost] => (item={'id': 2, 'installation_floor': 2})

TASK [debug] ***************************************************************
ok: [localhost] => 
  full_device_name:
  - swi-lon-101.txt
  - swi-lon-202.txt

让我们将属性 id 保留为字符串

switch_stacks:
  - id: '01'
    installation_floor: 1
  - id: '02'
    installation_floor: 2

任务

    - set_fact:
        full_device_name: "{{ [prefix]|product(sw_fl_id)|map('join')|
                                       product([postfix])|map('join')|list }}"
      vars:
        prefix: "{{ device_name }}-{{ site_abbrev }}-"
        postfix: ".txt"
        sw_id: "{{ switch_stacks|map(attribute='id')|list }}"
        sw_fl: "{{ switch_stacks|map(attribute='installation_floor')|list }}"
        sw_fl_id: "{{ sw_fl|zip(sw_id)|map('join')|list }}"

给你列表

full_device_name:
  - swi-lon-101.txt
  - swi-lon-202.txt

@β.εηοιτ.βε

感谢您的回复,成功了。

不过,我对它进行了微调,您将在下面看到。 再次感谢您指路

    name: Set Destination Directory & Filename for Switch Configurations
  set_fact:
    dest_dir: /home/usr/complete_config/{{ project_name }}
    full_device_name: >-
      {{
          device_name | lower ~ '-' ~
          site_abbrev | lower ~ '-' ~
          item.installation_floor  ~
          "%02d" | format(item.id)

      }}
  loop: "{{ switch_stacks }}"
  when: device_type == 'switch'