如何以级联方式删除 AWS Route 53 Hosted Zone(使用 AWS CLI)

发布: (2026年2月28日 GMT+8 13:12)
5 分钟阅读
原文: Dev.to

Source: Dev.to

AWS Route 53 中删除托管区域看似很简单……直到你遇到以下错误:

The hosted zone contains non‑required resource record sets

AWS 不会让你删除托管区域,除非先删除 所有非默认记录(即除 NSSOA 之外的所有记录)。本指南展示了如何使用 AWS CLI 以 级联方式 安全地删除托管区域。

为什么需要级联删除

当您创建托管区域时,Route 53 会自动创建:

  • NS 记录
  • SOA 记录

这两个记录是必需的,无法手动删除。在删除托管区域之前,您必须:

  • 删除所有自定义记录(AAAAACNAMEMXTXTALIAS 等)
  • 只保留 NSSOA
  • 然后删除托管区域

前置条件

  • 已安装 AWS CLI v2
  • 已安装 jq
  • IAM 权限:
    • route53:ListResourceRecordSets
    • route53:ChangeResourceRecordSets
    • route53:DeleteHostedZone
    • route53:GetHostedZone

级联删除脚本

创建一个名为 delete-hosted-zone-cascade.sh 的文件,并粘贴以下脚本:

#!/bin/bash

# ==========================================
# Script: delete-hosted-zone-cascade.sh
# Description:
#   Deletes all record sets in a Route53
#   hosted zone and then deletes the zone.
# ==========================================

set -euo pipefail

HOSTED_ZONE_ID="$1"
AWS_PROFILE="${2:-default}"

if [[ -z "$HOSTED_ZONE_ID" ]]; then
  echo "Usage: $0 <hosted_zone_id> [aws_profile]"
  exit 1
fi

echo "Using AWS Profile: $AWS_PROFILE"
echo "Target Hosted Zone: $HOSTED_ZONE_ID"

# Step 1: Get hosted zone name
ZONE_NAME=$(aws route53 get-hosted-zone \
  --id "$HOSTED_ZONE_ID" \
  --profile "$AWS_PROFILE" \
  --query 'HostedZone.Name' \
  --output text)

echo "Hosted Zone Name: $ZONE_NAME"

# Step 2: Fetch all record sets except default NS & SOA
echo "Fetching record sets..."

aws route53 list-resource-record-sets \
  --hosted-zone-id "$HOSTED_ZONE_ID" \
  --profile "$AWS_PROFILE" \
  --output json \
| jq '
  .ResourceRecordSets
  | map(select(.Type != "NS" and .Type != "SOA"))
  | map({
      Action: "DELETE",
      ResourceRecordSet: .
    })
  | {Changes: .}
' > changes.json

COUNT=$(jq '.Changes | length' changes.json)

if [[ "$COUNT" -eq 0 ]]; then
  echo "No non‑default records found."
else
  echo "Deleting $COUNT record sets..."

  aws route53 change-resource-record-sets \
    --hosted-zone-id "$HOSTED_ZONE_ID" \
    --change-batch file://changes.json \
    --profile "$AWS_PROFILE"

  sleep 10
fi

# Step 3: Delete hosted zone
echo "Deleting hosted zone..."

aws route53 delete-hosted-zone \
  --id "$HOSTED_ZONE_ID" \
  --profile "$AWS_PROFILE"

echo "Hosted zone $HOSTED_ZONE_ID deleted successfully."

rm -f changes.json

使用方法

使脚本可执行:

chmod +x delete-hosted-zone-cascade.sh

运行它:

./delete-hosted-zone-cascade.sh Z123456ABCDEFG traced
  • Z123456ABCDEFG → 您的托管区域 ID
  • traced → 可选的 AWS CLI 配置文件(默认是 default

脚本的作用(逐步说明)

1️⃣ 获取托管区域信息

aws route53 get-hosted-zone --id "$HOSTED_ZONE_ID"

2️⃣ 列出所有记录集

aws route53 list-resource-record-sets --hosted-zone-id "$HOSTED_ZONE_ID"

3️⃣ 使用 jq 过滤掉 NSSOA

仅将 NS SOA 的记录转换为删除操作。

4️⃣ 提交批量删除

aws route53 change-resource-record-sets \
  --hosted-zone-id "$HOSTED_ZONE_ID" \
  --change-batch file://changes.json

5️⃣ 删除托管区域

aws route53 delete-hosted-zone --id "$HOSTED_ZONE_ID"

重要说明

  • 这将永久删除所有 DNS 记录;此操作无法撤销。
  • 如果已启用 DNSSEC,请在运行脚本之前将其禁用。
  • 对于私有托管区域,请确保 VPC 关联得到适当处理。

何时适用?

  • CI/CD 清理临时环境
  • 销毁短暂的测试堆栈
  • Terraform 漂移修复
  • 多账户迁移
  • 退役整个 AWS 组织账户

生产硬化建议

  • 在继续之前添加确认提示。
  • 使用 aws route53 get-change 等待更改状态。
  • 将删除操作记录到文件或监控系统。
  • 实现 --dry-run 模式以预览删除操作。
  • 为记录数量庞大的区域处理分页。

最后思考

手动删除 Amazon Route 53 中的 DNS 记录既繁琐又容易出错。自动化级联删除:

  • 节省时间
  • 防止错误
  • 使账户清理可预测
  • 自然地融入自动化流水线
0 浏览
Back to Blog

相关文章

阅读更多 »