我目前在项目上使用route53_facts模块。我在一个托管区域中有250个记录集。我很难列出该区域中的所有记录集。 Route 53 API可以一次返回最多 100条记录的页面。为了检索下一页,必须将 NextRecordName 响应值传递到route53_facts模块的 start_record_name:字段(非常简单)。
我特别遇到的问题是让Ansible做到这一点。大概有人会使用一个循环来做到这一点,例如用伪代码:
start
get 100 records
do until response does not contain NextRecordName:
get 100 records (start_record_name=NextRecordName)
end
在Ansible中,我编写了以下任务来做到这一点:
- block:
- name: List record sets in a given hosted zone
route53_facts:
query: record_sets
hosted_zone_id: "/hostedzone/ZZZ1111112222"
max_items: 100
start_record_name: "{{ record_sets.NextRecordName | default(omit) }}"
register: record_sets
until: record_sets.NextRecordName is not defined
when: "'{{ hosted_zone['Name'] }}' == 'test.example.com.'"
...但是,这无法正常工作。而不是不断地翻页直到没有更多的记录,它会重复返回前100条记录(“第一页”)。
从Ansible调试输出中可以看到, start_record_name:反复 null :
"attempts": 2,
"changed": false,
"invocation": {
"module_args": {
"aws_access_key": null,
"aws_secret_key": null,
"change_id": null,
"delegation_set_id": null,
"dns_name": null,
"ec2_url": null,
"health_check_id": null,
"health_check_method": "list",
"hosted_zone_id": "/hostedzone/ZZZ1111112222",
"hosted_zone_method": "list",
"max_items": "100",
"next_marker": null,
"profile": null,
"query": "record_sets",
"region": null,
"resource_id": null,
"security_token": null,
"start_record_name": null,
"type": null,
"validate_certs": true
}
},
...我猜是 | default(omit)过滤器始终处于执行状态。换句话说, record_sets.NextRecordName 永远不会在任务中进行初始化。
我希望有人能帮助我让Ansible从Route 53的某个区域返回所有记录。我认为我已经纠结于Ansible的循环行为。谢谢!
答案 0 :(得分:1)
“尽我所能告诉”:
要回答您的问题,实际上// buildPerson() creates a new, complete 'person' object when called,
// and overrides its properties with the provided ones
expect(
changeName(buildPerson({ firstName: 'Juan' }))
).toEqual(
buildPerson({ firstName: 'Juan_firstName' })
);
和until:
的互动方式似乎与register:
和when:
的互动方式不同。我最好的解释是register:
的行为类似于数据库事务:如果条件为false,它将回退until:
分配,这意味着在再次尝试register:
的正文时,它使用的参数与第一次相同。阻止until:
成为无限循环的唯一事物是until:
值。
因此,在您的特定情况下,我认为这可以完成工作:
retries:
- name: initial record_set
route53_facts:
# bootstrap so the upcoming "when:" will evaluate correctly
register: record_facts
- set_fact:
# capture the initial answer
records0: '{{ record_facts.ResourceRecordSets }}'
- name: rest of them
route53_facts:
start_record_name: '{{ record_facts.NextRecordName }}'
register: record_facts
when: record_facts.NextRecordName | default("")
with_sequence: count=10
- set_fact:
all_records: >-
{{ record0 + (record_facts.results |
selectattr("ResourceRecordSets", "defined") |
map(attribute="ResourceRecordSets") | list) }}
是一种hack,因为with_sequence:
(loop:
是句法糖)需要迭代的项目列表,但是考虑到返回的响应没有{ {1}}会导致with_*
失败,跳过它们,会使(在您的情况下)3到10项几乎立即解决。
然后,您只需要从NextRecordName
个现在when:
个答复中提取实际的响应数据,然后将其粘贴到初始答复中即可得到完整的列表。
说了这么多,我现在确信list
(以及将迭代负担加到剧本中的任何其他AWS模块)的行为都是 bug 。模块调用者已经可以使用route53_facts:
了,但这是一个实现细节,任何值都不能大于某个随机分页截止值。