siderolabs / terraform-provider-talos

Mozilla Public License 2.0
123 stars 17 forks source link

Feature Request: parametrize `talos_machine_secrets.certs.k8sserviceaccount.key` or allow `RS256` #117

Closed leoslf closed 7 months ago

leoslf commented 1 year ago

Hi Team,

It would be nice if we could parametrize eithertalos_machine_secrets.certs.k8sserviceaccount.key or expose an option to choose RS256 for generatingtalos_machine_secrets.certs.k8sserviceaccount.key.

The use case is deploying a Talos cluster to AWS on EC2 and turns out AWS IAM Roles for Service Accounts (IRSA) doesn't accept service account tokens generated with ES256, which is the default generated by the provider.

Current workaround:

# generated cluster secrets
resource "talos_machine_secrets" "this" {
  talos_version = var.talos_version
}

resource "tls_private_key" "service_account_signing_key" {
  algorithm = startswith(var.service_account_signing_key_alg, "RS") ? "RSA" : "ECDSA"
  # rsa_bits = 2048
}

locals {
  machine_secrets_original = yamldecode(talos_machine_secrets.this.machine_secrets)

  talos_machine_secrets = yamlencode(merge(
    local.machine_secrets_original,
    {
      certs = merge(
        local.machine_secrets_original.certs,
        {
          k8sserviceaccount = {
            key = base64encode(local.service_account_signing_key.private_pem)
          }
        },
      ),
    },
  ))

  service_account_signing_key = {
    # RFC 1421 / PKCS#1
    private_pem = tls_private_key.service_account_signing_key.private_key_pem
  }
}

...

data "talos_machine_configuration" "this" {
  machine_secrets    = local.talos_machine_secrets
  ...
}

Thanks, Leo

frezbo commented 1 year ago

The recommended approach is to use a patch

either with the apply machine config resource or the generate machine config data source

resource "talos_machine_configuration_apply" "this" {
  ...
  config_patches = [
    yamlencode({
      cluster = {
        serviceAccount = {
          key = tls_private_key.service_account_signing_key.private_key_pem
        }
      }
    })
  ]
}

or

data "talos_machine_configuration" "this" {
  ...
  config_patches = [
    yamlencode({
      cluster = {
        serviceAccount = {
          key = tls_private_key.service_account_signing_key.private_key_pem
        }
      }
    })
  ]
}
leoslf commented 1 year ago

The recommended approach is to use a patch

Hi @frezbo,

Thanks for the prompt reply. The two suggested workarounds definitely look better than mine.

It would be nice if the talos_machine_secrets.machine_secrets could be self-contained (should not have to be patched elsewhere after creation), so the users can just use it without patching in every talos_machine_configuration data source.

Since talos_machine_secrets takes care of secrets generation, it would be just nice and give a better user experience to (a) have an optional parameter defaults to ECDSA -> ES256 but still provide a way to use RSA -> RS256 as an alternative algorithm for service account signing key, so it's backward compatible on the provider side, and (b) expose the key-pair as separate readable properties (I mean it's still fine to yamldecode the nested field).

Thanks, Leo

P.S. Did a little tracing here... The hardcoded value sits on this line in siderolabs/talos https://github.com/siderolabs/talos/blob/0bd1bdd744f68dc42ac64678972fede992a7189e/pkg/machinery/config/generate/secrets/bundle.go#L255

smira commented 7 months ago

That is fixed in Talos 1.7 (it defaults to RSA for service account key).

leoslf commented 7 months ago

@smira Thank you so much