首页 文章

如何测试除试验和错误之外的terraform模板

提问于
浏览
2

我正在使用Terraform创建 Cloud 资源 . 在配置之后,预期每个资源都处于特定的期望状态 . 例如,当我创建Google Cloud Bucket时,我希望自动应用某些权限 . 因此,我的计划包含了必要的代码,但我想确保无论在我申请之前这都是有效的 . 有没有可以帮助的测试工具/库?

3 回答

  • 3

    是的,我之前有过相同的想法 . 目前,当我应用新的terraform更改时,我会使用多种方法来降低风险 .

    他们无法保证100%成功 terraform apply ,但会在您申请之前解决最多的问题 .

    • 验证terraform配置文件 .

    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

    terraform plan 命令用于预览Terraform在应用计划时将进行的更改,这是我们在不触及"real" API的情况下测试Terraform配置的最接近的 .

    对于不同状态多次部署相同配置的情况,因此允许将其用作"staging"环境来测试更改而不影响主要环境 . Terraform 0.9中添加的State Environments功能可以使这更容易,因为可以使用Terraform CLI命令直接管理多个环境状态 .

    当谈到结果的自动化测试时,目前没有完整的解决方案可以集成到Terraform中,但是有一些构建块可以用来帮助用单独的编程语言编写测试 .

    Terraform以JSON格式生成状态文件,原则上,外部程序可以使用它来提取有关Terraform创建的特定数据 . 虽然这种格式尚未被认为是正式稳定的,但实际上它很少变化,人们已经成功地与它集成,接受他们可能需要在升级Terraform时进行调整 .

    这里适合的策略将在很大程度上取决于您想要测试的内容 . 例如:

    • 在一个启动虚拟服务器的环境中,可以使用Serverspec等工具从这些服务器的角度运行测试 . 这可以使用一些带外处理与Terraform分开运行,也可以使用remote-exec provisioner作为Terraform的一部分运行 . 这允许验证诸如"can the server reach the database?"之类的问题,但不适用于诸如"is the instance's security group restrictive enough?"之类的问题,因为强健地检查需要从实例本身外部访问数据 .

    • 可以使用现有的测试框架(例如Ruby的RSpec,Python的 unittest 等)编写测试,这些测试框架从Terraform状态文件中收集相关的资源ID或地址,然后使用相关平台的SDK来检索有关资源的数据和声称它们按预期设置 . 这是前一个想法的更一般形式,从被测基础设施之外的主机角度运行测试,因此可以收集更广泛的数据集来进行断言 .

    • 对于更适度的需求,人们可以选择相信Terraform状态是对现实的准确表示(在许多情况下是一个有效的假设)并且只是直接断言 . 这最适合于简单的“类似lint”的情况,例如验证为了成本分配目的而遵循正确的资源标记方案 .

    a relevant Terraform Github issue中有更多关于此的讨论 .

    在最新版本的Terraform中,强烈建议对任何非玩具应用程序使用远程后端,但这意味着状态数据不能直接在本地磁盘上使用 . 但是,可以使用 terraform state pull 命令从远程后端检索它的快照,该命令将JSON格式的状态数据打印到stdout,以便可以通过调用程序捕获和解析它 .

  • 5

    我们最近开源Terratest,我们的瑞士军刀用于测试基础设施代码 .

    今天,您可能通过部署,验证和取消部署手动测试所有基础架构代码 . Terratest帮助你自动执行此过程:

    • 在Go中编写测试 .

    • 在Terratest中使用帮助程序来执行真实的IaC工具(例如,Terraform,Packer等),以在真实环境(例如,AWS)中部署真实基础设施(例如,服务器) . 请注意,此环境将是一个单独的"sandbox"帐户而不是 生产环境 !

    • 在Terratest中使用帮助程序通过发出HTTP请求,API调用,SSH连接等来验证基础结构在该环境中是否正常工作 .

    • 在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)
    

    这些都是集成测试,并且取决于你的速度不快(虽然使用Dockertest stages,你可以加速一些事情),你必须努力使测试可靠,但是值得花时间 .

    查看Terratest repo以获取各种类型的基础架构代码及其相应测试的文档和大量示例 .

相关问题