Skip to content
Snippets Groups Projects
Commit ff599041 authored by Cédric OLIVIER's avatar Cédric OLIVIER
Browse files

feat(gcp): setup GCP credentials through ADC

New variant to allow GKE authentication with workload identity federation
parent a3edd395
No related branches found
No related tags found
No related merge requests found
...@@ -549,3 +549,64 @@ variables: ...@@ -549,3 +549,64 @@ variables:
K8S_DEFAULT_KUBE_CONFIG: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/my-app/kubernetes/noprod?field=kube_config" K8S_DEFAULT_KUBE_CONFIG: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/my-app/kubernetes/noprod?field=kube_config"
K8S_PROD_KUBE_CONFIG: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/my-app/kubernetes/prod?field=kube_config" K8S_PROD_KUBE_CONFIG: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/my-app/kubernetes/prod?field=kube_config"
``` ```
### Google Cloud variant
This variant uses [Application Default Credentials][gcp-adc] through the `GOOGLE_APPLICATION_CREDENTIALS` variable using Workload Identity federation.
List of requirements before using this variant:
1. You must have a Workload Identity Federation Pool and Provider configured,
2. You must have a Service Account with the `roles/iam.workloadIdentityUser` IAM role
granted to the Workload Identity [principal][gcp-iam-principals] matching your Gitlab project or group,
3. Optionally, you can set the `GOOGLE_CLOUD_PROJECT` template variable
to define the default Google Cloud project.
4. You must have create a `kubeconfig.yaml` configuration which [enable application default credentials for kubectl](https://cloud.google.com/kubernetes-engine/docs/how-to/api-server-authentication#environments-without-gcloud)
The Gitlab documentation has some [details about Workload Identity Federation integration][gcp-gitlab-wif].
This [blog post about OIDC impersonation through Workload Identify Federation][gcp-wif-example] might also be of help.
[gcp-adc]: https://cloud.google.com/docs/authentication/client-libraries
[gcp-provider]: https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#running-terraform-outside-of-google-cloud
[gcp-iam-principals]: https://cloud.google.com/iam/docs/principal-identifiers
[gcp-gitlab-wif]: https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/
[gcp-wif-example]: https://blog.salrashid.dev/articles/2021/understanding_workload_identity_federation/#oidc-impersonated
#### Configuration
The variant requires the additional configuration parameters:
| Input / Variable | Description | Default value |
| ----------------- | -------------------------------------- | ----------------- |
| `gcp-oidc-aud` / `GCP_OIDC_AUD` | The `aud` claim for the JWT token | `$CI_SERVER_URL` |
| `gcp-oidc-provider` / `GCP_OIDC_PROVIDER` | Default Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) | _none_ |
| `gcp-oidc-account` / `GCP_OIDC_ACCOUNT` | Default Service Account to which impersonate with OpenID Connect authentication | _none_ |
| `gcp-review-oidc-provider` / `GCP_REVIEW_OIDC_PROVIDER` | Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `review` environment _(only define to override default)_ | _none_ |
| `gcp-review-oidc-account` / `GCP_REVIEW_OIDC_ACCOUNT` | Service Account to which impersonate with OpenID Connect authentication on `review` environment _(only define to override default)_ | _none_ |
| `gcp-integ-oidc-provider` / `GCP_INTEG_OIDC_PROVIDER` | Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `integration` environment _(only define to override default)_ | _none_ |
| `gcp-integ-oidc-account` / `GCP_INTEG_OIDC_ACCOUNT` | Service Account to which impersonate with OpenID Connect authentication on `integration` environment _(only define to override default)_ | _none_ |
| `gcp-staging-oidc-provider` / `GCP_STAGING_OIDC_PROVIDER` | Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `staging` environment _(only define to override default)_ | _none_ |
| `gcp-staging-oidc-account` / `GCP_STAGING_OIDC_ACCOUNT` | Service Account to which impersonate with OpenID Connect authentication on `staging` environment _(only define to override default)_ | _none_ |
| `gcp-prod-oidc-provider` / `GCP_PROD_OIDC_PROVIDER` | Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `production` environment _(only define to override default)_ | _none_ |
| `gcp-prod-oidc-account` / `GCP_PROD_OIDC_ACCOUNT` | Service Account to which impersonate with OpenID Connect authentication on `production` environment _(only define to override default)_ | _none_ |
| `kubectl-image` / `K8S_KUBECTL_IMAGE` | The Docker image used to run Kubernetes `kubectl` commands on [GKE](https://cloud.google.com/kubernetes-engine/docs) | `gcr.io/google.com/cloudsdktool/cloud-sdk:latest` |
#### Example
With a common default `GCP_OIDC_PROVIDER` and `GCP_OIDC_ACCOUNT` configuration for non-prod environments, and a specific one for production:
```yaml
include:
# main template
- component: gitlab.com/to-be-continuous/kubernetes/gitlab-ci-k8s@6.2.0
# Google Cloud variant
- component: gitlab.com/to-be-continuous/kubernetes/gitlab-ci-k8ss-gcp@6.2.0
inputs:
# common OIDC config for non-prod envs
gcp-oidc-provider: "projects/<gcp_nonprod_proj_id>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>"
gcp-oidc-account: "<name>@$<gcp_nonprod_proj_id>.iam.gserviceaccount.com"
# specific OIDC config for prod
gcp-prod-oidc-provider: "projects/<gcp_prod_proj_id>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>"
gcp-prod-oidc-account: "<name>@$<gcp_prod_proj_id>.iam.gserviceaccount.com"
```
...@@ -303,6 +303,73 @@ ...@@ -303,6 +303,73 @@
"secret": true "secret": true
} }
] ]
},
{
"id": "gcp-auth-provider",
"name": "Google Cloud",
"description": "This variant uses [Application Default Credentials][gcp-adc] through the `GOOGLE_APPLICATION_CREDENTIALS` variable using Workload Identity federation.",
"template_path": "templates/gitlab-ci-k8s-gcp.yml",
"variables": [
{
"name": "GCP_OIDC_AUD",
"description": "The `aud` claim for the JWT token _(only required for [OIDC authentication](https://docs.gitlab.com/ee/ci/cloud_services/aws/))_",
"default": "$CI_SERVER_URL",
"advanced": true
},
{
"name": "GCP_OIDC_ACCOUNT",
"description": "Default Service Account to which impersonate with OpenID Connect authentication"
},
{
"name": "GCP_OIDC_PROVIDER",
"description": "Default Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/)"
},
{
"name": "GCP_REVIEW_OIDC_ACCOUNT",
"description": "Service Account to which impersonate with OpenID Connect authentication on `review` environment",
"advanced": true
},
{
"name": "GCP_REVIEW_OIDC_PROVIDER",
"description": "Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `review` environment",
"advanced": true
},
{
"name": "GCP_INTEG_OIDC_ACCOUNT",
"description": "Service Account to which impersonate with OpenID Connect authentication on `integration` environment",
"advanced": true
},
{
"name": "GCP_INTEG_OIDC_PROVIDER",
"description": "Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `integration` environment",
"advanced": true
},
{
"name": "GCP_STAGING_OIDC_ACCOUNT",
"description": "Service Account to which impersonate with OpenID Connect authentication on `staging` environment",
"advanced": true
},
{
"name": "GCP_STAGING_OIDC_PROVIDER",
"description": "Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `staging` environment",
"advanced": true
},
{
"name": "GCP_PROD_OIDC_ACCOUNT",
"description": "Service Account to which impersonate with OpenID Connect authentication on `production` environment",
"advanced": true
},
{
"name": "GCP_PROD_OIDC_PROVIDER",
"description": "Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `production` environment",
"advanced": true
},
{
"name": "K8S_KUBECTL_IMAGE",
"description": "The Docker image used to run Kubernetes `kubectl` commands on [GKE](https://cloud.google.com/kubernetes-engine/docs)",
"default": "gcr.io/google.com/cloudsdktool/cloud-sdk:latest"
}
]
} }
] ]
} }
# =====================================================================================================================
# === Google Cloud template variant
# =====================================================================================================================
spec:
inputs:
kubectl-image:
description: The Docker image used to run Kubernetes `kubectl` commands on [GKE](https://cloud.google.com/kubernetes-engine/docs)
default: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
gcp-oidc-aud:
description: The `aud` claim for the JWT token
default: $CI_SERVER_URL
gcp-oidc-account:
description: Default Service Account to which impersonate with OpenID Connect authentication
default: ''
gcp-oidc-provider:
description: Default Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/)
default: ''
gcp-review-oidc-account:
description: Service Account to which impersonate with OpenID Connect authentication on `review` environment
default: ''
gcp-review-oidc-provider:
description: Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `review` environment
default: ''
gcp-integ-oidc-account:
description: Service Account to which impersonate with OpenID Connect authentication on `integration` environment
default: ''
gcp-integ-oidc-provider:
description: Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `integration` environment
default: ''
gcp-staging-oidc-account:
description: Service Account to which impersonate with OpenID Connect authentication on `staging` environment
default: ''
gcp-staging-oidc-provider:
description: Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `staging` environment
default: ''
gcp-prod-oidc-account:
description: Service Account to which impersonate with OpenID Connect authentication on `production` environment
default: ''
gcp-prod-oidc-provider:
description: Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) on `production` environment
default: ''
---
variables:
# variabilized gcp-auth-provider image
GCP_OIDC_AUD: $[[ inputs.gcp-oidc-aud ]]
GCP_OIDC_ACCOUNT: $[[ inputs.gcp-oidc-account ]]
GCP_OIDC_PROVIDER: $[[ inputs.gcp-oidc-provider ]]
GCP_REVIEW_OIDC_ACCOUNT: $[[ inputs.gcp-review-oidc-account ]]
GCP_REVIEW_OIDC_PROVIDER: $[[ inputs.gcp-review-oidc-provider ]]
GCP_INTEG_OIDC_ACCOUNT: $[[ inputs.gcp-integ-oidc-account ]]
GCP_INTEG_OIDC_PROVIDER: $[[ inputs.gcp-integ-oidc-provider ]]
GCP_STAGING_OIDC_ACCOUNT: $[[ inputs.gcp-staging-oidc-account ]]
GCP_STAGING_OIDC_PROVIDER: $[[ inputs.gcp-staging-oidc-provider ]]
GCP_PROD_OIDC_ACCOUNT: $[[ inputs.gcp-prod-oidc-account ]]
GCP_PROD_OIDC_PROVIDER: $[[ inputs.gcp-prod-oidc-provider ]]
K8S_KUBECTL_IMAGE: $[[ inputs.kubectl-image ]]
.gcp-provider-auth:
before_script:
- echo "Installing GCP authentication with env GOOGLE_APPLICATION_CREDENTIALS file"
- echo $GCP_JWT > "$CI_BUILDS_DIR/.auth_token.jwt"
- |-
if [[ "$ENV_TYPE" ]]
then
case "$ENV_TYPE" in
review*)
env_prefix=REVIEW;;
integ*)
env_prefix=INTEG;;
staging*)
env_prefix=STAGING;;
prod*)
env_prefix=PROD;;
*)
;;
esac
env_oidc_provider=$(eval echo "\$GCP_${env_prefix}_OIDC_PROVIDER")
env_oidc_account=$(eval echo "\$GCP_${env_prefix}_OIDC_ACCOUNT")
fi
oidc_provider="${env_oidc_provider:-$GCP_OIDC_PROVIDER}"
oidc_account="${env_oidc_account:-$GCP_OIDC_ACCOUNT}"
- |-
cat << EOF > "$CI_BUILDS_DIR/google_application_credentials.json"
{
"type": "external_account",
"audience": "//iam.googleapis.com/${oidc_provider}",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"token_url": "https://sts.googleapis.com/v1/token",
"credential_source": {
"file": "$CI_BUILDS_DIR/.auth_token.jwt"
},
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${oidc_account}:generateAccessToken"
}
EOF
- export GOOGLE_APPLICATION_CREDENTIALS="$CI_BUILDS_DIR/google_application_credentials.json"
.k8s-deploy:
id_tokens:
GCP_JWT:
aud: "$GCP_OIDC_AUD"
before_script:
- !reference [.k8s-scripts]
- !reference [.gcp-provider-auth, before_script]
- install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
- k8s_login
.k8s-cleanup:
id_tokens:
GCP_JWT:
aud: "$GCP_OIDC_AUD"
before_script:
- !reference [.k8s-scripts]
- !reference [.gcp-provider-auth, before_script]
- install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
- k8s_login
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment