hashicorp / terraform-provider-kubernetes

Terraform Kubernetes provider
https://www.terraform.io/docs/providers/kubernetes/
Mozilla Public License 2.0
1.6k stars 980 forks source link

object.metadata.finalizers causes a diff on every plan #1669

Closed mathewpower closed 3 weeks ago

mathewpower commented 2 years ago

Terraform Version, Provider Version and Kubernetes Version

Terraform version: `v1.1.3`
Kubernetes provider version: `2.9.0`
Kubernetes version: `1.20`

Affected Resource(s)

Terraform Configuration Files

resource "kubernetes_manifest" "istio_control_plane" {
  computed_fields = ["metadata.finalizers"]

  manifest = {
    apiVersion = "install.istio.io/v1alpha1"
    kind       = "IstioOperator"

    metadata = {
      name       = "control-plane"
      namespace  = "istio-system"
    }

    spec = {
      profile = "minimal" 
    }
  }
}

Debug Output

Panic Output

Steps to Reproduce

  1. terraform apply

Expected Behavior

There should be no diffs in the terraform output when the resource has not changed.

Actual Behavior

Terraform decides there is a state change and wants to replace the istio_control_plane resource.

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  + create
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # kubernetes_manifest.istio_control_plane must be replaced
-/+ resource "kubernetes_manifest" "istio_control_plane" {
      ~ object          = {
          ~ metadata   = {
              - finalizers = [
                  - "istio-finalizer.install.istio.io",
                ] -> null
                # (2 unchanged elements hidden)
            }
            # (3 unchanged elements hidden)
        } # forces replacement
        # (2 unchanged attributes hidden)
    }

Important Factoids

References

Community Note

arybolovlev commented 2 years ago

Hi @mathewpower,

In your terraform, code example the attribute computed_fields is nested into the manifest attribute, but they are supposed to be on the same level. Could you please rewrite your code to something like this and try it again? Please let me know if that works.

resource "kubernetes_manifest" "istio_control_plane" {
  computed_fields = ["metadata.finalizers"]

  manifest = {
    apiVersion = "install.istio.io/v1alpha1"
    kind       = "IstioOperator"

    metadata = {
      name       = "control-plane"
      namespace  = "istio-system"
    }

    spec = {
      profile = "minimal" 
    }
  }
}

Thank you!

mathewpower commented 2 years ago

Apologies. This was a typo in the ticket. I've updated the example. The issue persists.

wjrogers commented 2 years ago

I am having the same problem with the resource mentioned in the referenced ticket #1442, elbv2.k8s.aws/v1beta1.TargetGroupBinding. I imported an existing resource using this configuration:

resource "kubernetes_manifest" "beanstalkd_targetgroupbinding" {
  manifest = {
    "apiVersion": "elbv2.k8s.aws/v1beta1",
    "kind": "TargetGroupBinding",
    "metadata": {
      "name": "beanstalkd"
      "namespace": helm_release.beanstalkd.namespace
    },
    "spec": {
      "serviceRef": {
        "name": "beanstalkd",
        "port": aws_lb_target_group.beanstalkd.port
      },
      "targetGroupARN": aws_lb_target_group.beanstalkd.arn,
      "targetType": aws_lb_target_group.beanstalkd.target_type
    }
  }

  computed_fields = [
    "metadata.annotations",
    "metadata.finalizers",
    "metadata.labels",
  ]
}

The provider wants to destroy and re-create the resource on a subsequent apply. Tested using the fresh release:

Edit: my issue might have more to do with the general import case in #1679

jbg commented 2 years ago

The kubernetes_manifest documentation is a bit vague about computed_fields, but it does imply that it's specifically for the case that the object returned immediately after apply is different.

Generally, I find that if you get an error when applying because the post-apply check found a different object than what was applied, then you need computed_fields.

On the other hand, if you find that apply works successfully, but a subsequent plan shows a diff since some other actor has modified the object (e.g. added a finalizer) in the meantime, then I suspect you might need lifecycle { ignore_changes = [ ... ] } instead. Unfortunately, ignore_changes doesn't seem to work at all on kubernetes_manifest resources (#1378).

github-actions[bot] commented 1 year ago

Marking this issue as stale due to inactivity. If this issue receives no comments in the next 30 days it will automatically be closed. If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. This helps our maintainers find and focus on the active issues. Maintainers may also remove the stale label at their discretion. Thank you!

msarfaty commented 1 year ago

Bump. like the above commenter said, it's a widely known issue that ignore_changes does not work for the returned object, and the computed_fields documentation is extremely vague. Our objects are changed async by webhooks after being set once initially, and computed_fields does nothing to remedy this.

github-actions[bot] commented 1 month ago

Marking this issue as stale due to inactivity. If this issue receives no comments in the next 30 days it will automatically be closed. If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. This helps our maintainers find and focus on the active issues. Maintainers may also remove the stale label at their discretion. Thank you!