尝试一下具有非常棒香气的terratest(1)始发篇
因为工作需要,我需要尝试使用terratest,在此记录下我所学到的内容。
terratest是什么?
terratest是gruntwork创建的基础设施结构的测试工具。从名称来看,它可能是为了编写terraform测试而诞生的,但它也支持Docker、Packer、Kubernetes和helm,并且还支持Azure、AWS和GCP等主要云服务提供商,如果想要编写基础设施测试,可能可以使用它来覆盖吧?让我们试试看是否真的如此。
-
- Testing Terraform code
-
- Testing Packer templates
-
- Testing Docker images
-
- Executing commands on servers over SSH
-
- Working with AWS APIs
-
- Working with Azure APIs
-
- Working with GCP APIs
-
- Working with Kubernetes APIs
-
- Testing Helm Charts
-
- Making HTTP requests
-
- Running shell commands
- And much more
看这个视频,可以看到全貌,很容易理解。
- How to test infrastructure code
安装
因为它是作为 Go 测试库使用的,所以不需要特别安装。但是,如果要使用 terraform,则需要事先安装好 terraform 并确保其位于 PATH 中。
开始
让我们通过阅读《Readme》上的《Getting Started》来了解一下情况。在进行预备工作之前,我们先克隆一下 terratest 的代码。
$ git clone git@github.com:gruntwork-io/terratest.git
让我们来运行一下测试用样例。
$ mkidir helloworld
$ cd helloworld
$ mkdir examples
$ mkdir test
在examples文件夹中放入待测试的脚本。从克隆的terratest存储库中复制最简单的示例。还要将测试代码复制到test文件夹中。
$ cp ../terratest/examples/terraform-basic-example/* examples
$ cp ../terratest/test/terraform_basic_example_test.go test
接下来,切换到test目录并初始化go module。顺便提一下,如果你没有安装Go,请从“GO:入门”页面下载安装。由于在使用Go Module,建议使用1.13及以上版本。我正在使用go version go1.13.4 linux/amd64。
對於 github.com/TsuyoshiUshio/Spike 的部分,這裡是初始化模組的地方。如果有專案需要進行此次測試,你可以使用該倉庫;但如果只是想要試試看,我建議你可以選擇一個不會與其他人衝突的虛擬 github.com 倉庫。
$ cd test
$ go mod init github.com/TsuyoshiUshio/Spike
我们只需要按照常规进行测试。让我们看一下示例中的主要测试类。它非常简单明了。
测试代码
terraform.Options を設定する
terraform.InitAndApply で、Options で定義した内容を variables として渡してterraform init, terraform apply を実行する
defer terraform.Destroy でテストが終わった後に、terraform destroy を実行してリソースを消す
这种感觉。我认为你会感兴趣的,我们来看看可以通过terraform.Options来设置的内容。虽然我没有试过,但它似乎可以设置重试和设置SSHAgent,感觉非常不错!
土地规划选项
type Options struct {
TerraformBinary string // Name of the binary that will be used
TerraformDir string // The path to the folder where the Terraform code is defined.
Vars map[string]interface{} // The vars to pass to Terraform commands using the -var option.
VarFiles []string // The var file paths to pass to Terraform commands using -var-file option.
Targets []string // The target resources to pass to the terraform command with -target
EnvVars map[string]string // Environment variables to set when running Terraform
BackendConfig map[string]interface{} // The vars to pass to the terraform init command for extra configuration for the backend
RetryableTerraformErrors map[string]string // If Terraform apply fails with one of these (transient) errors, retry. The keys are text to look for in the error and the message is what to display to a user if that error is found.
MaxRetries int // Maximum number of times to retry errors matching RetryableTerraformErrors
TimeBetweenRetries time.Duration // The amount of time to wait between retries
Upgrade bool // Whether the -upgrade flag of the terraform init command should be set to true or not
NoColor bool // Whether the -no-color flag will be set for any Terraform command or not
SshAgent *ssh.SshAgent // Overrides local SSH agent with the given in-process agent
NoStderr bool // Disable stderr redirection
}
测试类
以下是对测试类的主要要点的解释。t.Parrallel() 是用于并行执行测试的方法。顺便提一下,terraform 中所写的内容只是用于将文件简单地输出到本地。
terraform_basic_example_test.go 的基本示例测试
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
// An example of how to test the simple Terraform module in examples/terraform-basic-example using Terratest.
func TestTerraformBasicExample(t *testing.T) {
t.Parallel()
expectedText := "test"
expectedList := []string{expectedText}
expectedMap := map[string]string{"expected": expectedText}
terraformOptions := &terraform.Options{ /// Point 1. Parameter
// The path to where our Terraform code is located
TerraformDir: "../examples",
// Variables to pass to our Terraform code using -var options
Vars: map[string]interface{}{
"example": expectedText,
// We also can see how lists and maps translate between terratest and terraform.
"example_list": expectedList,
"example_map": expectedMap,
},
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"varfile.tfvars"},
// Disable colors in Terraform commands so its easier to parse stdout/stderr
NoColor: true,
}
// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions) // Point 2. Destroy
// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions) // Point 3. Init and Apply
// Run `terraform output` to get the values of output variables
actualTextExample := terraform.Output(t, terraformOptions, "example")
actualTextExample2 := terraform.Output(t, terraformOptions, "example2")
actualExampleList := terraform.OutputList(t, terraformOptions, "example_list")
actualExampleMap := terraform.OutputMap(t, terraformOptions, "example_map")
// Verify we're getting back the outputs we expect
assert.Equal(t, expectedText, actualTextExample)
assert.Equal(t, expectedText, actualTextExample2)
assert.Equal(t, expectedList, actualExampleList)
assert.Equal(t, expectedMap, actualExampleMap)
}
进行测试
执行测试与普通的 go 代码没有什么不同。顺便说一句,
-v 是用于在执行测试时生成详细报告的标志,如果想要生成测试报告,则必须使用它。另外,timeout 是指通常的 go test 的超时时间为10分钟,如果是部署相关的代码,这个时间可能不够用,所以设置得比较长。
$ go test -v -timeout 30m
:
--- PASS: TestTerraformBasicExample (4.31s)
PASS
ok github.com/TsuyoshiUshio/Spike 4.331s
调试和持续集成所必需的二进制文件。
当你执行之前的测试时,会在stdout中输出许多消息。如果要在CI流水线中使用它,你可能会思考如何生成测试报告。为此,该工具还提供了一个用于生成测试报告的二进制文件。你可以在Release版本中指定带有 terratest_log_parser 二进制文件的最新版本即可。执行以下命令并将二进制文件放置在任何可通过PATH访问的位置,即可完成设置环境的步骤。
$ curl --location --silent --fail --show-error -o terratest_log_parser https://github.com/gruntwork-io/terratest/releases/download/v0.23.0/terratest_log_parser_linux_amd64
$ chmod +x terratest_log_parser
在测试运行时,将标准输出输出到文件中,并执行terratest_log_parser即可。
$ go test -timeout 30m | tee test_output.log
$ terratest_log_parser -testlog test_output.log -outputdir test_output
这样一来,就可以生成一个目录,并输出日志、JUnit格式的XML文件和详细日志,所以在CI中显示测试结果报告看起来很简单。
这次总结
首先,我理解了基本内容并尝试了执行。感觉非常容易。同时,我也考虑了CI,并且安装也很简单,这让我很开心。
下一次
从下一次开始,我希望能够验证与具体的云服务供应商部署测试和所述的最佳实践相关的内容。