百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

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

connygpt 2024-09-09 03:10 9 浏览

译者 | 布加迪

审校 | 孙淑娟

手动设置基础架构是费时又费力的过程。这时候我们可以利用基础架构即代码(IaC)工具来自动管理基础架构。IaC自动化可用于任何类型的基础架构:虚拟机和存储等。随着越来越多的基础架构变成代码,有必要为IaC进行单元测试和集成测试。

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

一、基础架构即代码(IaC)

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

二、测试基础架构代码

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

1.健全性或静态分析

2.单元测试

3.集成测试

  • 健全性或静态分析

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

  • 单元测试

借助单元测试,我们不用实际配置基础架构即可评估代码。比如可以限制容器以便以非root用户身份运行,或者云网络安全组应该只有TCP协议。几个典型的单元测试是面向Terraform的Conftest和面向Chef Cookbooks的Chefspecs。

以非root用户身份执行的Conftest例子:

package main

deny[msg] {

input.kind == "Deployment"

not input.spec.template.spec.securityContext.runAsNonRoot

msg := "Containers must not run as root"

}1.2.3.4.5.6.7.8.9.10.11.
  • 集成测试?

在集成测试中,我们希望通过将IaC实际部署到所需的环境中对其进行测试。比如说,您部署了一个虚拟机,并在该机器的端口80上托管Nginx服务器。因此,您将在部署之后检查端口80是否在侦听。

以下是使用ServerSpec执行该操作的例子:

describe port(80) do

it { should be_listening }

end1.2.3.4.5.

我们在本文中介绍使用Terrratest对基础架构代码进行集成测试。

三、Terratest是什么?我们可以用它来做什么?

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

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

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

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

四、安装Terratest所需的二进制文件

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

  • 安装Terraform?

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

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

terraform version1.

Go & test依赖项安装可以通过以下步骤来完成:

  • 安装Go?

您可以使用Linux发行版的软件包管理器来安装Go,或者遵照Go的安装文档(https://go.dev/doc/install)。

  • Go测试需要gcc来执行测试?

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

五、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的output.tf的输出作为测试的输入。下面这个代码段用于测试我们是否在使用的ec2实例上有相同的ssh密钥。

package terratest
import (
  "testing"
"github.com/stretchr/testify/assert"
"github.com/gruntwork-io/terratest/modules/terraform"
)
func TestEc2SshKey(t *testing.T) {
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../terraform",
})
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
ec2SshKey := terraform.Output(t, terraformOptions, "instance_ssh_key") assert.Equal(t, "terratest", ec2SshKey)
}1.2.3.4.5.6.7.8.9.10.11.12.13.14.

我们将把它分成不同的部分以便理解:第一步,我们定义一个名为Terratest的Go软件包,然后我们导入测试执行所需的不同软件包。

package terratest
import (
"testing"
"github.com/stretchr/testify/assert" "github.com/gruntwork-io/terratest/modules/terraform"
)1.2.3.4.5.

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

func TestEc2SshKey(t *testing.T) {
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../terraform",
})
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
ec2SshKey := terraform.Output(t, terraformOptions, "instance_ssh_key") assert.Equal(t, "terratest", ec2SshKey)
}1.2.3.4.5.6.7.8.

借助以下部分,我们定义了Terratest应该在其中查找Terraform清单文件(即main.tf和output.tf)的目录,以便创建基础架构。

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

在Go中,我们使用defer方法来执行清理任务,它应该是terraform destroy。

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

defer terraform.Destroy(t, terraformOptions)1.

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

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

terraform.InitAndApply(t, terraformOptions)1.

如前所述,Terratest查找来自output.tf的输出,寻找变量定义。

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

ec2SshKey := terraform.Output(t, terraformOptions, "instance_ssh_key") assert.Equal(t, "terratest", ec2SshKey)1.

六、执行测试

将目录切换到已克隆存储库的位置。进入到测试文件所在的位置。

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

go mod init ec2_instance
go mod tidy1.2.

最后执行测试:

$ go test –v

--- PASS: TestEc2SshKey (98.72s)
PASS
ok command-line-arguments 98.735s1.2.3.4.5.

七、不妨继续使用Terratest

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

  • 高级功能

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

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

Terraform output.tf
output "lb_address" {
value = aws_lb.load-balancer.dns_name
description = "DNS of load balancer"
}
output "api_id" {
description = "REST API id"
value = aws_api_gateway_rest_api.api.id
}
output "deployment_invoke_url" {
description = "Deployment invoke url"
value = "${aws_api_gateway_stage.test.invoke_url}/resource"
}1.2.3.4.5.6.7.8.9.10.11.12.13.
  • 测试执行的代码片段

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

func TestApiGateway(t *testing.T) {
//awsRegion := "eu-west-2"
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../",
})
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
stageUrl := terraform.Output(t, terraformOptions,"deployment_invoke_url") time.Sleep(30 * time.Second)
statusCode := DoGetRequest(t, stageUrl)
assert.Equal(t, 200 , statusCode)
}
func DoGetRequest(t terra_test.TestingT, api string) int{
resp, err := http.Get(api)
if err != nil {
log.Fatalln(err)
}
//We Read the response status on the line below.
return resp.StatusCode
}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.

在上面的代码片段中,我们定义了函数DoGetRequest来运行HTTP GET测试。然后,我们将此函数的输出用作TestApiGateway函数的输入。

  • 测试执行和输出
TestApiGateway 2022-03-01T06:56:18Z logger.go:66: deployment_invoke_url = "https://iuabeqgmj2.execute-api.eu-west-1.amazonaws.com/test/resource" TestApiGateway 2022-03-01T06:56:18Z logger.go:66: lb_address = "my-demo-load-balancer-
376285754.eu-west-1.elb.amazonaws.com"
TestApiGateway 2022-03-01T06:56:18Z retry.go:91: terraform [output -no-color -json deployment_invoke_url]
TestApiGateway 2022-03-01T06:56:18Z logger.go:66: Running command terraform with args [output –
no-color -json deployment_invoke_url]
TestApiGateway 2022-03-01T06:56:19Z logger.go:66: "https://iuabeqgmj2.execute-api.eu-west-
1.amazonaws.com/test/resource"
--- PASS: TestApiGateway (42.34s)
PASS
ok command-line-arguments 42.347s1.2.3.4.5.6.7.8.9.10.

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

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

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

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

我们为API网关开发了Terratest检查机制。在该例子中,我们验证是否为您的API网关添加了Authorizer。

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

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

九、结语

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

原文链接:https://www.cncf.io/blog/2022/07/18/testing-your-infrastructure-as-code-using-terratest/

来源: 51CTO技术栈

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...