

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

# 从 Amazon VPC 发布 Amazon SNS 消息
<a name="sns-vpc-tutorial"></a>

本节介绍如何发布到 Amazon SNS 主题，同时保护消息在私有网络中的安全性。您从托管在 Amazon Virtual Private Cloud (Amazon VPC) 中的 Amazon EC2 实例发布消息。消息保留在 Amazon 网络中，无需通过公共互联网传输。通过从 VPC 私下发布消息，您可以提高应用程序与 Amazon SNS 之间的流量的安全性。这种安全性在您发布有关客户的个人身份信息（PII）或当您的应用程序受市场规定约束时至关重要。例如，如果您有一个必须符合健康保险可携性与责任法 (HIPAA) 的医疗保健系统或有一个必须符合支付卡行业数据安全标准 (PCI DSS) 的金融系统，则私下发布会很有用。

常见步骤如下：
+ 使用 Amazon CloudFormation 模板在您的中自动创建临时专用网络 Amazon Web Services 账户。
+ 创建一个用于连接 VPC 与 Amazon SNS 的 VPC 终端节点。
+ 登录 Amazon EC2 实例并将消息私下发布到 Amazon SNS 主题。
+ 验证消息是否已成功发送。
+ 删除您在此过程中创建的资源，这样它们就不会保留在您的资源中 Amazon Web Services 账户。

下图描述了您在完成这些步骤时在 Amazon 账户中创建的专用网络：

![\[您在这些步骤中创建的私有网络的架构。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-architecture.png)


此网络包含一个包含 Amazon EC2 实例的 VPC。该实例通过*接口 VPC 终端节点* 连接到 Amazon SNS。这种类型的端点连接到由提供支持的服务 Amazon PrivateLink。在建立此连接后，即使网络已从公共 Internet 断开连接，您也可以登录 Amazon EC2 实例并将消息发布到 Amazon SNS 主题。该主题将其收到的消息分散到两个订阅 Amazon Lambda 函数。这些函数将它们收到的消息记录在 Amazon CloudWatch 日志中。

完成这些步骤大约需要 20 分钟。

**Topics**
+ [开始前的准备工作](#sns-vpc-prereqs)
+ [步骤 1：创建密钥对](#sns-vpc-keypair)
+ [步骤 2：创建资源](#sns-vpc-resources)
+ [步骤 3：检查您的实例的 Internet 连接](#sns-vpc-connection)
+ [步骤 4：创建终端节点](#sns-vpc-endpoint)
+ [步骤 5：发布消息](#sns-vpc-publish)
+ [步骤 6：验证](#sns-vpc-verify)
+ [步骤 7：清除](#sns-vpc-delete)
+ [相关资源](#sns-vpc-resources-related)

## 开始前的准备工作
<a name="sns-vpc-prereqs"></a>

在开始之前，您需要 Amazon Web Services (Amazon) 账户。当您注册时，您的账户会自动注册使用中的所有服务 Amazon，包括亚马逊 SNS 和 Amazon VPC。如果您尚未创建账户，请前往 [https://www.amazonaws.cn/](https://www.amazonaws.cn/)，然后选择 **Create a Free Account**（创建免费账户）。

## 步骤 1：创建 Amazon EC2 密钥对
<a name="sns-vpc-keypair"></a>

*密钥对*用于登录 Amazon EC2 实例。它包含一个用于加密您的登录信息的公有密钥和一个用于解密该信息的私有密钥。创建密钥对时，下载该私有密钥的副本。稍后，您可以使用密钥对登录 Amazon EC2 实例。要登录，请指定密钥对的名称，然后提供密钥对。

**创建密钥对**

1. 登录 Amazon Web Services 管理控制台 并打开 Amazon EC2 控制台，网址为[https://console.aws.amazon.com/ec2/](https://console.amazonaws.cn/ec2/)。

1. 在左侧导航菜单中，找到 **Network & Security (网络与安全)** 部分。然后，选择 **Key Pairs (密钥对)**。

1. 选择**创建密钥对**。

1. 在**创建密钥对**窗口中，在**密钥对名称**中，键入 **VPCE-Tutorial-KeyPair**。然后选择 **Create**。  
![\[创建密钥对窗口，密钥对名称字段中包含文本 “vpce-tutorial-KeyPair”。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-key-pair.png)

1. 您的浏览器会自动下载私有密钥文件。将它保存至安全位置。Amazon EC2 会为该文件提供 `.pem` 的扩展名。

1. (可选) 如果您在 Mac 或 Linux 计算机上使用 SSH 客户端连接到您的实例，请使用 `chmod` 命令设置您的私有密钥文件的权限，以确保只有您可以读取该文件。

   1. 打开终端并导航到包含该私有密钥的目录：

      ```
      $ cd /filepath_to_private_key/
      ```

   1. 使用以下命令设置权限：

      ```
      $ chmod 400 VPCE-Tutorial-KeyPair.pem
      ```

## 步骤 2：创建 Amazon 资源
<a name="sns-vpc-resources"></a>

要设置基础架构，请使用 Amazon CloudFormation *模板*。模板是一种充当用于构建 Amazon 资源的蓝图的文件，例如 Amazon EC2 实例和 Amazon SNS 主题。此过程的模板已提供 GitHub 给您下载。

您可以向提供模板 Amazon CloudFormation Amazon CloudFormation ，并将所需的资源配置为*堆栈* Amazon Web Services 账户。堆栈是可作为单个单元管理的一系列资源。完成这些步骤后，您可以使用 Amazon CloudFormation 一次性删除堆栈中的所有资源。除非您愿意 Amazon Web Services 账户，否则这些资源不会保留在您的中。

此过程的堆栈包括以下资源：
+ VPC 和关联的网络资源，包括子网、安全组、Internet 网关和路由表。
+ 在 VPC 中的子网中启动的 Amazon EC2 实例。
+ Amazon SNS 主题。
+ 两个 Amazon Lambda 函数。这些函数接收发布到 Amazon SNS 主题的消息，并在日志中 CloudWatch 记录事件。
+ Amazon CloudWatch 指标和日志。
+ 一个允许亚马逊 EC2 实例使用亚马逊 SNS 的 IAM 角色和一个允许 Lambda 函数写入日志的 IAM 角色。 CloudWatch 

**创建 Amazon 资源**

1. 从 GitHub 网站下载[模板文件](https://github.com/aws-samples/aws-sns-samples/blob/master/templates/SNS-VPCE-Tutorial-CloudFormation.template)。

1. 登录 [Amazon CloudFormation 控制台](https://console.amazonaws.cn/cloudformation)。

1. 选择**创建堆栈**。

1. 在**选择模板**页面上，依次选择**将模板上传到 Amazon S3**、您的文件和**下一步**。

1. 在 **Specify Details (指定详细信息)** 页面上，指定堆栈和密钥名称：

   1. 对于 **Stack name**，键入 **VPCE-Tutorial-Stack**。

   1. 对于 **KeyName**，请选择 **VPCE 教程-。KeyPair**

   1. 对于 **SSHLocation**，保留默认值**0.0.0.0/0**。  
![\[“指定详细信息” 页面显示堆栈名称 KeyName、和的填充值字段 SSHLocation。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-stack-name.png)

   1. 选择**下一步**。

1. 在 **Options (选项)** 页面上，保留所有默认值，然后选择 **Next (下一步)**。

1. 在 **Review (审核)** 页面上，验证堆栈详细信息。

1. 在 “**权能**” 下，确认 Amazon CloudFormation 可能会使用自定义名称创建 IAM 资源。

1. 选择**创建**。

    Amazon CloudFormation 控制台打开 **Stacks** 页面。的 VPCE-Tutorial-Stack状态为 **CREATE\$1IN\$1** PROGRESS。在创建过程完成后的几分钟内，该状态将变为 **CREATE\$1COMPLETE**。  
![\[状态为 CREATE_COMPLETE 的 Amazon CloudFormation 堆栈。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-stack-create-complete.png)
**提示**  
选择**刷新**按钮以查看最新堆栈状态。

## 步骤 3：确认您的 Amazon EC2 实例缺少 Internet 访问
<a name="sns-vpc-connection"></a>

上一步中在您的 VPC 中启动的 Amazon EC2 实例缺少 Internet 访问。它不允许出站流量，而且无法将发布到 Amazon SNS。通过登录该实例验证此项。然后，尝试连接到公共终端节点，并尝试向 Amazon SNS 发布消息。

此时，发布操作尝试失败。在后面的步骤中，在您为 Amazon SNS 创建 VPC 终端节点后，您的发布尝试成功。

**要连接到您的 Amazon EC2 实例**

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.amazonaws.cn/ec2/) 的 Amazon EC2 控制台。

1. 在左侧导航菜单中，找到 **Instances (实例)** 部分。然后，选择 **Instances (实例)**。

1. 在实例列表中，选择 **VPCE-**。Tutorial-EC2Instance

1. 复制在**公有 DNS** 列中提供的主机名。  
![\[有关由启动的 Amazon EC2 实例的详细信息 Amazon CloudFormation。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-instance-details.png)

1. 打开终端。在包含密钥对的目录中，使用以下命令连接到实例，其中*instance-hostname*是您从 Amazon EC2 控制台复制的主机名：

   ```
   $ ssh -i VPCE-Tutorial-KeyPair.pem ec2-user@instance-hostname
   ```

**验证实例是否缺少 Internet 连接**
+ 在您的终端中，尝试连接到任何公共终端节点，如 amazon.com：

  ```
  $ ping amazon.com
  ```

  由于连接尝试失败，您可以随时进行取消（Windows 上按 Ctrl \$1 C 或 macOS 上按 Command \$1 C）。

**验证实例是否缺少到 Amazon SNS 的连接**

1. 登录 [Amazon SNS 控制台](https://console.amazonaws.cn/sns/home)。

1. 在左侧导航菜单中，选择 **Topics (主题)**。

1. 在 **Topics (主题)** 页面上，复制主题 **VPCE-Tutorial-Topic** 的 Amazon Resource Name (ARN)。

1. 在您的终端中，尝试向该主题发布消息：

   ```
   $ aws sns publish --region aws-region --topic-arn sns-topic-arn --message "Hello"
   ```

   由于发布尝试失败，您可以随时进行取消。

## 步骤 4：为 Amazon SNS 创建 Amazon VPC 终端节点
<a name="sns-vpc-endpoint"></a>

要将您的 VPC 连接到 Amazon SNS，请定义一个接口 VPC 终端节点。在添加终端节点后，您可以登录您的 VPC 中的 Amazon EC2 实例，然后在这里，您可以使用 Amazon SNS API。您可以将消息发布到该主题，而且私下发布消息。它们留在 Amazon 网络中，并且不会在公共互联网上旅行。

**注意**  
该实例仍然无法访问互联网上的其他 Amazon 服务和终端节点。

**创建终端节点**

1. 打开位于 [https://console.aws.amazon.com/vpc/](https://console.amazonaws.cn/vpc/) 的 Amazon VPC 控制台。

1. 在左侧导航菜单中，选择**端点**。

1. 选择**创建端点**。

1. 在 **Create Endpoint**（创建终端节点）页面上，对于 **Service category**（服务类别），保留默认选择 **Amazon 服务**。

1. 对于 **Service Name**（服务名称），选择 Amazon SNS 的服务名称。

   服务名称因所选区域而异。例如，如果您选择美国东部（弗吉尼亚北部），则服务名称为 **com.amazonaws。 *us-east-1*.sns。**

1. 对于 **VPC**，选择名为 **VPCE-Tutorial-VPC** 的 VPC。  
![\[“创建终端节点”页面上的 VPC 菜单。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-create-endpoint-vpc.png)

1. 对于 **Subnets (子网)**，选择在子网 ID 中具有 *VPCE-Tutorial-Subnet* 的子网。  
![\[“创建终端节点”页面上的子网。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-create-endpoint-subnet.png)

1. 对于 **Enable Private DNS Name (启用私有 DNS 名称)**，选择 **Enable for this endpoint (为此终端节点启用)**。

1. 对于**安全组，选择选择安全组****，然后选择** **vpce-T** utorial-。SecurityGroup  
![\[“创建终端节点”页面上的安全组。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-create-endpoint-security-group.png)

1. 选择**创建端点**。Amazon VPC 控制台确认已创建 VPC 终端节点。  
![\[确认消息在您创建终端节点后显示。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-create-endpoint-confirmation.png)

1. 选择**关闭**。

   Amazon VPC 控制台会打开 **Endpoints**（终端节点）页面。新终端节点的状态为 **pending (待处理)**。在创建过程完成后的几分钟内，该状态将变为 **available (可用)**。  
![\[状态为可用的 VPC 终端节点。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-create-endpoint-status-available.png)

## 步骤 5：向 Amazon SNS 主题发布消息
<a name="sns-vpc-publish"></a>

现在，您的 VPC 包含 Amazon SNS 的终端节点，您可以登录 Amazon EC2 实例并向该主题发布消息。

**发布消息**

1. 如果您的终端不再连接到您的 Amazon EC2 实例，请再次连接：

   ```
   $ ssh -i VPCE-Tutorial-KeyPair.pem ec2-user@instance-hostname
   ```

1. 运行您在之前执行过的相同命令，以向您的 Amazon SNS 主题发布消息。此时，发布尝试成功，并且 Amazon SNS 会返回一条消息 ID：

   ```
   $ aws sns publish --region aws-region --topic-arn sns-topic-arn --message "Hello"
   
   
   {
       "MessageId": "5b111270-d169-5be6-9042-410dfc9e86de"
   }
   ```

## 步骤 6：验证您的消息传输
<a name="sns-vpc-verify"></a>

当 Amazon SNS 主题收到消息时，它会通过将消息发送到两个订阅 Lambda 函数来扇出该消息。当这些函数收到消息时，它们会将事件记录到 CloudWatch 日志中。要验证您的消息传送是否成功，请检查函数是否已调用，并检查 CloudWatch 日志是否已更新。

**验证是否已调用 Lambda 函数**

1. 打开 Amazon Lambda 控制台，网址为[https://console.aws.amazon.com/lambda/](https://console.amazonaws.cn/lambda/)。

1. 在 **Functions (函数)** 页面上，选择 **VPCE-Tutorial-Lambda-1**。

1. 选择**监控**。

1. 检查 **Invocation count (调用计数)** 图表。此图显示了已运行 Lambda 函数的次数。

   调用计数与您向主题发布消息的次数匹配。  
![\[Lambda 控制台中的调用计数图表。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-lambda-invocation-count.png)

**验证 CloudWatch 日志是否已更新**

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/)。

1. 在左侧导航菜单中，选择 **Logs (日志)**。

1. 检查由 Lambda 函数写入的日志：

   1. 选择 /-Tutorial **aws/lambda/VPCE-Lambda-1/** 日志组。

   1. 选择日志流。

   1. 检查日志是否包含条目 `From SNS: Hello`。  
![\[该 CloudWatch 日志包含条目 “来自 SNS：你好”。\]](http://docs.amazonaws.cn/sns/latest/dg/images/vpce-tutorial-cloudwatch-log.png)

   1. 选择控制台顶部的 **Log Groups (日志组)** 以返回 **Log Groups (日志组)** 页面。然后，对/-Tutorial-aws/lambda/VPCE Lambda-2/ 日志组重复上述步骤。

恭喜您！通过将 Amazon SNS 的终端节点添加到 VPC，您能够从由 VPC 管理的网络内将消息发布到主题。消息是私下发布的，不会对公共 Internet 公开。

## 步骤 7：清除
<a name="sns-vpc-delete"></a>

除非您想要保留您创建的资源，否则可立即将其删除。通过删除不再使用的 Amazon 资源，可以防止对您的资源产生不必要的费用 Amazon Web Services 账户。

首先，使用 Amazon VPC 控制台删除您的 VPC 终端节点。然后，通过在 Amazon CloudFormation 控制台中删除堆栈来删除您创建的其他资源。当您删除堆栈时， Amazon CloudFormation 会将该堆栈的资源从中移除 Amazon Web Services 账户。

**删除您的 VPC 终端节点**

1. 打开位于 [https://console.aws.amazon.com/vpc/](https://console.amazonaws.cn/vpc/) 的 Amazon VPC 控制台。

1. 在左侧导航菜单中，选择**端点**。

1. 选择您创建的终端节点。

1. 选择 **Actions (操作)**，然后选择 **Delete Endpoint (终端节点)**。

1. 在 **Delete Endpoint (删除终端节点)** 窗口中，选择 **Yes, Delete (是，删除)**。

   终端节点状态将变为 **deleting (正在删除)**。删除操作完成后，终端节点将从页面中删除。

**删除您的 Amazon CloudFormation 堆栈**

1. 在 [https://console.aws.amazon.com/cloudformat](https://console.amazonaws.cn/cloudformation/) ion 上打开 Amazon CloudFormation 控制台。

1. 选择堆栈 **VPCE-Tutorial-Stack**。

1. 选择 **Actions**)（操作），然后选择 **Delete Stack**（删除堆栈）。

1. 在 **Delete Stack (删除堆栈)** 窗口中，选择 **Yes, Delete (是，删除)**。

   堆栈状态将变为 **DELETE\$1IN\$1PROGRESS**。删除操作完成后，堆栈将从页面中删除。

## 相关资源
<a name="sns-vpc-resources-related"></a>

有关详细信息，请参阅以下资源：
+ [Amazon 安全博客：使用保护发布到 Amazon SNS 的消息 Amazon PrivateLink ](https://www.amazonaws.cn/blogs/security/securing-messages-published-to-amazon-sns-with-aws-privatelink/)
+ [什么是 Amazon VPC？](https://docs.amazonaws.cn/vpc/latest/userguide/VPC_Introduction.html)
+ [VPC 端点](https://docs.amazonaws.cn/vpc/latest/userguide/vpc-endpoints.html)
+ [什么是 Amazon EC2？](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/concepts.html)
+ [Amazon CloudFormation 概念](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html)