如何快速有效地调试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个回答

1

0

0
如果您想要一种快速简便的方式来验证给定路径下的多个模板,只需使用我编写的这个 Python 脚本 :)

示例用法:python cf-validator.py --templates_path=../../environment-stack/

import boto3
import botocore
import argparse
import sys
import glob, os

def cli_parms_setup(arguments):
    """Setups inputs for parms"""
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('--templates_path', required=True, dest='templates_path')
    return parser.parse_args(arguments)


def get_template_file_names(templates_path):
    """Finds all yaml template within given path"""
    template_file_names = []
    for file in glob.glob(templates_path + "/**/*.yaml", recursive=True):
        template_file_names.append(file)
    print(template_file_names)
    return template_file_names

def cfn_validator(path, templates_to_vaildate):
    """Takes in list of templates to validate"""
    client = boto3.client('cloudformation')
    for yaml_template in templates_to_vaildate:
        cwd = os.getcwd()
        cf_template = open(cwd + path + yaml_template).read()
        try:
            client.validate_template(
                TemplateBody=cf_template
            )
        except botocore.exceptions.ClientError as e:
            print("botocore.exceptions.ClientError has occurred with template " + yaml_template)
            raise e

if __name__ == '__main__':
    cli_parms = cli_parms_setup(sys.argv[1:])
    template_file_names = get_template_file_names(cli_parms.templates_path)
    cfn_validator(cli_parms.templates_path,template_file_names)

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