View a markdown version of this page

在堆栈之间移动资源 - AWS CloudFormation

在堆栈之间移动资源

通过使用 resource import 功能,您可以在堆栈之间移动资源或重构 堆栈。您需要先在要移动的资源中添加 Retain 删除策略,以确保在从源堆栈中删除资源并将其导入到目标堆栈时保留该资源。

如果您不熟悉导入,建议您先查看 将 AWS 资源导入 CloudFormation 堆栈 主题中的介绍信息。

重要

并非所有资源都支持导入操作。在从堆栈中删除资源之前,请参阅支持导入操作的资源。如果您从堆栈中删除不支持导入操作的资源,则无法将该资源导入其他堆栈中或将其重新放回源堆栈中。

使用 AWS 管理控制台重构堆栈

  1. 在源模板中,为要移动的资源指定 Retain DeletionPolicy。

    在以下示例源模板中,Games 是该重构的目标。

    例 JSON
    { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "ServiceTable":{ "Type":"AWS::DynamoDB::Table", "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 } } } } }
  2. 打开 CloudFormation 控制台以执行堆栈更新,从而应用删除策略。

    1. 在堆栈页面上,在选择了堆栈的情况下,选择更新。

    2. 在 Prepare template (准备模板) 下面,选择 Replace current template (替换当前模板)。

    3. 在 Specify template (指定模板) 下面,在 GamesTable 上为更新的源模板提供 DeletionPolicy 属性,然后选择 Next (下一步)。

      • 选择 Amazon S3 URL,然后在文本框中指定更新的源模板的 URL。

      • 选择 Upload a template file (上传模板文件),然后浏览更新的源模板文件。

    4. 在 Specify stack details (指定堆栈详细信息) 页面上,不需要进行任何更改。选择下一步。

    5. 在 Configure stack options (配置堆栈选项) 页面上,不需要进行任何更改。选择下一步。

    6. 在查看 SourceStackName 页面上,检查所做的更改。如果您的模板包含 IAM 资源,请选择 I acknowledge that this template may create IAM resources (我确认此模板可创建 IAM 资源) 以指定您要使用模板中的 IAM 资源。有关在模板中使用 IAM 资源的更多信息,请参阅 使用 AWS Identity and Access Management 控制 CloudFormation 访问权限。然后,创建更改集以更新源堆栈,或者直接更新源堆栈。

  3. 从源模板中删除资源、相关参数和输出,然后将它们添加到目标模板中。

    现在,源模板如下所示。

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

    以下示例目标模板当前具有 PlayersTable 资源,现在还包含 GamesTable。

    例 JSON
    { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "PlayersTable": { "Type": "AWS::DynamoDB::Table", "Properties": { "TableName": "Players", "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 } } } } }
  4. 重复步骤 2 - 3 以再次更新源堆栈,此次是从堆栈中删除目标资源。

  5. 执行导入操作以将 GamesTable 添加到目标堆栈中。

    1. 在 Stacks (堆栈) 页面上,在选择了父堆栈的情况下,选择 Stack actions (堆栈操作),然后选择 Import resources into stack (将资源导入到堆栈)。

      控制台中的 Import resources into stack (将资源导入到堆栈) 选项。
    2. 访问 Import overview (导入概述) 页面,以查看在该操作期间需要提供的内容列表。然后选择下一步。

    3. 在 Specify template(指定模板)页面上,完成以下操作之一,然后选择 Next(下一步)。

      • 选择 Amazon S3 URL,然后在文本框中指定一个 URL。

      • 选择 Upload a template file (上传模板文件),然后浏览要上传的文件。

    4. 在 Identify resources (标识资源) 页面上,标识您要移动的资源(在本示例中为 GamesTable)。有关更多信息,请参阅 资源标识符。

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

      2. 在 Identifier value (标识符值) 下面,键入实际属性值。例如 GamesTables。

      3. 选择下一步。

    5. 在 Specify stack details (指定堆栈详细信息) 页面上,修改任何参数,然后选择 Next (下一步)。这会自动创建一个更改集。

      重要

      如果您修改的现有参数启动创建、更新或删除操作,导入操作将失败。

    6. 在查看 TargetStackName 页面上,确认正在导入正确的资源,然后选择导入资源。这会自动启动在上一步中创建的更改集。此时,任何堆栈级标签将应用于导入的资源。

    7. 将显示父堆栈的 Stack details(堆栈详细信息)页面的 Events(事件)窗格。

      控制台中的 Events (事件) 选项卡。
      注意

      在该导入操作完成后,无需对父堆栈运行偏差检测,因为 AWS::CloudFormation::Stack 资源已由 CloudFormation 进行管理。

使用 AWS CLI重构堆栈

  1. 在源模板中,为要移动的资源指定 Retain DeletionPolicy。

    在以下示例源模板中,GamesTable 是该重构的目标。

    例 JSON
    { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "ServiceTable":{ "Type":"AWS::DynamoDB::Table", "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 } } } } }
  2. 更新源堆栈以将删除策略应用于资源。

    aws cloudformation update-stack --stack-name SourceStackName
  3. 从源模板中删除资源、相关参数和输出,然后将它们添加到目标模板中。

    现在,源模板如下所示。

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

    以下示例目标模板当前具有 PlayersTable 资源,现在还包含 GamesTable。

    例 JSON
    { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "PlayersTable": { "Type": "AWS::DynamoDB::Table", "Properties": { "TableName": "Players", "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 } } } } }
  4. 更新源堆栈以从堆栈中删除 GamesTable 资源及其相关参数和输出。

    aws cloudformation update-stack --stack-name SourceStackName
  5. 按照以下 JSON 字符串格式,编写要导入的实际资源及其唯一标识符的列表。有关更多信息,请参阅 资源标识符。

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

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

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

    [ { "ResourceType":"AWS::DynamoDB::Table", "LogicalResourceId":"GamesTable", "ResourceIdentifier": { "TableName":"Games" } } ]
  6. 要创建更改集,请使用以下 create-change-set 命令并替换占位符文本。对于 --change-set-type 选项,请指定 IMPORT 的值。对于 --resources-to-import 选项,将示例 JSON 字符串替换为您刚刚创建的实际 JSON 字符串。

    aws cloudformation create-change-set \ --stack-name TargetStackName --change-set-name ImportChangeSet \ --change-set-type IMPORT \ --template-body file://TemplateToImport.json \ --resources-to-import "'[{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"GamesTable","ResourceIdentifier":{"TableName":"Games"}}]'"
    注意

    --resources-to-import 不支持内联 YAML。JSON 字符串中对转义引号的要求因终端而异。有关更多信息,请参阅《AWS Command Line Interface User Guide》中的 Using quotation marks inside strings。

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

    --resources-to-import file://ResourcesToImport.txt
  7. 查看更改集,以确保将正确的资源导入到目标堆栈中。

    aws cloudformation describe-change-set \ --change-set-name ImportChangeSet
  8. 要启动更改集并导入资源,请使用以下 execute-change-set 命令并替换占位符文本。此时,任何堆栈级标签将应用于导入的资源。在成功完成该操作后 (IMPORT_COMPLETE),将成功导入资源。

    aws cloudformation execute-change-set \ --change-set-name ImportChangeSet --stack-name TargetStackName
    注意

    在该导入操作完成后,无需对目标堆栈运行偏差检测,因为资源已由 CloudFormation 进行管理。