GoogleCloudPlatform / k8s-config-connector

GCP Config Connector, a Kubernetes add-on for managing GCP resources
https://cloud.google.com/config-connector/docs/overview
Apache License 2.0
895 stars 225 forks source link

Config connector should allow the generation of random service account names #451

Open stevebrennan opened 3 years ago

stevebrennan commented 3 years ago

Describe the feature or resource We would like to set up Workload Identity from inside Kubernetes (GKE) so that installing the same application in K8s multiple times in the same or different clusters (in the same project) GCP resources names created don't collide. In this case, problematic resources are service accounts created using Config Connector.

Importance A concrete example: Let's say we have a service named "foo" that requires roles/pubsub.subscriber in the GCP project nord-foo. For this we have to set up Workload Identity so that we create a GCP service account, which we assign the role roles/pubsub.subscriber and then configure Workload Identity policy for that GCP service account and the service account inside K8s (KSA). If we wanted to deploy that application e.g. on the same cluster in multiple namespaces we would like that a different GCP service account is always created and assigned that role and everything needed. We would also like it to work if we deploy that application in a different cluster on the same GCP project, it's basically the same thing.

If we reuse the service account (SA) then if the SA is created with one of the Helm charts and that chart is installed with two different releases (or in two different namespaces) if one chart gets uninstalled the SA could be deleted and the remaining chart will not function.

The end goal is to be able to do everything inside GKE, so that we don't have to combine Terraform and other tools to deploy our apps. We would like to be able to create a random SA name as we see happen when we create it in the console.

toumorokoshi commented 3 years ago

Thanks for the feature request! The use case is clear.

Regarding the implementation: would this creation of unique service accounts be achievable by using helm variables instead? I could imagine the variable that is most likely dictating the namespace name could also be used in the service account name.

In general we try to delegate higher-order functionality like generating random ids to other tools in the Kubernetes toolchain, such as helm, kustomize, or kpt. So our fix may be driving functionality in one of these other tools.

kustodian commented 3 years ago

There are so many combinations of how and where some chart can be installed e.g. multiple installs in the same namespace, single install per different namespace, or installed on two different GKE clusters, while the config connector is pointing to the same GCP project. Because of that SA name on GCP could be something like:

gke-{{ .Release.name }}-{{ .Chart.name }}-{{ .Release.namespace }}-{{ $cluster }}

just a random example. My biggest concern about this is why should a user be concerned about it, the user shouldn't care about cluster name, namespace, etc. Also, the problem with this is the limit of 30 characters max for the SA ID. It's very easy to go above that.

Solving this on the tooling level is a valid solution and that's how we tried to fix it, but we couldn't. We use Helm and we didn't find a valid function that would help us with that. There are many hash functions, but none of them has the option to limit to 30 chars (of course we could use substr 0 30 on the hash), but what would be the string to hash that will always be unique per instance of the chart and not worry about it. That's why having Config Connector deal with that feels the most natural.

Like when you create an Ingress that creates a GCP LB, backends and everything it needs with some random names so you never have to worry about it.

toumorokoshi commented 3 years ago

Thanks for the clarification! I think it's noted that it might be hard to ensure a constructed SA that is within the 30 character limit.

Regarding options: it does seem helm doesn't provide a lot in this regard. We've actually had a similar use case and have been working with the kpt team to see if it can be added to their tool. Kpt allows arbitrary code to run in their generation pipeline, so it's easier to integrate one-off changes. e.g. if the problem was SA character truncation, you could add a kpt function that would truncate those SAs to 30 characters. Another way is to build a hash off of the contents of the rendered SA that you gave above.

Regardless: we'll leave the issue open for further discussion, and we will consider it as we build our backlog.