hashicorp / terraform-provider-kubernetes

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

Updating `spec` on kubernetes_persistent_volume causes `claim_ref` namespace to update to "default" #1664

Closed johnathank-nuna closed 1 year ago

johnathank-nuna commented 2 years ago

Terraform Version, Provider Version and Kubernetes Version

Terraform v1.0.7
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v4.7.0
+ provider registry.terraform.io/hashicorp/external v1.2.0
+ provider registry.terraform.io/hashicorp/helm v2.4.1
+ provider registry.terraform.io/hashicorp/kubernetes v2.9.0
+ provider registry.terraform.io/hashicorp/template v2.2.0

Kubernetes Version: 1.21

Affected Resource(s)

Terraform Configuration Files

resource "kubernetes_persistent_volume" "pv" {
  metadata {
    name = "example-pv"
  }

  spec {
    capacity = {
      storage = "5Gi"
    }
    access_modes                     = ["ReadWriteMany"]
    volume_mode                      = "Filesystem"
    persistent_volume_reclaim_policy = "Retain"
    storage_class_name               = "example-sc"
    persistent_volume_source {
      csi {
        driver        = "efs.csi.aws.com"
        volume_handle = fs-XXXXXXXXX
      }
    }
  }
}

Debug Output

      ~ spec {
            # (6 unchanged attributes hidden)

          ~ claim_ref {
                name      = "example-claim"
              ~ namespace = "example" -> "default"
            }

Panic Output

Steps to Reproduce

  1. Deploy a PV
  2. Create a PVC for the PV
  3. Update the PV volume_attributes to set encryptInTransit to true.
  4. Run terraform apply

Expected Behavior

What should have happened?

resource "kubernetes_persistent_volume" "pv" {
  metadata {
    name = "example-pv"
  }

  spec {
    capacity = {
      storage = "5Gi"
    }
    access_modes                     = ["ReadWriteMany"]
    volume_mode                      = "Filesystem"
    persistent_volume_reclaim_policy = "Retain"
    storage_class_name               = "example-sc"
    persistent_volume_source {
      csi {
        driver        = "efs.csi.aws.com"
        volume_handle = fs-XXXXXXXXX
        volume_attributes = {
          encryptInTransit = "true"
        }
      }
    }
  }
}

After setting the volume_attributes we should ONLY see the volume_attributes change as the kubernetes_persistent_volume should detect the namespace of the existing PVC instead of using "default":

  ~ resource "kubernetes_persistent_volume" "pv" {
        id = "example-pv"

      ~ spec {
            # (6 unchanged attributes hidden)

          ~ persistent_volume_source {

              ~ csi {
                  ~ volume_attributes = {
                      ~ "encryptInTransit" = null -> "true"
                    }
                    # (3 unchanged attributes hidden)
                }
            }
        }
        # (1 unchanged block hidden)
    }

Actual Behavior

What actually happened?

Instead we see that when run against a PV with an existing claim, it leaves the name of the claim but falls back to the "default" namespace for the claim_ref in addition to the volume_attributes change:

  ~ resource "kubernetes_persistent_volume" "pv" {
        id = "example-pv"

      ~ spec {
            # (6 unchanged attributes hidden)

          ~ claim_ref {
                name      = "example-claim"
              ~ namespace = "example" -> "default"
            }

          ~ persistent_volume_source {

              ~ csi {
                  ~ volume_attributes = {
                      ~ "encryptInTransit" = null -> "true"
                    }
                    # (3 unchanged attributes hidden)
                }
            }
        }
        # (1 unchanged block hidden)
    }

Important Factoids

To work around this you can set the claim_ref for the PV:

resource "kubernetes_persistent_volume" "pv" {
  metadata {
    name = "example-pv"
  }

  spec {
    capacity = {
      storage = "5Gi"
    }
    access_modes                     = ["ReadWriteMany"]
    volume_mode                      = "Filesystem"
    persistent_volume_reclaim_policy = "Retain"
    storage_class_name               = "example-sc"
    claim_ref {
      namespace = "example"
      name      = "example-claim"
    }
    persistent_volume_source {
      csi {
        driver        = "efs.csi.aws.com"
        volume_handle = fs-XXXXXXXXX
        volume_attributes = {
          encryptInTransit = "true"
        }
      }
    }
  }
}

It was already called out in GH-1437, but claim_ref is undocumented and was a bit of a pain to figure out.

References

Community Note

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!