diff --git a/README.md b/README.md index 18ae827f0436361636034eb0e4b26d70aea5f396..09216d0048ffb7b3d9c39ee4a8fb366fabf3b8a9 100644 --- a/README.md +++ b/README.md @@ -485,3 +485,42 @@ variables: PYTHON_REPOSITORY_PASSWORD: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/pip-repo/repository?field=password" # $VAULT_ROLE_ID and $VAULT_SECRET_ID defined as a secret CI/CD variable ``` + +### Google Cloud variant + +This variant allows to use Python Google Clients. The variant follow the recommendation [Authenticate for using client libraries](https://cloud.google.com/docs/authentication/client-libraries) with [ADC](https://cloud.google.com/docs/authentication/application-default-credentials) + +[Detailed article on internal OIDC impersonated with Workload Identify Federation](https://blog.salrashid.dev/articles/2021/understanding_workload_identity_federation/#oidc-impersonated) + +List of requirements before using this variant for use Python Google Clients: + +1. You must have a Workload Identity Federation Pool, +2. You must have a Service Account with enough permissions to run your python job. +3. Optional, you can define `GOOGLE_CLOUD_PROJECT` in template variable to define the default Google project + +#### 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_ | + +#### Example + +```yaml +include: + - component: gitlab.com/to-be-continuous/python/gitlab-ci-python@6.7.0 + # 2: set/override component inputs + inputs: + image: registry.hub.docker.com/library/python:3.10 + pytest-enabled: true + + - component: gitlab.com/to-be-continuous/python/gitlab-ci-python-gcp@6.7.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" +``` diff --git a/kicker.json b/kicker.json index 8ec4b4564901eca6193f79a01d99416f03bb3275..79860fe050fe1c86f7490111b8f8c3f79fdc31b2 100644 --- a/kicker.json +++ b/kicker.json @@ -290,6 +290,28 @@ "secret": true } ] + }, + { + "id": "gcp-auth-provider", + "name": "Google Cloud", + "description": "Retrieves an [ADC](https://cloud.google.com/docs/authentication/application-default-credentials) for Python Google Client", + "template_path": "templates/gitlab-ci-python-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/)" + } + ] } ] -} +} \ No newline at end of file diff --git a/templates/gitlab-ci-python-gcp.yml b/templates/gitlab-ci-python-gcp.yml new file mode 100644 index 0000000000000000000000000000000000000000..dcc575bf9918d000bbb06a4fe2d5b912b4e838e5 --- /dev/null +++ b/templates/gitlab-ci-python-gcp.yml @@ -0,0 +1,58 @@ +# ===================================================================================================================== +# === GCP Auth template variant (provide ADC authentification) +# === https://cloud.google.com/docs/authentication/application-default-credentials +# ===================================================================================================================== +spec: + inputs: + gcp-oidc-aud: + description: The `aud` claim for the JWT token _(only required for [OIDC authentication](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/)))_ + 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: '' +--- +variables: + GCP_OIDC_AUD: $[[ inputs.gcp-oidc-aud ]] + GCP_OIDC_ACCOUNT: $[[ inputs.gcp-oidc-account ]] + GCP_OIDC_PROVIDER: $[[ inputs.gcp-oidc-provider ]] + +.gcp-provider-auth: + before_script: + - echo "Installing GCP authentication with env GOOGLE_APPLICATION_CREDENTIALS file" + - echo $GCP_JWT > "$CI_BUILDS_DIR/.auth_token.jwt" + - |- + cat << EOF > "$CI_BUILDS_DIR/google_application_credentials.json" + { + "type": "external_account", + "audience": "//iam.googleapis.com/${GCP_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/${GCP_OIDC_ACCOUNT}:generateAccessToken" + } + EOF + - export GOOGLE_APPLICATION_CREDENTIALS="$CI_BUILDS_DIR/google_application_credentials.json" + + +.python-base: + image: $PYTHON_IMAGE + services: + - name: "$TBC_TRACKING_IMAGE" + command: ["--service", "python", "6.7.0"] + variables: + GCP_JWT: $GCP_JWT + before_script: + - !reference [.gcp-provider-auth, before_script] + - !reference [.python-scripts] + - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}" + - cd ${PYTHON_PROJECT_DIR} + - guess_build_system + + id_tokens: + GCP_JWT: + aud: "$GCP_OIDC_AUD"