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

时间:2017-05-09 16:39:10

标签: terraform

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

3 个答案:

答案 0 :(得分:5)

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

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

  1. 验证terraform配置文件。
  2. 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也不错。

    1. terraform plan
    2. @Martin Atkins已经解释过,terraform.io有关于此命令的详细信息。

      1. 运行自动化测试厨房。
      2. 这是测试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可帮助您自动完成此过程:

  1. 在Go中编写测试。
  2. 在Terratest中使用帮助程序来执行您的真实IaC工具(例如,Terraform,Packer等)以在真实环境(例如,AWS)中部署真实基础设施(例如,服务器)。请注意,此环境将是一个单独的“沙盒”帐户,而不是生产!
  3. 使用Terratest中的帮助程序通过发出HTTP请求,API调用,SSH连接等来验证基础结构在该环境中是否正常工作。
  4. 在Terratest中使用帮助程序在测试结束时取消部署所有内容。
  5. 以下是一些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分钟。这不是很快(尽管使用Dockertest stages,你可以加速一些事情),你必须努力使测试可靠,但它很好值得的时间。

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