v3.0.0 moves the provider from the Terraform SDK v2 to the plugin framework. For most configurations the upgrade is a version bump: existing alekc/kubectl state migrates automatically on the first plan, and kubectl_manifest keeps v2's drift detection by default. Check the list below before you roll it out.
Before you upgrade
- Terraform 1.0 or newer is required. v3 speaks plugin protocol 6 only. If you still run Terraform 0.13 to 0.15, stay on 2.4.x. Any OpenTofu release works.
yaml_inclusterandlive_manifest_inclusterare gone fromkubectl_manifest. They are replaced bydrift(see below). State migrates on its own; only HCL that read those two attributes needs changing, usually tokubectl_manifest.x.drift != "".kubectl_server_version.triggersis nowmap(string). Non-string values fail atterraform validate. Wrap them intostring().force_conflicts = truewithoutserver_side_apply = truenow fails the plan. In v2 it was silently ignored. Either enable server-side apply or remove the flag.kubectl_filename_list.idchanges once. The hash format changed, so the id rotates on the first plan after upgrading. This only matters if you feedidinto atriggersmap elsewhere, which will then fire once.
What you get
- Readable drift.
kubectl_manifesthas a newdriftattribute that shows which paths differ from the live object, instead of an opaque fingerprint change.show_drift_valuescontrols how much is shown (none, the default, prints paths only;hashorfullshow values), andmask_pathshides specific paths. - Server-side drift detection, opt-in.
drift_engine = "server"compares against a server-side dry-run apply, the same waykubectl diffdoes. Use it for objects that report false drift on every refresh: operator-managed resources, CRDs with server-side defaults, or anything changed by admission webhooks. The default staysclient, which is the v2 behaviour, so existingignore_fieldslists keep working. - Ephemeral
kubectl_manifest(Terraform 1.10+). Reads an object from the cluster without writing the value to state, e.g. a token from a Secret. kubectl_kustomize_documentsdata source. Runskustomize buildin-process and returns the rendered documents, nokustomizebinary needed.wait_foron reads. Thekubectl_manifestdata source and the ephemeral resource can wait for a field or condition before returning.- Deferred actions. When the provider configuration is not known yet (for example a cluster endpoint from an EKS module that has not been applied), deferral-aware clients such as Terraform Stacks defer the kubectl resources to a follow-up apply instead of failing.
- Migrating from
gavinbunney/kubectl. Amoved {}block now migrateskubectl_manifeststate in place on Terraform. The README has the recipe. OpenTofu does not support this yet; usetofu state replace-providerthere.
Fixes you may notice
- Fewer
timed out fetching resources from discovery clienterrors on large clusters. The discovery client is now shared and bounded, and the apply retry covers discovery. apply_retry_countrejects negative values, and an unparseableKUBECTL_PROVIDER_APPLY_RETRY_COUNTis now an error instead of being ignored. Retries also stop as soon as the run is cancelled (Ctrl-C or a timeout) rather than finishing the backoff.wait_forand rollout waits no longer hang or misreport when the watch closes or returns an error.fieldsandwait_for.fieldpaths accept bracket-quoted keys, so labels and annotations with dots in the name are reachable, e.g.metadata.labels["app.kubernetes.io/name"].sensitive_fieldsvalues are no longer printed inTF_LOG=DEBUGoutput.
Upgrading
Bump the constraint to ~> 3.0, run terraform init -upgrade, then terraform plan. The plan should show no changes; CI checks exactly that for a 2.4.x state upgraded to 3.0. The per-resource notes are in the upgrade guide.