使用Ansible列出Route 53中的100多个记录

时间:2018-12-06 13:10:02

标签: ansible amazon-route53 ansible-facts

我目前在项目上使用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的循环行为。谢谢!

1 个答案:

答案 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:了,但这是一个实现细节,任何值都不能大于某个随机分页截止值。