AWS CLI CloudFront delete-distribution 完整指南:禁用、ETag 校验与安全删除
【免费下载链接】aws-cliUniversal Command Line Interface for Amazon Web Services项目地址: https://gitcode.com/GitHub_Trending/aw/aws-cli
本指南以 aws-cli 仓库中的官方示例 delete-distribution.rst 为主体,系统讲解如何通过 AWS CLI 安全删除 CloudFront 分发(Distribution):包括"必须先禁用再删除"的前置条件、如何通过update-distribution禁用、如何用get-distribution/get-distribution-config获取 ETag,以及delete-distribution命令的参数、底层 HTTP 语义与常见错误排查。读完本文,你将掌握一条可复现、可排错的 CloudFront 删除实战流程。
删除 CloudFront 分发的前置条件:必须先禁用
在 aws-cli 仓库的示例文档中明确指出,删除分发不是一步到位的操作:
Before you can delete a distribution, you must disable it.
CloudFront 出于安全设计,不允许直接删除一个处于启用状态(Enabled: true)的分发。官方底层 API 文档(服务模型)也给出了同样的强调说明:
Before you can delete a distribution, you must disable it, which requires permission to update the distribution. Once deleted, a distribution cannot be recovered.
这段说明出自仓库内的服务模型文件 service-2.json(DeleteDistribution操作的documentation字段),同时提醒了两个关键点:
- 禁用操作本身需要
cloudfront:UpdateDistribution权限,没有该权限将无法完成删除链路; - 删除操作不可逆,分发一旦删除无法恢复,请务必在删除前确认该分发已不再承担流量。
禁用分发需要用到update-distribution命令,官方示例见 update-distribution.rst。
完整删除链路:从禁用、取 ETag 到删除
服务模型 service-2.json 中DeleteDistributionRequest的文档部分,给出了官方推荐的 8 步 API 级删除流程,用 CLI 视角可以归纳为三个阶段:
- 禁用分发(Disable):将分发的
Enabled字段改为false并提交更新,等待传播完成(Status变为Deployed); - 获取 ETag(Get):通过
get-distribution或get-distribution-config拿到当前分发的ETag; - 删除分发(Delete):携带 ETag 调用
delete-distribution,确认删除成功。
下面按阶段给出完整可运行的 CLI 操作。
第一阶段:用 update-distribution 禁用分发
官方示例中,禁用分发需要同时提供--id、--if-match和--distribution-config。其中--distribution-config通过 JSON 文件传入完整配置,核心是把 JSON 中的Enabled字段改为false:
aws cloudfront update-distribution \ --id EMLARXS9EXAMPLE \ --if-match E2QWRUHEXAMPLE \ --distribution-config file://dist-config-disable.jsondist-config-disable.json的关键片段(完整文件见 update-distribution.rst 示例 2):
{ "CallerReference": "cli-1574382155-496510", "Origins": { "Quantity": 1, "Items": [ { "Id": "amzn-s3-demo-bucket.s3.amazonaws.com-1574382155-273939", "DomainName": "amzn-s3-demo-bucket.s3.amazonaws.com", "S3OriginConfig": { "OriginAccessIdentity": "" } } ] }, "DefaultCacheBehavior": { "TargetOriginId": "amzn-s3-demo-bucket.s3.amazonaws.com-1574382155-273939", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" } }, "ViewerProtocolPolicy": "allow-all" }, "Comment": "", "PriceClass": "PriceClass_All", "Enabled": false, "HttpVersion": "http2", "IsIPV6Enabled": true }注意:--distribution-config要求的是完整的 DistributionConfig(而非仅Enabled字段)。实践中可以从get-distribution-config的输出中提取当前完整配置,修改Enabled后再回传,避免因缺少必填字段导致校验失败。
update-distribution成功后会返回新的ETag(例如E9LHASXEXAMPLE)与分发对象,此时Distribution.Status为InProgress,需要等待 CloudFront 完成全局传播,直到再次查询时Status变为Deployed才能执行删除。
第二阶段:用 get-distribution / get-distribution-config 获取 ETag
删除分发必须提供分发的ETag。官方示例文档给出的获取方式是:
To get the ETag, use the
get-distributionorget-distribution-configcommand.
两个命令的用法一致(示例见 get-distribution.rst 与 get-distribution-config.rst):
aws cloudfront get-distribution \ --id EDFDVBD6EXAMPLEaws cloudfront get-distribution-config \ --id EDFDVBD6EXAMPLE两者都会在响应中返回顶层ETag字段。例如:
{ "ETag": "E2QWRUHEXAMPLE", "Distribution": { "Id": "EDFDVBD6EXAMPLE", "Status": "Deployed", "DomainName": "d111111abcdef8.cloudfront.net" } }两者的区别在于:get-distribution返回ETag+ 完整的Distribution对象(含运行时状态如Status、LastModifiedTime);get-distribution-config返回ETag+ 纯DistributionConfig(适合直接作为--distribution-config的修改底稿)。
关于分发 ID:示例文档说明,分发 ID 来自create-distribution或list-distributions命令的返回结果,这一点在 get-distribution.rst 中有明确记载。
delete-distribution 命令实战
官方示例 delete-distribution.rst 给出的删除命令如下:
aws cloudfront delete-distribution \ --id EDFDVBD6EXAMPLE \ --if-match E2QWRUHEXAMPLE参数说明:
| 参数 | 必填 | 说明 |
|---|---|---|
--id | 是 | 要删除的 CloudFront 分发 ID,例如EDFDVBD6EXAMPLE |
--if-match | 建议必填 | 分发的ETag值,例如E2QWRUHEXAMPLE;取自禁用后get-distribution/get-distribution-config的返回 |
官方文档对--if-match的取值有精确描述:它是禁用分发时收到的那份ETag。服务模型中IfMatch成员的说明为:
The value of the
ETagheader that you received when you disabled the distribution.
即正确姿势是:禁用 → 重新获取 ETag → 用新 ETag 删除,而不是复用创建时的旧值。
命令成功时没有任何输出(原文档原文:When successful, this command has no output)。这与服务模型中的 HTTP 语义完全吻合——见下文底层实现。
底层实现:HTTP DELETE 与 204 No Content
在仓库的 CloudFront 服务模型 service-2.json 中,DeleteDistribution操作的定义如下:
{ "name": "DeleteDistribution2020_05_31", "http": { "method": "DELETE", "requestUri": "/2020-05-31/distribution/{Id}", "responseCode": 204 } }从源码结构可以确认三个关键事实:
- 请求方式:CLI 内部将该命令映射为一次
HTTP DELETE请求,目标 URI 为/2020-05-31/distribution/{Id},分发 ID 直接嵌入 URL 路径; - 无输出原因:成功的响应码是
204 No Content,响应体为空,这正是"命令成功时没有输出"的底层依据; - 参数落点:
Id是 URI 路径参数(location: uri,locationName: Id);IfMatch是 HTTP 请求头参数(location: header,locationName: If-Match),CLI 的--if-match最终以If-Match请求头发送给 CloudFront,用于服务端做乐观并发控制(Precondition)。
另外,仓库的 cloudfront/data 目录下保留了从2014-05-31到2020-05-31共 19 个 API 版本的服务模型,当前 CLI 默认采用2020-05-31版本。不同版本的DeleteDistribution请求语义一致(均为 DELETE + 204),这也保证了脚本跨版本升级的兼容性。
错误码与排查指引
服务模型为DeleteDistribution定义了 6 个异常 shape("exception": true),CLI 遇到失败时会抛出对应的客户端异常。逐一说明触发场景:
| 错误 | 含义(来自服务模型) | 排查建议 |
|---|---|---|
DistributionNotDisabled | 指定的分发未禁用,必须先禁用才能删除 | 先执行update-distribution将Enabled置为false并等待Status变为Deployed |
PreconditionFailed | 请求字段中的前置条件求值为 false | 检查--if-match提供的 ETag 是否为最新值,ETag 过期/不匹配会触发该错误 |
InvalidIfMatchVersion | If-Match版本缺失或无效 | 确认 ETag 来自get-distribution/get-distribution-config的合法返回 |
NoSuchDistribution | 指定的分发不存在 | 核对--id是否正确,可用list-distributions确认 |
ResourceInUse | 资源正在使用中,无法删除 | 检查该分发是否仍被引用(例如仍有关联配置或资源在占用) |
AccessDenied | 访问被拒绝 | 确认 IAM 权限,需要包含cloudfront:DeleteDistribution,且禁用步骤还需要cloudfront:UpdateDistribution |
最常见的失败场景是遗漏--if-match。虽然服务模型中仅Id是必填项、IfMatch为可选,但官方示例与文档都强调删除时必须携带--if-match——不携带或携带过期 ETag 会导致前置条件校验失败,CloudFront 出于并发安全考虑拒绝删除。
完整操作清单:一条可复现的删除流程
综合以上所有步骤,给出一次完整的端到端操作序列:
# 1. 查看分发 ID(或从 create-distribution 输出中获取) aws cloudfront list-distributions # 2. 获取当前配置与 ETag,作为禁用修改的底稿 aws cloudfront get-distribution-config --id EDFDVBD6EXAMPLE # 3. 将 Enabled 改为 false,写入 dist-config-disable.json 后禁用分发 aws cloudfront update-distribution \ --id EDFDVBD6EXAMPLE \ --if-match E2QWRUHEXAMPLE \ --distribution-config file://dist-config-disable.json # 4. 等待传播完成(Status 变为 Deployed) aws cloudfront get-distribution --id EDFDVBD6EXAMPLE # 5. 重新获取最新 ETag(禁用后返回的新 ETag) aws cloudfront get-distribution --id EDFDVBD6EXAMPLE # 6. 携带最新 ETag 删除分发(成功时无输出) aws cloudfront delete-distribution \ --id EDFDVBD6EXAMPLE \ --if-match E9LHASXEXAMPLE需要强调的最后一点:删除不可逆。DeleteDistribution的服务模型文档(service-2.json)明确标注 "Once deleted, a distribution cannot be recovered.",因此生产环境中建议在删除前先记录分发配置(get-distribution-config输出留档),并确认域名流量已切换或终止。
【免费下载链接】aws-cliUniversal Command Line Interface for Amazon Web Services项目地址: https://gitcode.com/GitHub_Trending/aw/aws-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考