siderolabs / terraform-provider-talos

Mozilla Public License 2.0
141 stars 18 forks source link

Use `talos_cluster_kubeconfig` to setup kubernetes provider in terraform #47

Closed wind0r closed 1 year ago

wind0r commented 1 year ago

Currently I quite complicated parse the kubeconfig from talos_cluster_kubeconfig to setup the kubernetes provider so I can use helm and/or install flux via terraform

see:

resource "talos_cluster_kubeconfig" "kubeconfig" {
  talos_config = talos_client_configuration.talosconfig.talos_config
  endpoint     = [for k, v in var.node_data.controlplanes : k][0]
  node         = [for k, v in var.node_data.controlplanes : k][0]
}

provider kubernetes {
  host = yamldecode(talos_cluster_kubeconfig.kubeconfig.kube_config)["clusters"][0]["cluster"]["server"]

  cluster_ca_certificate = base64decode(yamldecode(talos_cluster_kubeconfig.kubeconfig.kube_config)["clusters"][0]["cluster"]["certificate-authority-data"])

  client_certificate = base64decode(yamldecode(talos_cluster_kubeconfig.kubeconfig.kube_config)["users"][0]["user"]["client-certificate-data"])
  client_key         = base64decode(yamldecode(talos_cluster_kubeconfig.kubeconfig.kube_config)["users"][0]["user"]["client-key-data"])
}

So i am wondering if there is a better way which i am are missing or if talos_cluster_kubeconfig may should be extended to directly provide host, cluster_ca_certificate, client_certificate and client_key.

rsmitty commented 1 year ago

hey @wind0r, thanks for filing the issue. I think what you're doing now is probably the best you can do at this moment. but we're talking internally about extending the output to include these fields explicitly as you say. stay tuned!

james-callahan commented 1 year ago

For what it's worth, I was able to do this manually via:

resource "tls_private_key" "kubernetes_cert" {
  algorithm = "ED25519"
}

resource "tls_cert_request" "kubernetes_cert" {
  private_key_pem = tls_private_key.kubernetes_cert.private_key_pem

  subject {
    organization = "system:masters"
    common_name  = "admin"
  }
}

resource "tls_locally_signed_cert" "kubernetes_cert" {
  cert_request_pem   = tls_cert_request.kubernetes_cert.cert_request_pem
  ca_private_key_pem = base64decode(local.talos_secrets.certs.k8s.key)
  ca_cert_pem        = base64decode(local.talos_secrets.certs.k8s.crt)

  validity_period_hours = 24 * 365 # same 1 year period that `talosctl kubeconfig` uses

  allowed_uses = [
    "digital_signature",
    "client_auth",
  ]
}

provider "kubernetes" {
  host = local.kubernetes_api_server_endpoint

  client_certificate     = tls_locally_signed_cert.kubernetes_cert.cert_pem
  client_key             = tls_private_key.kubernetes_cert.private_key_pem
  cluster_ca_certificate = base64decode(local.talos_secrets.certs.k8s.crt)
}