-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Workload Identity #414
Support Workload Identity #414
Conversation
Adds support for Workload Identity, with which credentials no longer need to be present in Secrets. If `InjectedIdentity` is specified, a token source for application default credentials by a GCP Service Account, which is specified in the `iam.gke.io/gcp-service-account` annotation of a provider's Kubernetes Service Account. Tested this in the following environment and process. ``` $ kubectl version --short Client Version: v1.20.7 Server Version: v1.20.12-gke.1500 ``` ``` $ gcloud container clusters describe $CLUSTER --format="value(workloadIdentityConfig.workloadPool)" $PROJECT_ID.svc.id.goog ``` ``` $ kubectl get deploy crossplane \ -o jsonpath="{.spec.template.spec.containers[*].image}" \ -n crossplane-system crossplane/crossplane:v1.6.2 ``` Created a `Provider` and `ProviderConfig` with `InjectedIdentity` and then created a `Topic` managed resource: ``` $ cat <<EOF | kubectl apply -f - apiVersion: pkg.crossplane.io/v1 kind: Provider metadata: name: gcp-provider spec: package: $PACKAGE # Use this version --- apiVersion: gcp.crossplane.io/v1beta1 kind: ProviderConfig metadata: name: default spec: projectID: $PROJECT_ID credentials: source: InjectedIdentity EOF $ cat <<EOF | kubectl apply -f - apiVersion: pubsub.gcp.crossplane.io/v1alpha1 kind: Topic metadata: name: foo spec: forProvider: {} EOF ``` Note that Pods are emitting authentication errors until Workload Identity is configured: ```console $ kubectl logs gcp-provider-f2edfcc2cd84-f68bc774f-7qscf // ... 2022-02-06T20:07:06.014Z DEBUG provider-gcp Cannot create external resource {"controller": "managed/topic.pubsub.gcp.crossplane.io", "request": "/foo", "uid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "version": "123456789", "external-name": "foo", "error": "cannot create Topic: googleapi: Error 403: User not authorized to perform this action., forbidden"} ``` Ensured the Service Account is specified in Deployment though it's obvious: ``` $ kubectl get sa -o custom-columns=":metadata.name" | grep 'gcp-provider' gcp-provider-xxxxxxxxxxxx $ kubectl get deploy gcp-provider-xxxxxxxxxxxx \ -o jsonpath="{.spec.template.spec.serviceAccountName}" \ gcp-provider-xxxxxxxxxxxx ``` Created a GCP Service Account and configured Workload Identity: ``` $ gcloud iam service-accounts create crossplane $ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:crossplane@$PROJECT_ID.iam.gserviceaccount.com" \ --role roles/admin $ gcloud iam service-accounts add-iam-policy-binding \ crossplane@$PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:$PROJECT_ID.svc.id.goog[crossplane-system/gcp-provider-xxxxxxxxxxxx]" $ kubectl annotate sa gcp-provider-xxxxxxxxxxxx \ iam.gke.io/gcp-service-account=crossplane@$PROJECT_ID.iam.gserviceaccount.com ``` Waited for a little while and then confirmed it was successfully created: ``` $ gcloud pubsub topics describe foo name: projects/$PROJECT_ID/topics/foo ``` Note that since Service Accounts managed by a controller are named the same as the current `ProviderRevision` and they are inconstant, it's necessary to fix a name for production use cases. Signed-off-by: micnncim <micnncim@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great, this is a highly requested feature.
Thanks a lot for your contribution @micnncim!
Your PR description looks awesome, would you mind migrating it to a similar document as AUTHENTICATION.md in provider-aws?
@turkenh Thanks for your approval. I’m happy to provide a document, but want to make sure if crossplane/crossplane#2880 looks good to you before that since the process (and then a document) will change depending on that change. |
@micnncim left a comment there. /cc @hasheddan |
@micnncim my suggestion would be to document with existing Crossplane versions similar to provider-aws and merge this PR. |
7dae141
to
33e155e
Compare
Yeah, that makes sense. I created a document for authentication. |
Adds a guide for configuring authentication to Google Cloud APIs. Though this provides enough information to cover the feature added in this PR, we should improve the way to configure a `ServiceAccount` for practical use cases since in any methods users need to reconfigure IAM stuff every time a new `ProviderRevision` is created. Signed-off-by: micnncim <micnncim@gmail.com>
33e155e
to
64d283e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking awesome, thanks a lot @micnncim!
Adds a step to define variables' names so that users can smoothly set up authentication with Workload Identity in `provider-gcp`. Signed-off-by: micnncim <micnncim@gmail.com>
12ebbd5
to
bd61620
Compare
this is a great feature, but is there any thoughts to augmenting this so it can support multi-tenant project infra. I asked about this on slack and was suggested to use vcluster as supplementary to address. Current implementation of ProviderConfig only support the use of Secret / keys but wondering if there are thoughts on how to achieve it workload identity |
Description of your changes
Adds support for Workload Identity, with which credentials no longer need to be present in Secrets.
If
InjectedIdentity
is specified, a token source for application default credentials by a GCP Service Account, which is specified in theiam.gke.io/gcp-service-account
annotation of a provider's Kubernetes Service Account, is used for authentication.Signed-off-by: micnncim micnncim@gmail.com
Fixes #173
I have:
make reviewable test
to ensure this PR is ready for review.How has this code been tested
Tested this in the following environment and process.
Created a
Provider
andProviderConfig
withInjectedIdentity
and then created aTopic
managed resource:Note that Pods are emitting authentication errors until Workload Identity is configured:
Ensured the Service Account is specified in Deployment though it's obvious:
Created a GCP Service Account and configured Workload Identity:
Waited for a little while and then confirmed it was successfully created:
Note that since Service Accounts managed by a controller are named the same as the current
ProviderRevision
and they are inconstant, it's necessary to fix a name for production use cases. crossplane/crossplane#2880 proposes a change for this.