

# 从现有的资源中创建堆栈
<a name="resource-import-new-stack"></a>

本主题演示了如何通过在模板中描述现有的 AWS 资源，从而利用这些资源创建堆栈。要改为扫描现有的资源并自动生成模板，以用于将现有资源导入 CloudFormation 或在新账户中复制资源，请参阅 [使用 IaC 生成器为现有资源生成模板](generate-IaC.md)。

**先决条件**

在开始之前，您必须具有以下内容：
+ 描述新堆栈中要包含的所有资源的模板。您可将模板保存在本地或 Amazon S3 存储桶中。
+ 对于要导入的每个资源，请包括以下内容：
  + 定义资源当前配置的属性和属性值。
  + 资源的唯一标识符，例如资源名称。有关更多信息，请参阅 [资源标识符](import-resources-manually.md#resource-import-identifiers-unique-ids)。
  + [DeletionPolicy 属性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html)。

**Topics**
+ [示例 模板](#resource-import-new-stack-example-template)
+ [使用 AWS 管理控制台 从现有的资源中创建堆栈](#resource-import-new-stack-console)
+ [使用 AWS CLI 从现有的资源中创建堆栈](#resource-import-new-stack-cli)

## 示例 模板
<a name="resource-import-new-stack-example-template"></a>

在本演练中，我们假设您使用以下名为 `TemplateToImport.json` 的示例模板，该模板指定了在 CloudFormation 之外创建的两个 DynamoDB 表。`ServiceTable` 和 `GamesTable` 都是要导入的目标。

**注意**  
此模板仅作为示例。要将其用于自己的测试目的，请使用您账户中的资源替换示例资源。

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
        "ServiceTable": {
            "Type": "AWS::DynamoDB::Table",
            "DeletionPolicy": "Retain",
            "Properties": {
                "TableName": "Service",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 1
                }
            }
        },
        "GamesTable": {
            "Type": "AWS::DynamoDB::Table",
            "DeletionPolicy": "Retain",
            "Properties": {
                "TableName": "Games",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 1
                }
            }
        }
    }
}
```

## 使用 AWS 管理控制台 从现有的资源中创建堆栈
<a name="resource-import-new-stack-console"></a>

1. 登录到 AWS 管理控制台 并打开 CloudFormation 控制台 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 在 **Stacks (堆栈)** 页面上，选择 **Create stack (创建堆栈)**，然后选择 **With existing resources (import resources) (使用现有的资源 (导入资源))**。  
![\[控制台中的 Create stack from existing resources (从现有的资源中创建堆栈) 选项。\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/create-stack-with-existing-resources.png)

1. 访问 **Import overview (导入概述)** 页面，以查看在该操作期间需要提供的内容列表。然后选择**下一步**。

1. 在 **Specify template (指定模板)** 页面上，使用以下方法之一提供模板，然后选择 **Next (下一步)**。
   + 选择 **Amazon S3 URL**，然后在文本框中指定您的模板的 URL。
   + 选择 **Upload a template file (上传模板文件)**，然后浏览您的模板。

1. 在 **Identify resources**（标识资源）页面上，标识每个目标资源。有关更多信息，请参阅 [资源标识符](import-resources-manually.md#resource-import-identifiers-unique-ids)。

   1. 在 **Identifier property (标识符属性)** 下面，选择资源标识符的类型。例如，可以使用 `TableName` 属性标识 `AWS::DynamoDB::Table` 资源。

   1. 在 **Identifier value (标识符值)** 下面，键入实际属性值。例如，示例模板中的 `GamesTable` 资源的 `TableName` 为 `Games`。

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

1. 在 **Specify stack details (指定堆栈详细信息)** 页面上，修改任何参数，然后选择 **Next (下一步)**。这会自动创建一个更改集。
**重要**  
如果您修改的现有参数启动创建、更新或删除操作，导入操作将失败。

1. 在 **Review *stack-name* (查看 <堆栈名称>)** 页面上，确认正在导入正确的资源，然后选择 **Import resources (导入资源)**。这会自动执行在上一步中创建的更改集。

   将显示新堆栈的 **Stack details**（堆栈详细信息）页面的 **Events**（事件）窗格。  
![\[控制台中的 Events (事件) 选项卡。\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/import-events.png)

1. （可选）对堆栈运行偏差检测，以确保导入的资源的模板和实际配置匹配。有关检测偏差的更多信息，请参阅 [在整个 CloudFormation 堆栈上检测偏差](detect-drift-stack.md)。

1. （可选）如果导入的资源与预期的模板配置不匹配，请更正模板配置或直接更新资源。在本演练中，我们更正模板配置以与其实际配置匹配。

   1. 为受影响的资源[恢复导入操作](resource-import-revert.md#resource-import-revert-console)。

   1. 再次将导入目标添加到模板中，从而确保模板配置与实际配置匹配。

   1. 使用修改的模板重复步骤 2 - 8，以再次导入资源。

## 使用 AWS CLI 从现有的资源中创建堆栈
<a name="resource-import-new-stack-cli"></a>

1. 要了解哪些属性标识模板中的每种资源类型，请运行 **get-template-summary** 命令并指定模板的 S3 URL。例如，可以使用 `TableName` 属性标识 `AWS::DynamoDB::Table` 资源。对于示例模板中的 `GamesTable` 资源，`TableName` 的值为 `Games`。您在下一步中需要此信息。

   ```
   aws cloudformation get-template-summary \
       --template-url https://amzn-s3-demo-bucket.s3.us-west-2.amazonaws.com/TemplateToImport.json
   ```

   有关更多信息，请参阅 [资源标识符](import-resources-manually.md#resource-import-identifiers-unique-ids)。

1. 按照以下 JSON 字符串格式，编写模板中的实际资源及其唯一标识符的列表。

   ```
   [{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"GamesTable","ResourceIdentifier":{"TableName":"Games"}},{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"ServiceTable","ResourceIdentifier":{"TableName":"Service"}}]
   ```

   或者，您可以在配置文件中指定 JSON 格式参数。

   例如，要导入 `ServiceTable` 和 `GamesTable`，可以创建一个包含以下配置的 *ResourcesToImport.txt* 文件。

   ```
   [
      {
         "ResourceType":"AWS::DynamoDB::Table",
         "LogicalResourceId":"GamesTable",
         "ResourceIdentifier":{
            "TableName":"Games"
         }
      },
      {
         "ResourceType":"AWS::DynamoDB::Table",
         "LogicalResourceId":"ServiceTable",
         "ResourceIdentifier":{
            "TableName":"Service"
         }
      }
   ]
   ```

1. 要创建更改集，请使用以下 **create-change-set** 命令并替换占位符文本。对于 `--change-set-type` 选项，请指定 **IMPORT** 的值。对于 `--resources-to-import` 选项，将示例 JSON 字符串替换为您刚刚创建的实际 JSON 字符串。

   ```
   aws cloudformation create-change-set \
       --stack-name TargetStack --change-set-name ImportChangeSet \
       --change-set-type IMPORT \
       --template-url https://amzn-s3-demo-bucket.s3.us-west-2.amazonaws.com/TemplateToImport.json \
       --resources-to-import '[{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"GamesTable","ResourceIdentifier":{"TableName":"Games"}},{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"ServiceTable","ResourceIdentifier":{"TableName":"Service"}}]'
   ```
**注意**  
`--resources-to-import` 不支持内联 YAML。JSON 字符串中对转义引号的要求因终端而异。有关更多信息，请参阅《AWS Command Line Interface User Guide**》中的 [Using quotation marks inside strings](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html#cli-usage-parameters-quoting-strings-containing)。

   或者，您可以使用文件 URL 作为 `--resources-to-import` 选项的输入内容，如以下示例所示。

   ```
   --resources-to-import file://ResourcesToImport.txt
   ```

1. 查看更改集，以确保将导入正确的资源。

   ```
   aws cloudformation describe-change-set \
       --change-set-name ImportChangeSet --stack-name TargetStack
   ```

1. 要启动更改集并导入资源，请使用以下 **execute-change-set** 命令并替换占位符文本。在成功完成该操作后 `(IMPORT_COMPLETE)`，将成功导入资源。

   ```
   aws cloudformation execute-change-set \
       --change-set-name ImportChangeSet --stack-name TargetStack
   ```

1. （可选）对 `IMPORT_COMPLETE` 堆栈运行偏差检测，以确保导入的资源的模板和实际配置匹配。有关检测偏差的更多信息，请参阅 [在单个堆栈资源上检测偏差](detect-drift-resource.md)。

   1. 对指定堆栈运行偏差检测。

      ```
      aws cloudformation detect-stack-drift --stack-name TargetStack
      ```

      如果成功，此命令将返回以下示例输出：

      ```
      { "Stack-Drift-Detection-Id" : "624af370-311a-11e8-b6b7-500cexample" }
      ```

   1. 查看指定堆栈偏差检测 ID 的偏差检测操作进度。

      ```
      aws cloudformation describe-stack-drift-detection-status \
          --stack-drift-detection-id 624af370-311a-11e8-b6b7-500cexample
      ```

   1. 查看已在指定堆栈中检查偏差的资源的偏差信息。

      ```
      aws cloudformation describe-stack-resource-drifts --stack-name TargetStack
      ```

1. （可选）如果导入的资源与预期的模板配置不匹配，请更正模板配置或直接更新资源。在本演练中，我们更正模板配置以与其实际配置匹配。

   1. 为受影响的资源[恢复导入操作](resource-import-revert.md#resource-import-revert-cli)。

   1. 再次将导入目标添加到模板中，从而确保模板配置与实际配置匹配。

   1. 使用修改的模板重复步骤 3 - 6，以再次导入资源。