IBM-Cloud/terraform

Using the ibmcloud_cs_cluster_config data resource will continually download the cluster config again and again (ad nauseum) resulting in tens if not hundreds of duplicate files

Closed this issue · 4 comments

Terraform Version

0.9.5

Affected Resource(s)

  • ibmcloud_cs_cluster_config

Terraform Configuration Files

data "ibmcloud_cs_cluster_config" "ad_server_cluster" {
  org_guid = "${data.ibmcloud_cf_org.bx_org.id}"
  space_guid = "${data.ibmcloud_cf_space.bx_space.id}"
  account_guid = "${data.ibmcloud_cf_account.bx_account.id}"
  cluster_name_id = "${ibmcloud_cs_cluster.ad_servers.id}"
  config_dir = "./k8s"
}

Debug Output

tree ./k8s/
./k8s/
├── 4e4603acb71e4cecabf10a611210f1b7_kubeconfig-1496318377202567976
│   ├── ca-prod-dal12-ref-arch-ad-serve.pem
│   └── kube-config-prod-dal12-ref-arch-ad-serve.yml
└── 4e4603acb71e4cecabf10a611210f1b7_kubeconfig-1496318616787356755
    ├── ca-prod-dal10-ref-arch-ad-serve.pem
    └── kube-config-prod-dal10-ref-arch-ad-serve.yml

Expected Behavior

I would expect that it only downloads the configuration once. It appears there is a timestamp or some other kind of UUID appended to the end of the directory name, so I'm guessing this was built in to avoid collision... but instead of doing that I think we should be checking if it already exists, and if so then don't download it again.

Actual Behavior

A new directory is created each time terraform plan or terraform apply or terraform refresh is run.

Steps to Reproduce

  • Create a cluster and a cluster config resource, plan and apply it
  • Run plan or apply a second time and note that the k8s configuration is downloaded twice

@ckelner ,

Thanks for the feedback 👍. I think that finding if file already exists is a bit tricky. It might exist already but it might be old. We had some discussion in the past and re-clarified that each time you download the config , refresh tokens , id-tokens etc are different in the file and have a direct impact on the authentication.

So user may want to download the new config even though he already has the config.

Since we are already creating unique folders to avoid collisions we can also add the cluster name or id to create folder name specific to a cluster name. So they become something like kubeconfig_myclustername-timestamp. When the data source runs it will scan the directory and look for some-prefix-myclustername-somesuffix and declare it to be present and not download it.

But if user want a new config since he started to see some problem with current config like authentication issues. He would need to delete kubeconfig_myclustername-timestamp manually and run the terraform again. In this case he has to go outside terraform and perform some operation which is deleting. (Provisioners could be used to delete the file though)

Another option is to provide some flag on the schema to skip the download. So once user has set it , it will not download and once he sees that the credentials have expired and not working anymore. He can disable the flag to download the latest config. All from terraform tf file.

Also every time a new config is downloaded for a particular cluster we will scan the directory and keep only the latest kubeconfig_myclustername-timestamp and remove all old ones in case one forgets to skip the download so as not bloat.

@albee-jhoney , @vkalangu

Also every time a new config is downloaded for a particular cluster we will scan the directory and keep only the latest kubeconfig_myclustername-timestamp and remove all old ones in case one forgets to skip the download so as not bloat.

I think the option quoted above is best, at least in my opinion.

I did something like this with a null resource and local exec provisioner to keep the directory clean:

resource "null_resource" "cluster" {
  triggers {
    ad_server_cluster = "${data.ibmcloud_cs_cluster_config.ad_server_cluster.config_file_path}"
  }
  provisioner "local-exec" {
    command = <<-EOF
              # change into the k8s config dir
              cd ${var.ad_server_config_path}
              # capture the latest k8s config directory
              curdir=$(echo ${data.ibmcloud_cs_cluster_config.ad_server_cluster.config_file_path} | cut -f2 -d"/")
              # remove (any)all k8s config directories which are not the current
              # directory.
              find . -maxdepth 1 ! -iname $curdir -exec rm -r {} \;
              EOF
  }
}

Sure, to avoid that work from the user we will let him control it

	"download": {
		Description: "If set to false will not download the config",
		Type:        schema.TypeBool,
		Optional:    true,
		Default:     true,
	},

Use kubeconfig_myclustername. We will have to make an assumption customer is going to take care of the uniquness of cluster config in the directory