Terraform-provider-kubernetes: Provider behavior differs from kubectl: unable to specify empty resource attribute

Created on 3 Jun 2020  ·  7Comments  ·  Source: hashicorp/terraform-provider-kubernetes

Terraform Version and Provider Version

Terraform v0.12.26
terraform-provider-kubernetes v1.11.3

Affected Resource(s)

kubernetes_persistent_volume_claim is the most widely reported, but the issue is at the SDK level and therefore affects all resources.

Terraform Configuration Files

This is one example of trying to specify an empty value for the storageclass.

resource "kubernetes_persistent_volume" "example" {
  metadata {
    name = "nfs-volume"
  }
  spec {
    capacity = {
      storage = "1T"
    }
    storage_class_name = ""
    access_modes = ["ReadWriteMany"]
    persistent_volume_source {
      nfs {
        server = google_filestore_instance.test.networks[0].ip_addresses[0]
        path = "/${google_filestore_instance.test.file_shares[0].name}"
      }
    }
  }
}

resource "kubernetes_persistent_volume_claim" "example" {
  metadata {
    name = "mariadb-data"
    namespace = "test"
  }
  spec {
    access_modes = ["ReadWriteMany"]
    storage_class_name = ""
    volume_name = kubernetes_persistent_volume.example.metadata[0].name
    resources {
      requests = {
        storage = "1T"
      }
    }
  }
}

Expected Behavior

Users should be able to specify an empty storageclass (storage_class = ""), which is behavior supported by kubectl.

Actual Behavior

The provider interprets "" to be the same as omitting the value altogether. There is no way to differentiate between null and empty values in the current version of the SDK.

Steps to Reproduce

  1. Create a PVC with an empty storage class.
  2. terraform apply

When terraform apply has finished, the storageclass is now set to default instead of empty (""). This behavior is unexpected because it differs from kubectl, subsequently breaking users' workflows.

References

The recommended work-around is to create a storageclass and use it in PVs and PVCs, instead of using "" for the storageclass name. An example of that work-around can be found here.

Other issues and PRs relating to this will be closed, so we can track them all in this single issue.

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
acknowledged bug

Most helpful comment

Any update on when this might be fixed?

When defining storage_class_name = "" OR commenting the line out on a persistent_volume resource then looking at kubectl get pv it shows the resource as belonging to "blank" storage class BOTH ways.

When doing the same for a persistent_volume_claim resource, either defining storage_class_name = "" or commenting it out, kubectl shows the resource belonging to the "default" storage class BOTH ways.

This makes it so the PVC will not come up because the storage_class_name doesn't match the PV.

Major bug!!

All 7 comments

@dak1n1 I'm also facing this issue. Created this PR for allowing empty strings for the storage_class_name attribute - https://github.com/hashicorp/terraform-provider-kubernetes/pull/923. Seems to be straightforward, please take a look.

Any update on when this might be fixed?

When defining storage_class_name = "" OR commenting the line out on a persistent_volume resource then looking at kubectl get pv it shows the resource as belonging to "blank" storage class BOTH ways.

When doing the same for a persistent_volume_claim resource, either defining storage_class_name = "" or commenting it out, kubectl shows the resource belonging to the "default" storage class BOTH ways.

This makes it so the PVC will not come up because the storage_class_name doesn't match the PV.

Major bug!!

@taylorturner See workaround documented in the PR References section. This one won't be fixed quickly.

Since version 2 of the Terraform SDK has been released, I followed up about potentially being able to support passing an empty value into a provider attribute (like storage_class_name=""). Unfortunately, this is not something the SDK can support. There is a lower-level SDK that can support the differentiation between null and empty, which I'll put here for reference: https://github.com/hashicorp/terraform-plugin-go

But we don't have any plans for the Kubernetes provider to use that SDK, since that would be a re-write of the entire provider.

The easiest work-around is to create a storage class (there is an example here). An alternative work-around, if you don't want to create a storage class, would be to use the Kubernetes alpha provider to create the PVC, which would allow you to write out the persistent volume claim similarly to yaml, where you could specify the empty storage class.

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

I re-opened this one since we're still getting PRs for the feature. I think the work-arounds are not sufficient. And with some information I recently learned about the SDK, implementing the empty storageclass might be possible. It's worth investigating further.

The easiest work-around in the mean time is to look at your cluster's default storage class (kubectl get storageclass) and then use the name of that storage class in your PVC and PV. Here's an example: https://gist.githubusercontent.com/dak1n1/6a95719c4e68cfc9e736c8a7624f53a1/raw/939f038b810d314a689bb687ddfbe674aacc69e6/gistfile1.txt

Was this page helpful?
0 / 5 - 0 ratings