Deploy To Google Cloud Run

Milad Fahmy
3 min readAug 18, 2024

--

Deploy to Cloud Run with GitHub Actions

Prerequisites

  • A Google Cloud project
  • A GitHub repository
  • Cloud Run Service (you can create it from the Google Cloud dashboard)

Create Workload Identity Federation

Using Workload Identity Federation, you can provide on-premises or multicloud workloads with access to Google Cloud resources by using federated identities instead of a service account key.

  1. Create a Workload Identity Pool
    It is recommended to create and manage workload identity pools from a single dedicated project.”

You can create it via the command line or the dashboard:

gcloud iam workload-identity-pools create "WORKLOAD_IDENTITY_POOL_ID" \
--location="global" \
--description="The pool to authenticate GitHub actions for my APIs pool." \
--display-name="My APIs Project Pool" \
--project="PROJECT_ID"

2. Create a Workload Identity Pool Provider The issuer-uri identifies GitHub as the identity provider and lets Workload Identity discover the OIDC metadata and JSON Web Key Set (JWKs) endpoints. Google Cloud uses these endpoints to validate tokens.

GitHub issues a unique token for each workflow job. This token contains claims that describe the identity of the workflow. By using attribute mapping, we translate the claims in the token so that we can use them in principal/principalSet identifiers to grant access to service accounts or create an attribute condition.

gcloud iam workload-identity-pools providers create-oidc gcr-d-apis-oidc \
--workload-identity-pool="gcr-d-apis-pool" \
--issuer-uri="https://token.actions.githubusercontent.com/" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner,attribute.branch=assertion.sub.extract('/heads/main/')" \
--location=global \
--attribute-condition="assertion.repository_owner=='SamTech-inc'" \
--project="PROJECT_ID"

Create a Service Account

Create a service account for each repository and assign them appropriate IAM permissions.

You can use the Dashboard, but the service account must have the following permissions:

  • roles/artifactregistry.admin
  • roles/artifactregistry.writer
  • roles/cloudbuild.builds.editor
  • roles/iam.serviceAccountUser
  • roles/iam.workloadIdentityUser
  • roles/run.admin
  • roles/storage.admin
  • roles/storage.objectAdmin
  • roles/viewer

Add IAM Bindings for the Workload Pool

Utilize previously mapped attributes to create principals/principalSets, and then use them in IAM bindings to grant permissions to create short-lived credentials for the appropriate service account.

gcloud iam service-accounts add-iam-policy-binding "SERVICE_ACCOUNT_EMAIL" \
--role="roles/iam.workloadIdentityUser" \
--member="principal://iam.googleapis.com/projects/PROJECT_ID/locations/global/workloadIdentityPools/gcr-d-apis-pool/subject/repo:SamTech-inc/gcr-d-apis:ref:refs/heads/main" \
--project="PROJECT_ID"

## And

gcloud iam service-accounts add-iam-policy-binding "SERVICE_ACCOUNT_EMAIL" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/"PROJECT_ID"/locations/global/workloadIdentityPools/gcr-d-apis-pool/attribute.repository/gcr-d-apis-oidc" \
--project="PROJECT_ID"

Update the GitHub Actions Workflow to Use the Workload Identity Pool to Authenticate to Google Cloud

In your GitHub repository, add a .github folder that contains the workflows folder.

## my-apis/.github/workflows/deploy-to-google-cloudrun.yml
name: Deploy to Cloud Run from Source

on:
push:
branches: [ "main" ]

env:
PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} # Update Google Cloud project ID
SERVICE: ${{ secrets.GCP_SERVICE_NAME }} # Update Cloud Run service name
REGION: ${{ secrets.GCP_REGION }} # Update Cloud Run service region
GCP_SERVICE_ACCOUNT_EMAIL: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} # Update service account email
WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} # Update workload identity provider

jobs:
deploy-to-cloudrun:
permissions:
id-token: write
contents: read

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- id: 'auth-to-google-cloud'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v1'
with:
create_credentials_file: true
workload_identity_provider: ${{ env.WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.GCP_SERVICE_ACCOUNT_EMAIL }}

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v0.2.1
with:
version: 'latest'
project_id: ${{ env.PROJECT_ID }}
credentials_file_path: ${{ steps.auth-to-google-cloud.outputs.credentials_file_path }}

- name: 'Build and push Docker image'
run: |
gcloud builds submit --tag gcr.io/${{ env.PROJECT_ID }}/${{ env.SERVICE }}:${{ github.sha }}

- name: 'Deploy to Cloud Run'
run: |
gcloud run deploy ${{ env.SERVICE }} \
--image gcr.io/${{ env.PROJECT_ID }}/${{ env.SERVICE }}:${{ github.sha }} \
--region ${{ env.REGION }} \
--platform managed \
--allow-unauthenticated

- name: 'Test deployment'
run: |
SERVICE_URL=$(gcloud run services describe ${{ env.SERVICE }} --region ${{ env.REGION }} --format "value(status.url)")
echo "Service URL: $SERVICE_URL"
curl "$SERVICE_URL"
continue-on-error: true

Add Secrets to GitHub Repository

Add the following secrets to your GitHub repository:

  • GCP_PROJECT_ID
  • GCP_SERVICE_NAME
  • GCP_REGION
  • GCP_SERVICE_ACCOUNT_EMAIL
  • GCP_WORKLOAD_IDENTITY_PROVIDER

Note that: The workload identity pool (GCP_WORKLOAD_IDENTITY_PROVIDER) is configured as

"projects/PROJECT_ID/locations/global/workloadIdentityPools/WORKLOAD_IDENTITY_POOL_ID/providers/WORKLOAD_IDENTITY_PROVIDER_ID"

Deploy to Cloud Run

Push your changes to the main branch, and the GitHub Actions workflow will deploy your application to Cloud Run.

Conclusion

In this tutorial, you learned how to use Workload Identity Federation to authenticate GitHub Actions to Google Cloud. You also learned how to create a Workload Identity Pool, a Workload Identity Pool Provider, and a Service Account. Finally, you updated the GitHub Actions workflow to use the Workload Identity Pool to authenticate to Google Cloud and deployed your application to Cloud Run.

References

--

--

Milad Fahmy
Milad Fahmy

Written by Milad Fahmy

I’m a JS Champion, I wrote about software engineering. I’m currently developing various open-source projects (like: https://encrypt-rsa.js.org)

No responses yet