|
| 1 | +#! /bin/bash |
| 2 | + |
| 3 | +# Copyright 2022 Google LLC |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# https://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
| 16 | + |
| 17 | +# variables required for below commands to properly build and deploy GroupSync |
| 18 | +echo "Setting environment variables..." |
| 19 | +######################## DEPLOYMENT variables ######################## |
| 20 | +export PROJECT_ID="" # project ID of project in which you want to deploy the service within |
| 21 | +export REGION="" # Google Cloud region to deploy GroupSync in |
| 22 | + |
| 23 | +######################## Service Account variables ######################## |
| 24 | +export SERVICE_ACCOUNT_NAME="" # name of service account to create and use with GroupSync |
| 25 | +export SERVICE_ACCOUNT_EMAIL="$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com" # email of service account to deploy Cloud Run with |
| 26 | + |
| 27 | +######################## PRIVATE IP / SHARED VPC variables ######################## |
| 28 | +export HOST_PROJECT_ID="" # project ID of Shared VPC host project (optional) |
| 29 | +export CONNECTOR_NAME="" # name to be given to Serverless VPC Access Connector |
| 30 | +export SUBNET="" # the name of an unused /28 subnet for Serverless VPC Access Connector |
| 31 | + |
| 32 | +######################## Cloud Scheduler variables ######################## |
| 33 | +export PATH_TO_JSON="" # file path to JSON payload containing instance-to-group mappings for Cloud Scheduler |
| 34 | +export SCHEDULE="*/10 * * * *" # schedule how often GroupSync Cloud Scheduler is called (defaults to 10 mins) |
| 35 | + |
| 36 | +# load IAM Groups and Cloud SQL Instance names from JSON payload |
| 37 | +IAM_GROUPS=$(cat "$PATH_TO_JSON" | jq '.iam_groups' | tr -d '[],"') |
| 38 | +SQL_INSTANCES=$(cat "$PATH_TO_JSON" | jq '.sql_instances' | tr -d '[],"') |
| 39 | + |
| 40 | +# check if required variables are set, otherwise give error and exit |
| 41 | +declare -a vars=(PROJECT_ID REGION PATH_TO_JSON IAM_GROUPS SQL_INSTANCES CONNECTOR_NAME HOST_PROJECT_ID SUBNET) |
| 42 | +for var_name in "${vars[@]}" |
| 43 | +do |
| 44 | + if [ -z "$(eval "echo \$$var_name")" ]; then |
| 45 | + echo "Missing environment variable $var_name in deployment.sh" |
| 46 | + exit 1 |
| 47 | + fi |
| 48 | +done |
| 49 | + |
| 50 | +echo "Successfully set environment variables..." |
| 51 | + |
| 52 | +######################## GCP PROJECT CONFIGURATION ######################## |
| 53 | +echo "Configuring GCP project and region..." |
| 54 | +# set project |
| 55 | +gcloud config set project "$PROJECT_ID" |
| 56 | + |
| 57 | +# set region |
| 58 | +gcloud config set compute/region "$REGION" |
| 59 | + |
| 60 | +echo "Enabling required APIs..." |
| 61 | +# enable required APIs within project |
| 62 | +gcloud services enable run.googleapis.com cloudscheduler.googleapis.com \ |
| 63 | + cloudbuild.googleapis.com sqladmin.googleapis.com admin.googleapis.com \ |
| 64 | + iamcredentials.googleapis.com vpcaccess.googleapis.com servicenetworking.googleapis.com |
| 65 | + |
| 66 | +######################## SERVICE ACCOUNT CONFIGURATION ######################## |
| 67 | +echo "Creating Service Account $SERVICE_ACCOUNT_EMAIL..." |
| 68 | +# create service account for use with GroupSync (REMOVE STEP IF USING PRE-EXISTING SERVICE ACCOUNT) |
| 69 | +gcloud iam service-accounts create "$SERVICE_ACCOUNT_NAME" \ |
| 70 | + --description="IAM Groups Authn Service Account" \ |
| 71 | + --display-name="IAM Database Groups Authentication" |
| 72 | + |
| 73 | +echo "Adding IAM Policies to service account: $SERVICE_ACCOUNT_EMAIL" |
| 74 | + |
| 75 | +# add Cloud Run Invoke Role to service account |
| 76 | +gcloud projects add-iam-policy-binding "$PROJECT_ID" \ |
| 77 | + --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \ |
| 78 | + --role="roles/run.invoker" |
| 79 | + |
| 80 | +# create custom IAM role and grant to service account |
| 81 | +gcloud iam roles create IamAuthnGroups \ |
| 82 | + --project="$PROJECT_ID" \ |
| 83 | + --title="IAM Groups Authn" \ |
| 84 | + --description="Custom role for IAM DB Authn for Groups Service" \ |
| 85 | + --permissions=cloudsql.instances.connect,cloudsql.instances.get,cloudsql.instances.login,cloudsql.users.create,cloudsql.users.list,iam.serviceAccounts.signBlob |
| 86 | + |
| 87 | +gcloud projects add-iam-policy-binding "$PROJECT_ID" \ |
| 88 | + --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \ |
| 89 | + --role="projects/$PROJECT_ID/roles/IamAuthnGroups" |
| 90 | + |
| 91 | +######################## IAM and DB ROLE CONFIGURATION ######################## |
| 92 | +echo "Adding Cloud SQL Instance User role to IAM Groups..." |
| 93 | +# grant Cloud SQL Instance User role to all IAM group emails (so users of Group can inherit) |
| 94 | +for GROUP in $IAM_GROUPS; |
| 95 | +do |
| 96 | + gcloud projects add-iam-policy-binding "$PROJECT_ID" \ |
| 97 | + --member="group:$GROUP" \ |
| 98 | + --role="roles/cloudsql.instanceUser" |
| 99 | +done |
| 100 | + |
| 101 | +echo "Adding $SERVICE_ACCOUNT_EMAIL as IAM DB User to Cloud SQL Instances..." |
| 102 | +# add service account as Cloud SQL IAM User to all mapped instances |
| 103 | +for INSTANCE in $SQL_INSTANCES; |
| 104 | +do |
| 105 | + IFS=: read -r PROJECT REGION_NAME INSTANCE_NAME <<< $INSTANCE |
| 106 | + gcloud sql users create $SERVICE_ACCOUNT_EMAIL \ |
| 107 | + --instance="$INSTANCE_NAME" \ |
| 108 | + --type=cloud_iam_service_account |
| 109 | +done |
| 110 | + |
| 111 | +######################## PRIVATE IP / SHARED VPC ######################## |
| 112 | +echo "Creating Serverless VPC Access Connector..." |
| 113 | +# create serverless VPC access connector |
| 114 | +gcloud compute networks vpc-access connectors create "$CONNECTOR_NAME" \ |
| 115 | + --region="$REGION" \ |
| 116 | + --subnet="$SUBNET" \ |
| 117 | + --subnet-project="$HOST_PROJECT_ID" # if you are not using Shared VPC, omit this line. |
| 118 | + |
| 119 | +############################## CLOUD RUN ################################ |
| 120 | +echo "Building docker container and deploying GroupSync Cloud Run Service..." |
| 121 | +# build container for Cloud Run |
| 122 | +gcloud builds submit \ |
| 123 | + --tag "gcr.io/$PROJECT_ID/groupsync-run" \ |
| 124 | + --project "$PROJECT_ID" \ |
| 125 | + --region "$REGION" |
| 126 | + |
| 127 | +# deploy Cloud Run service |
| 128 | +gcloud run deploy groupsync-run \ |
| 129 | + --image "gcr.io/$PROJECT_ID/groupsync-run" \ |
| 130 | + --no-allow-unauthenticated \ |
| 131 | + --service-account "$SERVICE_ACCOUNT_EMAIL" \ |
| 132 | + --project "$PROJECT_ID" \ |
| 133 | + --region "$REGION" \ |
| 134 | + --vpc-connector "$CONNECTOR_NAME" |
| 135 | + |
| 136 | +SERVICE_URL=$(gcloud run services describe groupsync-run --platform managed --region "$REGION" --format 'value(status.url)') |
| 137 | +echo "Deployed Cloud Run service at URL: $SERVICE_URL" |
| 138 | + |
| 139 | +########################### CLOUD SCHEDULER ############################ |
| 140 | +echo "Creating GroupSync Cloud Scheduler job..." |
| 141 | +# cloud scheduler command (schedules GroupSync to run every 10 minutes) |
| 142 | +gcloud scheduler jobs create http groupsync-scheduler \ |
| 143 | + --schedule="$SCHEDULE" \ |
| 144 | + --uri="$SERVICE_URL/run" \ |
| 145 | + --oidc-service-account-email=$SERVICE_ACCOUNT_EMAIL \ |
| 146 | + --http-method="PUT" \ |
| 147 | + --headers="Content-Type=application/json" \ |
| 148 | + --message-body-from-file="$PATH_TO_JSON" |
0 commit comments