#!/bin/bash # # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -e # Kubernetes Namespace NAMESPACE=${NAMESPACE:-kubeflow} # Google service Account (GSA) SYSTEM_GSA=${SYSTEM_GSA:-$RESOURCE_PREFIX-kfp-system} USER_GSA=${USER_GSA:-$RESOURCE_PREFIX-kfp-user} # Kubernetes Service Account (KSA) # Note, if deploying manifests/kustomize/env/gcp, you can add the following KSAs # to the array of SYSTEM_KSA: # * kubeflow-pipelines-minio-gcs-gateway needs gcs permissions # * kubeflow-pipelines-cloudsql-proxy needs cloudsql permissions SYSTEM_KSA=(ml-pipeline-ui ml-pipeline-visualizationserver) USER_KSA=(pipeline-runner kubeflow-pipelines-container-builder kubeflow-pipelines-viewer) if [ -n $USE_GCP_MANAGED_STORAGE ]; then SYSTEM_KSA+=(kubeflow-pipelines-minio-gcs-gateway) SYSTEM_KSA+=(kubeflow-pipelines-cloudsql-proxy) fi cat < RESOURCE_PREFIX= NAMESPACE= ./gcp-workload-identity-setup.sh ``` PROJECT_ID: GCP project ID your cluster belongs to. RESOURCE_PREFIX: Your preferred resource prefix for GCP resources this script creates. NAMESPACE: Optional. Kubernetes namespace your Kubeflow Pipelines standalone deployment belongs to. (Defaults to kubeflow) USE_GCP_MANAGED_STORAGE: Optional. Defaults to "false", specify "true" if you intend to use GCP managed storage (Google Cloud Storage and Cloud SQL) following instructions in: https://github.com/kubeflow/pipelines/tree/master/manifests/kustomize/sample EOF } if [ -z "$PROJECT_ID" ]; then usage echo echo "Error: PROJECT_ID env variable is empty!" exit 1 fi if [ -z "$RESOURCE_PREFIX" ]; then usage echo echo "Error: RESOURCE_PREFIX env variable is empty!" exit 1 fi echo "Env variables set:" echo "* PROJECT_ID=$PROJECT_ID" echo "* RESOURCE_PREFIX=$RESOURCE_PREFIX" echo "* NAMESPACE=$NAMESPACE" echo "* USE_GCP_MANAGED_STORAGE=${USE_GCP_MANAGED_STORAGE:-false}" echo SYSTEM_GSA_FULL="$SYSTEM_GSA@$PROJECT_ID.iam.gserviceaccount.com" USER_GSA_FULL="$USER_GSA@$PROJECT_ID.iam.gserviceaccount.com" cat </dev/null; then echo "KSA $name already exists" else kubectl create serviceaccount $name -n $NAMESPACE --save-config echo "KSA $name created" fi } # Bind KSA to GSA through workload identity. # Documentation: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity function bind_gsa_and_ksa { local gsa=${1} local ksa=${2} gcloud iam service-accounts add-iam-policy-binding $gsa@$PROJECT_ID.iam.gserviceaccount.com \ --member="serviceAccount:$PROJECT_ID.svc.id.goog[$NAMESPACE/$ksa]" \ --role="roles/iam.workloadIdentityUser" \ > /dev/null # hide verbose output create_ksa_if_not_present $ksa kubectl annotate serviceaccount \ --namespace $NAMESPACE \ --overwrite \ $ksa \ iam.gke.io/gcp-service-account=$gsa@$PROJECT_ID.iam.gserviceaccount.com echo "* Bound KSA $ksa to GSA $gsa" } echo "Binding each kfp system KSA to $SYSTEM_GSA" for ksa in ${SYSTEM_KSA[@]}; do bind_gsa_and_ksa $SYSTEM_GSA $ksa done echo "Binding each kfp user KSA to $USER_GSA" for ksa in ${USER_KSA[@]}; do bind_gsa_and_ksa $USER_GSA $ksa done echo echo "All the workload identity bindings have succeeded!" cat <