

# API Gateway 中私有 API 的自定义域名
<a name="apigateway-private-custom-domains"></a>

您可以为私有 API 创建自定义域名。使用私有自定义域名，可为 API 调用方提供更简单、更直观的 URL。使用私有自定义域名，您可以降低复杂性，配置 TLS 握手期间的安全措施，并使用 AWS Certificate Manager（ACM）控制域名的证书生命周期。有关更多信息，请参阅 [保护您的自定义域名的证书私有密钥](#apigateway-private-custom-domains-secure-certificate-private-key)。

私有 API 的自定义域名在多个账户中不必唯一。只要您的 ACM 证书可涵盖域名，您就可以在账户 111122223333 和账户 555555555555 中创建 `example.private.com`。要标识私有自定义域名，请使用私有自定义域名 ARN。此标识符对于私有自定义域名是唯一的。

当您在 API Gateway 中创建私有自定义域名时，您便成为了 *API 提供方*。您可以使用 API Gateway 或 AWS Resource Access Manager（AWS RAM），将您的私有自定义域名提供给其他 AWS 账户。

当您调用私有自定义域名时，您就是 *API 使用方*。您可以从自己的 AWS 账户使用私有自定义域名，也可以从其他 AWS 账户使用。

使用私有自定义域名时，您可以在 VPC 端点与私有自定义域名之间创建域名访问关联。通过域名访问关联，API 使用方可以在与公共互联网隔离的情况下调用您的私有自定义域名。有关更多信息，请参阅[私有 API 的自定义域名的 API 提供方和 API 使用方任务](apigateway-private-custom-domains-associations.md)。

## 保护您的自定义域名的证书私有密钥
<a name="apigateway-private-custom-domains-secure-certificate-private-key"></a>

当您使用 ACM 请求 SSL/TLS 证书为私有 API 创建自定义域名时，ACM 会生成一个公有/私有密钥对。导入证书时，将生成密钥对。公有密钥将成为证书的一部分。为了安全地存储私有密钥，ACM 使用 AWS KMS 创建另一个密钥，称为 KMS 密钥，其别名为 **aws/acm**。AWS KMS 使用此密钥加密证书的私有密钥。有关更多信息，请参阅《AWS Certificate Manager 用户指南》**中的 [AWS Certificate Manager 中的数据保护](https://docs.aws.amazon.com/acm/latest/userguide/data-protection.html)。

API Gateway 使用 AWS TLS Connection Manager（一项仅允许 AWS 服务 访问的服务），来保护和使用您的证书私有密钥。当您使用 ACM 证书创建 API Gateway 自定义域名时，API Gateway 会将您的证书与 AWS TLS Connection Manager 关联。为此，我们根据您的 AWS 托管密钥在 AWS KMS 中创建一个授权。此授权允许 TLS Connection Manager 使用 AWS KMS 来解密证书的私有密钥。TLS Connection Manager 使用证书和解密（明文）的私有密钥，与 API Gateway 服务的客户端建立安全连接（SSL/TLS 会话）。当证书与 API Gateway 服务取消关联时，该授权就会停用。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[授权](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html)。

有关更多信息，请参阅 [Amazon API Gateway 中的静态数据加密](data-protection-encryption.md#data-protection-at-rest)。

## 私有自定义域名的注意事项
<a name="apigateway-private-custom-domains-considerations"></a>

以下注意事项可能会影响您对私有自定义域名的使用：
+ API Gateway 需要大约 15 分钟的时间来配置私有自定义域名。
+ 如果您更新 ACM 证书，API Gateway 需要大约 15 分钟来完成更新。在此期间，您的域名处于 `UPDATING` 状态，您仍然可以访问该域名。
+ 要调用私有自定义域名，您必须创建域名访问关联。创建域名访问关联后，关联大约需要 15 分钟才可供使用。
+ 私有自定义域名 ARN 包含 *account-id* 和 *domain-name-id*。当您创建域名时，API Gateway 使用 ARN 格式 `arn:partition:apigateway:region::/domainnames/domain-name`。当您访问私有自定义域名时，您使用 ARN 格式 `arn:partition:apigateway:region:account-id:/domainnames/domain-name+domain-name-id`。

  创建私有域名后，您可能需要修改 IAM 权限以支持访问该域名。
+ 您不能从同一个 VPC 端点调用同名的私有自定义域名。例如，如果您想调用 `arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234` 和 `arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+xyz000`，请将每个私有自定义域名与另一个 VPC 端点相关联。
+ 支持通配符证书，例如 `*.private.example.com` 的证书。
+ 不支持通配符自定义域名。
+ 仅支持密钥长度为 2048 位的 RSA 证书，支持密钥长度为 256 位和 384 位的 ECDSA 证书。
+ 您不能将私有 API 的 IP 地址类型设置为仅支持 IPv4 地址调用私有 API。仅支持双堆栈。有关更多信息，请参阅 [API Gateway 中 REST API 的 IP 地址类型](api-gateway-ip-address-type.md)。
+ 要使用私有 API 发送流量，您可以使用 Amazon VPC 支持的所有 IP 地址类型。您可以通过配置 VPC 端点上的设置，发送双堆栈和 IPv6 流量。您无法使用 API Gateway 修改此项。有关更多信息，请参阅[为 VPC 添加 IPv6 支持](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html)。
+ 不支持多级基本路径映射，例如将私有 API 映射到 `/developers/feature`，但您可以使用路由规则来创建多级路径条件。有关更多信息，请参阅 [在 API Gateway 中通过自定义域名将流量发送到 API](rest-api-routing-mode.md)。
+ 您无法为私有自定义域名设置最低 TLS 版本。所有私有自定义域名的安全策略均为 `TLS-1-2`。
+ 您可以使用 VPC 端点策略来控制对私有自定义域名的访问。有关更多信息，请参阅[在 API Gateway 中为私有 API 使用 VPC 端点策略](apigateway-vpc-endpoint-policies.md)中的示例 4 和 5。
+ 您必须为私有 API 和私有自定义域名创建单独的资源策略。要调用私有自定义域名，API 使用方需要通过私有自定义域名资源策略、私有 API 资源策略以及私有 API 上的任何 VPC 端点策略或授权来获取访问权限。

## 将私有自定义域名与其他 API Gateway 资源结合使用的注意事项
<a name="apigateway-private-custom-domains-considerations-for-migration"></a>

以下注意事项可能会影响您如何将私有自定义域名与其它 API Gateway 资源结合使用：
+ 无法将流量从私有自定义域名发送到公有 API。
+ 将私有 API 映射到私有自定义域名时，您无法更改 API 的端点类型。
+ 您无法将公共自定义域名迁移到私有自定义域名。
+ 如果您有用于访问公共自定义域名的 VPC 端点，请不要使用该端点来创建与私有自定义域名的域名访问关联。

## 私有自定义域名与公共自定义域名的区别
<a name="apigateway-private-custom-domains-public-differences"></a>

下文介绍私有自定义域名与公有自定义域名之间的区别：
+ 私有自定义域名在多个账户中不必唯一。
+ 私有域名具有域名 ID。此 ID 唯一标识私有自定义域名，而不会为公有自定义域名生成此 ID。
+ 当您使用 AWS CLI 更新或删除您的私有自定义域名时，必须提供域名 ID。如果您有一个名为 `example.com` 的私有自定义域名和一个名为 `example.com` 的公共自定义域名，但您没有提供域名 ID，则 API Gateway 将修改或删除您的公共自定义域名。

## 私有 API 的自定义域名的后续步骤
<a name="apigateway-private-custom-domains-next-steps"></a>

有关 API 提供方和 API 使用方任务的信息，请参阅[私有 API 的自定义域名的 API 提供方和 API 使用方任务](apigateway-private-custom-domains-associations.md)。

有关创建可以在自己的 AWS 账户中调用的私有自定义域名的说明，请参阅[教程：创建和调用私有 API 的自定义域名](apigateway-private-custom-domains-tutorial.md)。

有关向其他 AWS 账户提供对您私有自定义域名的访问权限的说明，请参阅 [API 提供方：使用 AWS RAM 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share.md)。有关将您的 VPC 端点与另一个 AWS 账户中的私有自定义域名关联的说明，请参阅 [API 使用方：将您的 VPC 端点关联到与您共享的私有自定义域名](apigateway-private-custom-domains-consumer-create.md)。

# 私有 API 的自定义域名的 API 提供方和 API 使用方任务
<a name="apigateway-private-custom-domains-associations"></a>

在您创建私有自定义域名时，您便成为了 *API 提供方*。当您调用私有自定义域名时，您就是 *API 使用方*。您可以从自己的 AWS 账户使用私有自定义域名，也可以从其他 AWS 账户使用。

以下部分介绍了在使用私有自定义域名时，API 提供方和 API 使用方所需完成的任务。如果您想在自己的 AWS 账户中调用私有自定义域名，那么您既是 API 提供方，又是 API 使用方。如果您想在其他 AWS 账户中调用私有自定义域，则根据 AWS Organizations 中 API 提供方与 API 使用方之间的信任关系，AWS RAM 可能会为您完成一些任务。

## API 提供方的任务
<a name="apigateway-private-custom-domains-associations-provider"></a>

API 提供方创建私有 API 并将其映射到自定义域名。

 API 提供方管理两个资源策略来保护其私有自定义域名。第一个策略针对 `execute-api` 服务，控制哪些 VPC 端点可以调用您的私有自定义域名。在私有自定义域名配置中，这称为 `policy`。

第二个策略针对 Amazon API Gateway 管理服务，控制其他 AWS 账户中的哪些 VPC 端点可以与您的私有自定义域名建立域名访问关联。VPC 端点需要与私有自定义域名建立域名访问关联才能调用它。在私有自定义域名配置中，这是 `managementPolicy`。您可以使用 AWS RAM 或 API Gateway 来更新此策略。如果您不打算允许其他 AWS 账户中的 VPC 端点调用您的自定义域名，则无需编辑 `managementPolicy`。

如果您是 API 提供方，则必须完成以下任务：

1. 创建私有 API。

1. 更新私有 API 的 `policy`，向您的 VPC 端点授予对您私有 API 的访问权限。

1. 创建私有自定义域名。

1. 更新私有自定义域名的 `policy`，向您的 VPC 端点授予对您私有自定义域名的访问权限。

1. 创建基本路径映射或路由规则，以便将流量从私有 API 发送到私有自定义域名。有关更多信息，请参阅 [在 API Gateway 中通过自定义域名将流量发送到 API](rest-api-routing-mode.md)。

如果您想允许其他 AWS 账户中的 API 使用方访问您的私有自定义域名，请执行以下操作：

1. 更新您的私有自定义域名的 `managementPolicy`，允许其他账户中的 API 使用方将其 VPC 端点与您的私有自定义域名相关联。您可以使用以下方法执行此操作：  
**AWS RAM**  
对于 AWS RAM，如果 API 提供方和 API 使用方属于同一组织并使用 AWS Organizations，则会自动接受提供方和使用方之间的资源共享。否则，您需要等待 API 使用方接受资源共享。**我们建议您使用 AWS RAM 共享您的私有自定义域名。**  
**API Gateway**  
对于 API Gateway，仅支持 AWS CLI。您必须使用补丁操作更新您的私有自定义域名，并为 `managementPolicy` 提供自己的策略文档。

1. 更新您的私有自定义域名以及映射到该域名的所有私有 API 的 `policy`，授予对 API 使用方的 VPC 端点的访问权限。

有关如何向其他 AWS 账户提供您的 API 的说明，请参阅 [API 提供方：使用 AWS RAM 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share.md)。

## API 使用方的任务
<a name="apigateway-private-custom-domains-associations-consumer"></a>

API 使用方将其 VPC 端点与域名 ARN 关联，以便调用私有自定义域名。API 使用方不需要创建 API Gateway API。

如果您是 API 使用方，请执行以下操作：

1. 在 Amazon VPC 中创建启用私有 DNS 的 VPC 端点。

1. （可选 – 使用 AWS RAM 时）在资源共享后的 **12 小时**内，在 AWS RAM 中接受私有自定义域资源共享。如果您和 API 提供方位于同一个组织中，则会自动接受资源共享。

1. 获取私有自定义域名 ARN。由于私有自定义域名 URL 不唯一，因此您需要使用私有自定义域名 ARN，在您的 VPC 端点与私有自定义域名之间建立域名访问关联。您可以使用 AWS RAM 检索私有自定义域名 ARN。

1. 在 API Gateway 中将私有自定义域 ARN 与您的 VPC 端点相关联。这将在您的 VPC 端点与私有自定义域名之间创建安全连接。流量不会离开 Amazon 网络。

1. 等待 API 提供方向您的 VPC 端点授予访问权限，使其能够访问私有自定义域名以及映射到私有自定义域名的任何私有 API。如果您既是 API 提供方又是 API 使用方，则可以向自己授予对 VPC 端点的调用访问权限。

1. 创建 Route 53 私有托管区和 Route 53 记录，以便解析 Route 53 中的私有自定义域名。

有关如何使用其他 AWS 账户中 API 的说明，请参阅 [API 使用方：将您的 VPC 端点关联到与您共享的私有自定义域名](apigateway-private-custom-domains-consumer-create.md)。

# 教程：创建和调用私有 API 的自定义域名
<a name="apigateway-private-custom-domains-tutorial"></a>

在本教程中，您将创建一个私有自定义域名，您可以在自己账户的 VPC 中调用该域名。要做到这一点，您应该同时是 API 提供方和 API 使用方。为完成本教程，您需要已有私有 API 和 VPC 端点。如果您有用于访问公共自定义域名的 VPC 端点，请不要将该端点用于本教程，也不要用来创建任何域名访问关联。

## 步骤 1：创建私有自定义域名
<a name="apigateway-private-custom-domains-provider-create-domain"></a>

您可以指定域名、ACM 证书以及 `execute-api` 服务的策略，以此创建您的私有自定义域名，而策略用于控制哪些 VPC 端点可以对其进行调用。

------
#### [ AWS 管理控制台 ]

**创建私有自定义域名**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择**添加域列表**。

1. 对于**域名**，输入一个域名。

   您的 ACM 证书必须包含此域名，但域名不必唯一。

1. 选择**私有**。

1. 对于**路由模式**，选择**仅限 API 映射**。

1. 对于 **ACM 证书**，请选择证书。

1. 选择**添加域列表**。

API Gateway 对所有资源策略使用 `deny`，来预置域名。这是 `execute-api` 服务的资源策略。您需要更新此资源策略，授予对您 VPC 端点的访问权限，以便调用私有自定义域名。

**更新资源策略**

1. 选择**资源策略**选项卡，然后选择**编辑资源策略**。

1. 在代码编辑器中输入以下资源策略。将 VPC 端点 *vpce-abcd1234efg* 替换为您自己的 VPC 端点 ID。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": "*",
               "Action": "execute-api:Invoke",
               "Resource": [
                   "execute-api:/*"
               ]
           },
           {
               "Effect": "Deny",
               "Principal": "*",
               "Action": "execute-api:Invoke",
               "Resource": [
                   "execute-api:/*"
               ],
               "Condition" : {
                   "StringNotEquals": {
                       "aws:SourceVpce": "vpce-abcd1234"
                   }
               }
           }
       ]
   }
   ```

1. 选择**保存更改**。

------
#### [ AWS CLI ]

在使用 AWS CLI 创建私有自定义域名时，您可以使用 `--policy file://policy.json` 参数为 `execute-api` 服务提供资源策略，授予对 VPC 端点的访问权限，以便调用您的私有自定义域名。您可以稍后修改此策略。

在本示例中，您通过从文件加载参数，附加以下资源策略作为 `policy`。复制此文件并将其另存为 `policy.json`。此策略仅允许从 VPC 端点 *`vpce-abcd1234efg`* 传入到私有自定义域名的流量：

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-abcd1234"
                }
            }
        }
    ]
}
```

使用以下 [create-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-domain-name.html) 命令创建私有自定义域名：

```
aws apigateway create-domain-name \
    --domain-name 'private.example.com' \
    --certificate-arn 'arn:aws:acm:us-west-2:111122223333:certificate/a1b2c3d4-5678-90ab-cdef' \
    --security-policy 'TLS_1_2' \
    --endpoint-configuration '{"types":["PRIVATE"]}' \
    --policy file://policy.json
```

输出将与以下内容类似：

```
{
    "domainName": "private.example.com",
    "domainNameId": "abcd1234",
    "domainNameArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234",
    "certificateArn": "arn:aws:acm:us-west-2:111122223333:certificate/a1b2c3d4-5678-90ab-cdef",
    "certificateUploadDate": "2024-09-10T10:31:20-07:00",
    "endpointConfiguration": {
        "types": [
            "PRIVATE"
        ]
    },
    "domainNameStatus": "AVAILABLE",
    "securityPolicy": "TLS_1_2",
    "routingMode" : "API_MAPPING_ONLY",
    "policy": "..."
}
```

------

## 步骤 2：创建基本路径映射，以便将私有 API 映射到私有自定义域名
<a name="apigateway-private-custom-domains-base-path-mapping"></a>

创建私有自定义域名后，您可以将私有 API 映射到该域名。利用基本路径映射，就可以通过私有自定义域名和所关联基本路径的组合来访问 API。建议您使用一个私有自定义域名作为多个私有 API 的主机名。

即使您不打算调用自己的 API，所有 API 提供方也都需要创建基本路径映射。您还需要向 VPC 端点授予访问权限，来调用您映射到私有自定义域名的任何私有 API。

------
#### [ AWS 管理控制台 ]

**创建基本路径映射**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择私有自定义域名。

1. 在 **API 映射**选项卡上，选择**配置映射**。

1. 选择 **Add new mapping (添加新映射)**。

1. 输入 **API**、**阶段**以及可选的**路径**。

1. 选择**保存**。

------
#### [ AWS CLI ]

使用以下 [create-base-path-mapping](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-base-path-mapping.html) 命令在私有 API 与私有自定义域名之间创建映射：

```
aws apigateway create-base-path-mapping \
    --domain-name-id abcd1234 \
    --domain-name 'private.example.com' \
    --rest-api-id a1b2c3 \
    --stage prod \
    --base-path v1
```

输出将与以下内容类似：

```
{
    "basePath": "v1",
    "restApiId": "a1b2c3",
    "stage": "prod"
}
```

------

为了更灵活地将流量路由到 API，可以将路由模式更改为 `ROUTING_RULE_ONLY` 或 `ROUTING_RULE_THEN_API_MAPPING`，然后创建路由规则。有关更多信息，请参阅 [在 API Gateway 中通过自定义域名将流量发送到 API](rest-api-routing-mode.md)。

**注意**  
如果您需要其他 AWS 账户调用您的私有自定义域名，请在完成本教程后，按照 [API 提供方：使用 AWS RAM 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share.md)中的步骤进行操作。

## 步骤 3：在自定义域名与 VPC 端点之间创建域名访问关联。
<a name="apigateway-private-custom-domains-provider-associate-with-vpce"></a>

接下来，在私有自定义域名与 VPC 端点之间创建域名访问关联。您的 VPC 端点使用域名访问关联，在与公共互联网隔离的情况下，调用您的私有自定义域名。

------
#### [ AWS 管理控制台 ]

**创建域名访问关联**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择私有自定义域名。

1. 在**资源共享**选项卡中，对于**域名访问关联**，选择**创建域名访问关联**。

1. 对于**域名 ARN**，选择您的域名。

1. 对于 **VPC 端点 ID**，选择您在步骤 1 中提供了访问权限的 VPC 端点 ID。

1. 选择**域名访问关联**。

您也可以在控制台上，使用**域名访问关联**页面创建域名访问关联。

------
#### [ AWS CLI ]

使用以下 `create-domain-name-access-association` 命令在私有自定义域名与 VPC 端点之间创建域名访问关联。

```
aws apigateway create-domain-name-access-association \
    --domain-name-arn arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234 \
    --access-association-source vpce-abcd1234efg \
    --access-association-source-type VPCE \
    --region us-west-2
```

输出将与以下内容类似：

```
{
    "domainNameAccessAssociationARN": "arn:aws:apigateway:us-west-2:111122223333:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234efg",
    "accessAssociationSource": "vpce-abcd1234efg",
    "accessAssociationSourceType": "VPCE",
    "domainNameARN" : "arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234"
}
```

------

创建域名访问关联后，关联大约需要 15 分钟才可供使用。在等待期间，您可以继续执行以下步骤。

## 步骤 4：创建 Route 53 托管区
<a name="apigateway-private-custom-domains-provider-create-route-53-private-hosted-zone"></a>

在更新资源策略并将私有自定义域名与 VPC 端点关联后，您可以在 Route 53 中创建私有托管区，用于解析您的自定义域名。托管区是一个容器，其中包含的信息说明您希望如何在一个或多个 VPC 中，为某个域路由流量而不将您的资源公开到互联网。有关更多信息，请参阅[使用私有托管区域](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html)。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅《Amazon Route 53 Developer Guide》**中的 [Creating a private hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-creating.html)。

对于**名称**，请使用您的私有自定义域名。对于 **VPC ID**，请使用包含您在之前步骤中使用的 VPC 端点的 VPC。

------
#### [ AWS CLI ]

使用以下 [create-hosted-zone](https://docs.aws.amazon.com/cli/latest/reference/route53/create-hosted-zone.html) 命令创建私有托管区：

```
aws route53 create-hosted-zone --name private.example.com \
    --caller-reference 2014-04-01-18:47 \
    --hosted-zone-config Comment="command-line version",PrivateZone=true \
    --vpc VPCRegion=us-west-2,VPCId=vpc-abcd1234
```

输出中包含托管区 ID。您可以在以下步骤中使用托管区 ID。

------

## 步骤 5：创建 Route 53 DNS 记录
<a name="apigateway-private-custom-domains-provider-create-route-53-record"></a>

创建托管区后，您可以创建一条记录来解析您的私有自定义域名。您使用在上一步中创建的托管区 ID。在本示例中，您将创建一个 A 记录类型。如果您为 VPC 端点使用 IPv6，请创建 AAAA 记录类型。如果您为 VPC 端点使用双堆栈，请创建 AAAA 和 A 记录类型。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅 [Routing traffic to an Amazon API Gateway API by using your domain name](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-api-gateway.html)。

使用**快速创建**并打开**别名**。对于端点，请使用 VPC 端点 DNS 名称。

------
#### [ AWS CLI ]

要配置 DNS 记录将私有自定义域名映射到给定托管区 ID 的主机名，您需要创建一个 JSON 文件，其中包含用于为私有域名设置 DNS 记录的配置。

以下 `setup-dns-record.json` 演示如何创建 DNS `A` 记录，将私有自定义域名映射到其私有主机名。您需要提供 VPC DNS ID 的 `DNSName`，以及您在上一步中创建的托管区 ID。

```
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "private.example.com",
        "Type": "A",
        "AliasTarget": {
          "DNSName": "vpce-abcd1234.execute-api.us-west-2.vpce.amazonaws.com",
          "HostedZoneId": "Z2OJLYMUO9EFXC",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
```

使用以下 [change-resource-record-sets](https://docs.aws.amazon.com/cli/latest/reference/route53/change-resource-record-sets.html) 命令为私有自定义域名创建 DNS 记录：

```
aws route53 change-resource-record-sets \
    --hosted-zone-id ZABCDEFG1234 \
    --change-batch file://path/to/your/setup-dns-record.json
```

将 `hosted-zone-id` 替换为您账户中设置的 DNS 记录的 Route 53 托管区 ID。`change-batch` 参数值指向 JSON 文件。

------

如果您不打算调用自己的私有自定义域名，则在确认私有自定义域名可正常使用后，您可以删除这些资源。

## 第 6 步：调用您的私有自定义域名
<a name="apigateway-private-custom-domains-tutorial-invoke"></a>

现在，您可以在自己的 AWS 账户中调用您的私有自定义域名。在您的 VPC 中，使用以下 curl 命令可访问私有自定义域名。

```
curl https://private.example.com/v1
```

有关调用私有 API 的其他方法的更多信息，请参阅 [使用自定义域名调用私有 API](apigateway-private-api-test-invoke-url.md#apigateway-private-custom-domains-provider-invoke)。

## 步骤 7：清除
<a name="apigateway-private-custom-domains-cleanup"></a>

为避免不必要的费用，请删除您的 VPC 端点与私有自定义域名之间的关联，然后删除私有自定义域名。

------
#### [ AWS 管理控制台 ]

**删除域名访问关联**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**域名访问关联**。

1. 选择您的域名访问关联，然后选择**删除**。

1. 确认您的选择，然后选择**删除**。

在删除域名访问关联后，您可以删除自己的私有自定义域名。

**删除私有自定义域名**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择您的私有自定义域名。

1. 选择**删除**。

1. 确认您的选择，然后选择**删除**。

如有必要，您还可以删除 VPC 端点。有关更多信息，请参阅[删除接口端点](https://docs.aws.amazon.com/vpc/latest/privatelink/delete-interface-endpoint.html)。

------
#### [ AWS CLI ]

**清理**

1. 使用以下 `delete-access-association` 命令删除域名访问关联：

   ```
   aws apigateway delete-domain-name-access-association \
       --domain-name-access-association-arn 'arn:aws:apigateway:us-west-2:111122223333:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234efg' \
       --region us-west-2
   ```

1. 使用以下 `delete-domain-name` 命令删除您的私有自定义域名。此命令还会删除所有基本路径映射。

   ```
   aws apigateway delete-domain-name \
       --domain-name test.private.com \
       --domain-name-id abcd1234
   ```

如有必要，您还可以删除 VPC 端点。有关更多信息，请参阅[删除接口端点](https://docs.aws.amazon.com/vpc/latest/privatelink/delete-interface-endpoint.html)。

------

## 最佳实践
<a name="apigateway-private-custom-domains-best-practices"></a>

在创建私有自定义域名时，我们建议您使用以下最佳实践：
+ 使用基本路径映射或路由规则，以便将流量从一个私有自定义域名发送到多个私有 API。
+ 当 VPC 端点不再需要访问私有自定义域名时，请删除关联。此外，对于私有自定义域的 `execute-api` 服务，请从 `policy` 中删除 VPC 端点。
+ 每个 VPC 端点至少配置两个可用区。
+ 禁用默认端点。我们建议您禁用默认端点，这样就可以使得您的 API 使用方只能从自定义域名调用您的 API。有关更多信息，请参阅 [禁用 REST API 的默认端点](rest-api-disable-default-endpoint.md)。
+ 在设置私有自定义域名时，我们建议您预置 Route 53 私有托管区和 A 类型记录。如果您不打算调用自己的私有自定义域名，可在以后删除这些资源。

# 使用跨账户的私有自定义域名
<a name="apigateway-private-custom-domains-other-accounts"></a>

此部分介绍如何使用跨账户的私有自定义域名。您可以向其他 AWS 账户提供私有自定义域名，并使用其他 AWS 账户调用私有自定义域名。

您可以使用 AWS Resource Access Manager 或 API Gateway，与其他 AWS 账户共享您的私有自定义域名。AWS Resource Access Manager（AWS RAM）可帮助您跨 AWS 账户以及在组织或组织单位（OU）内部安全地共享资源。有关更多信息，请参阅[什么是 AWS Resource Access Manager](https://docs.aws.amazon.com/ram/latest/userguide/what-is.html)。

有关如何使用 AWS RAM 与其他 AWS 账户共享私有自定义域名的说明，请参阅 [API 提供方：使用 AWS RAM 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share.md)。

有关如何使用 API Gateway 与其他 AWS 账户共享私有自定义域名的说明，请参阅 [API 提供方：使用 API Gateway AWS CLI 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share-cli.md)。

有关如何在其他 AWS 账户中使用私有自定义域名的说明，请参阅 [API 使用方：将您的 VPC 端点关联到与您共享的私有自定义域名](apigateway-private-custom-domains-consumer-create.md)。

## 使用跨账户的私有自定义域名的最佳实践
<a name="apigateway-private-custom-domains-other-accounts-best-practices"></a>

对于使用跨账户的私有自定义域名，建议的最佳实践如下：
+ 使用 AWS RAM 共享您的私有自定义域名。当您使用 AWS RAM 时，您可以减少运营开销，而且无需为 Amazon API Gateway 管理服务创建 `managementPolicy`。
+ 在列出您的私有自定义域名或域名访问关联时，请使用 `resource-owner` 参数。仅在列出由您或其他 AWS 账户拥有的资源时，才使用 `resource-owner` 参数。

  以下示例演示如何获取您拥有的所有域名访问关联：

  ```
  aws apigateway get-domain-name-access-associations --resource-owner SELF
  ```

  使用 `--resource-owner OTHER_ACCOUNTS` 列出其他账户与您的私有自定义域名建立的所有域名访问关联。

# API 提供方：使用 AWS RAM 共享您的私有自定义域名
<a name="apigateway-private-custom-domains-provider-share"></a>

您可以向其他 AWS 账户中的 API 使用方提供对您私有自定义域名的访问权限。在本部分中，您将学习如何使用 AWS RAM 共享您的私有自定义域名，以及如何控制对您私有自定义域名的访问权限。

## 共享私有自定义域名的注意事项
<a name="apigateway-private-custom-domains-provider-share-considerations"></a>

以下注意事项可能会影响您如何使用 AWS RAM 来提供对私有自定义域名的访问权限。要了解如何不使用 AWS RAM 来共享您的私有自定义域名，请参阅 [API 提供方：使用 API Gateway AWS CLI 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share-cli.md)。
+ 私有自定义域名在 AWS 区域级别上共享。私有自定义域名和 VPC 端点必须位于同一个 AWS 区域中。
+ 您可以将一个资源共享用于多个主体，在创建资源共享之后，您可以向其中添加多个主体。我们建议您尽可能重用资源共享。
+ 您始终需要向 API 使用方的 VPC 端点授予访问权限，使其能够调用您的私有自定义域名以及映射到该域名的所有私有 API。
+ 如果 API 使用方和 API 提供方在同一个组织中使用 AWS Organizations，则会自动接受资源共享。您仍然需要使用 AWS RAM 创建资源共享。
+ 如果 API 使用方和 API 提供方在同一个组织中使用 AWS Organizations，并且您的组织中已经启用了资源共享，则组织中与您进行共享的所有主体将自动获得对资源共享的访问权限。此过程无需邀请，您可以跳过资源共享。
+ 如果 API 使用方未在 **12 小时**内接受资源共享，则 API 提供方必须重新共享资源。
+ 在您创建资源共享后，AWS RAM 为私有自定义域名更新 Amazon API Gateway 管理服务的 `managementPolicy`，以防止在未明确授予 `allow` 访问权限的情况下，向主体提供访问权限。有关更多信息，请参阅《IAM 用户指南》中的[确定是允许还是拒绝账户内的请求](https://docs.aws.amazon.com//IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)。

  更新后的 `managementPolicy` 类似于以下内容：

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Id": "abcd1234-1234-abcd-abcd-1234abcdefg",
      "Statement": [
          {
              "Sid": "APIGatewayPrivateDomainNameManagementPolicyDefaultPermission-org",
              "Effect": "Allow",
              "Principal": "*",
              "Action": "apigateway:CreateAccessAssociation",
              "Resource": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234",
              "Condition": {
                  "StringEquals": {
                      "aws:PrincipalOrgID": "o-1234abcd"
                  },
                  "StringNotEquals": {
                      "aws:PrincipalAccount": "111122223333"
                  }
              }
          }
      ]
  }
  ```

------

  AWS RAM 通过添加以下内容，针对没有明确授予 `allow` 访问权限的主体，阻止主体创建与您的私有自定义域名的访问关联：

  ```
  "StringNotEquals": {
      "aws:PrincipalAccount": "111122223333"
  }
  ```

  您仍然可以使用 AWS 账户中创建了私有自定义域名的主体，来创建域名访问关联。

## 允许其他账户创建与您的私有自定义域名的域名访问关联。
<a name="apigateway-private-custom-domains-provider-management-policy-update"></a>

首先，您向其他 AWS 账户授予访问权限，以便创建与您的私有自定义域名的域名访问关联。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅《AWS RAM User Guide**》中的 [Creating a resource share in AWS RAM](https://docs.aws.amazon.com/ram/latest/userguide/working-with-sharing-create.html)。

对于**选择资源类型**，选择 **API Gateway 私有自定义域**。

------
#### [ AWS CLI ]

使用以下 [create-resource-share](https://docs.aws.amazon.com/cli/latest/reference/ram/create-resource-share.html) 命令为您的私有自定义域名创建资源共享。可能需要花几分钟时间，才能完成资源和委托人关联。对于主体，请提供账户 ID 或 Organizations ID，例如 `arn:aws:organizations::123456789012:organization/o-1234abcd`。您可以为资源共享提供多个主体。

```
aws ram create-resource-share \
    --region us-west-2 \
    --name privateCustomDomain-resource-share \
    --permission-arns arn:aws:ram::aws:permission/APIGatewayPrivateDomainNameManagementPolicyDefaultPermission \
    --resource-arns arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234 \
    --principals 222222222222
```

------

在您向其他 AWS 账户提供访问权限后，该账户中的 API 使用方必须在其 VPC 端点与您的私有自定义域名之间创建域名访问关联。您无法为他们创建域名访问关联。有关更多信息，请参阅 [将您的 VPC 端点与共享私有自定义域名关联](apigateway-private-custom-domains-consumer-create.md#apigateway-private-custom-domains-consumer-associate)。

## 允许其他账户调用您的私有自定义域名
<a name="apigateway-private-custom-domains-provider-policy-update"></a>

接下来，您向 API 使用方的 VPC 端点授予访问权限，使其能够调用您的私有自定义域名以及映射到该域名的所有私有 API。

------
#### [ AWS 管理控制台 ]

**允许其他账户中的 VPC 端点调用您的私有自定义域名**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择您与其他 AWS 账户共享的私有自定义域名。

1. 在**资源策略**选项卡上，选择**编辑资源策略**。

1. 将 API 使用方的 VPC 端点 ID 添加到您的资源策略中。

   在您的私有自定义域名的**域详细信息**页面上，您可在**资源共享**选项卡的**域名访问关联**部分中找到 API 使用方的 VPC 端点 ID。

1. 选择**保存更改**。

------
#### [ AWS CLI ]

`execute-api` 服务的以下 `policy` 允许来自 VPC 端点 `vpce-abcd1234efg` 和 `vpce-xyz000abc` 流量传入到私有自定义域名。

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": [
                    "vpce-abcd1234",
                    "vpce-xyzz0000"
                    ]
                }
            }
        }
    ]
}
```

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令使用补丁操作来更新私有自定义域名的 `policy`：

```
aws apigateway update-domain-name
    --domain-name private.example.com \
    --domain-name-id abcd1234 \
    --patch-operations op=replace,path=/policy,value='"{\"Version\": \"2012-10-17\",		 	 	 \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\":[\"execute-api:/*\"]},{\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\":[\"execute-api:/*\"],\"Condition\":{\"StringNotEquals\":[\"vpce-abcd1234efg\", \"vpce-xyz000abc\"]}}}]}"
```

------

# API 提供方：使用 AWS RAM 停止共享私有自定义域名
<a name="apigateway-private-custom-domains-provider-stop-sharing"></a>

要停止共享您的私有自定义域名，请先取消关联资源共享，来阻止 API 使用方创建更多域名访问关联。然后，您拒绝域名访问关联，并从 `execute-api` 服务的 `policy` 中删除 API 使用方的 VPC 端点。API 使用方随之可以删除其域名访问关联。

## 停止共享您的私有自定义域名
<a name="apigateway-private-custom-domains-provider-dissociate-ram"></a>

首先，使用 AWS RAM 停止资源共享。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅 [Update a resource share in AWS RAM](https://docs.aws.amazon.com/ram/latest/userguide/working-with-sharing-update.html)。

------
#### [ AWS CLI ]

使用以下 [disassociate-resource-share](https://docs.aws.amazon.com/cli/latest/reference/ram/disassociate-resource-share.html) 命令为您的私有自定义域名取消资源共享关联。

```
aws ram disassociate-resource-share \
    --region us-west-2 \
    --resource-arns arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234 \
    --principals 222222222222
```

------

## 拒绝域名访问关联
<a name="apigateway-private-custom-domains-provider-reject"></a>

使用 AWS RAM 停止资源共享后，您需要拒绝其他账户中的 VPC 端点与您的私有自定义域名之间的域名访问关联。

**注意**  
您不能拒绝自己账户中的域名访问关联。要停止资源共享，请删除域名访问关联。有关更多信息，请参阅[删除域名访问关联](apigateway-private-custom-domains-tutorial.md#apigateway-private-custom-domains-cleanup)。

在您拒绝与某个 VPC 端点的域名访问关联时，如果 API 使用方尝试调用您的私有自定义域名，API Gateway 会拒绝该调用并返回状态代码 `403`。

------
#### [ AWS 管理控制台 ]

**拒绝域名访问关联**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择您与其他 AWS 账户共享的私有自定义域名。

1. 在**资源共享**上，选择要拒绝的域名访问关联。

1. 选择**拒绝关联**。

1. 确认选择，然后选择**拒绝**。

------
#### [ AWS CLI ]

以下 `reject-domain-name-access-association` 命令拒绝 VPC 端点与您的私有自定义域名之间的域名访问关联：

```
aws apigateway reject-domain-name-access-association \
    --domain-name-access-association-arn arn:aws:apigateway:us-west-2:444455556666:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234efg \
    --domain-name-arn arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234
```

------

## 拒绝 API 提供方调用您的私有自定义域名的访问权限
<a name="apigateway-private-custom-domains-provider-deny-access"></a>

拒绝域名访问关联后，您可以从 `execute-api` 服务的 `policy` 中删除 API 使用方的 VPC 端点。

------
#### [ AWS 管理控制台 ]

**从您的资源策略中删除 API 使用方的 VPC 端点**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**自定义域名**。

1. 选择您与其他 AWS 账户共享的私有自定义域名。

1. 在**资源策略**选项卡上，选择**编辑**。

1. 从策略中删除 VPC 端点。

1. 选择**保存更改**。

------
#### [ AWS CLI ]

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令使用补丁操作，为私有自定义域名的 `execute-api` 服务更新 `policy`。这个新的 `policy` 删除了在[允许其他账户调用您的私有自定义域名](apigateway-private-custom-domains-provider-share.md#apigateway-private-custom-domains-provider-policy-update)中添加的其他 VPC 端点 ID：

```
aws apigateway update-domain-name
    --domain-name private.example.com \
    --domain-name-id abcd1234 \
    --patch-operations op=replace,path=/policy,value='"{\"Version\": \"2012-10-17\",		 	 	 \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\":[\"execute-api:/*\"]},{\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\":[\"execute-api:/*\"],\"Condition\":{\"StringNotEquals\":{\"aws:SourceVpce\": \"vpce-abcd1234efg\"}}}]}"
```

------

API 使用方应随之删除域名访问关联。您无法为他们删除关联。有关更多信息，请参阅 [API 使用方：删除您与私有自定义域名的域名访问关联](apigateway-private-custom-domains-consumer-delete-domain-name-access-association.md)。

# API 提供方：使用 API Gateway AWS CLI 共享您的私有自定义域名
<a name="apigateway-private-custom-domains-provider-share-cli"></a>

您可以使用 API Gateway AWS CLI 来共享私有自定义域名，但我们建议您使用 AWS RAM 来减少运营开销。有关如何使用 AWS RAM 共享私有自定义域名的说明，请参阅 [API 提供方：使用 AWS RAM 共享您的私有自定义域名](apigateway-private-custom-domains-provider-share.md)。

要使用 API Gateway AWS CLI 共享私有自定义域名，您需要向其他 AWS 账户授予访问权限，使其能够创建域名访问关联和调用您的私有自定义域名。为此，您需要更新 API Gateway 管理服务的 `managementPolicy`，以及您私有自定义域名的 `execute-api` 服务的 `policy`。您还需要在资源策略中，向 API 使用方的 VPC 端点授予访问权限，使其能够访问映射到您的私有自定义域名的所有私有 API。

API 使用方仍需要在自己的账户中，在其 VPC 端点与您的私有自定义域名之间创建域名访问关联。您不能为他们完成此操作。

## 授予对私有自定义域名的访问权限
<a name="apigateway-private-custom-domains-provider-share-cli-allow"></a>

**授予对私有自定义域名的访问权限**

1. 要更新 API Gateway 管理服务的 `managementPolicy`，您需要创建一个 JSON 文件，其中包含用于更新策略的补丁操作。以下 `patch-managementPolicy.json` 将当前 `managementPolicy` 替换为示例策略，该策略向 AWS 账户 111122223333 和 444455556666 授予访问权限，使其能够创建与私有自定义域名 `private.example.com` 的域名访问关联。

   ```
   [{
       "op": "replace",
       "path": "/managementPolicy",
       "value": "{\"Version\":\"2012-10-17\",		 	 	 \"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam::111122223333:root\", \"arn:aws:iam::444455556666:root\"]},\"Action\":\"apigateway:CreateAccessAssociation\",\"Resource\":\"arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\"}]}"
   }]
   ```

    以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令使用 `patch-managementPolicy.json` 更新了 `managementPolicy`。

   ```
   aws apigateway update-domain-name \
       --domain-name private.example.com \
       --domain-name-id abcd1234 \
       --patch-operations file://patch-managementPolicy.json
   ```

   授予访问权限后，您需要通知 API 使用方，他们可以建立域名访问关联。如果您使用 AWS RAM，AWS RAM 将为您执行此步骤。

1. 要更新 `execute-api` 服务的 `policy`，您需要创建一个 JSON 文件，其中包含用于更新策略的补丁操作。以下 `patch-policy.json` 将当前 `policy` 替换为示例策略，该策略授予两个 VPC 端点调用私有自定义域名 `private.example.com` 的访问权限。

   ```
   [{
       "op": "replace",
       "path": "/policy",
       "value": "{\"Version\": \"2012-10-17\",		 	 	 \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\": \"arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\"},{\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"execute-api:Invoke\",\"Resource\": \"arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\",\"Condition\": {\"StringNotEquals\": {\"aws:SourceVpce\": [\"vpce-abcd1234\",\"vpce-xyzz0000\"]}}}]}"
   }]
   ```

    通过以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令，使用 `patch-policy.json` 更新 `policy`。

   ```
   aws apigateway update-domain-name \
       --domain-name private.example.com \
       --domain-name-id abcd1234 \
       --patch-operations file://patch-policy.json
   ```

## 拒绝对私有自定义域名的访问权限
<a name="apigateway-private-custom-domains-provider-share-cli-deny"></a>

要停止共享私有自定义域名，您需要拒绝私有自定义域名与 API 使用方的 VPC 端点之间的域名访问关联。

**拒绝对私有自定义域名的访问权限**

1. 以下 `reject-domain-name-access-association` 命令拒绝域名访问关联。

   ```
   aws apigateway reject-domain-name-access-association \
       --domain-name-access-association-arn arn:aws:apigateway:us-west-2:444455556666:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234 \
       --domain-name-arn arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234
   ```

1. 修改 `patch-managementPolicy.json` 以删除 API 提供方账户的权限，使其不能创建与您的私有自定义域名的域名访问关联。以下 `patch-managementPolicy.json` 从 `managementPolicy` 中删除一个账户：

   ```
   [{
        "op": "replace",
        "path": "/managementPolicy",
        "value": "{\"Version\":\"2012-10-17\",		 	 	 \"Statement\":[{\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"apigateway:CreateAccessAssociation\",\"Resource\":\"arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\"}]}"
   }]
   ```

   以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令使用 `patch-managementPolicy.json` 更新 `managementPolicy`。

   ```
   aws apigateway update-domain-name \
       --domain-name private.example.com \
       --domain-name-id abcd1234 \
       --patch-operations file://patch-managementPolicy.json
   ```

1. 修改 `patch-policy.json`，删除 API 提供方的 VPC 端点调用您的私有自定义域名的访问权限。以下 `patch-policy.json` 从 `policy` 中删除 VPC 端点 ID：

   ```
   [{
       "op": "replace",
       "path": "/policy",
       "value": "{\"Version\":\"2012-10-17\",		 	 	 \"Statement\":[{\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\"},{\"Effect\":\"Deny\",\"Principal\":\"*\",\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234\",\"Condition\":{\"StringNotEquals\":{\"aws:SourceVpce\":\"vpce-abcd1234\"}}}]}"
   }]
   ```

   以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-domain-name.html) 命令使用 `patch-policy.json` 更新了 `policy`。

   ```
   aws apigateway update-domain-name \
       --domain-name private.example.com \
       --domain-name-id abcd1234 \
       --patch-operations file://patch-policy.json
   ```

## 此过程中使用的示例策略
<a name="apigateway-private-custom-domains-provider-share-cli-policies"></a>

接下来的部分演示之前过程中使用的示例策略。

以下示例策略针对 Amazon API Gateway 管理服务的 `managementPolicy`。此策略向 AWS 账户 111122223333 和 444455556666 授予访问权限，使其能够创建与私有自定义域名 `private.example.com` 的域名访问关联。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "111122223333",
                    "444455556666"
                ]
            },
            "Action": "apigateway:CreateAccessAssociation",
            "Resource": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+a1b2c3"
        }
    ]
}
```

------

以下示例策略是用于 `execute-api` 服务的 `policy` 的策略。此策略授予 VPC 端点 `vpce-abcd1234` 和 `vpce-xyzz0000` 调用私有自定义域名的访问权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.example.com+abcd1234",
            "Condition": {
                "StringNotEquals": {
                    "aws:SourceVpce": [
                        "vpce-abcd1234",
                        "vpce-xyzz0000"
                    ]
                }
            }
        }
    ]
}
```

------

# API 使用方：将您的 VPC 端点关联到与您共享的私有自定义域名
<a name="apigateway-private-custom-domains-consumer-create"></a>

以下过程演示如何使用其他 AWS 账户中的私有域名。根据您与 API 提供方的信任关系，AWS RAM 可能会代表您完成一些任务。

当您与私有自定义域名处于不同的 AWS 账户中时，您只能将您的 VPC 端点与私有自定义域名关联，然后再调用该域名。您无法查看私有自定义域名的 `policy` 或任何其他参数。

## 先决条件
<a name="apigateway-private-custom-domains-consumer-prerequisites"></a>

使用其它 AWS 账户中的私有自定义域名需要满足以下先决条件：
+ 用于 `execute-api` 服务的 VPC 和 VPC 端点。您的 VPC 必须将 `enableDnsHostnames` 和 `enableDnsSupport` 设置为 `true`。
+ 我们建议您为每个 VPC 端点至少配置两个可用区。

## （可选）接受私有自定义域资源共享
<a name="apigateway-private-custom-domains-consumer-accept-resource-share"></a>

如果您的 API 提供方使用了 AWS RAM 来创建资源共享，则您有 **12 小时**的时间来接受该共享。如果您和 API 提供方在同一个组织中使用 AWS Organizations，则会自动接受共享。如果您所在的组织启用了自动共享资源，则会自动与您共享资源。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅**《AWS RAM User Guide》中的 [Accepting and rejecting resource share invitations](https://docs.aws.amazon.com/ram/latest/userguide/working-with-shared-invitations.html)。

------
#### [ AWS CLI ]

要查找与您共享的所有资源，请使用以下 [get-resource-share-invitations](https://docs.aws.amazon.com/cli/latest/reference/ram/get-resource-share-invitations.html) 命令：

```
aws ram get-resource-share-invitations \
    --region us-west-2
```

使用生成的资源共享 ARN 来接受资源共享邀请。以下 [accept-resource-share-invitation](https://docs.aws.amazon.com/cli/latest/reference/ram/accept-resource-share-invitation.html) 命令接受资源共享。

```
aws ram accept-resource-share-invitation \
    --resource-share-invitation-arn arn:aws:ram:us-west-2:123456789012:resource-share-invitation/1e3477be-4a95-46b4-bbe0-c4001EXAMPLE \
    --region us-west-2
```

------

## 将您的 VPC 端点与共享私有自定义域名关联
<a name="apigateway-private-custom-domains-consumer-associate"></a>

由于私有自定义域名不唯一，因此您需要将 VPC 端点与唯一的自定义域名 ARN 相关联。创建域名访问关联后，可能需要 15 分钟的时间，VPC 端点才能成功调用您的私有自定义域名。如果您有用于访问公共自定义域名的 VPC 端点，请不要将该端点用来创建任何域名访问关联。

------
#### [ AWS 管理控制台 ]

**将您的 VPC 端点与共享私有自定义域名关联**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**域名访问关联**。

1. 选择**创建域名访问关联**。

1. 对于**域名 ARN**，请选择 API 提供方与您共享的域名 ARN。

   域名 ARN 可能不会显示在下拉列表中。您可以使用 AWS RAM 控制台查看与您共享的域名，然后复制域名 ARN 并将其输入此字段。

1. 对于 **VPC 端点 ID**，选择要与之建立域名访问关联的 VPC 端点 ID。

1. 选择**创建域名访问关联**。

------
#### [ AWS CLI ]

由于私有自定义域名不唯一，因此您需要将 VPC 端点与唯一的自定义域名 ARN 相关联。要查找域名 ARN，请使用以下命令之一。

1.   
**AWS RAM**  
以下 [list-resources](https://docs.aws.amazon.com/cli/latest/reference/ram/list-resources.html) 命令列出与您共享的资源。API 提供方必须使用 AWS RAM 与您共享了其私有自定义域，才能使用此命令。  

   ```
   aws ram list-resources \
       --resource-owner OTHER-ACCOUNTS \
       --region us-west-2
       --resource-type apigateway:Domainnames
   ```  
**API Gateway**  
以下 `get-domain-names` 命令列出其他 AWS 账户拥有的所有私有自定义域名，您可以与这些域名建立域名访问关联。  

   ```
   aws apigateway get-domain-names \
       --resource-owner OTHER_ACCOUNTS \
       --region us-west-2
   ```

1.  检索 ARN 后，您可使用 API Gateway，在您的 VPC 端点与共享私有自定义域名之间创建域名访问关联。使用以下 `create-domain-name-access-association` 命令：

   ```
   aws apigateway create-domain-name-access-association \
       --access-association-source-type VPCE \
       --access-association-source 'vpce-1a2b3c4d5e6f1a2b3' \
       --domain-name-arn arn:aws:apigateway:us-west-2:111122223333:/domainnames/private.example.com+abcd1234"
   ```

   输出将与以下内容类似：

   ```
   {
       "domainNameAccessAssociationARN": "arn:aws:apigateway:us-west-2:444455556666:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234efg", 
       "accessAssociationSource": "vpce-1a2b3c4d5e6f1a2b3",
       "accessAssociationSourceType": "VPCE",
       "domainNameARN" : "arn:aws:apigateway:us-west-1:111122223333:/domainnames/private.example.com+a1b2c3"
   }
   ```

------

将您的 VPC 端点与私有自定义域名关联后，请确认您的 API 提供方已更新其私有自定义域名的策略，允许您的 VPC 端点调用其域名。有关更多信息，请参阅 [允许其他账户调用您的私有自定义域名](apigateway-private-custom-domains-provider-share.md#apigateway-private-custom-domains-provider-policy-update)。

## 创建 Route 53 托管区
<a name="apigateway-private-custom-domains-consumer-create-route-53-private-hosted-zone"></a>

要解析私有自定义域名，您需要创建 Route 53 私有托管区。托管区是一个容器，其中包含的信息说明您希望如何在一个或多个 VPC 中，为某个域路由流量而不将您的资源公开到互联网。有关更多信息，请参阅[使用私有托管区域](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html)。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅《Amazon Route 53 Developer Guide》**中的 [Creating a private hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-creating.html)。

对于**名称**，请使用私有自定义域名。对于 **VPC ID**，请使用包含您用于域名访问关联的 VPC 端点的 VPC。

------
#### [ AWS CLI ]

使用以下 [create-hosted-zone](https://docs.aws.amazon.com/cli/latest/reference/route53/create-hosted-zone.html) 命令创建私有托管区：

```
aws route53 create-hosted-zone --name private.example.com \
    --caller-reference 2014-04-01-18:47 \
    --hosted-zone-config Comment="command-line version",PrivateZone=true \
    --vpc VPCRegion=us-west-2,VPCId=vpc-abcd1234
```

输出中包含托管区 ID。您可以在以下步骤中使用托管区 ID。

------

## 创建 Route 53 DNS 记录。
<a name="apigateway-private-custom-domains-consumer-create-route-53-record"></a>

创建托管区后，您可以创建一条记录来解析私有自定义域。在本示例中，您将创建一个 A 记录类型。如果您为 VPC 端点使用 IPv6，请创建 AAAA 记录类型。如果您为 VPC 端点使用双堆栈，请创建 AAAA 和 A 记录类型。

------
#### [ AWS 管理控制台 ]

要使用 AWS 管理控制台，请参阅 [Routing traffic to an Amazon API Gateway API by using your domain name](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-api-gateway.html)。

使用**快速创建**并打开**别名**。对于端点，请使用 VPC 端点 DNS 名称。

------
#### [ AWS CLI ]

要配置 DNS 记录来将私有自定义域名映射到给定托管区 ID 的主机名，请先创建一个 JSON 文件，其中包含用于为私有域名设置 DNS 记录的配置。

以下 `setup-dns-record.json` 演示如何创建 DNS `A` 记录，将私有自定义域名映射到其私有主机名。您需要提供 VPC DNS ID 的 `DNSName`，以及您在上一步中创建的托管区 ID。

```
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "private.example.com",
        "Type": "A",
        "AliasTarget": {
          "DNSName": "vpce-abcd1234.execute-api.us-west-2.vpce.amazonaws.com",
          "HostedZoneId": "Z2OJLYMUO9EFXC",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
```

以下 [change-resource-record-sets](https://docs.aws.amazon.com/cli/latest/reference/route53/change-resource-record-sets.html) 命令为私有自定义域名创建 DNS 记录：

```
aws route53 change-resource-record-sets \
    --hosted-zone-id ZABCDEFG1234 \
    --change-batch file://path/to/your/setup-dns-record.json
```

将 `hosted-zone-id` 替换为您账户中设置的 DNS 记录的 Route 53 托管区 ID。`change-batch` 参数值指向 JSON 文件。

------

## API 使用方后续步骤
<a name="apigateway-private-custom-domains-consumer-next-steps"></a>

现在，您可以在自己的 AWS 账户中调用私有 API。在您的 VPC 中，您可以使用以下 curl 命令访问私有自定义域名。

```
curl https://private.example.com/v1
```

有关调用私有 API 的其他方法的更多信息，请参阅 [使用自定义域名调用私有 API](apigateway-private-api-test-invoke-url.md#apigateway-private-custom-domains-provider-invoke)。

# API 使用方：删除您与私有自定义域名的域名访问关联
<a name="apigateway-private-custom-domains-consumer-delete-domain-name-access-association"></a>

如果您是 API 使用方，则可以随时删除访问关联资源。API 提供方无法为您删除域名访问关联。

如果您不再使用某个域名访问关联，建议您始终将其删除。

------
#### [ AWS 管理控制台 ]

**删除域名访问关联**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在主导航窗格中，选择**域名访问关联**。

1. 选择您的域名访问关联，然后选择**删除**。

1. 确认您的选择，然后选择**删除**。

------
#### [ AWS CLI ]

以下 `delete-access-association` 命令删除访问关联：

```
aws apigateway delete-domain-name-access-association \
    --domain-name-access-association-arn 'arn:aws:apigateway:us-west-2:444455556666:/domainnameaccessassociations/domainname/private.example.com+abcd1234/vpcesource/vpce-abcd1234efg'
```

------

# 使用 CloudFormation 为私有 API 创建自定义域名
<a name="apigateway-private-custom-domains-cfn"></a>

以下示例 CloudFormation 模板创建私有 API 和私有自定义域名，将私有 API 映射到自定义域名，然后创建域名访问关联。您需要提供自己的 VPC 端点、域名和证书 ARN。

以下注意事项可能会影响您使用 CloudFormation 创建私有自定义域名。
+ 您不能使用 CloudFormation 拒绝域名访问关联。要拒绝域名访问关联，请使用 AWS CLI。
+ 使用 `AWS::ApiGateway::DomainNameV2` CloudFormation 属性创建私有自定义域名。
+ 使用 `AWS::ApiGateway:BasePathMappingV2` CloudFormation 属性创建基本路径映射。

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EndpointID:
    Type: String
    Default: vpce-abcd1234567efg
    Description: A VPC endpoint with enableDnsHostnames and enableDnsSupport set to true.
  DomainName:
    Type: String
    Default: private.example.com
    Description: A domain name that you own.
  CertificateArn:
    Type: String
    Default: arn:aws:acm:us-west-2:123456789:certificate/abcd-000-1234-0000-000000abcd
    Description: An ACM certificate that covers the domain name.
Resources:
  PrivateApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      EndpointConfiguration:
        Types:
          - PRIVATE
        VpcEndpointIds:
          - !Ref EndpointID
      Name: private-api
      Policy:
        Statement:
          - Action: 'execute-api:Invoke'
            Effect: Allow
            Principal: '*'
            Resource: 'execute-api:/*'
          - Action: 'execute-api:Invoke'
            Condition:
              StringNotEquals:
                'aws:SourceVpce': !Ref EndpointID
            Effect: Deny
            Principal: '*'
            Resource: 'execute-api:/*'
        Version: 2012-10-17		 	 	 
  PrivateApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref PrivateApi
      Description: Private API deployment
    DependsOn:
      - PrivateApiMethod
  PrivateApiStage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
      RestApiId: !Ref PrivateApi
      DeploymentId: !Ref PrivateApiDeployment
      StageName: prod
  PrivateApiMethod: 
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: ANY
      ResourceId: !GetAtt PrivateApi.RootResourceId
      RestApiId: !Ref PrivateApi
      AuthorizationType: NONE
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: "{\"statusCode\": 200}"
        IntegrationResponses:
          - StatusCode: '200'
      MethodResponses:
        - StatusCode: '200'
  PrivateDomainName:
    Type: AWS::ApiGateway::DomainNameV2
    Properties:
      DomainName: !Ref DomainName
      CertificateArn: !Ref CertificateArn
      EndpointConfiguration:
        Types:
          - PRIVATE
      SecurityPolicy: TLS_1_2
      Policy:
        Statement:
            - Action: 'execute-api:Invoke'
              Effect: Allow
              Principal: '*'
              Resource: 'execute-api:/*'
            - Action: 'execute-api:Invoke'
              Condition:
                StringNotEquals:
                  'aws:SourceVpce': !Ref EndpointID
              Effect: Deny
              Principal: '*'
              Resource: 'execute-api:/*'
        Version: 2012-10-17		 	 	 
  PrivateBasePathMapping:
    Type: AWS::ApiGateway::BasePathMappingV2
    DependsOn:
      - PrivateApiStage
    Properties:
      BasePath: prod
      DomainNameArn: !GetAtt PrivateDomainName.DomainNameArn
      RestApiId: !Ref PrivateApi
      Stage: prod
  DomainNameAccessAssociation: 
    Type: AWS::ApiGateway::DomainNameAccessAssociation
    Properties:
      DomainNameArn: !GetAtt PrivateDomainName.DomainNameArn
      AccessAssociationSource: !Ref EndpointID
      AccessAssociationSourceType: VPCE
```