亚马逊AWS官方博客

AWS CloudFormation 的新功能 – 从故障点快速重试堆栈操作

云计算的巨大优势之一是您有权访问可编程基础设施。这可让您管理基础设施即代码,并将相同的应用程序代码开发实践应用于基础设施预置。

AWS CloudFormation 为您提供了一种简单的方法,可以对相关 AWS 和第三方资源集合进行建模,快速、一致地预置它们,并在其整个生命周期中对它们进行管理。CloudFormation 模板描述了所需的资源及其依赖关系,以便您将它们作为堆栈共同启动和配置。您可以使用模板将整个堆栈作为单个单元创建、更新和删除,而不是单独管理资源。

创建或更新堆栈时,您的操作可能会由于不同的原因而失败。例如,模板、模板的参数中可能存在错误,也可能存在模板之外的问题,例如 AWS Identity and Access Management (IAM) 权限错误。发生此类错误时,CloudFormation 会将堆栈回滚到之前的稳定状态。对于堆栈创建,这意味着删除直到出错点之前创建的所有资源。对于堆栈更新,这意味着恢复以前的配置。

回滚到以前状态的操作对于生产环境来说非常合适,但您可能很难理解出现错误的原因。根据模板的复杂性和所涉及资源的数量,您可能会花很多时间等待所有资源回滚,然后再使用正确的配置更新模板并重试该操作。

今天,我很高兴与大家分享的功能是,CloudFormation 目前可让您禁用自动回滚,在错误发生之前保持资源成功创建或更新,以及从故障点重试堆栈操作。通过这种方式,您可以快速迭代以解决和修复错误,并大大减少在开发环境中测试 CloudFormation 模板所需的时间。您可以在创建堆栈、更新堆栈时以及执行更改集时应用此新功能。我们来看看这些步骤的实际操作。

快速迭代以解决和修复 CloudFormation 堆栈问题
对于我的一个应用程序,我需要设置 Amazon Simple Storage Service (Amazon S3) 存储桶、Amazon Simple Queue Service (SQS) 队列和 Amazon DynamoDB 表,该表将项目级更改串流至 Amazon Kinesis 数据流。对于此设置,我编写了 CloudFormation 模板的第一个版本。

AWSTemplateFormatVersion: "2010-09-09"
说明:一个用于解决和修复问题的示例模板
Parameters:
  ShardCountParameter:
    Type: Number
    说明:Kinesis 流的分区数
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
  MyQueue:
    Type: AWS::SQS::Queue
  MyStream:
    Type: AWS::Kinesis::Stream
    Properties:
      ShardCount: !Ref ShardCountParameter
  MyTable:
    Type: AWS::DynamoDB::Table
    Properties:
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: "ArtistId"
          AttributeType: "S"
        - AttributeName: "Concert"
          AttributeType: "S"
        - AttributeName: "TicketSales"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "ArtistId"
          "KeyType": "HASH"
        - AttributeName: "Concert"
          KeyType: "RANGE"
      KinesisStreamSpecification:
        StreamArn: !GetAtt MyStream.Arn
Outputs:
  BucketName:
    Value: !Ref MyBucket
    说明:我的 S3 存储桶的名称
  QueueName:
    Value: !GetAtt MyQueue.QueueName
    说明:我的 SQS 队列的名称
  StreamName:
    Value: !Ref MyStream
    说明:我的 Kinesis 流的名称
  TableName:
    Value: !Ref MyTable
    说明:我的 DynamoDB 表的名称

现在,我想用这个模板创建一个堆栈。在 CloudFormation 控制台上,我选择创建堆栈。然后,我上传模板文件并选择下一步

控制台屏幕截图。

我输入堆栈的名称。然后,我填写堆栈参数。我的模板文件有一个参数 (ShardCountParameter),用于配置 Kinesis 数据流的分区数量。我知道分区数量应该大于或等于 1,但错误地输入 0 并选择下一步

控制台屏幕截图。

为了创建、修改或删除堆栈中的资源,我使用 IAM 角色。这样,我就明确界定了 CloudFormation 可用于堆栈操作的权限。此外,我可以使用相同的角色来在标准化和可重复的环境中自动部署堆栈。

权限中,我选择要用于堆栈操作的 IAM 角色。

控制台屏幕截图。

现在是使用新功能的时候了! 在堆栈故障选项中,我选择保留成功预置的资源,以便在出错时保留已创建的资源。失败的资源始终回滚到最近一个已知的稳定状态。

控制台屏幕截图。

我将所有其他选项保留为默认值,然后选择下一步。然后,我查看自己的配置并选择创建堆栈

堆栈的创建操作会执行几秒钟,然后由于错误而失败。在事件选项卡中,我查看事件的时间表。开始创建堆栈的事件位于底部。最近的事件位于顶部。由于分区的数量 (ShardCount) 低于最小值,因此流资源的属性验证失败。因此,堆栈现在处于 CREATE_FAILED 状态。

控制台屏幕截图。

我选择保留预置的资源,因此在错误发生之前创建的所有资源仍然存在。在资源选项卡中,S3 存储桶和 SQS 队列处于 CREATE_COMPLETE 状态,而 Kinesis 数据流处于 CREATE_FAILED 状态。DynamoDB 表的创建取决于 Kinesis 数据流是否可用,因为该表将数据流用于其属性之一 (KinesisStreamSpecification)。因此,表的创建尚未开始,并且该表不在列表中。

控制台屏幕截图。

回滚现在已暂停,并且我有一些新的选项:

重试 – 在不作任何更改的情况下重试堆栈操作。如果资源由于模板之外的问题而无法预置,此选项就非常有用。我可以修复这个问题,然后从故障点重试。

更新 – 在重试堆栈创建之前更新模板或参数。堆栈更新从最近一个操作因错误而中断的位置开始。

回滚 – 回滚到最近一个已知的稳定状态。这类似于默认的 CloudFormation 行为。

控制台屏幕截图。

修复参数中的问题
我很快意识到输入了错误的分区数量参数,因此选择更新

我不需要更改模板来修复此错误。 在参数中,我修复了之前的错误并输入正确的分区数量:一个分区。

控制台屏幕截图。

我将所有其他选项保留为当前值,然后选择下一步

更改集预览中,我看到更新将尝试修改 Kinesis 流 (当前处于 CREATE_FAILED 状态) 并添加 DynamoDB 表。我查看其他配置并选择更新堆栈

控制台屏幕截图。

现在更新进行中。我解决了所有问题吗? 还没有。一段时间后,更新失败。

修复模板之外的问题
Kinesis 流已创建,但 CloudFormation 担任的 IAM 角色没有创建 DynamoDB 表的权限。

控制台屏幕截图。

IAM 控制台中,我向堆栈操作使用的角色添加额外权限,以便该角色能够创建 DynamoDB 表。

控制台屏幕截图。

返回 CloudFormation 控制台,我选择重试选项。具备新权限后,DynamoDB 表的创建将开始,但一段时间后,出现另一个错误。

修复模板中的问题
这一次,在定义 DynamoDB 表的模板中存在错误。在 AttributeDefinitions 部分中,有一个未在架构中使用的属性 (TicketSales)。

控制台屏幕截图。

对于 DynamoDB,模板中定义的属性应用于主键或索引。我更新了模板并删除 TicketSales 属性定义。

由于正在编辑模板,因此我借此机会将 MinValueMaxValue 属性添加到分区数量参数 (ShardCountParameter) 中。这样,CloudFormation 可以在开始部署之前检查值是否在正确的范围内,而我可以避免进一步的错误。

我选择更新选项。我选择更新当前模板,然后上传新的模板文件。我确认了参数的当前值。然后,我将所有其他选项保留为当前值,接下来选择更新堆栈

这次,堆栈成功创建,其状态为 UPDATE_COMPLETE。我可以在资源选项卡中查看所有资源,并在输出选项卡中查看它们的说明 (基于模板的输出部分)。

控制台屏幕截图。

以下是模板的最终版本:

AWSTemplateFormatVersion: "2010-09-09"
说明:一个用于解决和修复问题的示例模板
Parameters:
  ShardCountParameter:
    Type: Number
    MinValue: 1
    MaxValue: 10
    说明:Kinesis 流的分区数
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
  MyQueue:
    Type: AWS::SQS::Queue
  MyStream:
    Type: AWS::Kinesis::Stream
    Properties:
      ShardCount: !Ref ShardCountParameter
  MyTable:
    Type: AWS::DynamoDB::Table
    Properties:
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: "ArtistId"
          AttributeType: "S"
        - AttributeName: "Concert"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "ArtistId"
          "KeyType": "HASH"
        - AttributeName: "Concert"
          KeyType: "RANGE"
      KinesisStreamSpecification:
        StreamArn: !GetAtt MyStream.Arn
Outputs:
  BucketName:
    Value: !Ref MyBucket
    说明:我的 S3 存储桶的名称
  QueueName:
    Value: !GetAtt MyQueue.QueueName
    说明:我的 SQS 队列的名称
  StreamName:
    Value: !Ref MyStream
    说明:我的 Kinesis 流的名称
  TableName:
    Value: !Ref MyTable
    说明:我的 DynamoDB 表的名称

这是一个简单的示例,但从故障点重试堆栈操作的新功能为我节省了大量时间。它可让我快速解决和修复问题,从而减少了反馈循环并增加了在同一时间内完成的迭代次数。除了使用其进行调试之外,该功能对于模板的增量交互式开发也非常有用。对于更复杂的应用程序,我们将可节省大量的时间!

使用 AWS CLI 解决和修复 CloudFormation 堆栈问题
我可以使用 AWS 命令行界面 (CLI) 保留成功预置的资源,方法是在创建堆栈、更新堆栈或执行更改集时指定 --disable-rollback 选项。例如:

aws cloudformation create-stack --stack-name my-stack \
    --template-body file://my-template.yaml -–disable-rollback
aws cloudformation update-stack --stack-name my-stack \
    --template-body file://my-template.yaml --disable-rollback
aws cloudformation execute-change-set --stack-name my-stack --change-set-name my-change-set \
    --template-body file://my-template.yaml --disable-rollback

对于现有堆栈,我可以查看是否使用 describe stack 命令启用了 DisableRollback 属性:

aws cloudformation describe-stacks --stack-name my-stack

我现在可以更新处于 CREATE_FAILEDUPDATE_FAILED 状态的堆栈。要手动回滚处于CREATE_FAILEDUPDATE_FAILED 状态的堆栈,我可以使用新的 rollback stack 命令:

aws cloudformation rollback-stack --stack-name my-stack

可用性和定价
AWS CloudFormation 从故障点重试堆栈操作的功能在以下 AWS 区域免费提供:美国东部 (弗吉尼亚北部、俄亥俄)、美国西部 (俄勒冈、加利福尼亚北部)、AWS GovCloud (美国东部、美国西部)、加拿大 (中部)、欧洲 (法兰克福、爱尔兰、伦敦、米兰、巴黎、斯德哥尔摩)、亚太地区 (香港、孟买、大阪、首尔、新加坡、悉尼、东京)、中东 (巴林)、非洲 (开普敦) 和南美洲 (圣保罗)。

您更喜欢使用熟悉的编程语言 (例如 JavaScript、TypeScript、Python、Java、C# 和 Go) 来定义云应用程序资源吗? 好消息! AWS Cloud Development Kit (AWS CDK) 团队计划在接下来的几周内增加对本文中所介绍新功能的支持。

借助从故障点开始重试堆栈操作的新功能,可以用更少的时间来解决和修复 CloudFormation 堆栈问题。

Danilo