亚马逊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
属性定义。
由于正在编辑模板,因此我借此机会将 MinValue
和 MaxValue
属性添加到分区数量参数 (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
选项。例如:
对于现有堆栈,我可以查看是否使用 describe stack 命令启用了 DisableRollback
属性:
我现在可以更新处于 CREATE_FAILED
或 UPDATE_FAILED
状态的堆栈。要手动回滚处于CREATE_FAILED
或 UPDATE_FAILED
状态的堆栈,我可以使用新的 rollback stack 命令:
可用性和定价
AWS CloudFormation 从故障点重试堆栈操作的功能在以下 AWS 区域免费提供:美国东部 (弗吉尼亚北部、俄亥俄)、美国西部 (俄勒冈、加利福尼亚北部)、AWS GovCloud (美国东部、美国西部)、加拿大 (中部)、欧洲 (法兰克福、爱尔兰、伦敦、米兰、巴黎、斯德哥尔摩)、亚太地区 (香港、孟买、大阪、首尔、新加坡、悉尼、东京)、中东 (巴林)、非洲 (开普敦) 和南美洲 (圣保罗)。
您更喜欢使用熟悉的编程语言 (例如 JavaScript、TypeScript、Python、Java、C# 和 Go) 来定义云应用程序资源吗? 好消息! AWS Cloud Development Kit (AWS CDK) 团队计划在接下来的几周内增加对本文中所介绍新功能的支持。
借助从故障点开始重试堆栈操作的新功能,可以用更少的时间来解决和修复 CloudFormation 堆栈问题。
— Danilo