Permissions required by the Cloud Run function (runtime) service account
Minimal initial setup (enable APIs and grant these roles to the Cloud Run runtime SA) so the function can create tenant DBs, SAs and Cloud Run services and then wire impersonation:
-
Required APIs:
sqladmin.googleapis.comiam.googleapis.comrun.googleapis.com
-
Minimal project roles to grant to the function runtime SA (
RUN_SA) before you run the orchestrator:roles/cloudsql.admin— create/manage Cloud SQL databasesroles/iam.serviceAccountCreator— create tenant service accountsroles/iam.serviceAccountAdmin— read/set IAM policy on service accounts (needed so the function can add impersonation binding)roles/run.admin— create Cloud Run services
-
Note: the function will attempt to add
roles/iam.serviceAccountUserfor the runtime SA on the tenant service account it creates (so the tenant Cloud Run service can run as that tenant SA). Because the function must callgetIamPolicy/setIamPolicy, the runtime SA needsroles/iam.serviceAccountAdmin(or equivalent) at project level. -
Enable Cloud Resource Manager API so that the function service account can manage cloud run instance and IAM. Cloud Resource Management API
Example commands (replace PROJECT, REGION, SERVICE):
PROJECT=peoplecloud-test
REGION=europe-west1
SERVICE=test-php-fc
# find the runtime service account used by the deployed function
RUN_SA=$(gcloud run services describe $SERVICE \
--region $REGION --project $PROJECT \
--format="value(spec.template.spec.serviceAccountName)")
echo "Runtime service account: $RUN_SA"
# enable APIs
gcloud services enable sqladmin.googleapis.com iam.googleapis.com run.googleapis.com \
--project=$PROJECT
# grant minimal roles to the runtime SA (adjust if you prefer narrower scopes)
gcloud projects add-iam-policy-binding $PROJECT \
--member="serviceAccount:${RUN_SA}" --role="roles/cloudsql.admin"
gcloud projects add-iam-policy-binding $PROJECT \
--member="serviceAccount:${RUN_SA}" --role="roles/iam.serviceAccountCreator"
gcloud projects add-iam-policy-binding $PROJECT \
--member="serviceAccount:${RUN_SA}" --role="roles/iam.serviceAccountAdmin"
gcloud projects add-iam-policy-binding $PROJECT \
--member="serviceAccount:${RUN_SA}" --role="roles/run.admin"
Troubleshooting tips:
- If the function reports 403 from the SQL Admin API, confirm
RUN_SAhasroles/cloudsql.adminand thesqladmin.googleapis.comAPI is enabled. - If the function cannot add the impersonation binding, confirm
RUN_SAhasroles/iam.serviceAccountAdmin(needed to callgetIamPolicy/setIamPolicy). - Check logs for the function and Cloud Run API audit logs if a create fails.
Run the deploy.bat script. It requires google cloud sdk shell to be installed and authenticated. Replace the arguments with your project, cloud sql instance name and region.
The env.yaml file requires some input as well. Create an admin account for the SQL instance which you can pass to the cloud function as well. That account will be used to grant permissions. At the moment the cloud function will deploy a generic hello world container, but this can be swapped to your Cloud Run container. Something like gcloud builds submit --tag gcr.io/PROJECT_ID/IMAGE_NAME in stead of gcloud run deploy.
Once all the values are set simply use the deploy.bat file on windows or just copy and execute the command in your terminal on another OS. Gcloud CLI should work identically cross-platform.
Easiest way is to go to Google Cloud Console and navigate to the Cloud Run function. Once opened there's a Test button on top. When that is pressed you can pick to run the function within Gcloud shell. Something similar to the Rest call bellow will be generated:
curl -X POST "https://test-php-fc-913213171428.europe-west1.run.app" -H "Authorization: bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" -d '{ "name": "<tenant name>" }'
You can simply call this endpoint directly from your APP when you want to instantiate a new tenant.
Notes:
- Do NOT store production DB admin passwords in
env.yamlin source control; use Secret Manager and give the functionroles/secretmanager.secretAccessorinstead. The exampleenv.yamlin this repo is for local testing only. - To allow Cloud Run services to connect to Cloud SQL using the platform-managed connector, the created tenant Cloud Run services should be deployed with
--add-cloudsql-instances=${CLOUD_SQL_CONNECTION_NAME}and the tenant service account must haveroles/cloudsql.client.