有没有办法对 AWS Cloudformation 模板进行单元测试
Is there a way to unit test AWS Cloudformation template
当我们说cloudformation是'Infrastructure as Code'时,下一个立即想到的问题就是如何测试这段代码。
我们可以对这段代码做一些基本的单元测试吗
我不考虑 cloudformation 验证,因为这只是一种进行语法验证的方式,我可以使用任何其他免费的 JSON/YAML 验证器。
我更倾向于某种功能验证,可能是测试我是否定义了所有用作参考的变量。
可能测试我正在使用的任何属性实际上是该组件支持的属性
没想到它应该测试权限是否正确或者我没有用尽我的限制。但至少超出了基本 JSON/YAML 语法验证
您描述的测试(至少在 JSON 解析之外)可以通过用于 generate/read 模板的编程库解析 CloudFormation 模板来部分实现。它们不会显式测试模板,但会在您使用未为资源定义的 属性 的情况下抛出异常或错误。
查看 go-cloudformation:https://github.com/crewjam/go-cloudformation
除此之外,您需要 运行 堆栈才能看到错误。我相信测试 IaaC 是基础设施自动化的主要挑战之一。不仅是单元测试,还有集成测试和持续验证。
这里详细介绍了如何将几种软件测试方法应用于 CloudFormation templates/stacks:
林丁
对于 linting(检查 CloudFormation 模板代码的 syntax/grammar 正确性),您可以使用 ValidateTemplate API to check basic template structure, and the CreateChangeSet
API 来更详细地验证您的资源属性。
- 请注意,
ValidateTemplate
执行的检查比简单的 JSON/YAML 语法检查器更彻底 - 它验证正确的 Template Anatomy, correct syntax/usage of Intrinsic Functions, and correct resolution of all Ref
值。
ValidateTemplate
检查基本的 CloudFormation 语法,但不会根据特定 属性 模式验证模板的资源。为了根据 AWS 资源类型检查模板的参数、资源和属性的结构,如果任何参数或资源属性格式不正确,CreateChangeSet
应该 return 出错。
单元测试
执行单元测试首先需要回答以下问题:要测试can/should 的最小独立单元 功能是什么?对于 CloudFormation,我认为最小的可测试单元是 Resource.
官方 AWS Resource Types 是 AWS supported/maintained(无论如何都是专有实现),因此不需要最终用户开发人员编写任何额外的单元测试。
但是,您自己的 Custom Resources could and should be unit-tested. This can be done using a suitable testing framework in the implementation's own language (e.g., for Lambda-backed Custom Resources, perhaps a library like lambda-tester
将是一个很好的起点。
集成测试
这是 CloudFormation 堆栈(主要用于将各种资源绑定到一个集成应用程序中)的最重要和最相关的测试类型,也是可以使用更多改进和最佳实践开发的类型。以下是关于如何通过实际 creating/updating 包含真实 AWS 资源的完整堆栈来集成测试 CloudFormation 代码的一些初步想法:
- 使用脚本语言,使用该语言的 AWS SDK 执行 CloudFormation 堆栈创建。将模板设计为 return Stack Outputs 以反映您要测试的行为。在脚本语言创建堆栈后,将堆栈输出与预期值进行比较(然后可选择在清理过程中删除堆栈)。
- 使用
AWS::CloudFormation::WaitCondition
个资源代表成功tests/assertions,这样一个成功的堆栈创建就代表一个成功的集成测试运行,一个失败的堆栈创建代表一个失败的集成测试运行.
除了 CloudFormation 之外,在 space 测试基础架构即代码中值得一提的一个有趣工具是 kitchen-terraform
, a set of plugins for Test Kitchen which allow you to write fully-automated integration test suites for Terraform 模块。最终可能会为 CloudFormation 构建类似的集成测试工具,但目前还不存在。
此工具“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 存储桶、SQS 等)
匹配在某些方面过于宽松的策略(例如操作或主体中的通配符)
安全组入口和出口规则
匹配过于宽松的规则(例如,入口规则对 0.0.0.0/0 开放,端口范围 1-65535 开放)
访问日志
查找未为适用资源(例如 Elastic Load Balancer 和 CloudFront 分配)启用的访问日志
加密
未对适用资源(例如 EBS 卷或 S3 存储桶上的 PutObject 调用)启用或强制执行的(服务器端)加密
特别说到CloudFormation,AWS推荐使用taskcat,这是一个在所有AWS区域内部署基础设施/模板的工具,在这个过程中它已经执行了代码验证。
TaskCat Github 存储库:https://github.com/aws-quickstart/taskcat
此外,通过Visual Studio代码您可以使用扩展Cloud conformity template scanner
或使用趋势科技当前购买的功能进行安全验证,其名称已从云符合性更改为Trend Micro Template scanner
.
它将基本上执行模板和架构代码的验证,这些代码链接到来自 AWS 的 Well Architected Framework 的模型和用例。
VS 代码扩展云整合:https://marketplace.visualstudio.com/items?itemName=raphaelbottino.cc-template-scanner
此外,还有一个 VS Code 扩展 Linter,您可以将其用作 pre-commit
验证,名称为:CloudFormation Linter
.
CloudFormation 短绒:https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint
如果您想使用 DevSecOps“SEC”实现基础设施代码管道,您还可以使用更高级的功能,这是 Scout 套件.它有自己的云验证器,可以在构建容器中 运行,它将审核云以验证是否存在安全标准之外的资源。
Scout Suite Github 存储库:https://github.com/nccgroup/ScoutSuite
如果您想更深入地了解在 AWS 上使用验证和资源测试/合规性,我建议您使用配置服务研究“合规性即代码”。
Link 介绍此服务:https://www.youtube.com/watch?v=fBewaclMo2s
我找不到真正的 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。
新工具现已上市。测试所有 CloudFormation 东西! (TaskCat)
什么是taskcat?
taskcat 是一个测试 AWS CloudFormation 模板的工具。它会在多个 AWS 区域部署您的 AWS CloudFormation 模板,并为每个区域生成一份具有 pass/fail 等级的报告。您可以指定要包含在测试中的区域和可用区数量,并从您的 AWS CloudFormation 模板传入参数值。 taskcat 被实现为一个 Python class ,您可以导入、实例化和 运行.
用法
笔记
- taskcat 无法读取 AWS_PROFILE 环境变量。如果不是默认配置文件,则需要在
general
的一部分中定义配置文件。
general:
auth:
default: dev-account
有一个 bash 库 xsh-lib/aws
,它的一个工具可以从 CLI 部署 AWS CloudFormation 模板。
可在以下位置找到该工具:https://github.com/xsh-lib/aws/blob/master/functions/cfn/deploy.sh
它处理模板验证和上传、堆栈命名、监管、更新、清理、超时、回滚和状态检查。
除上述之外,它还处理嵌套模板和非内联 Lambda。这节省了上传嵌套模板和非内联 Lambda 函数的工作,如果手动进行测试,这些工作可能会让人们抓狂。
它支持自定义的配置文件,这使得部署更加容易。真实世界的配置文件是 here.
从 CLI 调用该工具的简单示例如下所示:
xsh aws/cfn/deploy -t template.json -s mystack -o OPTIONS=Param1Key=Param1Value
xsh-lib/aws is a library of xsh,要使用它,您必须先安装 xsh
。
当我们说cloudformation是'Infrastructure as Code'时,下一个立即想到的问题就是如何测试这段代码。 我们可以对这段代码做一些基本的单元测试吗
我不考虑 cloudformation 验证,因为这只是一种进行语法验证的方式,我可以使用任何其他免费的 JSON/YAML 验证器。
我更倾向于某种功能验证,可能是测试我是否定义了所有用作参考的变量。 可能测试我正在使用的任何属性实际上是该组件支持的属性
没想到它应该测试权限是否正确或者我没有用尽我的限制。但至少超出了基本 JSON/YAML 语法验证
您描述的测试(至少在 JSON 解析之外)可以通过用于 generate/read 模板的编程库解析 CloudFormation 模板来部分实现。它们不会显式测试模板,但会在您使用未为资源定义的 属性 的情况下抛出异常或错误。
查看 go-cloudformation:https://github.com/crewjam/go-cloudformation
除此之外,您需要 运行 堆栈才能看到错误。我相信测试 IaaC 是基础设施自动化的主要挑战之一。不仅是单元测试,还有集成测试和持续验证。
这里详细介绍了如何将几种软件测试方法应用于 CloudFormation templates/stacks:
林丁
对于 linting(检查 CloudFormation 模板代码的 syntax/grammar 正确性),您可以使用 ValidateTemplate API to check basic template structure, and the CreateChangeSet
API 来更详细地验证您的资源属性。
- 请注意,
ValidateTemplate
执行的检查比简单的 JSON/YAML 语法检查器更彻底 - 它验证正确的 Template Anatomy, correct syntax/usage of Intrinsic Functions, and correct resolution of allRef
值。 ValidateTemplate
检查基本的 CloudFormation 语法,但不会根据特定 属性 模式验证模板的资源。为了根据 AWS 资源类型检查模板的参数、资源和属性的结构,如果任何参数或资源属性格式不正确,CreateChangeSet
应该 return 出错。
单元测试
执行单元测试首先需要回答以下问题:要测试can/should 的最小独立单元 功能是什么?对于 CloudFormation,我认为最小的可测试单元是 Resource.
官方 AWS Resource Types 是 AWS supported/maintained(无论如何都是专有实现),因此不需要最终用户开发人员编写任何额外的单元测试。
但是,您自己的 Custom Resources could and should be unit-tested. This can be done using a suitable testing framework in the implementation's own language (e.g., for Lambda-backed Custom Resources, perhaps a library like lambda-tester
将是一个很好的起点。
集成测试
这是 CloudFormation 堆栈(主要用于将各种资源绑定到一个集成应用程序中)的最重要和最相关的测试类型,也是可以使用更多改进和最佳实践开发的类型。以下是关于如何通过实际 creating/updating 包含真实 AWS 资源的完整堆栈来集成测试 CloudFormation 代码的一些初步想法:
- 使用脚本语言,使用该语言的 AWS SDK 执行 CloudFormation 堆栈创建。将模板设计为 return Stack Outputs 以反映您要测试的行为。在脚本语言创建堆栈后,将堆栈输出与预期值进行比较(然后可选择在清理过程中删除堆栈)。
- 使用
AWS::CloudFormation::WaitCondition
个资源代表成功tests/assertions,这样一个成功的堆栈创建就代表一个成功的集成测试运行,一个失败的堆栈创建代表一个失败的集成测试运行.
除了 CloudFormation 之外,在 space 测试基础架构即代码中值得一提的一个有趣工具是 kitchen-terraform
, a set of plugins for Test Kitchen which allow you to write fully-automated integration test suites for Terraform 模块。最终可能会为 CloudFormation 构建类似的集成测试工具,但目前还不存在。
此工具“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 存储桶、SQS 等) 匹配在某些方面过于宽松的策略(例如操作或主体中的通配符)
安全组入口和出口规则 匹配过于宽松的规则(例如,入口规则对 0.0.0.0/0 开放,端口范围 1-65535 开放)
访问日志 查找未为适用资源(例如 Elastic Load Balancer 和 CloudFront 分配)启用的访问日志
加密 未对适用资源(例如 EBS 卷或 S3 存储桶上的 PutObject 调用)启用或强制执行的(服务器端)加密
特别说到CloudFormation,AWS推荐使用taskcat,这是一个在所有AWS区域内部署基础设施/模板的工具,在这个过程中它已经执行了代码验证。
TaskCat Github 存储库:https://github.com/aws-quickstart/taskcat
此外,通过Visual Studio代码您可以使用扩展Cloud conformity template scanner
或使用趋势科技当前购买的功能进行安全验证,其名称已从云符合性更改为Trend Micro Template scanner
.
它将基本上执行模板和架构代码的验证,这些代码链接到来自 AWS 的 Well Architected Framework 的模型和用例。
VS 代码扩展云整合:https://marketplace.visualstudio.com/items?itemName=raphaelbottino.cc-template-scanner
此外,还有一个 VS Code 扩展 Linter,您可以将其用作 pre-commit
验证,名称为:CloudFormation Linter
.
CloudFormation 短绒:https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint
如果您想使用 DevSecOps“SEC”实现基础设施代码管道,您还可以使用更高级的功能,这是 Scout 套件.它有自己的云验证器,可以在构建容器中 运行,它将审核云以验证是否存在安全标准之外的资源。
Scout Suite Github 存储库:https://github.com/nccgroup/ScoutSuite
如果您想更深入地了解在 AWS 上使用验证和资源测试/合规性,我建议您使用配置服务研究“合规性即代码”。
Link 介绍此服务:https://www.youtube.com/watch?v=fBewaclMo2s
我找不到真正的 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。
新工具现已上市。测试所有 CloudFormation 东西! (TaskCat)
什么是taskcat?
taskcat 是一个测试 AWS CloudFormation 模板的工具。它会在多个 AWS 区域部署您的 AWS CloudFormation 模板,并为每个区域生成一份具有 pass/fail 等级的报告。您可以指定要包含在测试中的区域和可用区数量,并从您的 AWS CloudFormation 模板传入参数值。 taskcat 被实现为一个 Python class ,您可以导入、实例化和 运行.
用法
笔记
- taskcat 无法读取 AWS_PROFILE 环境变量。如果不是默认配置文件,则需要在
general
的一部分中定义配置文件。
general:
auth:
default: dev-account
有一个 bash 库 xsh-lib/aws
,它的一个工具可以从 CLI 部署 AWS CloudFormation 模板。
可在以下位置找到该工具:https://github.com/xsh-lib/aws/blob/master/functions/cfn/deploy.sh
它处理模板验证和上传、堆栈命名、监管、更新、清理、超时、回滚和状态检查。
除上述之外,它还处理嵌套模板和非内联 Lambda。这节省了上传嵌套模板和非内联 Lambda 函数的工作,如果手动进行测试,这些工作可能会让人们抓狂。
它支持自定义的配置文件,这使得部署更加容易。真实世界的配置文件是 here.
从 CLI 调用该工具的简单示例如下所示:
xsh aws/cfn/deploy -t template.json -s mystack -o OPTIONS=Param1Key=Param1Value
xsh-lib/aws is a library of xsh,要使用它,您必须先安装 xsh
。