来自站点 yaml 或模板的 Ansible 剧本循环?
Ansible playbook loop from site yaml or template?
我正在尝试使用我的 Ansible 剧本来调用站点 YAML 引用来创建一个文件名,该文件名可以为多个开关递增。我究竟做错了什么?我相信剧本是从主机 YAML 中提取的?
格式:<switch>-<site>-<floor><stackid>.txt
例如:有两个开关:
- swi-lon-101.txt
- swi-lon-202.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'
我正在尝试使用我的 Ansible 剧本来调用站点 YAML 引用来创建一个文件名,该文件名可以为多个开关递增。我究竟做错了什么?我相信剧本是从主机 YAML 中提取的?
格式:<switch>-<site>-<floor><stackid>.txt
例如:有两个开关:
- swi-lon-101.txt
- swi-lon-202.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'