如何快速有效地调试CloudFormation模板?

110

CloudFormation是AWS提供的强大工具,可通过单个API调用以编程方式创建AWS资源堆栈,例如应用程序的Web层高性能计算群集整个应用程序堆栈。它非常强大。特别是与ChefPuppetcloud-init结合使用时,使用它肯定被认为是一种良好的AWS实践。调试它让我痛苦不堪。

拿一个生产示例来说:库存中的MongoDB群集模板对我无效。我不知道原因。我相信这通常是一些简单的东西。我的问题不在于我找不出错在哪里。而在于它需要花费20到30分钟才能失败,然后再花费三到四分钟来删除,假设它完全正确地删除资源。

我错过了什么吗?我知道有--disable-rollback标志,并像氧气一样使用它。很久以前我就学会了用cfn-signal包装退出消息,并像从沉没的船上扔下去的压舱物一样进行抛出。我如何使模板调试过程更快,还是我永远卡在半小时后才发现我的错误?


4
有时 JSON 中的拼写错误只有在构建过程进行了10分钟或更长时间后才能被发现,因为直到尝试启动资源时,它才会注意到某个特定的资源类型缺少某个属性名称。 - Eric Hammond
1
我的最爱没有特定的顺序:当你切换资源上下文并遇到几乎但不完全相同的属性时,忘记在用户脚本声明中添加转义引号标记,以及任何与VolumeAttachments有关的事情,因为它们偶尔会无缘无故地失败。 - Christopher
3
感谢提及“禁用自动回滚”——这对于获得子堆栈更好的错误信息非常有帮助。 - izikandrw
1
我发现策略段中的错误会导致像BucketPolicy这样的事物永远停留在CREATE阶段 - 如果某些东西被卡在CREATE阶段,请从那里开始解决。 - Eric Nord
@Christopher,请问您能否通过编辑问题简要解释一下使用--disable-rollbackcfn-signal的好处? - Chris Halcrow
13个回答

52
使用AWS CLI工具中的aws cloudformation validate-template命令。它仅验证模板是否为有效的JSON或YAML格式,并不验证键和值的正确性(例如,不检查键名错字)。

1
这也可以在统一的CLI中使用。http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-validate-template.html - mp3foley
7
顺便提一下,这是新版AWS CLI工具中的aws cloudformation validate-template - Christopher
9
如果有人在2017年及之后看到这个问题,现在应该使用aws cloudformation validate-template命令来验证模板是否为有效的JSON或YAML格式,但它并不检查键和值是否正确(例如不会检查键中是否存在拼写错误)。 - Daniel Kats
1
由于某种原因,它似乎忽略了行长度,例如 Property validation failure: [Length of value {XYZ} for property {/RepositoryDescription} is greater than maximum allowed length {100}]。根据 validate-template 命令,这不是问题,但 UI 返回此错误。 - 030
3
如果这个工具只进行文件格式验证,那么 jsonlint 或者 yamllint 是否足够?此外,这个工具的文件大小限制为51,200字节。 - Siva Senthil
显示剩余2条评论

25

另一个选择是在一年后将这些模板抽象为第三方库,例如troposphere。该库可以为您构建JSON负载,并沿途执行许多验证。这也解决了"管理1000行JSON文件真的很痛苦"的问题。


3
“管理一个有1000行的JSON文件确实很令人沮丧” - 这正是为什么嵌套堆栈被创建的原因吧?;-) 虽然我同意 - Troposphere真是太棒了! - YFP

14
我该如何使模板调试过程更快,或者我会永远陷入在制作错误后半小时才发现的困境中?
以下是一些最佳实践建议,专注于提高复杂CloudFormation模板开发的迭代速度:
使用CloudFormation工具验证模板和堆栈更新
AWS已经在自己的最佳实践文档中概述了这些内容,因此我不会重复它们: 此步骤的目的是在执行堆栈创建/更新之前捕获明显的语法或逻辑错误。
隔离测试资源

在使用复杂堆栈中的任何单独CloudFormation资源之前,确保您彻底了解该资源的创建/更新/删除行为的全部范围,包括使用限制和典型启动/拆除时间,先通过在较小的、独立的堆栈中测试它们的行为来加深理解。

  • 如果您正在开发或使用任何第三方自定义资源,请使用适当的语言平台库编写单元测试,以确保应用程序逻辑在所有用例中表现符合预期。
  • 请注意,个别资源的创建/更新/删除所需的时间可能会因底层API调用的行为而异。例如,复杂的AWS::CloudFront::Distribution资源有时需要30-60分钟才能完成创建/更新/删除,而AWS::EC2::SecurityGroup可以在几秒钟内更新。
  • 个别资源可能存在实现上的错误/问题/限制,当与较大的堆栈中一起测试时,很容易进行调试和开发解决方法。请记住以下限制,如AWS服务限制取决于您的个人AWS帐户设置,或者服务区域可用性取决于您创建堆栈的区域。

分步骤构建复杂的堆栈

在执行堆栈创建/更新时,如果任何单个资源出现故障,将会导致堆栈回滚整个一组资源更改,这可能会不必要地销毁其他成功创建的资源,并在构建具有长依赖资源图的复杂堆栈时需要很长时间。

解决方法是通过较小的更新批次分步骤构建您的堆栈,逐个添加资源。这样,当资源创建/更新失败时,回滚不会导致整个堆栈的资源被销毁,而只会销毁最新更新中更改的一组资源。

监控堆栈更新进度

请务必监视堆栈更新进度, 查看堆栈事件,以便在执行创建/更新时进行调试单个资源问题的起点。


关于CloudFront以及它需要多长时间,您是否知道有什么方法可以让堆栈处于完成状态,而无需等待?我想获取输出,但在我的情况下不需要等待分发部署。 - mcfedr

10
你看过包含在AWS Toolkit for Eclipse中的 AWS CloudFormation 模板编辑器吗?它具有语法高亮、语句完成和部署到 AWS CloudFormation 的功能。

7
"AWS Toolkit for Visual Studio"对我来说是不可或缺的。 - Ed Norris

7

AWS CloudFormation linter 提供了除 aws cloudformation validate-template 之外的额外静态分析。

它会通知您哪些资源类型和实例类型在某些区域不可用,将属性值与允许值进行验证,捕获循环资源依赖关系、语法错误、模板限制等等

除了命令行界面 (CLI) 外,最流行的机制之一是安装编辑器插件,例如 Visual Studio Code 扩展程序,它会在每次保存文件时运行 linter。

其他机制如此处所述的 Git 预提交钩子。

Visual Studio Code 扩展程序示例屏幕截图


5
晚来的人可能会觉得这个答案很基础,但花点时间配置和学习你的编辑器是值得的。在我的情况下,使用vim时,一旦我花了一些时间安装json语法插件并(最终)理解了折叠技术以便轻松导航大型CF文件,我的表现就好多了。现在我的编辑器会建议拼写错误(逗号等),而颜色高亮功能则通过提供清晰的视觉线索节省了很多时间。这可能有助于减轻语法错误,但模板内的逻辑错误最好由其他工具修复。希望有一天CF能够有“预览”模式。

2
这并不是一个可笑的建议。我不确定如果没有语法高亮,我是否能编写代码。 - Christopher
2
有一个 CFN 的预览,展示了所有要创建的资源,并告诉您堆栈将花费多少成本。我正在使用 Java API,因此不确定 CLI 是否可用,但请尝试此链接:[link](http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_EstimateTemplateCost.html)。 - iGili

4

对于JetBrains的IDE(IntelliJ IDEA PhpStorm WebStorm PyCharm RubyMine AppCode CLion Gogland DataGrip Rider Android Studio),有一个AWS CloudFormation插件,支持对JSON和YAML CFN模板进行深度检查。


2
如果你正在处理 EC2 机器,我建议你登录到 EC2 机器并查看 boot.log 文件(在 RHEL6/Centos 中是 /var/log/boot.log)。这个文件会更新所有你的 shell 活动(比如:安装、下载文件、复制文件等)。
另外,使用像 http://www.jsoneditoronline.org/ 这样的编辑器可以获得 JSON 的 TREE 表示,这有助于检查 JSON 元素的顺序。
当你更新文件时,始终使用像 http://www.git-tower.com/blog/diff-tools-mac/ 或实际版本控制系统这样的工具,以确保你没有意外更改可能会破坏你的脚本的内容。

2

1
去年12月,Cloudformation新增了一个功能额外参数类型。这些新类型允许您的模板执行更强的数据检查,并且在创建资源和嵌套Cloudformation堆栈时也可以“快速失败”。您还可以使用新的ConstraintDescription属性提供更好的人类可读自定义错误消息,以指示无效值被传递。
在处理各种VPC资源时,新类型特别有用。您可以确保模板的参数是正确的类型,并且明确期望单个值与列表。
例如:
"Parameters" : {
  "SingleGroup": { "Type": "AWS::EC2::SecurityGroup::Id", ...},
  "GroupList": {"Type": "List<AWS::EC2::SecurityGroup::Id>", ...}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接