Terraform - staggered provider population

2/14/2019

I have been looking at implementing Kubernetes with Terraform over the past week and I seem to have a lifecycle issue.

While I can make a Kubernetes resource depend on a cluster being spun up, the KUBECONFIG file isn't updated in the middle of the terraform apply.

The kubernete

resource "kubernetes_service" "example" {
  ...
depends_on = ["digitalocean_kubernetes_cluster.example"]
}
resource "digitalocean_kubernetes_cluster" "example" {
  name    = "example"
  region  = "${var.region}"
  version = "1.12.1-do.2"

  node_pool {
    name       = "woker-pool"
    size       = "s-1vcpu-2gb"
    node_count = 1
  }

  provisioner "local-exec" {
    command = "sh ./get-kubeconfig.sh" // gets KUBECONFIG file from digitalocean API.

    environment = {
      digitalocean_kubernetes_cluster_id = "${digitalocean_kubernetes_cluster.k8s.id}"
      digitalocean_kubernetes_cluster_name = "${digitalocean_kubernetes_cluster.k8s.name}"
      digitalocean_api_token = "${var.digitalocean_token}"
    }
  }

While I can pull the CONFIG file down using the API, terraform won't use this file, because the terraform plan is already in motion

I've seen some examples using ternary operators (resource ? 1 : 0) but I haven't found a workaround for non count created clusters besides -target

Ideally, I'd like to create this with one terraform repo.

-- denski
digital-ocean
kubernetes
terraform

1 Answer

2/16/2019

It turns out that the digitalocean_kubernetes_cluster resource has an attribute which can be passed to the provider "kubernetes" {} like so:

resource "digitalocean_kubernetes_cluster" "k8s" {
  name    = "k8s"
  region  = "${var.region}"
  version = "1.12.1-do.2"

  node_pool {
    name       = "woker-pool"
    size       = "s-1vcpu-2gb"
    node_count = 1
  }
}

provider "kubernetes" {
  host = "${digitalocean_kubernetes_cluster.k8s.endpoint}"

  client_certificate     = "${base64decode(digitalocean_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
  client_key             = "${base64decode(digitalocean_kubernetes_cluster.k8s.kube_config.0.client_key)}"
  cluster_ca_certificate = "${base64decode(digitalocean_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
}

It results in one provider being dependant on the other, and acts accordingly.

-- denski
Source: StackOverflow