terraform-provider-kubernetes
terraform-provider-kubernetes copied to clipboard
Error: data source `kubernetes_resource` returns null when resource does not exist
When k8s resource described in data.kubernetes_resource
does not exist terraform plan/apply
ends with error.
When resource exists, data is correctly returned.
I am trying to use this data source to verify if required Helm chart (MetalLB) is installed and CRDs exist.
Terraform Version, Provider Version and Kubernetes Version
Terraform version: v1.3.7
Kubernetes provider version: v2.16.1
Kubernetes version: v1.23.10
Affected Resource(s)
- data source
kubernetes_resource
Terraform Configuration Files
provider "kubernetes" {
config_path = "${path.module}/secrets/kube_config/kube_config.yml"
}
Debug Output
https://gist.github.com/redzioch/967808d1b7b3eb436ba3a2f4177f41a6
Steps to Reproduce
- Clone sample code from repo:
git clone https://github.com/redzioch/terraform-kubernetes-resource-error.git
-
terraform plan
Expected Behavior
When resource does not exist, data.kubernetes_resource.address_pool_crd.object
should be null
.
terraform plan
data.kubernetes_resource.address_pool_crd: Reading...
data.kubernetes_resource.address_pool_crd: Read complete after 1s
Changes to Outputs:
+ address_pool_crd = {
+ api_version = "apiextensions.k8s.io/v1"
+ kind = "CustomResourceDefinition"
+ metadata = [
+ {
+ name = "addresspools.metallb.io"
+ namespace = null
},
]
+ object = null
}
Actual Behavior
terraform plan
data.kubernetes_resource.address_pool_crd: Reading...
╷
│ Error: Provider produced null object
│
│ Provider "provider[\"registry.terraform.io/hashicorp/kubernetes\"]" produced a null value for data.kubernetes_resource.address_pool_crd.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
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
I have come across the same thing
When trying to check for an already existent or not deployment -
of course when it exists it works
when it doesn't Fail with the same error output : Error: Provider produced null object
this is really stupid in my opinion - should be either in a try block or someother way to indicate that it returned a null instead of failing
now one has to find workaround to achieve this...
Has anyone found a workaround for this issue? I'm trying to check if a CRD exists in the cluster so I know if another resource can be installed.
This is possibile using data kubernetes_resources using field_selector
or label_selector
, so to check if CRD is created use:
data "kubernetes_resources" "example" {
api_version = "apiextensions.k8s.io/v1"
kind = "CustomResourceDefinition"
field_selector = "metadata.name==awsnodetemplates.karpenter.k8s.aws"
}
then use conditional resource like:
resource "kubernetes_manifest" "awsnodetemplate_provider" {
count = length(data.kubernetes_resources.example.objects)>0 ? 1 : 0
...
}
be careful as there are kubernetes_resource
and kubernetes_resources
. Selectors are available only in plural version ending with "s".
This is possibile using data kubernetes_resources using
field_selector
orlabel_selector
, so to check if CRD is created use:data "kubernetes_resources" "example" { api_version = "apiextensions.k8s.io/v1" kind = "CustomResourceDefinition" field_selector = "metadata.name==awsnodetemplates.karpenter.k8s.aws" }
then use conditional resource like:
resource "kubernetes_manifest" "awsnodetemplate_provider" { count = length(data.kubernetes_resources.example.objects)>0 ? 1 : 0 ... }
be careful as there are
kubernetes_resource
andkubernetes_resources
. Selectors are available only in plural version ending with "s".
This doesn't work because count
needs to be known in the plan
phase, and the result of data
is after apply:
The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the count depends on.