

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用与静态 IP 地址关联的端点整合 Amazon S3 预签名 URL 生成和对象下载
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses"></a>

*Song Jin、Eunhye Jo 和 Jun Soung Lee，Amazon Web Services*

## Summary
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-summary"></a>

此模式通过创建安全的自定义对象下载 URLs 预签名，简化了对亚马逊简单存储服务 (Amazon S3) Simple Service 的访问。该解决方案提高了一个具有唯一域和静态 IP 地址的单个端点。如果客户需要将 API 和 Amazon S3 端点整合到具有静态 IP 地址的统一域，则该解决方案就非常合适。在该使用案例中，用户需要遵守 IP 和域允许列表防火墙策略，即限制 API 访问权限仅限于特定的域和 IP 地址。

该架构采用密钥 AWS 服务，包括 AWS Global Accelerator Amazon API Gateway AWS Lambda、Application Load Balancer 和 Amazon S3。 AWS PrivateLink此设计将用于生成预签名的 API URLs 和 Amazon S3 终端节点集中到一个域下，该域链接到具有两个静态 IP 地址的加速器。因此，用户可以通过具有静态 IP 地址的统一域终端节点毫不费力地请求 URLs 和下载 Amazon S3 对象。

此架构特别适合具有严格策略或合规要求的客户，例如公共、医疗和金融领域的客户。

## 先决条件和限制
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-prereqs"></a>

**先决条件**
+ 活跃的 AWS 账户
+ 您的自定义域名的公有托管区
+ 在您选择的 AWS Certificate Manager (ACM) 中导入 AWS 区域 的域名

**限制**
+ Amazon S3 存储桶名称必须与端点的域名匹配。这一要求是为了确保可以通过单个 API 端点为 Amazon S3 端点提供服务。
+ API Gateway 中使用的自定义域名应与单个 API 端点的域名保持一致。
+ 有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性，请参阅[按区域划分的AWS 服务](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。有关特定端点，请参阅[服务端点和配额](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)，然后选择相应服务的链接。

## 架构
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-architecture"></a>

下图显示了此模式的目标架构和工作流。

![\[用于预签名 URL 生成和对象下载的组件和工作流。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/e19ebcb5-2138-481e-952e-3cfee9ad9e97/images/effd197c-d4d7-4990-8b66-3eb1c64aab4c.png)


该图阐释了以下概念和工作流：

1. 用户使用提供的自定义终端节点、自定义域名和关联的 IP 地址 AWS Global Accelerator，发起生成预签名 URL 的请求。

1. Lambda 函数生成指向自定义端点的预签名 URL。它使用 301 重定向进行响应，其中包含生成的预签名 URL。通过重定向的预签名 URL，用户可以使用通过 Global Accelerator 提供的自定义端点，进而自动下载对象。

预签名 URL 生成和对象下载工作流的整体架构组件如下所示：
+ 由 Global Accelerator 预调配的静态 IP 地址。
+ 使用自定义域，将加速器以 A 记录为别名注册到 Amazon Route 53 公有托管区中。
+ 创建一个 Amazon S3 存储桶，且该存储桶的名称与注册的自定义域名匹配。
+ 为 API Gateway 和 Amazon S3 服务创建 VPC 端点。
+ 配置面向内部的应用程序负载均衡器，以连接到 Global Accelerator。
+ 为附有 ACM 证书的 API Gateway 分配自定义域名。
+ 部署与 Lambda 函数集成的私有 API Gateway。
+ Lambda 函数配备了一个附加的 AWS Identity and Access Management (IAM) 角色（具有[GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)权限）。

## 工具
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-tools"></a>

**AWS 服务**
+ [Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) 可帮助您创建、发布、维护、监控和保护任何规模的 RES WebSocket APIs T、HTTP。
+ [应用程序负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/)将传入的应用程序流量分配到多个可用区域中的多个目标，例如亚马逊弹性计算云 (Amazon EC2) 实例。
+ [AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html) 可帮助您创建、存储和续订 X.509 公有和私有 SSL/TLS X.509 证书和密钥，以保护您的 AWS 网站和应用程序。
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html)是一个软件开发框架，可帮助您在代码中定义和配置 AWS 云 基础架构。
+ [AWS Global Accelerator](https://docs.aws.amazon.com/global-accelerator/latest/dg/what-is-global-accelerator.html) 是一项全球服务，可支持多个 AWS 区域中的端点。您可以创建加速器，通过 AWS 全球网络将流量引导到最佳端点。这可提高全球受众使用的 Internet 应用程序的可用性和性能。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 通过控制谁经过身份验证并有权使用 AWS 资源，从而帮助您安全地管理对资源的访问权限。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，无需预调配或管理服务器。它只在需要时运行您的代码，并自动进行扩展，因此您只需为使用的计算时间付费。
+ [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html)帮助您创建从您的虚拟私有云 (VPCs) 到 VPC 外部服务的单向私有连接。
+ [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) 是一种可用性高、可扩展性强的 DNS Web 服务。
+ [Amazon Simple Storage Service（Amazon S3）](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)是一项基于云的对象存储服务，可帮助您存储、保护和检索任意数量的数据。

**其他工具**
+ [Terraform](https://www.terraform.io/) 是一款基础设施即代码 (IaC) 工具 HashiCorp ，可帮助您创建和管理云和本地资源。

**代码存储库**

您可以根据自己的喜好使用 AWS CDK 或 Terraform 来部署此模式。[操作说明](#consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-epics)部分包含两种部署方法的说明。此模式的代码可在以下 GitHub 存储库中找到：
+ **AWS CDK**— [s3-presignedurl-staticips-endpoint-with-cdk](https://github.com/aws-samples/s3-presignedurl-staticips-endpoint-with-cdk)
+ **Terraform** — [s3](https://github.com/aws-samples/s3-presignedurl-staticips-endpoint-with-terraform)-terraform presignedurl-staticips-endpoint-with

## 最佳实践
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-best-practices"></a>
+ 为了增强生产环境的安全性，务必要实施授权机制（例如 [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html)），以限制对 `PresignedUrl` 生成 API 的访问。
+ 遵循最低权限原则，并授予执行任务所需的最低权限。有关详情，请参阅 IAM 文档中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#grant-least-priv)和[安全最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

## 操作说明
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-epics"></a>

### 准备环境
<a name="prepare-the-environment"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 决定域名。 | 决定统一 Amazon S3 端点的公有域名。域名还可用作 Amazon S3 存储桶的名称。 | AWS 管理员、网络管理员 | 
| 创建公有托管区域。 | 在 Amazon Route 53 中，[创建一个公有托管区](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html)。其域名必须与 API Gateway 中使用的域名相匹配。 | AWS 管理员、网络管理员 | 
| 准备 SSL 证书。 | 使用 AWS Certificate Manager (ACM) 为您的 Web 应用程序域[请求](https://docs.aws.amazon.com/acm/latest/userguide/acm-public-certificates.html)或[导入](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html) SSL 证书。 | AWS 管理员、网络管理员 | 

### 使用 Terraform 部署模式
<a name="deploy-the-pattern-with-terraform"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 设置 Terraform 开发环境。 | 要设置开发环境，请执行以下操作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses.html) | AWS 管理员、云管理员 | 
| 修改 `.tfvars` 和 ** **`provider.tf` 文件。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses.html)**请注意以下几点：**[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses.html) | AWS 管理员、云管理员 | 
| 预调配网络资源。 | 要预调配网络资源，请运行以下命令：<pre>cd ./2.vpc_alb_ga<br />terraform init<br />terraform plan --var-file=apg.tfvars<br />terraform apply --var-file=apg.tfvars</pre>在 `apply ` 命令执行过程中，出现提示时键入 **yes**。 | AWS 管理员、云管理员 | 
| 预调配 API Gateway、Amazon S3 和 Lambda。 | 要预调配网络资源，请使用以下命令：<pre>cd ./2.apigw_s3_lambda<br />terraform init<br />terraform plan --var-file=apg.tfvars<br />terraform apply --var-file=apg.tfvars</pre> | AWS 管理员、云管理员 | 

### 使用部署模式 AWS CDK
<a name="deploy-the-pattern-with-cdk"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 设置 AWS CDK 开发环境。 | 要设置开发环境，请执行以下操作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses.html) | AWS 管理员、云管理员 | 
| 在 `config/index.ts` 文件中配置域设置。 | 要编辑常量变量的选项，请使用以下命令：<pre>export const options = {<br />    certificateArn: '{arn of the acm which created before}',<br />    dnsAttr: {<br />        zoneName: '{public hosted zone name}',<br />        hostedZoneId: 'hosted zone Id',<br />    },<br />    domainNamePrefix: '{Prefix for the domain}',<br />    presignPath: 'presign',<br />    objectsPath: 'objects',<br />};</pre>在以下命令中，将每个占位符替换为您自己的信息：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses.html) | AWS 管理员、云管理员 | 
| 部署堆栈。 | 要部署两个堆栈，一个用于虚拟私有云（VPC），另一个用于应用程序，请使用以下命令：<pre>$ npm install <br />$ cdk synth <br />$ cdk deploy --all</pre> | AWS 管理员、云管理员 | 

### 测试模式
<a name="test-the-pattern"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 验证端点的 IP 地址。 | 要验证此模式的域是否具有静态 IP 地址，请使用以下命令：<pre>nslookup ${s3-bucket-prefix}.${domain}</pre> | 网络管理员 | 
| 上传测试文件，且之后您可下载该文件。 | 将测试文件上传到 Amazon S3 存储桶中的 `'/objects'` 文件夹。 | AWS 管理员、云管理员 | 
| 调用 API 以生成预签名 URL。 | 要生成预签名 URL，请采用以下格式，从浏览器或 API 客户端（例如 [Postman](https://www.postman.com/product/what-is-postman/)）调用该 URL：<pre>https://${s3-bucket-prefix}.${domain}/presign/objects/${uploaded-filename}</pre>将 `${s3-bucket-prefix}` 和 `${domain}` 中的占位符值替换为您在前面的步骤中设置的值。 | 应用程序所有者 | 
| 检查结果。 | 预期结果是，您应该会收到 301（永久移动）重定向状态码。此响应将包含预签名 URL，而 URL 应会自动启动测试文件的下载。 | 测试工程师 | 

### 使用 Terraform 清理
<a name="clean-up-with-terraform"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 销毁 API Gateway、Amazon S3 和 Lambda 资源。 | 要删除资源，请使用以下命令：<pre>cd ./2.apigw_s3_lambda<br />terraform init<br />terraform plan --destroy --var-file=apg.tfvars<br />terraform destroy --var-file=apg.tfvars<br /></pre> | AWS 管理员、云管理员 | 
| 销毁网络资源。 | 要删除网络资源，请使用以下命令：<pre>cd ./1.vpc_alb_ga<br />terraform init<br />terraform plan --destroy --var-file=apg.tfvars<br />terraform destroy --var-file=apg.tfvars<br /></pre> | AWS 管理员、云管理员 | 

### 用清理干净 AWS CDK
<a name="clean-up-with-cdk"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 部署堆栈。 | 要销毁 VPC 和应用程序堆栈，请使用以下命令：<pre>$ cdk destroy --all</pre> | AWS 管理员、云管理员 | 
| 清空和删除 Amazon S3 存储桶。 | [清空](https://docs.aws.amazon.com/AmazonS3/latest/userguide/empty-bucket.html)和[删除](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html)默认情况下不会删除的对象 Amazon S3 存储桶和日志 Amazon S3 存储桶。Amazon S3 存储桶名称为 `${s3-bucket-prefix}.${domain}` 和 `${s3-bucket-prefix}.${domain}-logs`。如果您偏好使用 [AWS Command Line Interface （AWS CLI）](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)来删除存储桶，请使用以下命令：<pre>$ aws s3 rm s3://${s3-bucket-prefix}.${domain} --recursive<br />$ aws s3 rb s3://${s3-bucket-prefix}.${domain} --force<br />$ aws s3 rm s3://${s3-bucket-prefix}.${domain}-logs --recursive<br />$ aws s3 rb s3://${s3-bucket-prefix}.${domain}-logs --force</pre>将 `${s3-bucket-prefix}` 和 `${domain}` 替换为在您上一步中设置的值。,/p> | AWS 管理员、云管理员 | 

## 相关资源
<a name="consolidate-amazon-s3-presigned-url-generation-and-object-downloads-by-using-an-endpoint-associated-with-static-ip-addresses-resources"></a>

**AWS 博客**
+ [通过提供的静态 IP 地址访问 Amazon API Gateway AWS Global Accelerator](https://aws.amazon.com/blogs/networking-and-content-delivery/accessing-an-aws-api-gateway-via-static-ip-addresses-provided-by-aws-global-accelerator/) 
+ [生成模块化 AWS CDK 预签名 URL JavaScript](https://aws.amazon.com/blogs/developer/generate-presigned-url-modular-aws-sdk-javascript/) 
+ [使用 ALB、S3 和 PrivateLink](https://aws.amazon.com/blogs/networking-and-content-delivery/hosting-internal-https-static-websites-with-alb-s3-and-privatelink/) 