我正在使用Terraform创建云资源。在配置之后,预期每个资源都处于特定的期望状态。例如,当我创建Google Cloud Bucket时,我希望自动应用某些权限。所以,我的计划包含了必要的代码,但我想确保在我申请之前这一切都能正常运行。有没有可以提供帮助的测试工具/库?
答案 0 :(得分:5)
是的,我之前有同样的想法。目前,当我应用新的terraform更改时,我会使用多种方法来降低风险。
他们无法保证100%成功terraform apply
,但会在您申请之前解决最多问题。
Terraform有validate function开始。但是通过子文件夹不够聪明。我创建了一个小shell函数并添加了CI / CD管道,以便在terraform apply
之前自动运行它。
validate() {
modules=$(find . -type f -name "*.tf" -exec dirname {} \;|sort -u)
for m in ${modules}
do
(terraform validate "$m" && echo "√ $m") || exit 1
done
}
当然,在提交更改之前做terraform fmt
也不错。
@Martin Atkins已经解释过,terraform.io有关于此命令的详细信息。
这是测试Terraform配置的测试Kitchen插件
https://github.com/newcontext-oss/kitchen-terraform
这是一次集成测试。测试将在单独的VPC中运行,与您添加的测试用例一样多。在CI / CD管道中添加自动化测试,以便每次向主分支引发合并请求时触发自动化测试。只有在通过测试后才应用更改。
答案 1 :(得分:3)
terraform plan
命令用于预览Terraform在应用计划时将做出哪些更改,这是我们最接近测试Terraform配置而不触及"真实&#34 ; API。
对于不够的情况,以不同的状态多次部署相同的配置是很常见的,因此允许将其用作" staging"在不影响主要环境的情况下测试更改的环境。 Terraform 0.9中添加的State Environments功能可以使这更容易,因为可以使用Terraform CLI命令直接管理多个环境状态。
当谈到结果的自动化测试时,目前没有完整的解决方案可以集成到Terraform中,但是有一些构建块可以用来帮助用单独的编程语言编写测试。
Terraform以JSON格式生成状态文件,原则上,外部程序可以使用它来提取有关Terraform创建的特定数据。虽然这种格式尚未被认为是官方稳定的,但实际上它很少变化,人们已经成功地与它集成,接受他们可能需要在升级Terraform时进行调整。
这里适合的策略在很大程度上取决于您想要测试的内容。例如:
在虚拟服务器旋转的环境中,Serverspec等工具可用于从这些服务器的角度运行测试。这可以使用一些带外处理与Terraform分开运行,也可以使用remote-exec
provisioner作为Terraform的一部分运行。这样可以验证诸如服务器是否可以到达数据库之类的问题?"但是不适合诸如"实例的安全组是否足够限制等问题?" ,因为强力检查需要从实例本身外部访问数据。
可以使用现有的测试框架(例如Ruby的RSpec,Python的unittest
等)编写测试,这些测试框架从Terraform状态文件中收集相关的资源ID或地址,然后使用相关平台的SDK来检索有关资源的数据,并断言它们是按预期设置的。这是前一个想法的更一般形式,从被测基础设施的主机外部的角度运行测试,因此可以收集更广泛的数据集来进行断言。
对于更适度的需求,人们可以选择相信Terraform状态是对现实的准确表示(在许多情况下是一个有效的假设),并且只是直接断言。这最适合简单的" lint-like"案例,例如验证是否正在遵循正确的资源标记方案以进行成本分配。
在a relevant Terraform Github issue中有更多关于此问题的讨论。
在最新版本的Terraform中,强烈建议对任何非玩具应用程序使用远程后端,但这意味着状态数据不能直接在本地磁盘上使用。但是,可以使用terraform state pull
命令从远程后端检索它的快照,该命令将JSON格式的状态数据打印到stdout,以便可以通过调用程序捕获和解析它。
答案 2 :(得分:3)
我们最近开源Terratest,我们的瑞士军刀用于测试基础设施代码。
今天,您可能通过部署,验证和取消部署手动测试所有基础架构代码。 Terratest可帮助您自动完成此过程:
以下是一些Terraform代码的示例测试:
terraformOptions := &terraform.Options {
// The path to where your Terraform code is located
TerraformDir: "../examples/terraform-basic-example",
}
// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)
// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)
// Run `terraform output` to get the value of an output variable
instanceUrl := terraform.Output(t, terraformOptions, "instance_url")
// Verify that we get back a 200 OK with the expected text
// It can take a minute or so for the Instance to boot up, so retry a few times
expected := "Hello, World"
maxRetries := 15
timeBetweenRetries := 5 * time.Second
http_helper.HttpGetWithRetry(t, instanceUrl, 200, expected, maxRetries, timeBetweenRetries)
这些是集成测试,根据您正在测试的内容,可能需要5到50分钟。这不是很快(尽管使用Docker和test stages,你可以加速一些事情),你必须努力使测试可靠,但它很好值得的时间。
查看Terratest repo以获取各种类型的基础架构代码及其相应测试的文档和大量示例。