

# 教程：创建和调用私有 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 端点可以对其进行调用。

------
#### [ Amazon Web Services 管理控制台 ]

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

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.amazonaws.cn/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. 选择**保存更改**。

------
#### [ Amazon CLI ]

在使用 Amazon 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.amazonaws.cn/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。

------
#### [ Amazon Web Services 管理控制台 ]

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

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

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

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

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

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

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

1. 选择**保存**。

------
#### [ Amazon CLI ]

使用以下 [create-base-path-mapping](https://docs.amazonaws.cn/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)。

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

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

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

------
#### [ Amazon Web Services 管理控制台 ]

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

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

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

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

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

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

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

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

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

------
#### [ Amazon 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.amazonaws.cn/Route53/latest/DeveloperGuide/hosted-zones-private.html)。

------
#### [ Amazon Web Services 管理控制台 ]

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

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

------
#### [ Amazon CLI ]

使用以下 [create-hosted-zone](https://docs.amazonaws.cn/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 记录类型。

------
#### [ Amazon Web Services 管理控制台 ]

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

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

------
#### [ Amazon 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.amazonaws.cn/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>

现在，您可以在自己的 Amazon Web Services 账户中调用您的私有自定义域名。在您的 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 端点与私有自定义域名之间的关联，然后删除私有自定义域名。

------
#### [ Amazon Web Services 管理控制台 ]

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

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

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

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

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

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

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

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

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

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

1. 选择**删除**。

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

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

------
#### [ Amazon 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.amazonaws.cn/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 类型记录。如果您不打算调用自己的私有自定义域名，可在以后删除这些资源。