The terraform-provider-kubectl is a Terraform provider that enables management of Kubernetes resources using raw YAML manifests within Terraform's declarative infrastructure-as-code workflow. This provider bridges the gap between Terraform's resource lifecycle management and Kubernetes' native YAML-based resource definitions, allowing users to apply, update, and delete Kubernetes resources while maintaining Terraform state tracking and drift detection. The architecture is built to treat a free-form YAML object as a first-class Terraform resource, which means Kubernetes manifests that originate from operators, Helm charts, or hand-authored files can be ingested into Terraform without translation into HCL resource schemas. The real world impact of this design is that platform teams can keep existing Kubernetes YAML authoring practices intact while gaining Terraform's planning, dependency graph, and state reconciliation. The contextual layer connects directly to the provider's stated role as a robust bridge between Terraform's infrastructure management capabilities and Kubernetes' declarative resource model, enabling users to leverage YAML-based Kubernetes configurations within Terraform workflows while maintaining state consistency and drift detection.
The provider's core promise is expressed as the best way of managing Kubernetes resources in Terraform, by allowing you to use the thing Kubernetes loves best - yaml. The core of this provider is the kubectl_manifest resource, allowing free-form yaml to be processed and applied against Kubernetes. This yaml object is then tracked and handles creation, updates and deleted seamlessly - including drift detection. A set of helpful data resources to process directories of yaml files and inline templating is available. This terraform-provider-kubectl provider has been used by many large Kubernetes installations to completely manage the lifecycle of Kubernetes resources. The operational impact for engineering organizations is a reduction in context switching between kubectl apply workflows and Terraform plans, and the contextual connection is that drift detection moves Kubernetes from a fire-and-forget apply model to a continuously reconciled state model.
Architecture and Core Components
The provider overview covers the provider's architecture, core components, and development infrastructure. For detailed configuration options, see Provider Configuration. For comprehensive documentation of the primary resource, see kubectl_manifest Resource.
The provider implements a bridge pattern where Terraform's resource lifecycle is mapped onto kubectl apply semantics. Terraform state stores the identity and desired YAML content of each kubectl_manifest instance, while the provider uses Kubernetes client-go machinery to read live cluster objects for comparison. The impact for users is that Terraform plan output can surface out-of-band changes made by kubectl, operators, or other controllers. The contextual layer ties this to the provider's use of Kubernetes discovery mechanisms to dynamically determine available API resources and their REST mappings, which allows the provider to operate against clusters with custom resources without hard-coded schema.
Key Go modules for Kubernetes integration and Terraform provider functionality are specified in the module inventory:
| Module | Version | Purpose |
|---|---|---|
| github.com/hashicorp/terraform-plugin-sdk/v2 | v2.35.0 | Terraform provider framework |
| k8s.io/client-go | v0.32.1 | Kubernetes Go client |
| k8s.io/kubectl | v0.32.1 | kubectl functionality |
| k8s.io/cli-runtime | v0.32.1 | Kubernetes CLI runtime |
| sigs.k8s.io/kustomize/api | v0.19.0 | Kustomize integration |
The module selection reflects a deliberate reliance on upstream Kubernetes tooling rather than re-implementing API clients. The impact is compatibility with the same Kubernetes API versions that kubectl uses, and reduced maintenance surface. The contextual connection is that kustomize/api integration enables processing of Kustomize overlays within Terraform configurations, aligning with directory-based data resources.
Installation and Binary Distribution
Terraform 0.13+ is required for use. The provider can be installed and managed automatically by Terraform. Sample versions.tf file is referenced as the conventional mechanism for pinning provider versions. If you don't want to use the one-liner above, you can download a binary for your system from the release page, then either place it at the root of your Terraform folder or in the Terraform plugin folder on your system. See User Guide for details on installation and all the provided data and resource types.
The automatic installation path reduces manual plugin management for teams that already use Terraform Cloud or Enterprise. The impact is faster onboarding and version consistency across CI pipelines. The alternative binary path supports air-gapped environments where fetching providers from the registry is prohibited.
Provider configuration patterns observed in reference material include:
provider "kubectl" {
host = var.eks_cluster_endpoint
cluster_ca_certificate = base64decode(var.eks_cluster_ca)
token = data.aws_eks_cluster_auth.main.token
load_config_file = false
}
This pattern shows the provider being pointed at a managed EKS endpoint with explicit certificate and token authentication, and loadconfigfile disabled to prevent leakage from local kubeconfig.
A resource example illustrates raw YAML ingestion:
resource "kubectl_manifest" "test" {
yaml_body = <<YAML
apiVersion: couchbase.com/v1
kind: CouchbaseCluster
metadata:
name: name-here-cluster
spec:
baseImage: name-here-image
version: name-here-image-version
authSecret: name-here-operator-secret-name
exposeAdminConsole: true
adminConsoleServices:
- data
cluster:
dataServiceMemoryQuota: 256
indexServiceMemoryQuota: 256
searchServiceMemoryQuota: 256
eventingServiceMemoryQuota: 256
analyticsServiceMemoryQuota: 1024
indexStorageSetting: memory_optimized
autoFailoverTimeout: 120
autoFailoverMaxCount: 3
autoFailoverOnDataDiskIssues: true
autoFailoverOnDataDiskIssuesTimePeriod: 120
autoFailoverServerGroup: false
YAML
}
The impact of yaml_body as a string heredoc is that complex operator CRDs can be managed without translating each field into HCL. The contextual layer is that this resource is tracked for creation, updates and deleted seamlessly, including drift detection, which means manual edits via kubectl will be reverted on next Terraform apply if they diverge from state.
Development Environment and Build Process
If you wish to work on the provider, you'll first need Go installed on your machine, version 1.12+ is required. You'll also need to correctly setup a GOPATH, as well as adding $GOPATH/bin to your $PATH. To compile the provider, run make build.
The Go version requirement ensures compatibility with the terraform-plugin-sdk/v2 v2.35.0 dependency. The impact for contributors is a stable build toolchain that matches the module versions listed in go.mod. The contextual connection is that the same client-go v0.32.1 and kubectl v0.32.1 dependencies are compiled into the binary, so local builds reproduce release behavior.
Build and packaging steps referenced in material include:
. && \
chmod +x terraform-provider-kubectl* && \
rm -rf terraform-provider-kubectl-tmp && \
rm -rf terraform-provider-kubectl.zip && \
popd
These commands show post-build permission fixing and cleanup of temporary artifacts, which is typical for CI release workflows.
Retry Logic and Resilience Configuration
The provider implements configurable retry logic through the kubectlApplyRetryCount variable, allowing resilient operations against unstable clusters.
| Argument | Provider Argument | Environment Variable |
|---|---|---|
| applyretrycount | applyretrycount | KUBECTLPROVIDERAPPLYRETRYCOUNT |
The retry configuration is implemented in kubernetes/provider.go. The impact for production clusters is that transient API server errors, throttling, or temporary network partitions during apply do not immediately fail Terraform runs. The contextual layer links this to large Kubernetes installations that have used the provider to completely manage the lifecycle of Kubernetes resources, where reliability under load is essential.
Data Resources for Directory and Template Processing
A set of helpful data resources to process directories of yaml files and inline templating is available. This design supports bulk import of manifests from a directory without enumerating each file as a separate resource. The impact is reduced boilerplate for teams that store Kubernetes manifests in GitOps repositories and want Terraform to reflect the entire directory as state. The contextual connection is that the kustomize/api v0.19.0 module enables transformation of directory-based manifests before apply.
Kubernetes Discovery and API Mapping
The provider uses Kubernetes discovery mechanisms to dynamically determine available API resources and their REST mappings. This avoids static schema definitions for custom resources. The impact is that new CRDs can be adopted immediately without waiting for provider updates. The contextual layer is that discovery feeds into drift detection, allowing the provider to correctly read live objects for comparison even when API versions evolve.
Interaction With HashiCorp Kubernetes Provider
Reference material also documents the HashiCorp kubernetes provider as a complementary tool. A tutorial configuration shows:
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 3.0"
}
}
}
variable "host" {
type = string
}
variable "client_certificate" {
type = string
}
variable "client_key" {
type = string
}
variable "cluster_ca_certificate" {
type = string
}
provider "kubernetes" {
host = var.host
client_certificate = base64decode(var.client_certificate)
client_key = base64decode(var.client_key)
cluster_ca_certificate = base64decode(var.cluster_ca_certificate)
}
The steps to prepare a cluster include:
$ mkdir learn-terraform-deploy-nginx-kubernetes
$ cd learn-terraform-deploy-nginx-kubernetes
Then create kubernetes.tf with the configuration above. To properly configure this provider, you need to define the variables. First, view your kind cluster information.
$ kubectl config view --minify --flatten --context=kind-terraform-learn
The impact of documenting both providers is that users can provision clusters with the HashiCorp kubernetes provider and then manage manifest-based workloads with terraform-provider-kubectl in the same Terraform workflow. The contextual layer reinforces the Unified Workflow benefit where teams already provisioning Kubernetes clusters with Terraform can use the same configuration language to deploy applications into the cluster.
Terraform benefits for Kubernetes management highlighted in tutorial material include:
- Unified Workflow - If you are already provisioning Kubernetes clusters with Terraform, use the same configuration language to deploy your applications into your cluster.
- Full Lifecycle Management - Terraform doesn't only create resources, it updates, and deletes tracked resources without requiring you to inspect the API to identify those resources.
- Graph of Relationships - Terraform understands dependency relationships between resources. For example, if a Persistent Volume Claim claims space from a particular Persistent Volume, Terraform won't attempt to create the claim if it fails to create the volume.
These benefits map directly to the terraform-provider-kubectl value proposition of bridging Terraform lifecycle management with Kubernetes YAML.
Operational Considerations and State Management
The provider tracks YAML objects in Terraform state, which means state files contain the rendered manifest content and metadata for identification. The impact is that state locking and remote backends become critical for concurrent team access. The contextual connection is that drift detection relies on accurate state, so teams must avoid manual kubectl edits that bypass Terraform.
The provider can be installed and managed automatically by Terraform, which means version pinning in versions.tf controls the exact binary used in CI. The impact is reproducible runs across environments. The contextual layer is that downloading a binary for your system from the release page provides an offline installation path for regulated environments.
Conclusion
The terraform-provider-kubectl provider represents a deliberate engineering choice to keep Kubernetes manifest authoring in YAML while gaining Terraform's declarative control plane. By centering on the kubectlmanifest resource, the provider allows free-form yaml to be processed and applied against Kubernetes, with creation, updates and deletion handled seamlessly including drift detection. The integration of terraform-plugin-sdk/v2, client-go, kubectl, cli-runtime, and kustomize/api provides a stable dependency stack that mirrors upstream Kubernetes tooling. Configurable retry logic via applyretrycount and KUBECTLPROVIDERAPPLYRETRY_COUNT addresses real-world cluster instability, while Kubernetes discovery mechanisms ensure dynamic API resource support without provider churn. The availability of data resources for directories of yaml files and inline templating extends the model from single manifest management to bulk GitOps style workflows. Installation options span automatic Terraform managed plugins for standard workflows and manual binary placement for air-gapped scenarios. Development requires Go 1.12+ and a correctly configured GOPATH with make build for compilation. The provider has been used by many large Kubernetes installations to completely manage the lifecycle of Kubernetes resources, validating its role as a bridge between Terraform infrastructure management and Kubernetes declarative configuration. When combined with the HashiCorp kubernetes provider for cluster provisioning, teams achieve a unified Terraform workflow for both cluster and workload lifecycle, with full lifecycle management and dependency graph awareness that kubectl alone cannot provide.