View a markdown version of this page

将 DNS 记录批量迁移至 Amazon Route 53 私有托管区 - AWS 规范指引

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 DNS 记录批量迁移至 Amazon Route 53 私有托管区

Ram Kandaswamy,Amazon Web Services

Summary

这种模式可自动将 DNS 记录批量迁移到 Amazon Route 53 托管区域。它使用带有 Python AWS 软件开发工具包 (Boto3) 的 Python 脚本从存储在亚马逊简单存储服务 (Amazon S3) 的 JSON 文件中读取记录数据,然后使用 Route 53 API 以编程方式创建记录。

如果您的源系统导出标准的 BIND 区域文件,那么 Route 53 原生导入功能或 c li53(社区维护的开源 CLI 工具,不隶属于 AWS)无需自定义脚本即可处理迁移。但是,在许多企业环境中,DNS 记录存在于 Excel 工作表中,而不是区域文件中。Excel 导出通常包含标准导入工具无法处理的数据质量问题,例如不间断空格和 Unicode 字符。这种模式解决了这一差距:它从 Excel 读取数据并清理数据以创建端到端的记录。

如果您需要将大量 DNS 记录从现有系统迁移到 Route 53 托管区域,而无需通过控制台手动创建每条记录,请使用此模式。

先决条件和限制

先决条件

  • 一个活跃的 AWS 账户

  • 包含托管区域记录的 Excel 工作表,其中包含完全限定域名 (FQDN)、记录类型、生存时间 (TTL) 和值列

  • Python 3.12 或更高版本(参见下载 Python

  • 熊猫 Python 库已安装 () pip3 install pandas

  • 熟悉 DNS 记录类型,例如 A、NAPTR 和 SRV 记录(请参阅支持的 DNS 记录类型)

  • 熟悉 Python 语言及其库

限制

  • 此模式不使用 change_resource_record_sets API 调用的所有可用属性。根据您的用例的需要扩展代码。

  • 在 Excel 工作表中,假定每行中的值是唯一的。每个 FQDN 的多个值应出现在同一行中。如果不是这样,请修改代码以连接同一 FQDN 的多个值。

  • 此模式使用 Boto3 直接调用 Route 53 API。您可以增强代码以使用create_stackupdate_stack命令的 AWS CloudFormation 包装器,并使用 JSON 值填充模板资源。

  • 如果您的源系统可以以 BIND 区域文件格式导出记录,请考虑改用 Route 53 导入功能。

  • 有些 AWS 服务并非全部可用 AWS 区域。有关区域可用性,请参阅按地区划分的 AWS服务。有关特定端点,请参阅服务端点和配额页面,然后选择相应服务的链接。

架构

  1. 用户将包含 DNS 记录数据的 Excel 工作表上传到亚马逊 S3 存储桶。

  2. 在本地(或在像 Kiro 这样的 IDE 中)运行的 Python 脚本使用 Boto3 从 Amazon S3 存储桶中读取 JSON 文件。

  3. 该脚本处理记录并调用 Route 53 change_resource_record_sets API 操作在托管区域中创建记录。

工具

AWS 服务

  • Route 53-提供创建 DNS 记录的托管区域。此模式使用create_hosted_zonechange_resource_record_sets API 操作。

  • Amazon S3-存储包含要迁移的 DNS 记录数据的 JSON 文件。

其他工具

  • Kiro — 具有代理人工智能功能的 IDE,用于开发和运行 Python 迁移脚本。有关更多信息,请参阅 Kiro。

  • p@@ andas — 一个 Python 数据分析库,用于将 Excel 工作表转换为 JSON 格式。

最佳实践

  • 在对所有记录运行脚本之前,先对一小部分 5-10 条记录进行测试,以验证数据格式并正确创建记录。

  • 使用UPSERT操作代替CREATE。如果记录不存在,则该UPSERT操作会创建记录,如果记录存在,则会对其进行更新。这使得脚本是等效的,可以安全地重新运行。

  • Batch 更改以保持在ChangeResourceRecordSets请求限制之内。使用该UPSERT操作时,每个ResourceRecord元素的计数会在 1,000 个元素的最大值中计数两次。

  • 在插入数据之前验证数据。验证 FQDN 是否以句点 (.) 结尾,TTL 值是否为正整数,以及记录类型是否与支持的 DNS 记录类型相匹配。

  • 在进行批量更改之前,请@@ 备份现有记录。使用list_resource_record_sets提供回滚点来导出当前托管区域记录。

  • 使用指数退避实现重试逻辑,以处理 Route 53 API 速率限制。有关更多信息,请参阅中的错误重试和指数退缩。 AWS

  • 遵循最低权限原则,并授予执行任务所需的最低权限。有关更多信息,请参阅 AWS Identity and Access Management (IAM) 文档中的授予最低权限安全最佳实践

操作说明

Task说明所需技能

创建一个 Excel 文件作为记录。

  1. 从您当前的 DNS 系统中导出记录。

  2. 使用以下列创建一个 Excel 工作表:FqdnNameRecordType、、ValueTTL

  3. 对于 NAPTR 和 SRV 记录,请使用 Excel 的 CONCAT 函数将多个属性值合并到列中。Value

  4. 验证每个 FQDN 是否以句点 (.) 结尾,并且 TTL 值是否为正整数。

示例行:

FqdnName

RecordType

TTL

something.example.org

A

192.0.2.1

900

数据工程师

将 Excel 工作表数据转换为 JSON。

  1. 通过在终端python3 --version中运行来验证 Python 3.12 或更高版本是否已安装。

  2. 通过在终端pip3 install pandas --user中运行来安装 pandas 库。

  3. 使用以下代码创建 Python 文件,将 Excel 工作表转换为 JSON:

import pandas as pd data=pd.read_excel('./Book1.xls') data.to_json(path_or_buf='my.json',orient='records')
  1. 运行 脚本。验证输出文件是否my.json包含预期的记录。

数据工程师、Python 开发者

将 JSON 文件上传到亚马逊 S3 存储桶。

  1. 如果尚不存在一个 Amazon S3 存储桶,请创建一个。有关更多信息,请参阅 Amazon S3 文档中的创建存储桶

  2. my.json文件上传到存储桶。

应用程序开发人员
Task说明所需技能

创建一个托管区域。

  1. 使用以下代码创建 Python 文件以创建托管区域。用您的值替换<hosted-zone-name><vpc-region>、和<vpc-id>

import boto3 import random hostedZoneName ="xxx" vpcRegion = "us-east-1" vpcId="vpc-xxxx" route53_client = boto3.client('route53') response = route53_client.create_hosted_zone( Name= hostedZoneName, VPC={ 'VPCRegion': vpcRegion, 'VPCId': vpcId }, CallerReference=str(random.random()*100000), HostedZoneConfig={ 'Comment': "private hosted zone created by automation", 'PrivateZone': True } ) print(response)
  1. 运行脚本并记下响应中的托管区域 ID。

您也可以使用基础设施即代码 (IaC) 工具,例如 AWS CloudFormation 将这些步骤替换为使用适当资源和属性的堆栈的模板。有关更多信息,请参阅 CloudFormation 文档HostedZone中的 AWS Route 53::

云架构师、网络管理员、Python 技能

读取 Amazon S3 中的 JSON 数据。

  1. 使用此代码从 Amazon S3 存储桶中读取数据并将其作为 Python 字典加载。 

import json import boto3 s3_client = boto3.client('s3') fileobj = s3_client.get_object( Bucket='<your-bucket-name>', Key='my.json' ) filedata = fileobj['Body'].read() contents = filedata.decode('utf-8') json_content = json.loads(contents)
  1. 通过打印前几个条目来验证是否json_content包含预期的记录。

应用程序开发者、Python 开发者

清理数据值并插入记录。

  1. 使用此代码清理数据值并将记录插入托管区域。<hosted-zone-id>替换为先前配置的托管区域中的 ID。

import unicodedata import time for item in json_content: fqn_name = unicodedata.normalize( "NFKD", item["FqdnName"].replace("u'", "'").replace('\xa0', '').strip() ) rec_type = item["RecordType"].replace('\xa0', '').strip() res_rec = {'Value': item["Value"].replace('\xa0', '').strip()} change_response = route53_client.change_resource_record_sets( HostedZoneId='<hosted-zone-id>', ChangeBatch={ 'Comment': 'Created by automation', 'Changes': [ { 'Action': 'UPSERT', 'ResourceRecordSet': { 'Name': fqn_name, 'Type': rec_type, 'TTL': item["TTL"], 'ResourceRecords': [res_rec] } } ] } ) time.sleep(1) # Delay to avoid PriorRequestNotComplete errors
  1. 监视输出是否存在错误。如果出现节流,请增加延迟或实施指数退缩。

应用程序开发人员,Python 技能

问题排查

问题解决方案

PriorRequestNotComplete错误

在两次通话之间change_resource_record_sets增加 1—2 秒的time.sleep()延迟。Route 53 以异步方式处理更改,之前的更改可能仍在进行中。

InvalidChangeBatch错误

当您尝试使用CREATE操作创建已存在的记录时,就会发生此错误。UPSERT改为使用使脚本具有等性。

限制错误(超出速率限制)

您已超过每秒 5 个 API 请求。使用抖动实现指数回退。有关更多信息,请参阅中的错误重试和指数退缩。 AWS

记录无法解析

验证 VPC 是否与托管区域关联,并且已在 VPC 上启用 DNS 解析。enableDnsSupport和都enableDnsHostnames必须设置为true

InvalidInput记录值出现错误

数据包含不间断空格 (\xa0) 或 leading/trailing 空格。在插入之前,应用 “清理数据值并插入记录” 任务中的数据清理代码。

相关资源

参考

教程和视频

使用 Amazon Route 53 进行 DNS 设计(视频)

附加信息

对于 NAPTR 和 SRV 记录,Excel 工作表中的Value字段必须包含连接成单个字符串的所有必需组件。在导出为 JSON 之前,使用 Excel 的 CONCAT 函数合并各个属性(顺序、首选项、标志、服务、正则表达式、NAPTR 的替换;SRV 的优先级、权重、端口、目标)。

如果您的迁移涉及超过 1,000 条记录,请将 JSON 文件分成批次,然后分别处理每个批次,以保持在 Route 53 API 限制范围内。使用该UPSERT操作时,每个ResourceRecord元素在每次请求的最大值 1,000 个元素之间计数两次。ChangeResourceRecordSets

附件

要访问与此文档相关联的其他内容,请解压以下文件:attachment.zip