

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將大量 DNS 記錄遷移至 Amazon Route 53 私有託管區域
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone"></a>

*Ram Kandaswamy，Amazon Web Services*

## 摘要
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-summary"></a>

此模式會自動將 DNS 記錄大量遷移到 Amazon Route 53 託管區域。它使用 Python 指令碼搭配適用於 Python 的 AWS SDK (Boto3)，從存放在 Amazon Simple Storage Service (Amazon S3) 中的 JSON 檔案讀取記錄資料，並使用 Route 53 API 以程式設計方式建立記錄。

如果您的來源系統匯出標準 BIND 區域檔案，Route 53 原生匯入功能或 [cli53 ](https://github.com/barnybug/cli53)（與 無關的社群維護開放原始碼 CLI 工具 AWS) 可以處理遷移，而無需自訂指令碼。不過，在許多企業環境中，DNS 記錄都存在於 Excel 工作表中，而不是區域檔案。Excel 匯出通常包含非中斷空間和 Unicode 字元等資料品質問題，標準匯入工具不會處理這些問題。此模式可解決該差距：它會從 Excel 讀取並清除資料，以end-to-end建立記錄。

當您需要將大量 DNS 記錄從現有系統遷移到 Route 53 託管區域，而無需透過主控台手動建立每個記錄時，請使用此模式。

## 先決條件和限制
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-prereqs"></a>

**先決條件**
+ 作用中的 AWS 帳戶
+ 包含託管區域記錄的 Excel 工作表，其中包含完整網域名稱 (FQDN)、記錄類型、存留時間 (TTL) 和值的資料欄
+ Python 3.12 或更新版本 （請參閱[下載 Python](https://www.python.org/downloads/))
+ 已安裝 pandas Python 程式庫 (`pip3 install pandas`)
+ 熟悉 DNS 記錄類型，例如 A、NAPTR 和 SRV 記錄 （請參閱[支援的 DNS 記錄類型](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html))
+ 熟悉 Python 語言及其程式庫

**限制**
+ 此模式不會使用 `change_resource_record_sets` API 呼叫的所有可用屬性。根據您的使用案例視需要擴展程式碼。
+ 在 Excel 工作表中，假設每一列中的值是唯一的。每個 FQDN 的多個值預期會出現在相同的資料列中。如果不是這種情況，請修改程式碼來串連相同 FQDN 的多個值。
+ 此模式使用 Boto3 直接呼叫 Route 53 API。 Boto3 您可以增強程式碼以使用 `create_stack`和 `update_stack`命令的 AWS CloudFormation 包裝函式，並使用 JSON 值填入範本資源。
+ 如果您的來源系統可以 BIND 區域檔案格式匯出記錄，請考慮改用 Route 53 匯入功能。
+ 有些 AWS 服務無法全部使用 AWS 區域。如需區域可用性，請參閱 AWS[依區域列出的 服務](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。如需特定端點，請參閱[服務端點和配額](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)頁面，然後選擇服務的連結。

## Architecture
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-architecture"></a>



![](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/a81c29ea-f0c5-4d4a-ba87-93111a0f1ee9/images/e5c65fa5-346e-4a24-bddf-a523f30afa95.png)


1. 使用者將具有 DNS 記錄資料的 Excel 工作表上傳至 Amazon S3 儲存貯體。

1. 在本機 （或在 Kiro 等 IDE 中） 執行的 Python 指令碼會使用 Boto3 從 Amazon S3 儲存貯體讀取 JSON 檔案。

1. 指令碼會處理記錄並呼叫 Route 53 `change_resource_record_sets` API 操作，以在託管區域中建立記錄。

## 工具
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-tools"></a>

*AWS 服務*
+ [Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) –  提供建立 DNS 記錄的託管區域。此模式使用 `create_hosted_zone`和 `change_resource_record_sets` API 操作。
+ [Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) - 存放 JSON 檔案，其中包含要遷移的 DNS 記錄資料。

*其他工具*
+ **Kiro** — 具有代理式 AI 功能的 IDE，用於開發和執行 Python 遷移指令碼。如需詳細資訊，請參閱 [Kiro](https://kiro.dev/)。
+ **pandas** — Python 資料分析程式庫，用於將 Excel 工作表轉換為 JSON 格式。

## 最佳實務
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-best-practices"></a>
+ 在對所有記錄執行指令碼之前，使用 5-10 個記錄的小子集進行測試，以驗證資料格式和正確的記錄建立。
+ 使用 `UPSERT`動作，而非 `CREATE`。如果記錄不存在，`UPSERT`則動作會建立記錄，如果記錄不存在，則會對其進行更新。這可讓指令碼具有等冪性且安全地重新執行。
+ [將您的變更批次](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests-changeresourcerecordsets)處理，以保持在`ChangeResourceRecordSets`請求限制內。當您使用 `UPSERT`動作時，每個`ResourceRecord`元素會計入最多 1，000 個元素。
+ [插入前驗證資料](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html)。確認 FQDNs以句點 (`.`) 結尾、TTL 值為正整數，且記錄類型符合支援的 DNS 記錄類型。
+ [在您進行大量變更之前，請先備份現有的記錄](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53.html#Route53.Client.list_resource_record_sets)。使用 匯出目前的託管區域記錄`list_resource_record_sets`，以提供轉返點。
+ 實作具有指數退避的重試邏輯，以處理 Route 53 API 速率限制。如需詳細資訊，請參閱[錯誤重試和指數退避 AWS](https://docs.aws.amazon.com/general/latest/gr/api-retries.html)。
+ 遵循最低權限原則，並授予執行任務所需的最低許可。如需詳細資訊，請參閱《 AWS Identity and Access Management (IAM) 文件》中的[授予最低權限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)和[安全最佳實務](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

## 史詩
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-epics"></a>

### 準備資料以進行自動化
<a name="prepare-data-for-automation"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 為您的記錄建立 Excel 檔案。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)範例資料列：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html) | 資料工程師 | 
| 將 Excel 工作表資料轉換為 JSON。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)<pre>import pandas as pd<br /><br />data=pd.read_excel('./Book1.xls')<br />data.to_json(path_or_buf='my.json',orient='records')</pre>[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html) | 資料工程師，Python 開發人員 | 
| 將 JSON 檔案上傳至 Amazon S3 儲存貯體。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html) | 應用程式開發人員 | 
| FqdnName | RecordType | Value | TTL | 
| something.example.org | A | 192.0.2.1 | 900 | 

### 將記錄插入託管區域
<a name="insert-records-into-the-hosted-zone"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 建立託管區域。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)<pre>import boto3<br />import random<br /><br />hostedZoneName ="xxx"<br />vpcRegion = "us-east-1"<br />vpcId="vpc-xxxx"<br />route53_client = boto3.client('route53')<br />response = route53_client.create_hosted_zone(<br />        Name= hostedZoneName,<br />        VPC={<br />            'VPCRegion': vpcRegion,<br />            'VPCId': vpcId<br />        },<br />        CallerReference=str(random.random()*100000),<br />        HostedZoneConfig={<br />            'Comment': "private hosted zone created by automation",<br />            'PrivateZone': True<br />        }<br />    )<br /><br /> print(response)</pre>[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)您也可以使用基礎設施做為程式碼 (IaC) 工具，例如 AWS CloudFormation ，將這些步驟取代為使用適當資源和屬性建立堆疊的範本。如需詳細資訊，請參閱 CloudFormation 文件中的 [AWS Route 53：：HostedZone](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-route53-hostedzone.html)。 | 雲端架構師、網路管理員、Python 技能 | 
| 從 Amazon S3 讀取 JSON 資料。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)<pre>import json<br />import boto3<br /><br />s3_client = boto3.client('s3')<br />fileobj = s3_client.get_object(<br />    Bucket='<your-bucket-name>',<br />    Key='my.json'<br />)<br /><br />filedata = fileobj['Body'].read()<br />contents = filedata.decode('utf-8')<br />json_content = json.loads(contents)</pre>[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html) | 應用程式開發人員、Python 開發人員 | 
| 清除資料值並插入記錄。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html)<pre>import unicodedata<br />import time<br /><br />for item in json_content:<br />    fqn_name = unicodedata.normalize(<br />        "NFKD",<br />        item["FqdnName"].replace("u'", "'").replace('\xa0', '').strip()<br />    )<br />    rec_type = item["RecordType"].replace('\xa0', '').strip()<br />    res_rec = {'Value': item["Value"].replace('\xa0', '').strip()}<br /><br />    change_response = route53_client.change_resource_record_sets(<br />        HostedZoneId='<hosted-zone-id>',<br />        ChangeBatch={<br />            'Comment': 'Created by automation',<br />            'Changes': [<br />                {<br />                    'Action': 'UPSERT',<br />                    'ResourceRecordSet': {<br />                        'Name': fqn_name,<br />                        'Type': rec_type,<br />                        'TTL': item["TTL"],<br />                        'ResourceRecords': [res_rec]<br />                    }<br />                }<br />            ]<br />        }<br />    )<br /><br />    time.sleep(1)  # Delay to avoid PriorRequestNotComplete errors</pre>[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone.html) | 應用程式開發人員、Python 技能 | 

## 疑難排解
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| `PriorRequestNotComplete` 錯誤  | 在`change_resource_record_sets`通話之間新增 1–2 秒的`time.sleep()`延遲。Route 53 程序會以非同步方式變更，先前的變更可能仍在進行中。 | 
| `InvalidChangeBatch` 錯誤 | 當您嘗試使用 `CREATE`動作建立已存在的記錄時，就會發生此錯誤。請`UPSERT`改用 讓指令碼成為等冪。 | 
| 調節錯誤 （超過速率限制）  | 您已超過每秒五個 API 請求。使用抖動實作指數退避。如需詳細資訊，請參閱[錯誤重試和指數退避 AWS](https://docs.aws.amazon.com/general/latest/gr/api-retries.html)。 | 
| 記錄未解析 | 確認 VPC 與託管區域相關聯，且已在 VPC 上啟用 DNS 解析。`enableDnsSupport` 和 `enableDnsHostnames` 必須同時設定為 `true`。 | 
| `InvalidInput` 記錄值發生錯誤 | 資料包含非中斷空格 (`\xa0`) 或前置/追蹤空格。在插入之前，套用來自「清除資料值和插入記錄」任務的資料清理程式碼。 | 

## 相關資源
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-resources"></a>

**參考**
+ [透過匯入區域檔案建立記錄 ](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating-import.html)(Route 53 文件）
+ [create\_hosted\_zone](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53/client/create_hosted_zone.html) (Boto3 文件）
+ [change\_resource\_record\_sets](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53/client/change_resource_record_sets.html) (Boto3 文件）
+ [支援的 DNS 記錄類型](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html) ( Route 53 文件）
+ [中的錯誤重試和指數退避 AWS](https://docs.aws.amazon.com/general/latest/gr/api-retries.html)

**教學課程和影片 **

[使用 Amazon Route 53 的 DNS 設計](https://www.youtube.com/watch?v=example) （影片）

## 其他資訊
<a name="migrate-dns-records-in-bulk-to-an-amazon-route-53-private-hosted-zone-additional"></a>

對於 NAPTR 和 SRV 記錄，Excel 工作表中的 `Value` 欄位必須包含串連為單一字串的所有必要元件。在匯出至 JSON 之前，使用 Excel 的 CONCAT 函數合併個別屬性 （訂單、偏好設定、旗標、服務、regexp、取代 NAPTR； 優先順序、權重、連接埠、SRV 目標）。

如果您的遷移涉及超過 1，000 個記錄，請將 JSON 檔案分割為批次，並分別處理每個批次，以保持在 Route 53 API 限制內。當您使用 `UPSERT`動作時，每個`ResourceRecord`元素會計入每個`ChangeResourceRecordSets`請求的 1，000 個元素上限兩次。

## 附件
<a name="attachments-a81c29ea-f0c5-4d4a-ba87-93111a0f1ee9"></a>

若要存取與本文件相關聯的其他內容，請下載並解壓縮下列檔案： [attachment.zip](samples/p-attach/a81c29ea-f0c5-4d4a-ba87-93111a0f1ee9/attachments/attachment.zip)