

# 第 3 步：在生产环境中使用 DynamoDB 服务进行部署
<a name="TicTacToe.Phase3"></a>

**Topics**
+ [3.1：为 Amazon EC2 创建一个 IAM 角色](#TicTacToe.DeployInProd.IAMCreateRole)
+ [3.2：在 Amazon DynamoDB 中创建 Games 表](#TicTacToe.DeployInProd.CreateTable)
+ [3.3：捆绑和部署井字游戏应用程序代码](#TicTacToe.DeployInProd.IAMBundleDeployCode)
+ [3.4：设置 AWS Elastic Beanstalk 环境](#TicTacToe.DeployInProd.SetUpElasticBeanstalk)

在前面的部分中，您在使用 DynamoDB local 的计算机上本地部署并测试了井字游戏应用程序。现在，您可以按如下所示在生产环境中部署应用程序：
+ 使用 AWS Elastic Beanstalk 部署应用程序，这是一种易用的服务，用于部署和扩展 Web 应用程序及服务。有关更多信息，请参阅[将 Flask 应用程序部署到 AWS Elastic Beanstalk](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-flask.html)。

  Elastic Beanstalk 会启动一个或多个 Amazon Elastic Compute Cloud (Amazon EC2) 实例，您可以通过 Elastic Beanstalk 配置您的井字游戏应用程序将在其上运行的实例。
+ 使用 Amazon DynamoDB 服务，创建位于 AWS 上，而不是计算机本地的 `Games` 表。

此外，您还必须配置权限。您创建的任何 AWS 资源（例如 DynamoDB 中的 `Games` 表）在默认情况下是专用资源。只有资源所有者（也就是创建 `Games` 表的 AWS 账户）可以访问此表。因此，默认情况下您的井字游戏应用程序无法更新 `Games` 表。

要授予必要的权限，请创建一个 AWS Identity and Access Management (IAM) 角色，并授予此角色访问 `Games` 表的权限。您的 Amazon EC2 实例首先使用此角色。作为响应，AWS 会返回临时安全凭证，Amazon EC2 实例可使用此凭证来代表井字游戏应用程序来更新 `Games` 表。配置 Elastic Beanstalk 应用程序时，可以指定 Amazon EC2 实例可以担任的 IAM 角色。有关 IAM 角色的更多信息，请参阅 [Amazon EC2 用户指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)中的*适用于 Amazon EC2 的 IAM 角色*。

**注意**  
在您为井字游戏应用程序创建 Amazon EC2 实例之前，您必须先确定希望 Elastic Beanstalk 在其中创建实例的 AWS 区域。创建 Elastic Beanstalk 应用程序后，您需要在配置文件中提供相同的区域名称和终端节点。井字游戏应用程序会使用此文件中的信息来创建 `Games` 表，并在特定 AWS 区域中发送后续请求。DynamoDB `Games` 表和 Elastic Beanstalk 启动的 Amazon EC2 实例必须位于同一区域中。有关可用区域的列表，请参阅《Amazon Web Services 一般参考》中的 [Amazon DynamoDB](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)**。

总之，您可在生产环境中执行以下操作来部署井字游戏应用程序：

1. 利用 IAM 服务创建 IAM 角色。将策略连接到此角色，以授予 DynamoDB 操作访问 `Games` 表的权限。

1. 打包井字游戏应用程序的代码和配置文件，创建一个 `.zip` 文件。使用此 `.zip` 文件将井字游戏应用程序代码提供给 Elastic Beanstalk 以放在您的服务器上。有关创建捆绑包的更多信息，请参阅《AWS Elastic Beanstalk 开发人员指南》**中的[创建应用程序源包](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.deployment.source.html)。

   在配置文件 (`beanstalk.config`) 中提供 AWS 区域和终端节点的信息。井字游戏应用程序使用此信息来确定要与哪个 DynamoDB 区域通信。

1. 设置 Elastic Beanstalk 环境 Elastic Beanstalk 会启动一个或多个 Amazon EC2 实例，并在其上部署您的井字游戏应用程序包。在 Elastic Beanstalk 环境准备就绪后，添加 `CONFIG_FILE` 环境变量来提供配置文件名称。

1. 创建 DynamoDB 表。使用 Amazon DynamoDB 服务，在 AWS，而不是在计算机本地创建 `Games` 表。请记住，此表具有简单主键，由字符串类型的 `GameId` 分区键组成。

1. 在生产环境中测试游戏。

## 3.1：为 Amazon EC2 创建一个 IAM 角色
<a name="TicTacToe.DeployInProd.IAMCreateRole"></a>

创建 **Amazon EC2** 类型的 IAM 角色将允许运行您的井字游戏应用程序的 Amazon EC2 实例使用正确的角色，并发出应用程序请求以访问 `Games` 表。创建角色时，请选择**自定义策略**选项，然后复制和粘贴以下策略。

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

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Action":[
            "dynamodb:ListTables"
         ],
         "Effect":"Allow",
         "Resource":"*"
      },
      {
         "Action":[
            "dynamodb:*"
         ],
         "Effect":"Allow",
         "Resource":[
            "arn:aws:dynamodb:us-west-2:922852403271:table/Games",
            "arn:aws:dynamodb:us-west-2:922852403271:table/Games/index/*"
         ]
      }
   ]
}
```

------

有关更多说明，请参阅《IAM 用户指南》**中的[为 AWS 服务创建角色（AWS 管理控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

## 3.2：在 Amazon DynamoDB 中创建 Games 表
<a name="TicTacToe.DeployInProd.CreateTable"></a>

DynamoDB 的 `Games` 表用来存储游戏数据。如果该表不存在，则应用程序将为您创建该表。在这种情况下，请让应用程序创建 `Games` 表。

## 3.3：捆绑和部署井字游戏应用程序代码
<a name="TicTacToe.DeployInProd.IAMBundleDeployCode"></a>

如果您按照了此示例中的步骤操作，则您已下载井字游戏应用程序。否则，请下载应用程序并将所有文件提取到本地计算机上的文件夹。有关说明，请参阅 [第 1 步：在本地进行部署和测试](TicTacToe.Phase1.md)。

提取所有文件之后，您会有一个 `code` 文件夹。要将此文件夹交给 Elastic Beanstalk，请将此文件夹中的内容捆绑为 `.zip` 文件。首先，您需要为该文件夹添加配置文件。您的应用程序将使用区域和终端节点信息在指定区域创建一个 DynamoDB 表，并使用指定的终端节点执行后续的表操作请求。

1. 切换到井字游戏应用程序下载到的文件夹。

1. 在应用程序的根目录文件夹中，使用以下内容创建一个名为 `beanstalk.config` 的文本文件。

   ```
   [dynamodb]
   region={{<AWS region>}}
   endpoint={{<DynamoDB endpoint>}}
   ```

   例如，您可以使用以下内容。

   ```
   [dynamodb]
   region=us-west-2
   endpoint=dynamodb.us-west-2.amazonaws.com
   ```

   有关 Amazon S3 区域的列表，请参阅 *Amazon Web Services 一般参考*的 [Amazon DynamoDB](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)。
**重要**  
在配置文件中指定的区域是井字游戏应用程序在 DynamoDB 中创建 `Games` 表的位置。您必须在同一区域中创建将在下一部分中讨论的 Elastic Beanstalk 应用程序。
**注意**  
创建 Elastic Beanstalk 应用程序时，您将请求启动一个可以在其中选择环境类型的环境。要测试井字游戏示例应用程序，您可以选择**单实例**环境类型，跳过后面的内容，然后转到下一步。  
但是，**负载均衡、自动扩展**环境类型提供了高度可用和可扩展的环境，在您创建和部署其他应用程序时应考虑这一点。如果您选择此环境类型，则需要生成 UUID 并将其添加到配置文件中，如下所示。  

   ```
   [dynamodb]
   region=us-west-2
   endpoint=dynamodb.us-west-2.amazonaws.com
   [flask]
   secret_key= 284e784d-1a25-4a19-92bf-8eeb7a9example
   ```
在客户端和服务器通信中，出于安全考虑，服务器在发送响应时会发送一个签名 Cookie，客户端在下一个请求中会将其发送回服务器。只有一台服务器时，服务器可在启动时在本地生成加密密钥。有多台服务器时，所有服务器都需要知道相同的加密密钥，否则，它们将无法读取由对等服务器设置的 Cookie。通过将 `secret_key` 添加到配置文件，您告知所有服务器使用此加密密钥。

1. 压缩应用程序的根文件夹的内容（其中包括 `beanstalk.config` 文件）—例如 `TicTacToe.zip`。

1. 将 `.zip` 文件上传到 Amazon Simple Storage Service (Amazon S3) 存储桶。在下一节中，您将此 `.zip` 文件提供给 Elastic Beanstalk 以上传到一台或多台服务器。

   有关如何将文件上传到 Amazon S3 存储桶的说明，请参阅《Amazon Simple Storage Service 用户指南》**中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)和[将对象添加到存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PuttingAnObjectInABucket.html)。

## 3.4：设置 AWS Elastic Beanstalk 环境
<a name="TicTacToe.DeployInProd.SetUpElasticBeanstalk"></a>

在此步骤中，您将创建一个 Elastic Beanstalk 应用程序，该应用程序是包含环境的组件集合。在本示例中，您将启动一个 Amazon EC2 实例以部署和运行您的井字游戏应用程序。

1. 输入以下自定义 URL 以设置 Elastic Beanstalk 控制台，从而设置环境。

   ```
   https://console.aws.amazon.com/elasticbeanstalk/?region={{<AWS-Region>}}#/newApplication
   ?applicationName=TicTacToe{{your-name}}
   &solutionStackName=Python
   &sourceBundleUrl=https://s3.amazonaws.com/{{<bucket-name>}}/{{TicTacToe.zip}}
   &environmentType=SingleInstance
   &instanceType=t1.micro
   ```

   有关自定义 URL 的更多信息，请参见*AWS Elastic Beanstalk开发人员指南*的[构建 Launch Now URL](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/launch-now-url.html)。对于此 URL，请记录以下内容：
   + 您必须提供一个 AWS 区域名称（与您在配置文件中提供的名称相同），一个 Amazon S3 存储桶名称和对象名称。
   + 在测试中，此 URL 会请求 **SingleInstance** 环境类型，并将 `t1.micro` 作为实例类型。
   + 应用程序名称必须唯一。因此，在上述 URL 中，我们建议您将 `applicationName` 放在您的名字之后。

   此操作将打开 Elastic Beanstalk 控制台。在部分情况下，您可能需要登录。

1. 在 Elastic Beanstalk 控制台中选择 **Review and Launch (审核并启动)**，然后选择 **Launch (启动)**。

1. 记录 URL 供以后引用。此 URL 可打开您的井字游戏应用程序主页。  
![在主页上显示正在为其创建消息的环境的应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-beanstalk-setup-50.png)

1. 配置井字游戏应用程序，向其提供配置文件的位置。

   Elastic Beanstalk 创建应用程序后，选择 **Configuration (配置)**。

   1. 选择 **Software Configuration (软件配置)** 旁边的齿轮图标，如以下屏幕截图中所示。  
![在软件配置旁边显示齿轮图标的井字游戏应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-beanstalk-setup-60.png)

   1. 在 **Environment Properties (环境属性)** 部分的最后，输入 **CONFIG\_FILE** 及其值 **beanstalk.config**，然后选择 **Save (保存)**。

      此环境的更新可能需要几分钟才能完成。  
![显示“环境属性”部分的应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-beanstalk-setup-70.png)

   更新完成后，您可以开始玩游戏。

1. 在浏览器中，输入上一步中复制的 URL，如以下示例中所示。

   ```
   http://{{<pen-name>}}.elasticbeanstalk.com
   ```

   执行此操作将打开应用程序主页。  
![显示创建按钮、邀请、正在进行的游戏和最近历史记录的应用程序主页屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-inprod-playgame-10.png)

1. 以 testuser1 身份登录，然后选择 **CREATE (创建)** 以启动新的井字游戏。

1. 在 **Choose an Opponent (选择对手)** 框中输入 **testuser2**。  
![显示“选择对手”框的应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-inprod-playgame-20.png)

1. 打开另一个浏览器窗口。

   确保您在浏览器窗口中清除了所有 Cookie，这样您才不会作为同一用户登录。

1. 输入同一 URL 以打开应用程序主页，如以下示例中所示。

   ```
   http://{{<env-name>}}.elasticbeanstalk.com
   ```

1. 以 testuser2 身份登录。

1. 对于等待接受邀请列表中来自 testuser1 的邀请，选择**接受**。  
![在邀请列表中显示 testuser1 邀请的应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-inprod-playgame-30.png)

1. 现在将显示游戏页面。  
![显示一个空的井字游戏网格的应用程序屏幕截图。](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/tic-tac-toe-inprod-playgame-40.png)

   testuser1 和 testuser2 可以一起玩游戏。对于每次移动，应用程序都会将移动保存在 `Games` 表中的相应项目中。