当我们说cloudformation是' Infrastructure as Code'时,立即想到的下一个问题是如何测试这些代码。 我们可以对此代码进行某种基本的单元测试吗
我正在对云形式验证进行折扣,因为这只是一种进行语法验证的方法,而且我可以使用任何其他免费的JSON / YAML验证器。
我更倾向于某种功能验证,可能测试我已经定义了所有用作引用的变量。 可能测试我正在使用的任何属性实际上是该组件支持的属性
不期望它应该测试权限是否正确或我没有用尽我的限制。但至少还有基本的JSON / YAML语法验证
答案 0 :(得分:28)
以下是关于如何将多种测试软件方法应用于CloudFormation模板/堆栈的细分:
有关掉毛(检查语法/语法正确性CloudFormation模板代码),则可以使用ValidateTemplate API来检查基本模板结构,和CreateChangeSet
API来更详细地验证资源特性
ValidateTemplate
比简单的JSON / YAML语法检查程序执行更彻底的检查 - 它验证了Template Anatomy的正确Intrinsic Functions,正确的Ref
语法/用法,并正确解决了所有问题Resource值。ValidateTemplate
会检查基本的CloudFormation语法,但不会针对特定的属性架构验证模板的资源。要根据AWS资源类型检查模板的参数,资源和属性的结构,CreateChangeSet
如果任何参数或资源属性格式不正确,则应返回错误。首先执行单元测试需要回答问题:可以/应该测试的最小的自包含单元功能是什么?对于CloudFormation,我认为最小的可测试单元是AWS Resource Types。
官方Custom Resources由AWS支持/维护(无论如何都是专有实施),因此不需要最终用户开发人员编写的任何其他单元测试。
但是,您自己的lambda-tester
可以而且应该进行单元测试。这可以使用实现自己语言中的合适测试框架来完成(例如,对于Lambda支持的自定义资源,也许像Outputs这样的库将是一个很好的起点)。
这是CloudFormation堆栈最重要和最相关的测试类型(主要用于将各种资源整合到一个集成的应用程序中),以及可以使用更多细化和最佳实践开发的类型。以下是关于如何通过实际创建/更新包含真实AWS资源的完整堆栈来集成测试CloudFormation代码的一些初步想法:
AWS::CloudFormation::WaitCondition
。在通过脚本语言创建堆栈之后,将堆栈输出与预期值进行比较(然后可选择在清理过程中删除堆栈)。kitchen-terraform
资源来表示成功的测试/断言,以便成功的堆栈创建表明成功的集成测试运行,并且创建失败的堆栈表明集成测试运行失败。除了CloudFormation,一个值得一提的测试空间有趣的工具基础设施即代码Test Kitchen,一组插件Terraform这允许你写的完全自动化的集成测试套件https://stripe.com/docs/charges个模块。最终可以为CloudFormation构建类似的集成测试工具,但尚未存在。
答案 1 :(得分:6)
此工具“cfn-nag”解析CloudFormation模板的集合,并应用规则来查找可能导致不安全基础结构的代码模式。该工具的结果包括违反资源的逻辑资源标识符以及违反规则的解释。 进一步阅读:https://stelligent.com/2016/04/07/finding-security-problems-early-in-the-development-process-of-a-cloudformation-template-with-cfn-nag/
虽然该工具会尝试匹配许多特定规则,但粗略的类别是:
IAM和资源政策(S3 Bucket,SQS等) 匹配以某种方式过度宽松的策略(例如,动作或主体中的通配符)
安全组入口和出口规则 匹配过于自由的规则(例如,入口规则打开到0.0.0.0/0,端口范围1-65535打开)
访问日志 查找未启用适用资源的访问日志(例如Elastic Load Balancers和CloudFront Distributions)
加密 (服务器端)加密未针对适用资源启用或强制执行(例如,EBS卷或S3存储桶上的PutObject调用)
答案 2 :(得分:0)
您所描述的测试(至少超出JSON解析)可以通过用于生成/读取模板的程序库解析CloudFormation模板来实现。它们不会显式测试模板,但会在您使用未为资源定义的属性的情况下抛出异常或错误。
查看go-cloudformation:https://github.com/crewjam/go-cloudformation
除此之外,您需要运行堆栈才能看到错误。我认为测试IaaC是基础设施自动化的主要挑战之一。不仅是单元测试,还包括集成测试和连续验证。
答案 3 :(得分:0)
特别说到 CloudFormation,AWS 建议使用 taskcat,这是一个在所有 AWS 区域内部署基础设施/模板的工具,在这个过程中它已经执行了代码验证。
TaskCat Github 存储库:https://github.com/aws-quickstart/taskcat
此外,通过 Visual Studio 代码,您可以使用扩展程序 Cloud conformity template scanner
或使用趋势科技目前已购买的功能进行名称已从云一致性更改为 Trend Micro Template scanner
的安全验证.
它将基本上执行与来自 AWS 的架构完善的框架的模型和用例相关联的模板和架构代码的验证。
VS Code 扩展云一致性:https://marketplace.visualstudio.com/items?itemName=raphaelbottino.cc-template-scanner
此外,还有一个 VS Code 扩展 Linter 可以用作 pre-commit
进行验证,名称为:CloudFormation Linter
。
CloudFormation Linter:https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint
如果您想使用 DevSecOps“SEC”实现基础设施即代码管道,您还可以使用更高级的功能,这是Scout 套件。它有自己的云验证器,可以在构建容器中运行,它将审核云以验证是否存在安全标准之外的资源。
Scout Suite Github 存储库:https://github.com/nccgroup/ScoutSuite
如果您想更深入地了解在 AWS 上使用验证和资源测试/合规性的情况,我建议您使用配置服务研究“合规性即代码”。
链接到此服务的演示文稿:https://www.youtube.com/watch?v=fBewaclMo2s
答案 4 :(得分:0)
我找不到真正的 Cloudformation 模板单元测试解决方案,所以我创建了一个。 https://github.com/DontShaveTheYak/cloud-radar
Cloud-Radar 允许您获取模板,传入您要设置的参数。然后将该模板渲染为其最终形式。意味着所有条件和内在函数都已解决。
这允许您使用 this 之类的模板并编写以下测试:
from pathlib import Path
from unittest.mock import mock_open, patch
import pytest
from cloud_radar.cf.unit import Template
@pytest.fixture
def template():
template_path = Path(__file__).parent / "../../templates/log_bucket/log_bucket.yaml"
return Template.from_yaml(template_path.resolve(), {})
def test_log_defaults(template):
result = template.render({"BucketPrefix": "testing"})
assert "LogsBucket" in result["Resources"]
bucket_name = result["Resources"]["LogsBucket"]["Properties"]["BucketName"]
assert "us-east-1" in bucket_name
def test_log_retain(template):
result = template.render(
{"BucketPrefix": "testing", "KeepBucket": "TRUE"}, region="us-west-2"
)
assert "LogsBucket" not in result["Resources"]
bucket = result["Resources"]["RetainLogsBucket"]
assert "DeletionPolicy" in bucket
assert bucket["DeletionPolicy"] == "Retain"
bucket_name = bucket["Properties"]["BucketName"]
assert "us-west-2" in bucket_name
编辑:如果您对测试 Cloudformation 模板感兴趣,请查看我的博客系列 Hypermodern Cloudformation。