Terraform-provider-kubernetes: Allow to update default service account

Created on 6 Feb 2019  ยท  10Comments  ยท  Source: hashicorp/terraform-provider-kubernetes

I want to add "image_pull_secret" to my default service account, but I'm getting the error "serviceaccounts "default" already exists"

Terraform Version

Terraform v0.11.11

Affected Resource(s)

  • kubernetes_service_account

Terraform Configuration Files

resource "kubernetes_service_account" "default" {
  metadata {
    name = "default"
    namespace = "default"
  }
  automount_service_account_token = "true"

  image_pull_secret = [{
    name = "docker-login"
  }]
}

Expected Behavior

It should modify the default service account to have the new imagePullSecrets attached as it happens when I directly apply a k8s manifest with that configuration.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
imagePullSecrets:
  - name: docker-login

Actual Behavior

Error: Error applying plan:
1 error(s) occurred:
* module.cluster.module.k8s_manifests.kubernetes_service_account.default: 1 error(s) occurred:
* kubernetes_service_account.default: serviceaccounts "default" already exists

Steps to Reproduce

terraform apply

Suggested Workaround

Add import support on the kubernetes_service_account resource.
Currently: resource kubernetes_service_account doesn't support import

enhancement

Most helpful comment

PR up: https://github.com/terraform-providers/terraform-provider-kubernetes/pull/876

Please ๐Ÿ‘ the PR if you're interested in this feature and comment if you test it out or have comments about the approach.

All 10 comments

This should require some investigation:

        // This resource is not importable because the API doesn't offer
        // any way to differentiate between default & user-defined secret
        // after the account was created.

https://github.com/terraform-providers/terraform-provider-kubernetes/blame/cef8ec0499890c5ccaa7bbacc4eb21a8763c506e/kubernetes/resource_kubernetes_service_account.go#L25

+1

+1 Trying to do the exact same thing with the default account.

+1 same issue.

Running Terraform 0.12.24 with Kubernetes provider 1.11.1, I am able to terraform import the default service account as a workaround.

But it's a frustrating manual step in the middle of setting up a new namespace:

  1. Add a new kubernetes_namespace resource
  2. terraform apply
  3. Add a new kubernetes_service_account resource for the default service account
  4. terraform import kubernetes_service_account.default_service_account mynamespace/default
  5. terraform apply again

@aljane's workaround worked for me.

Seems like a hack, though.

I believe, while it's intuitive to adjust the default user, it's actually a lot easier to simply make a new kubernetes user named something else with automounting properties, instead.

This means you don't need to hack around terraform.

Here's what I came up with, gluing together this current ticket, this ticket, this blog post.

Unfortunately, this doesn't quite work.

resource "kubernetes_secret" "image-puller" {
  metadata {
    name = "image-puller"
  }

  data = {

    ".dockerconfigjson" = jsonencode({
      "auths" : {
        "gcr.io" : {
          email    = "[email protected]"
          username = "_json_key"
          password = file(var.credentials_file)
        }
      }
    })
  }

  type = "kubernetes.io/dockerconfigjson"
}

resource "kubernetes_service_account" "image-puller-account" {
  metadata {
    name = "default"
    namespace = "default"
  }
  image_pull_secret {
    name = "image-puller"
  }

  automount_service_account_token = "true"

}

Getting unauthorized when trying to pull these images.

Is there a standard way to link GCR, GKE and Terraform together? That's really what I'm trying to accomplish here, but this doesn't seem to work.

I found a good workaround. All I need to do is create the kubernetes_secret and then in my helm deployment point explicitly to the imagePullSecret. This means the credential isn't picked up automatically, but I think this is _a lot cleaner_ than using an import hack.

I didn't need to add the service account, since the automount never really worked how I expected it to.

I also wanted to use the same service account json I used to authenticate with the rest of the GCP on terraform, so I didn't have to have multiple secret json files that are tracked. This works great.

resource "kubernetes_secret" "gcr-docker-configuration" {
  metadata {
    name = "gcr-docker-configuration"
  }

  data = {

    ".dockerconfigjson" = jsonencode({
      "auths" : {
        "gcr.io" : {
          email    = "[email protected]"
          username = "_json_key"
          password = file(var.credentials_file)
        }
      }
    })
  }

  type = "kubernetes.io/dockerconfigjson"
}

I added this to my helm deployment (full file context):

      imagePullSecrets:
        - name: gcr-docker-configuration

Hope this helps someone else who runs into this issue! If there's a better way to do this, would love to see alternatives, too.

Here's an example to look to for "adopting" default resources:

https://www.terraform.io/docs/providers/aws/r/default_vpc.html

The way I'd recommend doing this is with a new resource, kubernetes_default_service_account, that overrides the Create method of kubernetes_service_account. Rather than creating anything, that method just sets an ID, calls Read to load the existing attributes (especially the default secret), and then calls Update to persist any locally defined values.

Working on a PR for that now.

PR up: https://github.com/terraform-providers/terraform-provider-kubernetes/pull/876

Please ๐Ÿ‘ the PR if you're interested in this feature and comment if you test it out or have comments about the approach.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error ๐Ÿค– ๐Ÿ™‰ , please reach out to my human friends ๐Ÿ‘‰ [email protected]. Thanks!

Was this page helpful?
0 / 5 - 0 ratings