

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 從 Amazon VPC 發佈 Amazon SNS 訊息
<a name="sns-vpc-tutorial"></a>

本節說明如何發佈訊息到 Amazon SNS 主題，同時在私有網路中保持安全。您從託管在 Amazon Virtual Private Cloud (Amazon VPC) 中的 Amazon EC2 執行個體發佈訊息。訊息會保留在 AWS 網路中，而不會傳輸公有網際網路。透過從 VPC 私下發佈訊息，您可以改善應用程式和 Amazon SNS 之間的流量安全性。當您發佈客戶的個人身分識別資訊 (PII)，或是當您的應用程式受限於市場法規時，此安全性是很重要的。例如，如果您的醫療系統必須遵守「健康保險流通與責任法案」(HIPAA)，或金融系統必須遵守「支付卡產業資料安全標準」(PCI DSS)，則私下發佈會很有幫助。

一般步驟如下：
+ 使用 AWS CloudFormation 範本在您的 中自動建立暫時私有網路 AWS 帳戶。
+ 以 Amazon SNS 建立與 VPC 連線的 VPC 端點。
+ 登入到 Amazon EC2 執行個體並私下和發佈訊息到 Amazon SNS 主題。
+ 確認該訊息已成功傳遞。
+ 刪除您在此程序期間建立的資源，使其不會保留在您的 中 AWS 帳戶。

下圖說明您在完成以下步驟時在 AWS 帳戶中建立的私有網路：

![您在這些步驟中建立的私有網路架構。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-architecture.png)


這個網路包含一個 VPC，其中包含 Amazon EC2 執行個體。該執行個體透過*介面 VPC 端點*連接至 Amazon SNS。這種端點類型會連線至採用 AWS PrivateLink 技術的 服務。建立此連接後，即使網路與公有網際網路中斷，您也可以登入 Amazon EC2 執行個體，並將訊息發佈到 Amazon SNS 主題。主題會向兩個訂閱 AWS Lambda 函數說明收到的訊息。這些函數會記錄它們在 Amazon CloudWatch Logs 中所收到的訊息。

完成這些步驟需約 20 分鐘。

**Topics**
+ [開始之前](#sns-vpc-prereqs)
+ [步驟 1：建立金鑰對](#sns-vpc-keypair)
+ [步驟 2：建立資源](#sns-vpc-resources)
+ [步驟 3：檢查執行個體的網際網路連線](#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 (AWS) 帳戶。當您註冊時，您的帳戶會自動註冊所有 服務 AWS，包括 Amazon SNS 和 Amazon VPC。如果您尚未建立帳戶，請前往 [https://aws.amazon.com/](https://aws.amazon.com/)，然後選擇 **Create a Free Account** (建立免費帳戶)。

## 步驟 1：建立 Amazon EC2 金鑰對
<a name="sns-vpc-keypair"></a>

*金鑰對*是用來登入 Amazon EC2 執行個體的。它包含用於加密您登入資訊的公有金鑰，以及用來解密的私有金鑰。當您建立金鑰對時，您會下載一份私有金鑰複本。稍後，您可以使用金鑰對登入 Amazon EC2 執行個體。若要登入，您需指定金鑰對名稱，並提供私有金鑰。

**建立一組金鑰對**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)：// 開啟 Amazon EC2 主控台。

1. 在左側導覽功能表，找到 **Network & Security** (網路和安全) 部分。然後，選擇 **Key Pairs** (金鑰對)。

1. 選擇 **Create Key Pair** (建立金鑰對)。

1. 在 **Create Key Pair** (建立金鑰對) 視窗中，對於 **Key pair name** (金鑰對名稱)，輸入 **VPCE-Tutorial-KeyPair**。然後，選擇 **Create** (建立)。  
![在金鑰對名稱欄位中，使用文字 "VPCE-Tutorial-KeyPair" 建立金鑰對視窗。](http://docs.aws.amazon.com/zh_tw/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：建立 AWS 資源
<a name="sns-vpc-resources"></a>

若要設定基礎設施，請使用 an CloudFormation *template*。範本是一種檔案，是一種用來建置 Amazon EC2 執行個體與 Amazon SNS 主題之類等 AWS 資源的藍圖。在 GitHub 上有提供此流程的範本，供您下載。

您可以將範本提供給 CloudFormation，並 CloudFormation 佈建做為 *堆疊*所需的資源 AWS 帳戶。堆疊是一組視為單一單位進行管理的資源。完成這些步驟後，您可以使用 一次 CloudFormation 刪除堆疊中的所有資源。除非您想要 AWS 帳戶，否則這些資源不會保留在您的 中。

此過程的堆疊包含下列資源：
+ 一個 VPC 和關聯的網路資源，包括子網路、安全群組、網際網路閘道和路由表。
+ 在 VPC 中子網路啟動的 Amazon EC2 執行個體。
+ Amazon SNS 主題。
+ 兩個 AWS Lambda 函數。這些函數接收發佈到 Amazon SNS 主題的訊息，並在 CloudWatch Logs 中記錄事件。
+ Amazon CloudWatch 指標和日誌。
+ 允許 Amazon EC2 執行個體使用 Amazon SNS 的 IAM 角色，以及允許 Lambda 函數寫入至 CloudWatch Logs 的 IAM 角色。

**建立 AWS 資源**

1. 從 GitHub 網站下載[範本檔案](https://github.com/aws-samples/aws-sns-samples/blob/master/templates/SNS-VPCE-Tutorial-CloudFormation.template)。

1. 登入 [CloudFormation 主控台](https://console.aws.amazon.com/cloudformation)。

1. 選擇 **Create Stack** (建立堆疊)。

1. 在 **Select Template** (選擇範本) 頁面中，選擇 **Upload a template to Amazon S3** (上傳範本到 Amazon S3)、選擇檔案，並選擇 **Next** (下一步)。

1. 在 **Specify Details** (指定詳細資訊) 頁面，指定堆疊和金鑰名稱：

   1. 在 **Stack Name** (堆疊名稱) 中輸入 **VPCE-Tutorial-Stack**。

   1. 對於 **KeyName** (金鑰名稱)，選擇 **VPCE-Tutorial-KeyPair** (VPCE-教學-金鑰對)。

   1. 對於 **SSHLocation** (SSH 位置)，保留預設值 **0.0.0.0/0**。  
![指定詳細資訊頁面顯示堆疊名稱、KeyName 和 SSHLocation 的填入值欄位。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-stack-name.png)

   1. 選擇**下一步**。

1. 在 **Options** (選項) 頁面，保留所有預設值，然後選擇 **Next** (下一步)。

1. 請在 **Review** (檢閱) 頁面上確認堆疊詳細資訊。

1. 在**功能**下，確認 CloudFormation 可能會建立具有自訂名稱的 IAM 資源。

1. 選擇**建立**。

    CloudFormation 主控台會開啟 **Stacks** 頁面。VPCE-Tutorial-Stack (VPCE-教學-堆疊) 的狀態為 **CREATE\_IN\_PROGRESS** (正在建立中)。在幾分鐘的時間內，狀態會在建立程序完成後變更為 **CREATE\_COMPLETE** (建立完成)。  
![狀態為 CREATE_COMPLETE 的 CloudFormation 堆疊。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-stack-create-complete.png)
**提示**  
選擇 **Refresh** (重新整理) 按鈕以查看最新的堆疊狀態。

## 步驟 3：確認您的 Amazon EC2 執行個體無法存取網際網路
<a name="sns-vpc-connection"></a>

之前步驟中，在您的 VPC 啟動的 Amazon EC2 執行個體無法存取網際網路。它不允許傳出流量，而且無法發佈訊息到 Amazon SNS。請登入執行個體以驗證。然後，嘗試連接到公有端點，並嘗試傳送訊息至 Amazon SNS。

此時您的發佈嘗試失敗。後續步驟中，在您為 Amazon SNS 建立 VPC 端點後，您的發佈嘗試成功。

**連線到您的 Amazon EC2 執行個體。**

1. 前往 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 開啟 Amazon EC2 主控台。

1. 在左側導覽功能表，找到 **Instances** (執行個體) 部分。然後，選擇 **Instances** (執行個體)。

1. 在執行個體清單中，選取 **VPCE-Tutorial-EC2Instance** (VPCE-教學-EC2 執行個體)。

1. 複製**公有 DNS** 欄中提供的主機名稱。  
![由 啟動之 Amazon EC2 執行個體的詳細資訊 CloudFormation。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-instance-details.png)

1. 開啟終端機。從包含金鑰對的目錄中，使用以下命令連線到執行個體，其中 {{instance-hostname}} (執行個體主機名稱) 是您從 Amazon EC2 主控台複製的主機名稱：

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

**驗證該執行個體沒有網際網路連線能力**
+ 在您的終端機中，嘗試連接到任何公有端點，例如 amazon.com：

  ```
  $ ping amazon.com
  ```

  由於連線嘗試失敗，您可以隨時取消 (在 Windows 上鍵入 Ctrl\+C，或在 macOS 上鍵入 Command\+C)。

**確認該執行個體沒有連線至 Amazon SNS 的能力**

1. 登入 [Amazon SNS 主控台](https://console.aws.amazon.com/sns/home)。

1. 在左側的導覽功能表中，選擇 **Topics** (主題)。

1. 在 **Topics** (主題) 頁面，為主題 **VPCE-Tutorial-Topic** (VPCE-教學-主題) 複製 Amazon 資源名稱 (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。您可以將訊息發佈到主題，該訊息為私下發佈。它們會留在 AWS 網路中，而且不會前往公有網際網路。

**注意**  
執行個體仍然無法存取網際網路上的其他服務 AWS 和端點。

**建立端點**

1. 在 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 開啟 Amazon VPC 主控台。

1. 在左側的導覽功能表中，選擇 **Endpoints** (端點)。

1. 選擇 **Create Endpoint** (建立端點)。

1. 在 **Create Endpoint** (建立端點) 頁面上，對於 **Service category** (服務類別)，保留 **AWS services** ( 服務) 的預設選擇。

1. 對於 **Service Name** (服務名稱)，選擇 Amazon SNS 服務名稱。

   該服務名稱取決於所選區域。例如，如果您選擇美國東部 (維吉尼亞北部)，服務名稱會是 **com.amazonaws.{{us-east-1}}.sns**。

1. 對於 **VPC**，選擇名稱為 **VPCE-Tutorial-VPC** (VPCE-教學-VPC) 的 VPC。  
![在「建立端點」頁面上的 VPC 功能表。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-create-endpoint-vpc.png)

1. 對於 **Subnets** (子網路)，在子網路 ID 中選擇有 *VPCE-Tutorial-Subnet* 的子網路。  
![在「建立端點」頁面上的子網路。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-create-endpoint-subnet.png)

1. 對於 **Enable Private DNS Name** (啟用私有 DNS 名稱)，選擇 **Enable for this endpoint** (為此端點啟用)。

1. 對於 **Security group** (安全群組)，選擇 **Select security group** (選取安全群組)，並選擇 **VPCE-Tutorial-SecurityGroup** (VPCE-教學-安全群組)。  
![在「建立端點」頁面上的安全群組。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-create-endpoint-security-group.png)

1. 選擇 **Create endpoint** (建立端點)。Amazon VPC 主控台確認 VPC 端點已建立。  
![在建立端點後，會顯示確認訊息。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-create-endpoint-confirmation.png)

1. 選擇**關閉**。

   Amazon VPC 主控台開啟 **Endpoints** (端點) 頁面。新的端點狀態為 **pending** (等待中)。在幾分鐘的時間內，狀態會在建立程序完成後變更為 **available** (可用)。  
![VPC 端點狀態為可用。](http://docs.aws.amazon.com/zh_tw/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 Logs。為了驗證您的訊息交付成功，可檢查已呼叫的函數，並檢查 CloudWatch Logs 已更新。

**確認 Lambda 函數已呼叫**

1. 在 https：//[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 開啟 AWS Lambda 主控台。

1. 在 **Functions** (函數) 頁面，選擇 ** VPCE-Tutorial-Lambda-1** (VPCE-教學-Lambda-1)。

1. 選擇 **Monitoring** (監控)。

1. 檢查 **Invocation count** (呼叫次數) 圖表。此圖表顯示 Lambda 函數已執行的次數。

   叫用次數符合您發佈訊息到主題的發佈次數。  
![Lambda 主控台中的呼叫次數圖表。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-lambda-invocation-count.png)

**確認 CloudWatch Logs 已更新**

1. 透過 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 開啟 CloudWatch 主控台。

1. 在左側的導覽功能表中，選擇 **Logs** (日誌)。

1. 檢查由 Lambda 函數所寫入的日誌：

   1. 選擇 **/aws/lambda/VPCE-Tutorial-Lambda-1/** 日誌群組。

   1. 選擇日誌串流。

   1. 檢查該日誌包含項目 `From SNS: Hello`。  
![該 CloudWatch Logs 包含項目「From SNS: Hello」。](http://docs.aws.amazon.com/zh_tw/sns/latest/dg/images/vpce-tutorial-cloudwatch-log.png)

   1. 在主控台頂端選擇 **Log Groups**(日誌群組)，以返回 **Log Groups** (日誌群組) 頁面。然後，請為 /aws/lambda/VPCE-Tutorial-Lambda-2/ 日誌群組重複上述步驟。

恭喜您！透過為 Amazon SNS 新增端點至 VPC，您可以在由 VPC 管理的網路中發佈訊息到主題。私下發佈的訊息不會公開到公有網際網路。

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

除非您想要保留建立的資源，否則您現在便可將它們刪除。透過刪除您不再使用 AWS 的資源，您可以避免不必要的 費用 AWS 帳戶。

首先，請使用 Amazon VPC 主控台刪除您的 VPC 端點。然後，刪除您在 CloudFormation 主控台中刪除堆疊所建立的其他資源。當您刪除堆疊時， CloudFormation 會從 中移除堆疊的資源 AWS 帳戶。

**刪除您的 VPC 端點**

1. 在 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 開啟 Amazon VPC 主控台。

1. 在左側的導覽功能表中，選擇 **Endpoints** (端點)。

1. 選擇您建立的端點。

1. 選擇 **Actions** (動作)，然後選擇 **Delete Endpoint** (刪除端點)。

1. 在 **Delete Endpoint** (刪除端點) 視窗中，選擇 **Yes, Delete** (是的，刪除)。

   該端點狀態變更為 **deleting** (刪除)。當刪除完成後，該端點便從頁面刪除。

**刪除您的 CloudFormation 堆疊**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選取堆疊 **VPCE-Tutorial-Stack** (VPCE-教學-堆疊)。

1. 選擇 **Actions** (動作)，然後選擇 **Delete Stack** (刪除堆疊)。

1. 在 **Delete Stack** (刪除堆疊) 視窗中，選擇 **Yes, Delete** (是的，刪除)。

   該堆疊狀態變更為 **DELETE\_IN\_PROGRESS** (正在刪除中)。當刪除完成後，該堆疊便從頁面刪除。

## 相關資源
<a name="sns-vpc-resources-related"></a>

如需詳細資訊，請參閱下列資源。
+ [AWS 安全部落格：使用 AWS PrivateLink 保護發佈至 Amazon SNS 的訊息 ](https://aws.amazon.com/blogs/security/securing-messages-published-to-amazon-sns-with-aws-privatelink/)
+ [什麼是 Amazon VPC？](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Introduction.html)
+ [VPC 端點](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints.html)
+ [什麼是 Amazon EC2？](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html)
+ [CloudFormation 概念](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html)