Skip to content

Commit 64d283e

Browse files
committed
Add authentication guide for Google Cloud APIs
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>
1 parent 4d50c5a commit 64d283e

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

docs/AUTHENTICATION.md

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Authenticating to Google Cloud APIs
2+
3+
`provider-gcp` requires credentials to be provided in order to authenticate to
4+
the Google Cloud APIs. This can be done in one of the following ways:
5+
6+
- Authenticating using a base-64 encoded service account key in a Kubernetes
7+
`Secret`. This is described in detail [here](https://crossplane.io/docs/v1.6/getting-started/install-configure.html#get-gcp-account-keyfile).
8+
- Authenticating using [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity).
9+
This is described in the [section below](#authenticating-with-workload-identity).
10+
11+
## Authenticating with Workload Identity
12+
13+
*Note: This method is supported in `provider-gcp` v0.20.0 and later.*
14+
15+
Using Workload Identity requires some additional setup.
16+
Many of the steps can also be found in the [documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity).
17+
18+
### Steps
19+
20+
These steps assume you already have a running GKE cluster which has already
21+
enabled Workload Identity and has a sufficiently large node pool.
22+
23+
Note that you can specify any valid strings to the variables below unless the
24+
variable is explicitly assigned.
25+
26+
#### 1. Install Crossplane
27+
28+
Install Crossplane from `stable` channel:
29+
30+
```bash
31+
$ helm repo add crossplane-stable https://charts.crossplane.io/stable
32+
$ helm install crossplane --create-namespace --namespace crossplane-system crossplane-stable/crossplane
33+
```
34+
35+
`provider-gcp` can be installed with either the [Crossplane CLI](https://crossplane.io/docs/v1.6/getting-started/install-configure.html#install-crossplane-cli)
36+
or a `Provider` resource as below:
37+
38+
```console
39+
$ cat <<EOF | kubectl apply -f -
40+
apiVersion: pkg.crossplane.io/v1
41+
kind: Provider
42+
metadata:
43+
name: ${PROVIDER_GCP}
44+
spec:
45+
package: crossplane/provider-gcp:v${VERSION} # v0.20.0 or later
46+
# Set a controllerConfigRef if you have a ControllerConfig:
47+
# controllerConfigRef:
48+
# name: ${CONTROLLER_CONFIG}
49+
EOF
50+
```
51+
52+
#### 2. Configure service accounts to use Workload Identity
53+
54+
Create a GCP service account, which will be used for provisioning actual
55+
infrastructure in GCP, and grant IAM roles you need for accessing the Google
56+
Cloud APIs:
57+
58+
```console
59+
$ gcloud iam service-accounts create ${GCP_SERVICE_ACCOUNT}
60+
$ gcloud projects add-iam-policy-binding ${PROJECT_ID} \
61+
--member "serviceAccount:${GCP_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
62+
--role ${ROLE} \
63+
--project ${PROJECT_ID}
64+
```
65+
66+
Get the name of your current `ProviderRevision` of this provider:
67+
68+
```console
69+
$ REVISION=$(kubectl get providers.pkg.crossplane.io ${PROVIDER_GCP} -o jsonpath="{.status.currentRevision}")
70+
```
71+
72+
Next, you'll configure IAM to use Workload Identity.
73+
In this step, you can choose one of the following options to configure service accounts:
74+
75+
- [Option 1] Use a Kubernetes `ServiceAccount` managed by a provider's controller.
76+
- [Option 2] Use a Kubernetes `ServiceAccount` which you created and is specified to `.spec.serviceAccountName`
77+
in a [`ControllerConfig`](https://doc.crds.dev/github.com/crossplane/crossplane/pkg.crossplane.io/ControllerConfig/v1alpha1@v1.6.2).
78+
79+
##### 2.1. [Option 1] Use a controller-managed `ServiceAccount`
80+
81+
Specify a Kubernetes `ServiceAccount` with the revision you got in the last
82+
step:
83+
84+
```console
85+
$ KUBERNETES_SERVICE_ACCOUNT=${REVISION}
86+
```
87+
88+
##### 2.1. [Option 2] Use a user-managed `ServiceAccount`
89+
90+
Create a `ServiceAccount`, `ControllerConfig`, and `ClusterRoleBinding`:
91+
92+
```console
93+
$ cat <<EOF | kubectl apply -f -
94+
apiVersion: v1
95+
kind: ServiceAccount
96+
metadata:
97+
name: ${KUBERNETES_SERVICE_ACCOUNT}
98+
namespace: crossplane-system
99+
---
100+
apiVersion: pkg.crossplane.io/v1alpha1
101+
kind: ControllerConfig
102+
metadata:
103+
name: ${CONTROLLER_CONFIG}
104+
spec:
105+
serviceAccountName: ${KUBERNETES_SERVICE_ACCOUNT}
106+
---
107+
apiVersion: rbac.authorization.k8s.io/v1
108+
kind: ClusterRoleBinding
109+
metadata:
110+
name: crossplane:provider:${PROVIDER_GCP}:system
111+
roleRef:
112+
apiGroup: rbac.authorization.k8s.io
113+
kind: ClusterRole
114+
name: crossplane:provider:${REVISION}:system
115+
subjects:
116+
- kind: ServiceAccount
117+
name: ${KUBERNETES_SERVICE_ACCOUNT}
118+
namespace: crossplane-system
119+
EOF
120+
```
121+
122+
#### 2.2. Allow the Kubernetes `ServiceAccount` to impersonate the GCP service account
123+
124+
Grant `roles/iam.workloadIdentityUser` to the GCP service account:
125+
126+
```console
127+
$ gcloud iam service-accounts add-iam-policy-binding \
128+
${GCP_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com \
129+
--role roles/iam.workloadIdentityUser \
130+
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[crossplane-system/${KUBERNETES_SERVICE_ACCOUNT}]" \
131+
--project ${PROJECT_ID}
132+
```
133+
134+
Annotate the `ServiceAccount` with the email address of the GCP service account:
135+
136+
```console
137+
$ kubectl annotate serviceaccount ${KUBERNETES_SERVICE_ACCOUNT} \
138+
iam.gke.io/gcp-service-account=${GCP_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com \
139+
-n crossplane-system
140+
```
141+
142+
### 3. Configure a `ProviderConfig`
143+
144+
Create a `ProviderConfig` with `InjectedIdentity` in `.spec.credentials.source`:
145+
146+
```console
147+
$ cat <<EOF | kubectl apply -f -
148+
apiVersion: gcp.crossplane.io/v1beta1
149+
kind: ProviderConfig
150+
metadata:
151+
name: default
152+
spec:
153+
projectID: $PROJECT_ID
154+
credentials:
155+
source: InjectedIdentity
156+
EOF
157+
```
158+
159+
### 4. Next steps
160+
161+
Now that you have configured `provider-gcp` with Workload Identity supported,
162+
you can [provision infrastructure](https://crossplane.io/docs/v1.6/getting-started/provision-infrastructure).

0 commit comments

Comments
 (0)