Ваша проблема вызвана тем, что переменные, определенные через set_fact
, недоступны до тех пор, пока не будет завершена задача set_fact
. Это означает, что когда вы устанавливаете:
foo: "{{ foo + template }}"
, вы видите значение template
из предыдущей итерации l oop.
Один из способов справиться с этим - переписать вашу set_fact
задачу, чтобы установить foo
напрямую:
---
- hosts: localhost
gather_facts: false
vars:
fqdn: "test.com"
portlist:
- {port: 9091, index: 1}
- {port: 9092, index: 2}
- {port: 9093, index: 3}
- {port: 9094, index: 4}
tasks:
- name: generate policy
set_fact:
foo: >-
{{
foo + [{
'name': 'traffic to {}'.format(item.port),
'index': item.index,
'match': {
'desc': "[{}]".format(item.port),
'name': '{}_{}'.format(fqdn, item.port),
'port': item.port
}
}]
}}
vars:
foo: []
loop: "{{ portlist }}"
- debug:
var: foo
Это выведет:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
"foo": [
{
"index": 1,
"match": {
"desc": "[9091]",
"name": "test.com_9091",
"port": 9091
},
"name": "traffic to 9091"
},
{
"index": 2,
"match": {
"desc": "[9092]",
"name": "test.com_9092",
"port": 9092
},
"name": "traffic to 9092"
},
{
"index": 3,
"match": {
"desc": "[9093]",
"name": "test.com_9093",
"port": 9093
},
"name": "traffic to 9093"
},
{
"index": 4,
"match": {
"desc": "[9094]",
"name": "test.com_9094",
"port": 9094
},
"name": "traffic to 9094"
}
]
}
Если вы найдете решение на основе шаблона более читабельным, вы можете переписать его, используя две задачи set_fact
, например:
---
- hosts: localhost
gather_facts: false
vars:
fqdn: "test.com"
portlist:
- {port: 9091, index: 1}
- {port: 9092, index: 2}
- {port: 9093, index: 3}
- {port: 9094, index: 4}
tasks:
- name: generate policy
set_fact:
template:
name: "traffic to {{ item.port }}"
index: "{{ item.index }}"
match:
desc: "[{{ item.port }}]" # The field needs to be passed as a list
name: "{{ fqdn }}_{{ item.port }}"
port: "{{ item.port }}"
loop: "{{ portlist }}"
register: foo
- set_fact:
foo: "{{ foo.results | map(attribute='ansible_facts.template') | list }}"
- debug:
var: foo