In the complex landscape of modern DevOps, configuration drift and environment inconsistency remain persistent challenges that erode engineering efficiency and security posture. A common scenario emerges when teams manage a pile of YAML files alongside a stack of Terraform modules. Each component appears functional in isolation, yet systemic failures occur when variables change in staging, causing production environments to diverge from expected states. This disconnect arises because Kustomize and Terraform, while powerful in their respective domains, do not natively share a common language for state management and manifest generation. Kustomize operates as a tool for transforming Kubernetes manifests, applying environment-specific overlays without altering original files, much like a chef seasoning a base recipe. Terraform, conversely, orchestrates the underlying infrastructure, declaring and provisioning clusters, load balancers, and identity resources through providers such as AWS or Google Kubernetes Engine (GKE). When these two systems align, deployments transition from unpredictable creative experiments into predictable, automated workflows. The core logical chain that enables this synergy is straightforward: Terraform owns the state of the infrastructure, while Kustomize owns the mutation of the configuration.
The integration of these tools allows infrastructure state to flow upward and configuration overlays to flow downward, creating a closed feedback loop that eliminates manual guessing about what is currently live. By exporting Terraform outputs, such as OIDC issuer URLs or service account credentials, and referencing them within Kustomize overlays, teams can ensure that Kubernetes manifests point cleanly to the resources Terraform built. This connection is typically achieved by passing Terraform outputs into Kustomize variables or through a pipeline substitution step. This methodology ensures that Kubernetes manifests reference live infrastructure values without manual edits, making deployments consistent across environments and reducing the reliance on copy-paste operations.
Architectural Logic and Data Flow
The fundamental architecture of a combined Terraform and Kustomize workflow relies on a strict separation of concerns. Terraform is responsible for the creation and management of the underlying cloud resources. These include the Kubernetes cluster itself, virtual private clouds, subnets, security groups, and identity providers. Once these foundational elements are provisioned, Kustomize takes over the management of the Kubernetes objects that depend on that infrastructure. The data flow is unidirectional in its primary intent: infrastructure state generated by Terraform is exported and consumed by Kustomize to generate the final deployment manifests.
This separation prevents the common anti-pattern of hardcoding cluster IPs, DNS names, or role ARNs directly into YAML files. Instead, dynamic values are injected at the point of application. For example, if a Terraform module provisions an Amazon EKS cluster, it outputs the cluster endpoint and the OIDC identity provider URL. These outputs are then mapped into Kustomize variables. When Kustomize builds the overlay for a specific environment, such as staging or production, it substitutes these variables with the actual values retrieved from the Terraform state. This ensures that even if the underlying infrastructure is destroyed and recreated, the Kustomize configuration remains valid as long as the variable mappings are preserved.
The benefits of this architectural alignment are multifaceted. First, it significantly reduces the number of environment-specific YAML edits, as the base manifests remain static and are only modified through standardized overlay mechanisms. Second, it ensures consistent cluster setup across development, staging, and production environments. Third, it creates an automatic connection between Terraform outputs and Kubernetes inputs, eliminating manual synchronization errors. Fourth, it accelerates developer onboarding by reducing the need for tribal knowledge, as the relationship between infrastructure and configuration is explicit in the code. Finally, it simplifies compliance verification in audits such as SOC 2, because the configuration remains traceable through the version-controlled codebase and state history.
Terraform Provider Options for Kustomize
While the basic workflow involves passing outputs from Terraform to Kustomize via shell scripts or CI/CD pipeline steps, dedicated Terraform providers offer more robust integration by allowing Terraform to directly manage Kustomize resources. Several providers exist to facilitate this, each with distinct capabilities and design philosophies. The most prominent among these are the kbst/terraform-provider-kustomization and signifyd/terraform-provider-kustomize.
The kbst/terraform-provider-kustomization is a standalone Terraform provider that is also utilized within the Kubestack framework. Kubestack is an open-source GitOps framework designed to build reliable automation for Azure Kubernetes Service (AKS), Amazon EKS, and Google Kubernetes Engine (GKE) clusters. This provider offers specific data sources and resources to interact with Kustomize configurations. It includes the kustomization_build and kustomization_overlay data sources, which allow users to process Kustomize directories and apply overlays respectively. Additionally, it provides a kustomization_resource for managing resources defined within Kustomize overlays. This provider is maintained by kbst and is available from the Terraform registry. It is part of a broader ecosystem that includes the Kubestack Framework CLI, which scaffolds Infrastructure as Code repositories and deploys platform stacks locally for faster iteration, and the kbst/catalog, a collection of cluster services as Kustomize bases that are continuously tested and updated.
| Feature | kbst/terraform-provider-kustomization | signifyd/terraform-provider-kustomize |
|---|---|---|
| Primary Use Case | Standalone provider and Kubestack framework integration | Solving common kubectl apply issues via Terraform |
| Data Sources | kustomization_build, kustomization_overlay |
N/A (Focus on resource management) |
| Resources | kustomization_resource |
kustomization (Implied by context of replacing kubectl) |
| Key Capability | Scaffolding GitOps repos, local deployment | Feedback on changes, purging stale resources, handling immutable changes |
| Framework Integration | Kubestack | Standalone or in place of provisioners |
| Documentation | Available via provider docs | Available via provider docs |
The signifyd/terraform-provider-kustomize addresses specific pain points associated with applying Kustomizations using kubectl. It aims to solve three common issues: the lack of feedback regarding what changes will be applied, the failure to purge resources from a previous apply that are no longer present in the current apply, and the failure of applies midway due to immutable changes, such as modifying a Deployment's selector. To address these challenges, the provider leverages the Terraform state to show changes to each resource individually during the plan phase and to track resources that need to be purged. It also utilizes server-side dry runs to validate changes to the desired state. This validation allows the provider to translate changes into a Terraform plan, indicating whether a resource will be updated in-place or requires a delete and recreate operation. This approach makes the provider useful both as a replacement for kubectl integrated into a Terraform configuration as a provisioner and as a standalone kubectl diff/apply step in CI/CD pipelines. Notably, this provider uses HashiCorp Configuration Language (HCL) to build the kustomization.yaml file, allowing for programmatic generation of Kustomize configurations. Where the Kustomize specification requires a file path, the provider allows a map or a YAML string instead, creating an in-memory file with the YAML content.
Development and Testing Protocols
Developing and maintaining a custom or modified Terraform provider for Kustomize requires specific tooling and environments. Both the kbst and signifyd providers are built using Go, utilizing go mod for dependency management, which means the legacy GOPATH environment variable is not required. To compile the provider, developers must execute the make build command. This process builds the provider and places the resulting binary in the terraform.d/plugins/linux_amd64/ directory, assuming a standard Linux environment.
Testing the provider involves running acceptance tests, which are executed via the make test command. A critical requirement for these tests is the setting of the KUBECONFIG_PATH environment variable, which must point to a valid Kubernetes configuration file. Each test utilizes an individual namespace to ensure isolation and prevent interference between test cases. Local Kubernetes clusters such as Kind or Minikube are well-suited for these testing scenarios. For advanced debugging, a four-step process is employed: launching the plugin in debug mode under Delve, connecting the Integrated Development Environment (IDE) to Delve, connecting Terraform to the plugin, and finally running Terraform. This rigorous testing protocol ensures that the provider behaves predictably in both controlled local environments and production-like settings.
```bash
Example of setting up the environment for testing
export KUBECONFIG_PATH="$HOME/.kube/config"
make test
```
Production Implementation and Best Practices
Implementing this workflow in a production environment requires adherence to strict best practices to avoid misfires and security vulnerabilities. A robust setup typically involves a fully working EKS environment designed with production best practices, including environment isolation between Management and Dev layers, remote Terraform state management, and a real-world path to deploy Kubernetes workloads using Helm and Kustomize.
The stack generally creates two main environments: Management (MGMT) and Development (DEV). The Management environment contains shared resources such as DNS zones, Virtual Private Networks (VPN), IAM roles, and base networking. The Development environment contains the actual application workloads, Virtual Private Cloud (VPC), EKS cluster, and supporting services. This structure is built using Terraform 1.13.x or later and follows a modular design, making it simple and maintainable to extend or reuse components.
The technology stack for such an implementation includes Terraform 1.13+ for Infrastructure as Code, AWS CLI 2.x for interacting with accounts and buckets, kubectl 1.32+ for Kubernetes management, Helm 3.16+ for controller deployments, and Kustomize 5.7+ for per-environment overlays. Before running terraform init, it is essential to create a dedicated S3 bucket for remote state with versioning enabled. This ensures that the state is backed up and recoverable.
bash
export REGION="eu-west-1"
export TFSTATE_BUCKET="demo-terraform-eks-fullstack-$(openssl rand -hex 3)"
aws s3api create-bucket \
--bucket $TFSTATE_BUCKET \
--region $REGION \
--create-bucket-configuration LocationConstraint=$REGION
Best practices for avoiding operational errors include using Terraform Cloud or a CI system to control runs and version the state. Role-Based Access Control (RBAC) must be mapped carefully so that Kubernetes service accounts created by Terraform inherit least-privilege roles from the Identity and Access Management (IAM) provider, whether that is Okta or AWS IAM. Secrets should be rotated at build time, and it must be verified that all environment overlays in Kustomize reference dynamic rather than static credentials. Treating infrastructure as code and configuration as code separately but respectfully is crucial. This separation allows teams to manage the lifecycle of the infrastructure independently of the application configuration, while still maintaining the necessary data flow between the two.
Developer experience and speed are significantly enhanced once the workflow is correctly wired. Developers can spin up test clusters without requiring operations teams to provide credentials files manually. The automation of the connection between Terraform outputs and Kustomize inputs reduces friction and allows for faster iteration cycles. This is particularly beneficial in organizations where multiple teams share infrastructure, as it standardizes the deployment process and reduces the risk of human error.
Conclusion
The integration of Terraform and Kustomize represents a critical evolution in DevOps practices, addressing the inherent fragility of managing Kubernetes infrastructure through disparate tools. By establishing a clear division of labor where Terraform manages infrastructure state and Kustomize manages configuration mutation, organizations can achieve a high degree of predictability and consistency across their environments. The use of dedicated Terraform providers such as kbst/terraform-provider-kustomization and signifyd/terraform-provider-kustomize further enhances this workflow by providing programmatic feedback, resource purging, and validation capabilities that are absent in raw kubectl operations.
The implementation of these tools in production environments, particularly in complex setups involving EKS, requires a modular architecture with distinct Management and Development layers. Remote state management, rigorous RBAC implementation, and dynamic secret handling are not optional but mandatory components of a secure and scalable deployment pipeline. As the industry moves towards GitOps and declarative infrastructure management, the synergy between Terraform and Kustomize becomes increasingly vital. It allows teams to reduce environmental drift, accelerate onboarding, and maintain compliance through traceable, automated processes. The future of infrastructure management lies in this tight coupling of provisioning and configuration, ensuring that every change is auditable, repeatable, and safe.
Sources
- hoop.dev/blog/what-kustomize-terraform-actually-does-and-when-to-use-it
- pkg.go.dev/github.com/kbst/terraform-provider-kustomize
- github.com/kbst/terraform-provider-kustomization
- github.com/signifyd/terraform-provider-kustomize
- yuriibohdan.medium.com/from-zero-to-production-building-a-full-stack-eks-environment-with-terraform-helm-kustomize