gavinbunney / terraform-provider-kubectl

Terraform provider to handle raw kubernetes manifest yaml files
https://registry.terraform.io/providers/gavinbunney/kubectl
Mozilla Public License 2.0
619 stars 105 forks source link

missing ~/.kube/config causes kubectl provider to fail #152

Open james-valente-simplisafe opened 2 years ago

james-valente-simplisafe commented 2 years ago

When a ~/.kube/config file does not exist and the kubectl provider block is not explicitly set with a load_config_file = "false", a terraform apply will fail with the following error message.

╷
│ Error: failed to create kubernetes rest client for read of resource: Get "http://localhost/api?timeout=32s": dial tcp [::1]:80: connect: connection refused
│ 
│   with module.ingress.kubectl_manifest.ingress_nginx_controller_ext[0],
│   on .terraform/modules/ingress/eks_modules/tf-eks-module-ingress-controller/main.tf line 149, in resource "kubectl_manifest" "ingress_nginx_controller_ext":
│  149: resource "kubectl_manifest" "ingress_nginx_controller_ext" {
│ 
╵

Creating an empty kubernetes config file will resolve this.

touch ~/.kube/config

According to the documentation, when unspecified, the default value for local_config_file is true.

load_config_file - (Optional) Flag to enable/disable loading of the local kubeconf file. Default true. Can be sourced from KUBE_LOAD_CONFIG_FILE.

I have both the kubernetes and the kubectl providers configured exactly the same. The kubernetes provider works correctly. However, the kubectl fails, as I have described above.

provider "kubernetes" {
  host                   = module.eks_cluster.eks_endpoint
  cluster_ca_certificate = base64decode(module.eks_cluster.eks_ca_data)
  token                  = data.aws_eks_cluster_auth.cluster_auth.token
}

provider "kubectl" {
  host                   = module.eks_cluster.eks_endpoint
  cluster_ca_certificate = base64decode(module.eks_cluster.eks_ca_data)
  token                  = data.aws_eks_cluster_auth.cluster_auth.token
}

I understand that setting load_config_file = "false" on the kubectl provider will resolve the issue.

However, I am opening this issue because there is a difference in behavior (with regard to configuration) between the kubernetes and kubectl providers. My understanding is that kubectl is generally intended to match the configuration behavior of the kubernetes provider. And, for the most part, both providers support nearly identical arguments.

Perhaps there is a bug in the kubectl provider? With the default behavior of load_config_file = "true", the kubectl provider seems to be taking two different code paths, depending on whether the ~/.kube/config file exists or not. It defaults to an endpoint of http://localhost/api?timeout=32s when the file does not exist. However, if the file does exist (e.g. empty 0-byte file), the kubectl provider seems to then respect the other configuration values of host, cluster_ca_certificate and token arguments, with success.

I turned on Terraform debugging, and the following messages seem to be related to the case where the ~/.kube/config file does not exist.

2022-01-27T11:39:44.808-0500 [DEBUG] provider.terraform-provider-kubectl_v1.13.1: 2022/01/27 11:39:44 [DEBUG] Using kubeconfig: /Users/jvalente11/.kube/config
2022-01-27T11:39:44.808-0500 [DEBUG] provider.terraform-provider-kubectl_v1.13.1: 2022/01/27 11:39:44 [WARN] Invalid provider configuration was supplied. Provider operations likely to fail: stat /Users/jvalente11/.kube/config: no such file or directory

When I re-run, after creating an empty kube config, only the first debug line appears. The second line does not appear.

The code corresponding to the DEBUG lines above is here and here.

Maybe this is caused by an uncaught error?

In any event, when the ~/.kube/config file does not exist, perhaps the kubectl provider should behave as though load_config_file were set to false, even if the default for that argument is true.


Additional information ...

Terraform binary and provider versions:

$ terraform version
Terraform v1.0.11
on darwin_amd64
+ provider registry.terraform.io/gavinbunney/kubectl v1.13.1
+ provider registry.terraform.io/hashicorp/kubernetes v2.7.1
[...]

I do not have any KUBE_* environment variables that would affect behavior.

$ env | grep KUBE
KUBE_EDITOR=vim
james-valente-simplisafe commented 2 years ago

Perhaps when the conditional on line 318 fails, an else block should revert or unset the loader attributes that were set on lines 308 or 310?

Then, perhaps lines 377 to 379 will not fail with an error.

Alternatively, maybe remove the return nil, nil on line 381 (leaving the condition as a warning), but letting the code fall back to the return cfg, nil on line 384.