Terratest: integration testing for Terraform, Packer and Kubernetes in Go
Terratest is a Go library that makes it easier to write automated tests for your infrastructure code.
At a glance
- What is it?
- Terratest is an Apache-2.0 Go library for writing automated tests against real infrastructure. It suits teams that already write Go and want to assert on deployed resources, not just on plan output.
- Who is it for?
- Adopt Terratest if your team writes Go and needs assertions against resources that were actually created, such as a Terraform apply followed by an AWS API call. Do not adopt it if you want plan-time checks without credentials or a deployed environment: the Terraform CLI's own test framework runs faster and cheaper for that.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Terratest solves, and who it is written for
Terraform's own tooling validates syntax and plans. It does not tell you whether the S3 bucket that was created actually has the encryption setting you intended, or whether the Kubernetes deployment that was applied reaches a ready state. Terratest exists to close that gap. The README describes it as "a Go library that makes it easier to write automated tests for your infrastructure code", and the helper list covers Terraform, Packer, Docker, SSH command execution, AWS, Azure, GCP and Kubernetes APIs, Helm charts, HTTP requests and shell commands.
The audience is narrow on purpose. You write tests in Go, using the standard testing package and testify, and you run them like any other Go test. If your team does not write Go, the entry cost is real: you are not configuring a DSL, you are writing compiled code with typed structs and explicit error handling. In exchange, the assertions are ordinary program logic. You can retry, poll, branch and clean up in the same file that provisions the infrastructure.
This is also why it is a poor fit for pure static analysis. Terratest does not parse your HCL looking for policy violations. It runs terraform apply and then asks the cloud provider what happened.
How a Terratest test actually runs
The mechanism is process orchestration plus API assertions. A typical test calls a helper that shells out to the Terraform binary in a directory, passing variables and capturing outputs. That helper blocks until the apply finishes, then returns the outputs as a Go struct you define. From there you call AWS, Azure, GCP or Kubernetes clients to verify the result, and you register a deferred destroy so the resources are torn down when the test ends.
The repository layout reflects this. The modules/ directory holds the helper packages, examples/ holds runnable test suites organised by target (terraform-aws-example, kubernetes-basic-example, packer-docker-example, helm-basic-example and others), and test-docker-images/ supports the Docker-based tests. The go.mod file shows the dependency surface this implies: aws-sdk-go-v2, several Azure resource manager SDKs, cloud.google.com/go/storage, k8s.io/client-go and k8s.io/api are all direct or indirect requirements. A test binary that imports the AWS and Kubernetes helpers links those SDKs.
That is the trade-off worth naming. Because the library drives real tools and real cloud APIs, a test run needs credentials, network access and a disposable environment. It is integration testing by construction, and it inherits the flakiness of everything it touches. The helpers mitigate this with retry and polling utilities, but they cannot remove eventual consistency from the provider side.
Installing Terratest and writing a first test
The README gives a single install command and a version floor: Go 1.26 or later. Run this inside your module:
go get github.com/gruntwork-io/terratest@latestThe README notes that you can pin to a specific release instead of @latest, and links to a version-pinning page for that. If you want the v2 line, note that it ships under new /v2 module paths, so the import path differs from the one above.
Once the module is in your go.mod, the tests themselves are ordinary Go test files. The repository ships runnable suites under examples/, including examples/terraform-basic-example, examples/terraform-aws-example, examples/kubernetes-basic-example, examples/helm-basic-example and examples/packer-basic-example. Those directories are the closest thing to a worked tutorial: each one pairs a Terraform or Packer configuration with a Go test that applies it, asserts on the result, and destroys it. The README points readers at a quick-start page and a documentation site for the step-by-step version, so the repository itself is the reference implementation rather than a tutorial.
What you should see when you run go test in one of those example directories: the helper compiles the test, initialises and applies the configuration, reads the outputs back, and runs the deferred destroy at the end. The exact output names and variables belong to each example, so read the example's own files rather than assuming keys.
The cost that does not show up in the README
Terratest tests are slow and they cost money. Every run creates real resources in a real account, and the destroy step only executes if the test process reaches it. A panic, a timeout or a killed CI job can leave infrastructure behind, and Terratest does not document a rollback mechanism for that case. The cleanup story is the deferred destroy call, which is a Go defer and therefore subject to Go's defer semantics.
Credentials are the second constraint. The helpers for AWS, Azure, GCP and Kubernetes assume working credentials in the environment. That makes local development awkward for anyone without account access, and it means the test suite's blast radius is whatever the credentials permit. Teams commonly run these tests against a dedicated sandbox account for that reason.
Finally, the v1 line has entered maintenance. The README states that with v2 in development, v1 receives security fixes only, delivered on the v1 branch, until 12 months after v2.0.0 reaches general availability. The latest v1 release listed is v1.0.1, and the v2 line is at v2.0.0-beta.2. Pinned v1 consumers are unaffected by the /v2 module paths, but they should not expect new features on that branch.
Terratest compared with Terraform's native test framework
The closest alternative is the test framework built into the Terraform CLI itself. The difference in approach is where the assertions live. Terraform's framework keeps tests in .tftest.hcl files next to the configuration, runs plan and apply through the same binary, and can assert on plan output without a separate compilation step. Terratest puts the test in Go, which means the assertion language is a general-purpose one.
That matters when the check crosses a boundary Terraform cannot see. Verifying that an EC2 instance answers on a port over SSH, that a Helm release's pods become ready, or that an HTTP endpoint returns a particular body are all natural in Go and awkward or impossible in plan assertions. Conversely, if your test only checks that a variable produces the expected resource attribute, the native framework is lighter: no Go module, no compiled test binary, no testify dependency. Terratest's own README positions the library as a helper collection rather than a replacement for Terraform's execution, so the two can coexist in one repository.
Checkov sits in a different category again. It inspects configuration for policy violations before anything is deployed, which is static analysis, not integration testing. A team worried about a public S3 bucket wants that check at plan time, not after an apply.
Licence, versioning and what an upgrade costs
Terratest is released under the Apache 2.0 License, with LICENSE and NOTICE files at the repository root. Apache 2.0 permits commercial use and modification and includes a patent grant; it also requires that you preserve the NOTICE file's attribution when redistributing. That last point is the one teams miss when they vendor the library. This is a description of the licence text, not legal advice, and your counsel should review redistribution plans.
On versioning, the README states that from v1.0.0 the project follows semantic versioning, with breaking changes to the public API only in major releases. Symbols renamed or replaced in v1 carry Deprecated annotations pointing at the new name, and removals happen in v2. Migration guides exist for v0.x to v1 and for v1 to v2. Because v2 uses new /v2 module paths, a v1 pin keeps resolving to v1 code, so the upgrade is opt-in rather than forced at the next go get.
The practical upgrade cost is the breadth of the import surface. A test that touches Terraform, AWS and Kubernetes pulls in versions of aws-sdk-go-v2, k8s.io/client-go and the Azure SDKs that must be compatible with the rest of your module graph. Bumping Terratest across a major version means re-resolving those. The repository's own lint configuration is generated from the terragrunt repository's .golangci.yml and updated weekly by a workflow, which tells you the project tracks a shared lint baseline rather than maintaining its own.
Editorial conclusion
Adopt Terratest if your team writes Go and needs assertions against resources that were actually created, such as a Terraform apply followed by an AWS API call. Do not adopt it if you want plan-time checks without credentials or a deployed environment: the Terraform CLI's own test framework runs faster and cheaper for that. Before committing, verify that your toolchain is on Go 1.26 or later and decide which module path you are pinning, because v2 ships under /v2 paths while the v1 line receives security fixes only.
Frequently asked questions
What is Terratest used for?
It is a Go library for writing automated tests against infrastructure code. The README lists helpers for Terraform, Packer, Docker images, SSH commands, AWS, Azure, GCP and Kubernetes APIs, Helm charts, HTTP requests and shell commands.
How do I install Terratest?
Run go get github.com/gruntwork-io/terratest@latest inside your Go module. The README states that Go 1.26 or later is required, and that you can pin to a specific release instead of @latest.
Is Terratest free and open source?
Yes. The repository is released under the Apache 2.0 License, with LICENSE and NOTICE files at the root, and the source is publicly hosted on GitHub.
What are the key differences between Terratest and Terraform testing?
Terraform's own test framework keeps assertions in .tftest.hcl files and runs through the Terraform binary, while Terratest writes the assertions in Go and can call cloud provider APIs, SSH into servers and check Kubernetes state after an apply. Terratest is the heavier option because it compiles a test binary and needs credentials.
Is Terratest the same as Terragrunt?
No. Terragrunt is a separate Gruntwork tool for Terraform configuration management, while Terratest is a Go testing library. The only link visible in the repository is that Terratest's lint configuration is generated from Terragrunt's .golangci.yml.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gruntwork-io-terratest)