Hetzner DNS 指南
community.dns 集合提供了多个模块来处理 Hetzner DNS 服务。这些模块使用 基于 JSON REST 的 API。
该集合提供了六个用于处理 Hetzner DNS 的模块
- community.dns.hetzner_dns_record: 创建/更新/删除单个 DNS 记录 
- community.dns.hetzner_dns_record_info: 检索 DNS 记录的信息 
- community.dns.hetzner_dns_record_set: 创建/更新/删除 DNS 记录集 
- community.dns.hetzner_dns_record_set_info: 检索 DNS 记录集的信息 
- community.dns.hetzner_dns_record_sets: 批量同步 DNS 记录集 
如果您有兴趣从 markuman.hetzner_dns 集合迁移,请参阅 从 markuman.hetzner_dns 迁移。
它还提供了一个清单插件
- community.dns.hetzner_dns_records: 从 DNS 记录创建清单 
身份验证
要使用 Hetzner 的 API,您需要创建一个 API 令牌。您可以在 DNS 控制台的用户菜单中的“API 令牌”菜单项中管理 API 令牌。您必须将令牌提供给模块的 hetzner_token 选项、其别名 api_token 或将其传递到 HETZNER_DNS_TOKEN 环境变量中
- community.dns.hetzner_dns_record:
    hetzner_token: '{{ token }}'
    ...
在本指南的示例中,我们将省略身份验证选项。请注意,您可以使用 module_defaults(请参阅 模块默认值)或使用环境变量为运行模块的用户和机器全局设置它们。
使用 community.dns.hetzner 模块默认组
为了避免在每个任务中为所有 Hetzner DNS 模块指定公共参数,您可以使用 community.dns.hetzner 模块默认组
---
- name: Hetzner DNS
  hosts: localhost
  gather_facts: false
  module_defaults:
    group/community.dns.hetzner
      hetzner_token: '{{ token }}'
  tasks:
    - name: Query zone information
      community.dns.hetzner_dns_zone_info:
        zone_name: example.com
      register: result
    - name: Set A records for www.example.com
      community.dns.hetzner_dns_record_set:
        state: present
        zone_name: example.com
        type: A
        prefix: www
        value:
          - 192.168.0.1
这里所有两个任务都将使用为模块默认组设置的选项。
使用 DNS 区域
community.dns.hetzner_dns_zone_info 模块允许查询区域的信息。可以通过其名称和 ID(一个整数)来识别该区域
- name: Query zone information by name
  community.dns.hetzner_dns_zone_info:
    zone_name: example.com
  register: result
- name: Query zone information by ID
  community.dns.hetzner_dns_zone_info:
    zone_id: aBcDeFgHiJlMnOpQrStUvW
  register: result
该模块返回区域名称和区域 ID,因此该模块可用于从区域 ID 转换为区域名称,反之亦然
- ansible.builtin.debug:
    msg: |
        The zone ID: {{ result.zone_id }}
        The zone name: {{ result.zone_name }}
使用 DNS 记录
注意
默认情况下,此集合中的模块和插件返回和接受的 TXT 记录值是不带引号的。这意味着您不必添加双引号 ("),并转义双引号 (如 \") 和反斜杠 (如 \\)。所有处理 DNS 记录的模块和插件都支持 txt_transformation 选项,该选项允许配置此行为。
查询 DNS 记录和记录集
community.dns.hetzner_dns_record_set_info 模块允许从 API 查询 DNS 记录集。它可用于查询单个记录集
- name: Query single record
  community.dns.hetzner_dns_record_set_info:
    zone_name: example.com
    type: A  # IPv4 addresses
    what: single_record  # default value
    # Either specify a record name:
    record: www.example.com
    # Or a record prefix ('' is the zone itself):
    prefix: www
  register: result
- name: Show IPv4 addresses if record exists
  ansible.builtin.debug:
    msg: >
      IPv4s are {{ result.set.value | join(', ') }},
      TTL is {{ result.set.ttl }}
  when: result.set
- name: Show that record is not set
  ansible.builtin.debug:
    msg: There is no A record for www.example.com
  when: not result.set
在本节的所有示例中,您可以用区域的 ID 字符串将 zone_name=example.com 替换为 zone_id=aBcDeFgHiJlMnOpQrStUvW。
您还可以查询记录名称或前缀的所有记录集列表
- name: Query all records for www.example.com
  community.dns.hetzner_dns_record_set_info:
    zone_name: example.com
    what: all_types_for_record
    # Either specify a record name:
    record: www.example.com
    # Or a record prefix ('' is the zone itself):
    prefix: www
  register: result
- name: Show all records for www.example.com
  ansible.builtin.debug:
    msg: >
      {{ item.type }} record with TTL {{ item.ttl }} has
      values {{ item.value | join(', ') }}
  loop: result.sets
最后,您可以查询一个区域的所有记录集
- name: Query all records for a zone
  community.dns.hetzner_dns_record_set_info:
    zone_name: example.com
    what: all_records
  register: result
- name: Show all records for the example.com zone
  ansible.builtin.debug:
    msg: >
      {{ item.type }} record for {{ item.record }} with
      TTL {{ item.ttl }} has values {{ item.value | join(', ') }}
  loop: result.sets
如果您对单个 DNS 记录(而不是记录集)感兴趣,则应使用 community.dns.hetzner_dns_record_info 模块。它支持与 community.dns.hetzner_dns_record_set_info 模块 相同的限制选项。
创建和更新 DNS 单个记录
如果您不想添加/删除值,而是替换值,您将需要修改一个记录集,而不是单个记录。这在使用 CNAME 和 SOA 记录时尤为重要。
community.dns.hetzner_dns_record 模块 允许设置、更新和删除单个 DNS 记录。设置和更新可以按如下方式完成。记录将通过记录名称和类型进行匹配,如果需要,TTL 值将会更新。
- name: Add an A record with value 1.1.1.1 for www.example.com, resp. make sure the TTL is 300
  community.dns.hetzner_dns_record:
    state: present
    zone_name: example.com
    type: A  # IPv4 addresses
    # Either specify a record name:
    record: www.example.com
    # Or a record prefix ('' is the zone itself):
    prefix: www
    value: 1.1.1.1
    ttl: 300
要删除记录,只需使用 state=absent。记录将通过记录名称和类型进行匹配,并且 TTL 将被忽略。
- name: Remove A values for www.example.com
  community.dns.hetzner_dns_record:
    state: absent
    zone_name: example.com
    type: A  # IPv4 addresses
    record: www.example.com
    value: 1.1.1.1
对于具有相同记录名称且类型相同的记录,具有其他值的记录将被忽略。
创建和更新 DNS 记录集
community.dns.hetzner_dns_record_set 模块 允许设置、更新和删除 DNS 记录集。设置和更新可以按如下方式完成。
- name: Make sure record is set to the given value
  community.dns.hetzner_dns_record_set:
    state: present
    zone_name: example.com
    type: A  # IPv4 addresses
    # Either specify a record name:
    record: www.example.com
    # Or a record prefix ('' is the zone itself):
    prefix: www
    value:
      - 1.1.1.1
      - 8.8.8.8
如果您想断言某个记录具有特定值,请设置 on_existing=keep。如果发生这种情况,使用 keep_and_warn 将发出警告,而 keep_and_fail 将使模块失败。
要删除值,您可以将值覆盖为 [],或使用 state=absent。
- name: Remove A values for www.example.com
  community.dns.hetzner_dns_record_set:
    state: present
    zone_name: example.com
    type: A  # IPv4 addresses
    record: www.example.com
    value: []
- name: Remove TXT values for www.example.com
  community.dns.hetzner_dns_record_set:
    zone_name: example.com
    type: TXT
    prefix: www
    state: absent
- name: Remove specific AAAA values for www.example.com
  community.dns.hetzner_dns_record_set:
    zone_name: example.com
    type: AAAA  # IPv6 addresses
    prefix: www
    state: absent
    on_existing: keep_and_fail
    ttl: 300
    value:
      - '::1'
在第三个示例中,存在 on_existing=keep_and_fail,并给出了显式值和 TTL。这使得模块仅在 www.example.com 的 AAAA 记录的当前值为 ::1 且 TTL 为 300 时删除当前值。如果设置了另一个值,则该模块不会进行任何更改,但会失败。这对于避免意外删除您不想更改的值非常有用。要发出警告而不是失败,请使用 on_existing=keep_and_warn,而要简单地不进行任何更改而不指示这种情况,请使用 on_existing=keep。
批量同步 DNS 记录集
如果您想一次设置/更新多个记录,或者甚至确保您提供的精确记录集存在并且没有其他记录,则可以使用 community.dns.hetzner_dns_record_sets 模块。
以下示例显示了一次如何设置/更新多个记录
- name: Make sure that multiple records are present
  community.dns.hetzner_dns_record_sets:
    zone_name: example.com
    record_sets:
      - prefix: www
        type: A
        value:
          - 1.1.1.1
          - 8.8.8.8
      - prefix: www
        type: AAAA
        value:
          - '::1'
下一个示例显示了如何确保仅给定记录可用,并且所有其他记录都被删除。请注意,对于 record_sets[].type=NS 记录,我们使用了 record_sets[].ignore=true,这允许我们跳过该值。它告诉模块不应该触碰 example.com 的 NS 记录。
- name: Make sure that multiple records are present
  community.dns.hetzner_dns_record_sets:
    zone_name: example.com
    prune: true
    record_sets:
      - prefix: www
        type: A
        value:
          - 1.1.1.1
          - 8.8.8.8
      - prefix: www
        type: AAAA
        value:
          - '::1'
      - prefix: ''
        type: NS
        ignore: true
从 markuman.hetzner_dns 迁移
本节介绍如何将 playbook 和角色从使用 markuman.hetzner_dns 集合 迁移到 community.dns 集合中的 Hetzner 模块和插件。
迁移有三个步骤。其中两个步骤必须在迁移时完成,第三个步骤也可以稍后完成。
- 将使用的模块和插件替换为新的模块和插件。 
- 如果需要,调整模块和插件选项。 
- 避免使用已弃用的别名以简化过渡。 
markuman.hetzner_dns 集合 集合提供了三个模块和一个清单插件。
注意
使用 TXT 记录时,请查看 txt_transformation 选项。默认情况下,此集合中的模块和插件使用不带引号的值(您不必添加双引号和转义双引号和反斜杠),而 markuman.hetzner_dns 中的模块和插件使用部分带引号的值。您可以通过传递 txt_transformation=api 或 txt_transformation=quoted 来切换 community.dns 模块的行为。
markuman.hetzner_dns.record 模块
可以根据用途将 markuman.hetzner_dns.zone_info 模块替换为 community.dns.hetzner_dns_record 模块 和 community.dns.hetzner_dns_record_set 模块。
在创建、更新或删除单个记录时,应使用 community.dns.hetzner_dns_record 模块。当指定 purge=false(默认值)时,就是这种情况。请注意,replace、overwrite 和 solo 是 purge 的别名。
# Creating and updating DNS records
- name: Creating or updating a single DNS record with markuman.hetzner_dns
  markuman.hetzner_dns.record:
    zone_name: example.com
    name: localhost
    type: A
    value: 127.0.0.1
    ttl: 60
    # This means the module operates on single DNS entries. If not specified,
    # this is the default value:
    purge: false
- name: Creating or updating a single DNS record with community.dns
  community.dns.hetzner_dns_record:
    zone_name: example.com
    # 'state' must always be specified:
    state: present
    # 'name' is a deprecated alias of 'prefix', so it can be
    # kept during a first migration step:
    name: localhost
    # 'type', 'value' and 'ttl' do not change:
    type: A
    value: 127.0.0.1
    ttl: 60
    # If type is TXT, you either have to adjust the value you pass,
    # or keep the following option:
    txt_transformation: api
当 markuman.hetzner_dns.record 模块处于替换模式时,应将其替换为 community.dns.hetzner_dns_record_set 模块,因为它此时操作的是记录集,而不仅仅是单个记录。
# Creating and updating DNS record sets
- name: Creating or updating a record set with markuman.hetzner_dns
  markuman.hetzner_dns.record:
    zone_name: example.com
    name: localhost
    type: A
    value: 127.0.0.1
    ttl: 60
    # This means the module operates on the record set:
    purge: true
- name: Creating or updating a record set with community.dns
  community.dns.hetzner_dns_record_set:
    zone_name: example.com
    # 'state' must always be specified:
    state: present
    # 'name' is a deprecated alias of 'prefix', so it can be
    # kept during a first migration step:
    name: localhost
    # 'type' and 'ttl' do not change:
    type: A
    ttl: 60
    # 'value' is now a list:
    value:
      - 127.0.0.1
    # Ansible allows to specify lists as a comma-separated string.
    # So for records which do not contain a comma, you can also
    # keep the old syntax, in this case:
    #
    #     value: 127.0.0.1
    #
    # If type is TXT, you either have to adjust the value you pass,
    # or keep the following option:
    txt_transformation: api
删除记录时,取决于是否指定了 value。如果指定了 value,则该模块正在删除单个 DNS 记录,应使用 community.dns.hetzner_dns_record 模块。
# Deleting single DNS records
- name: Deleting a single DNS record with markuman.hetzner_dns
  markuman.hetzner_dns.record:
    zone_name: example.com
    state: absent
    name: localhost
    type: A
    value: 127.0.0.1
    ttl: 60
- name: Deleting a single DNS record with community.dns
  community.dns.hetzner_dns_record:
    zone_name: example.com
    state: absent
    # 'name' is a deprecated alias of 'prefix', so it can be
    # kept during a first migration step:
    name: localhost
    # 'type', 'value' and 'ttl' do not change:
    type: A
    value: 127.0.0.1
    ttl: 60
    # If type is TXT, you either have to adjust the value you pass,
    # or keep the following option:
    txt_transformation: api
当未指定 value 时,markuman.hetzner_dns.record 模块将删除此前缀和类型的所有记录。在这种情况下,它操作的是记录集,应使用 community.dns.hetzner_dns_record_set 模块。
# Deleting multiple DNS records
- name: Deleting multiple DNS records with markuman.hetzner_dns
  markuman.hetzner_dns.record:
    zone_name: example.com
    state: absent
    name: localhost
    type: A
- name: Deleting a single DNS record with community.dns
  community.dns.hetzner_dns_record_set:
    zone_name: example.com
    state: absent
    # 'name' is a deprecated alias of 'prefix', so it can be
    # kept during a first migration step:
    name: localhost
    # 'type' does not change:
    type: A
markuman.hetzner_dns.record_info 模块
markuman.hetzner_dns.record_info 模块可以被 community.dns.hetzner_dns_record_info 模块 替代。 主要区别在于,输出不再由 filters 选项控制,而是由 what 选项控制(选项包括 single_record、all_types_for_record 和 all_records),以及 type 选项(当 what=single_record 时需要),和 record 和 prefix 选项(当 what 不是 all_records 时需要)。
markuman.hetzner_dns.zone_info 模块
markuman.hetzner_dns.zone_info 模块可以被 community.dns.hetzner_dns_zone_info 模块 替代。 主要区别在于:
markuman.hetzner_dns.inventory 清单插件
markuman.hetzner_dns.inventory 清单插件可以被 community.dns.hetzner_dns_records 清单插件 替代。 除了插件名称之外,不需要进行任何更改。
