# Kubestack: one Terraform code base for the whole cloud native platform

> Kubestack is an open source Terraform framework for Kubernetes platform engineering teams, holding provider modules for AWS, Azure, Google, OCI and Scaleway under a common convention so that a cluster, its node pools and its add-ons are declared once and evolved through GitOps. It suits a platform team that wants to own its whole stack in one repository, and it is still a 1.0 beta with a stated plan to stabilise its module interfaces.

**kbst/terraform-kubestack** — Kubestack is a framework for Kubernetes platform engineering teams to define the entire cloud native stack in one Terraform code base and continuously evolve the platform safely through GitOps.

- Repository: https://github.com/kbst/terraform-kubestack
- Website: https://www.kubestack.com
- Stars: 713 · Forks: 98
- Language: HCL
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/kbst-terraform-kubestack

## Convention over configuration, applied to the platform itself

Kubestack is a Terraform framework for Kubernetes platform engineering teams to define the entire cloud native stack in one Terraform code base and continuously evolve the platform safely through GitOps. The README puts it more simply as the open source Terraform framework for Kubernetes platform engineering.

The three highlights describe what the framework actually is. It is a convention over configuration platform engineering framework, described as making the power of platforms accessible to your whole engineering team. It provides a platform architecture and a GitOps workflow, described as enabling all team members to safely iterate while protecting your application environments. And it aims at an extendable, future-proof, low-maintenance Terraform code base with dependable automation even for complex Kubernetes platforms.

The convention part is the load-bearing word. In the ordinary reading of the phrase, conventions describe what goes inside an application, how a deployment is shaped, what a service looks like. Here the conventions describe the platform itself, so that a platform team can hand a cluster to product teams and know that every cluster comes out the same way. The repository topics name the same intent with gitops-framework and terraform-framework alongside platform-engineering, aws, azure and gcp.

The GitOps half is the constraint that shapes the rest. Continuous evolution through GitOps means the platform is changed the way an application is changed, by a pull request, and the framework has to make that safe for people who are not Terraform experts. The documentation site separates the two concerns into a platform-architecture page and a gitops-process page, which is a hint about where the design work sits.

The licence is Apache-2.0, the primary language is HCL, the default branch is master, and the last push was on 2026-10-05.

## One directory per provider, and a common layer underneath

The repository layout is the clearest statement of the design, and the contributing section explains it directly.

This repository holds Terraform modules in directories matching the respective provider name, with aws, azurerm, google, oci and scaleway at the top level. Additionally, a common directory holds the modules that are used for all providers. Most notably, the metadata module in common ensures a consistent naming scheme, and the kustomization/overlay module integrates Kustomize into the Terraform apply for platform features.

That common layer is what makes the framework a framework rather than a collection of modules. A naming convention enforced in one place means a cluster resource, a node pool and a service all derive their names the same way regardless of which cloud they land on, and that is exactly what you need when a platform team runs more than one provider.

The Kustomize integration is the other structural decision worth naming. A Kubernetes platform in practice means overlay directories, patches and bases, and a plain Terraform module does not naturally hold those. Folding Kustomize into the apply means the Kustomize layer stays where Kustomize users expect it while Terraform remains the thing that is applied, and the separate terraform-provider-kustomization repository provides a Kubestack maintained Terraform provider for Kustomize that is available in the Terraform registry.

Each cloud provider specific module directory always has a cluster directory and a _modules directory. The cluster module is the user facing one, and the _modules directory holds the actual implementation that the cluster module uses internally.

## The cluster module is the contract, and beta means it can still move

The contributing section contains the sentence that should govern any adoption decision. The cluster module is user facing and, once Kubestack is out of beta, the goal is to not change the module interface unless the major version changes.

Two things follow. First, the interface is not frozen yet, because the project is not out of beta. Second, the project has made a public commitment about what happens after it is: the interface stops moving except at a major version.

The release list shows how close that is. The most recent tags are v1.0.0-beta.1 and v1.0.0-beta.0, both published on 2026-09-28, and before them v0.19.2-beta.0 from 2024-12-11. So the 1.0 line was cut within a day of each other in late September 2026, and the previous beta sat on the 0.19 line for roughly two years. A framework in this position is close to its final interface, and also in the part of its life where the last set of changes is the most likely to be disruptive.

The repository also carries DEVIATIONS.md, and the existence of that file is a good sign. It is not described in the README, but a framework that layers conventions over five cloud providers has to make choices that differ from the provider defaults, and a document that records those departures is how a user finds out which surprises are deliberate. A team evaluating Kubestack should read it before reading the tutorial, because it is the file most likely to change their expectations.

For the same reason, the guidance on how to start is deliberately thin in the README. The fastest way to get started is to follow the Kubestack tutorial, and the tutorial will help you get started with the framework and build a Kubernetes platform application teams love. Everything deeper is behind the official documentation link, and community questions go to the #kubestack channel on the Kubernetes community Slack, where an account is requested through an invitation link.

The repository also carries a tests directory holding a set of happy path tests, plus a Makefile, an AGENTS.md, CONTRIBUTING.md and CODE_OF_CONDUCT.md.

## The build and test loop runs OpenTofu inside a container

The Makefile shows how the framework is exercised, and the tooling choice is visible in the targets. The binary invoked inside the container is tofu, which is OpenTofu, and the targets are named around validate, plan, test and unittests.

The validate target runs a validation pass inside the test container.

```bash
validate: .init
	docker exec \
		test-container-$(GIT_SHA) \
		entrypoint tofu validate
```

The plan target is where the shape of the framework becomes visible, because it names the zero-config modules for four providers by their target address.

```bash
plan: .init
	docker exec \
		test-container-$(GIT_SHA) \
		entrypoint tofu plan --target module.aks_zero --target module.eks_zero --target module.gke_zero --target module.scw_zero --input=false
```

Those four are AKS, EKS, GKE and Scaleway, each at a zero configuration entry point, and the same set of targets appears in the test target that applies them. The Scaleway and Google providers are not in that target list, so the happy path tests cover the zero modules for Azure, AWS, Google and Scaleway by name but only target four of them in the plan and apply sequence.

The unit test target runs tests in two of the common directories, configuration and metadata.

```bash
unittests: .check-container
	docker exec \
		-w /infra/common/configuration \
		test-container-$(GIT_SHA) \
		entrypoint tofu test
	docker exec \
		-w /infra/common/metadata \
		test-container-$(GIT_SHA) \
		entrypoint tofu test
```

The build target is a buildx build using the oci/Dockerfile, with the git ref and sha passed as build arguments so the image knows which commit it came from, and a registry cache keyed on a dev buildcache target. The default DOCKER_TARGET is multi-cloud, and when DOCKER_PUSH is true the build runs for both linux/arm64 and linux/amd64 and pushes to the registry, with the cache exported to ghcr.io under the kbst organisation.

## Three repositories, and the CLI that writes the code for you

Kubestack is three related repositories, and the division of labour between them is worth understanding before you start.

This repository, kbst/terraform-kubestack, is the Terraform framework itself, the set of modules a platform is built from.

The second is kbst/kbst, the Kubestack CLI. The README describes it as helping you scaffold the Terraform code that defines the clusters, node pools or services of your platform, with a property the README states plainly: the CLI works on local files only, and you can see any change it makes with git status.

That detail is the point. A generator that rewrites files in place is a generator you cannot trust, because a reviewer cannot tell a generated change from a hand-edited one. One that only touches local files and shows up in git status keeps the commit reviewable, and keeps the person who wrote the code responsible for what is in it. For a framework whose entire claim is that platform changes are safe because they go through GitOps, a scaffolder that could hide changes would undercut the argument.

The third is kbst/terraform-provider-kustomization, the Kustomize Terraform provider, a Kubestack maintained provider for Kustomize available in the Terraform registry.

So the workflow the repositories imply is: the CLI scaffolds the Terraform for a cluster, a node pool or a service, the framework modules provide the platform conventions across providers, and the Kustomize provider handles the overlay layer. A team can adopt the modules without the CLI, and use the CLI without the Kustomize provider, but the three are designed to fit.

## Conclusion

Kubestack fits a platform engineering team that already runs Kubernetes in production, wants the cluster and its add-ons declared in one Terraform repository rather than three, and has the capacity to own the convention layer itself. It does not fit a team that only needs a cluster, because the framework assumes the platform is the product. Before committing, read DEVIATIONS.md, which exists to document where the framework departs from the underlying providers, and pin to the v1.0.0 beta line, since the project states that once Kubestack is out of beta the goal is not to change the cluster module interface unless the major version changes.

## FAQ

### Which cloud providers does the Kubestack Terraform framework support?

The repository holds Terraform modules in directories matching the provider name, with aws, azurerm, google, oci and scaleway at the top level, and a common directory holding the modules shared by all providers. The Makefile plan target exercises the zero configuration modules for AKS, EKS, GKE and Scaleway.

### What does the common module directory in Kubestack hold?

It holds the modules used for all providers, most notably the metadata module that ensures a consistent naming scheme and the kustomization/overlay module that integrates Kustomize into the Terraform apply for platform features.

### Is the Kubestack cluster module interface stable?

Not yet. The README states that once Kubestack is out of beta the goal is to not change the module interface unless the major version changes, and the recent releases are v1.0.0-beta.0 and v1.0.0-beta.1 from 2026-09-28, so the interface can still move.

### What does the Kubestack CLI do and how does it change files?

The kbst CLI helps you scaffold the Terraform code that defines the clusters, node pools or services of your platform. It works on local files only, and the README notes that you can see any change it makes with git status.

## Sources

- [kbst/terraform-kubestack on GitHub](https://github.com/kbst/terraform-kubestack)
- [License: Apache-2.0](https://github.com/kbst/terraform-kubestack/blob/master/LICENSE)
- [Project website](https://www.kubestack.com)
- [README](https://github.com/kbst/terraform-kubestack/blob/master/README.md)
- [Releases](https://github.com/kbst/terraform-kubestack/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kbst-terraform-kubestack
