Terratest v2.0.0 - Module Split and GCP Reads


Terratest v2.0.0 shipped on 23 September 2026 under the tag modules/core/v2.0.0. This is the first stable release of v2. All 16 modules are tagged at v2.0.0 in lockstep, and a test now compiles only the SDKs of the modules it imports.

The full release notes and downloads are on the GitHub release page.

v1.0.1 shipped as one module with a 675 line go.sum. A test that only runs Terraform imports terraform/v2, whose go.sum is 77 lines. No AWS, Azure, GCP, or Kubernetes SDK enters that build.

Each module installs on its own:

go get github.com/gruntwork-io/terratest/modules/terraform/[email protected]

The module names are core, ssh, httphelper, dnshelper, docker, packer, database, opa, aws, azure, gcp, k8s, helm, terraform, terragrunt, and teststructure. Paths use github.com/gruntwork-io/terratest/modules/<name>/v2.

A CI check holds dependencies between modules to an explicit allowlist, so a new import cannot quietly pull one module into another. random, files, logger, shell, retry, and testing now live in core/v2. v2 import paths differ from v1, so a repository pinned to v1.0.1 still builds. Migration can move one module at a time.

Most of a v1 upgrade is import rewriting. The compiler catches the other API breaks, except two Kubernetes behavior changes. The migration guide walks through the move. The rewriting imports page has the sed commands, and the cases a blind find and replace gets wrong.

http-helper, dns-helper, and test-structure become httphelper, dnshelper, and teststructure, in the import path and in the package identifier.

terraform.Apply is removed. Callers use terraform.ApplyContext(t, ctx, ...), the replacement already named by the v1 deprecation warnings.

collections, environment, git, version-checker, slack, oci, and the two cmd/ binaries are gone. v1.0.1 names a replacement for the first five in each package deprecation notice.

Eight teststructure save and load helpers now live beside their types, in aws, k8s, packer, and ssh. Signatures are unchanged.

Two behavior changes compile cleanly. Read them before upgrading a Kubernetes test. The behavior changes page covers both.

k8s.FindNodeHostnameContextE, and k8s.GetServiceEndpointContextE for a NodePort service, return the node ExternalIP when the cluster records one. On EKS that address is the public IP, so the common path no longer needs ec2:DescribeInstances. A test that expected another address still compiles.

KubectlOptions that carry a RestConfig refuse to serialize. MarshalJSON returns k8s.ErrRestConfigNotSerializable. v1 failed here too, with an unclear error. Saving the options without that config would have authenticated a reloaded test against the ambient kubeconfig.

Since beta.2, the gcp module can read settings for 82 kinds of Google Cloud resource. A test can assert on what Terraform created. Each read has three forms: one that fails the test, one that returns the error, and a WithClient form that takes an injected client for a unit test with no credentials. The reads add no dependencies. The go.sum of gcp/v2 stays at 267 lines.

bucket := gcp.GetStorageBucketAttrs(t, ctx, bucketName)
assert.True(t, bucket.UniformBucketLevelAccess.Enabled)

Storage and data reads cover Cloud Storage buckets, Storage Transfer agent pools, BigQuery datasets and tables, and Cloud SQL instances, databases, and users. They also cover Spanner, Bigtable, Firestore, Filestore, Redis, AlloyDB, Dataproc, Dataflow, Composer, and Dataplex lakes. Pub/Sub topics, subscriptions, and schemas are included. Compute, networking, GKE, identity, logging, and Cloud DNS reads are in the same release.

Kubernetes libraries moved to v0.37.0 in pull 1889. The go.sum of k8s/v2 grows from 160 lines to 178. The migration guide shipped in pull 1884. Module boundaries in beta.2 follow feedback in issue 1875.

Fixes since v1.0.1:

  • random.UniqueID no longer collides between calls made in the same instant (pull 1860).
  • Dependencies were bumped to versions that resolve known CVEs (pull 1861). The notes do not name the CVE identifiers.
  • ssh.SaveSSHKeyPair no longer writes the private key to the test log.
  • Saved test data is written with 0o600 permissions rather than 0o644.
  • core/teststate stops after a fatal error. A marshal failure used to leave an empty file behind (pull 1880).
  • IPv6 service endpoints are built with net.JoinHostPort, so the address is bracketed.
  • Malformed AWS provider IDs return an error where v1 panicked.

v1 is frozen at v1.0.1 and receives security fixes only, on the v1 branch, for 12 months after this release. A project that stays on v1 needs no import edit for this tag.

The v2 upgrade is an import rewrite, then a manual pass on Kubernetes tests. Renames, removed packages, and moved helpers fail compilation. ExternalIP selection and RestConfig serialization do not. The diff from v1.0.1 is the compare view.