如何解决在为 CloudFront 分配设置 CNAME 别名时出现的 CNAMEAlreadyExists 错误?

2 分钟阅读
0

在为 Amazon CloudFront 分配设置规范名称记录(CNAME)别名时,我收到“CNAMEAlreadyExists”错误。

简短描述

您不能对多个 CloudFront 分配使用相同的 CNAME 别名。当您尝试添加的 CNAME 别名已经与另一个 CloudFront 分配关联时,您会收到错误:

“您提供的一个或多个 CNAME 已经与其他资源关联。(服务: AmazonCloudFront;状态代码: 409;错误代码: CNAMEAlreadyExists;请求 ID:a123456b-c78d-90e1-23f4-gh5i67890jkl*"

如果您有权访问源和目标分配,则手动从现有 CloudFront 分配中删除 CNAME 关联。然后,将 CNAME 与新的 CloudFront 分配关联。

注意:如果您要手动关联 CNAME,则可能需要等到旧分配的状态为已部署后才能继续。

如果您不知道分配 ID,则可以使用 ListConflictingAliases CloudFront API。这使您可以查找有关分配的部分信息,以及冲突的 CNAME 别名的账户 ID。然后,使用 AssociateAlias API 将您的 CNAME 从现有分配(源分配)移至新分配(目标分配)。根据您的场景使用以下解决方法之一:

  • 对于同一账户中的源和目标分配,请参阅使用 AssociateAlias API 移动 CNAME 部分。
  • 有关跨账户的源和目标分配,请参阅停用具有冲突 CNAME 的源分配部分。
  • 如果由于现有流量停机而无法停用源分配,请参阅使用通配符移动备用域名
    **注意:**您不能使用通配符来移动顶点域(example.com)。要在源分配和目标分配位于不同的 AWS 账户中时移动顶点域,请联系 AWS Support 以移动备用域名

解决方法

使用 AssociateAlias API 移动 CNAME

注意: 如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请确保您使用的是最新的 AWS CLI 版本

1.    在发出 API 请求的用户或角色的 AWS Identity and Access Management(IAM)策略中,添加以下资源级别的权限:

重要事项: 提出请求的 IAM 用户或角色必须在源分配和目标分配中拥有这些资源级别的权限。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudFrontCnameSwapSameAcc",
      "Effect": "Allow",
      "Action": [
        "cloudfront:GetDistribution",
        "cloudfront:ListConflictingAliases",
        "cloudfront:AssociateAlias",
        "cloudfront:UpdateDistribution"
      ],
      "Resource": [
        "arn:aws:cloudfront::SourceAcccount:distribution/SourceDistroID",
        "arn:aws:cloudfront::TargetAccount:distribution/TargetDistroID"
      ]
    }
  ]
}

**注意:**将 SourceAcccount 替换为源分配的 AWS 账号。将 SourceDistroID 替换为源分配 ID。将 TargetAccountID 替换为目标分配的 AWS 账号。将 TargetDistroID 替换为目标分配 ID。

2.    确定具有冲突 CNAME 的分配。如果您不知道哪个分配具有冲突 CNAME,则使用 ListConflictingAliases API 来查找该分配:

$ aws cloudfront list-conflicting-aliases --distribution-id YourDistributionID --alias YourCNAME

**注意:**将 YourDistributionID 替换为您的分配 ID。将 YourCNAME 替换为冲突的 CNAME 别名。

3.    要验证域的所有权,您必须拥有对 YourDistributionID 的读取访问权限。您还必须拥有与 CloudFront 分配关联的 SSL 证书,用以保护冲突的 CNAME。

在准备好验证所有权时,为 CNAME 创建一个 DNS TXT 记录,该记录可解析为目标分配的规范名称。您的 TXT 记录必须在 CNAME、Apex 或通配符前面包含下划线:

_.example.com.         900   IN   TXT     "dexample123456.cloudfront.net"
_cname.example.com.    900   IN   TXT     "dexample123456.cloudfront.net"
_*.example.com.        900   IN   TXT     "dexample123456.cloudfront.net"

4.    验证目标分配是否具有有效的 SSL 证书。

**注意:**主题名称或主题备用名称必须与给定的 CNAME 别名匹配或重叠。最佳做法是拥有 Mozilla 的 CA 证书列表AWS Certificate Manager 中列出的可信 CA 颁发的有效证书。

5.    从拥有目标分配的账户运行 AssociateAlias API 请求:

$ aws cloudfront associate-alias --target-distribution-id YourTargeDistributiontID --alias your_cname.example.com

停用具有冲突 CNAME 的源分配

如果您的源分配和目标分配位于不同的 AWS 账户中,请首先禁用与冲突的域关联的源分配。然后,使用 AssociateAlias API 移动 CNAME。

您可以使用 associate-alias 命令在不同的 AWS 账户之间移动顶点域

1.    打开 CloudFront 控制台

2.    在导航窗格中,选择分配

3.    选择源分配,然后选择禁用

如果您不知道哪个分配具有冲突的 CNAME,则使用 ListConflictingAliases API 来查找该分配。将 YourDistributionID 替换为您的分配 ID,并将 YourCNAME 替换为冲突的 CNAME 的名称:

$ aws cloudfront list-conflicting-aliases --distribution-id YourDistributionID --alias YourCNAME

注意ListConflictingAliases API 需要 GetDistributionListConflictingAliases 权限。

在停用源分配后,按照使用 AssociateAlias API 移动 CNAME 部分中的步骤操作。

如果您无权访问包含源分配的 AWS 账户,或者无法停用源分配,请联系 AWS Support

使用通配符移动备用域名

如果您的源分配和目标分配位于不同的账户中,但您无法停用源分配,则可以移动 CNAME。为此,请使用通配符。在此过程中,您必须同时拥有对源分配和目标分配的访问权限。

此过程涉及对源分配和目标分配的多次更新。等待每个分配完全部署最新的更改,然后再继续下一步。

1.    更新目标分配,以便添加涵盖了要移动的备用域名的通配符 CNAME。如果您的域是 www.example.com,则将通配符备用域名 *.example.com 添加到目标分配中。

**注意:**您必须在目标分配中拥有用于保护通配符域名的 SSL/TLS 证书

2.    更新 CNAME 的 DNS 设置,以便指向目标分配的规范名称。例如,如果您的域是 www.example.com,则更新 www.example.com 的 DNS 记录,以便将流量路由到目标分配的规范名称:

www.example.com.         86400   IN   CNAME     "dexample123456.cloudfront.net"

注意: 即使在您更新了 DNS 设置之后,源分配也会为使用备用域名的请求提供服务。这是因为备用域名仍与源分配关联。

3.    更新源分配以删除备用域名。

**注意:**在此步骤中,实时流量不会发生中断。由于请求的域名与添加到目标分配的通配符域相匹配,因此实时流量会使用目标分配设置。

4.    要添加您打算移动的备用域名,请更新目标分配。

5.    要验证 CNAME 的 DNS 记录,请使用 dig 或类似的 DNS 查询工具:

dig CNAME www.example.com +short
nslookup example.com

6.    (可选)要删除通配符备用域名,请更新目标分配。

AWS 官方
AWS 官方已更新 1 年前