Automating Serverless Deployment: Integrating GitHub Actions with Google Cloud Run

Google Cloud Run represents a significant shift in how modern applications are hosted, offering a fully managed serverless container platform that allows developers to deploy stateless containers on a pay-as-you-go basis. Unlike traditional virtual machine instances, Cloud Run automatically scales applications based on incoming traffic, ensuring resources are allocated only when necessary. This model provides a unique value proposition in the cloud infrastructure landscape, as it has no direct equivalent on AWS and Azure specifically for containers, where Google charges exclusively for compute time when the container is actively performing work. To leverage this infrastructure effectively, development teams increasingly rely on continuous integration and continuous deployment (CI/CD) pipelines. GitHub Actions serves as a powerful workflow automation tool that integrates seamlessly with Google Cloud Run, streamlining the process of deploying applications directly from GitHub repositories to the Google Cloud Platform.

Prerequisites and Environment Setup

Before initiating the deployment workflow, specific prerequisites must be met to ensure compatibility and successful authentication between the GitHub environment and Google Cloud. Developers must possess an active Google Cloud Platform account and a GitHub account. Additionally, Docker must be installed on the local machine to facilitate the creation and testing of container images prior to automation. The initial step involves creating a new project within the Google Cloud Platform and explicitly enabling the Cloud Run API. This permission is critical, as it grants the necessary permissions for deployment actions to interact with the service.

For the repository structure, it is essential to establish a consistent directory layout that houses the application code, the container configuration, and the automation scripts. A typical setup assumes a private repository to protect source code. The directory structure should include the .github/workflows directory for storing GitHub Actions configurations, a Dockerfile for defining the container image, and the application source code, such as main.py. The resulting file tree should resemble the following structure:

text . ├── .github │ └── workflows │ └── docker-build.yaml ├── Dockerfile └── main.py

This organization ensures that the automation workflow can correctly locate the context required to build and push the Docker image.

Authentication and Federated Identity

A critical component of modern cloud deployment is secure authentication. Relying on static service account keys stored as secrets is increasingly discouraged in favor of more secure, federated identity providers. The deploy-cloudrun GitHub Action supports authentication via Workload Identity Federation, which allows GitHub Actions to assume a Google Cloud service account role without storing long-lived credentials.

To configure this, developers must extract and save several key variables from their Google Cloud environment. These include the image name, the workload identity provider location, and the service account email address. The commands to retrieve these values are as follows:

bash echo "us-central1-docker.pkg.dev/$PROJECT_ID/docker-registry/app" echo "$WORKLOAD_IDENTITY_PROVIDER_LOCATION" echo "$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com"

The resulting variables are crucial for the GitHub Actions script:
- image_name: The fully qualified path to the container image in Artifact Registry.
- workload_identity_provider: The identifier for the provider in the Workload Identity Pool.
- service_account: The email address of the service account authorized to deploy to Cloud Run.

When using the google-github-actions/auth action, the workflow must define specific permissions. The contents permission must be set to 'read' to allow the repository checkout, and id-token must be set to 'write' to enable the generation of OIDC tokens for Google Cloud authentication. The configuration block for this step typically looks like this:

```yaml
permissions:
contents: 'read'
id-token: 'write'

steps:
- uses: 'actions/checkout@v4'
- uses: 'google-github-actions/auth@v3'
with:
workloadidentityprovider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
service_account: '[email protected]'
```

It is important to note that the deploy-cloudrun action requires Google Cloud credentials authorized to access the secrets being requested. If using self-hosted GitHub Actions runners, the runner version must support Node 24 or newer, as the action itself runs on this runtime.

Configuring the GitHub Actions Workflow

The core of the automation lies in the GitHub Actions workflow file, typically named docker-build.yaml or similar, located in the .github/workflows directory. This workflow triggers on specific events, such as pushes to the main branch, pull requests to main, or manual triggers via workflow_dispatch.

A comprehensive workflow involves several distinct steps: checking out the code, authenticating with Google Cloud, configuring Docker, building and pushing the image, and finally deploying to Cloud Run. Below is an example of a workflow configuration that integrates these steps:

```yaml
name: cloud-run
on:
push:
branches: [main]
pullrequest:
branches: [main]
workflow
dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: "read"
id-token: "write"
env:
IMAGE_NAME: 'us-central1-docker.pkg.dev//docker-registry/app'
steps:
- name: Checkout code
uses: actions/checkout@v4

  - name: Set up Google Cloud SDK
    uses: google-github-actions/setup-gcloud@v3

  - name: Configure docker for GCP
    run: gcloud auth configure-docker

  - name: Build and push Docker image
    uses: docker/build-push-action@v5
    with:
      context: .
      push: true
      tags: ${{ env.IMAGE_NAME }}
      build-args: |
        HTTP_PORT=8080

  - name: Deploy to Cloud Run
    id: deploy
    uses: google-github-actions/deploy-cloudrun@v3
    with:
      service: <your-service-name>
      image: ${{ env.IMAGE_NAME }}
      region: us-central1
      platform: managed
      allow-unauthenticated: true
      env_vars: |
        FOO=bar
        ZIP=zap

```

This workflow utilizes the google-github-actions/deploy-cloudrun action. The action accepts various inputs to control the deployment behavior. The service input specifies the ID of the Cloud Run service, which is required unless providing metadata or job inputs. Alternatively, the job input can be used to deploy Cloud Run jobs, and the metadata input allows for a full YAML service description. The region input specifies the deployment location, and platform is typically set to managed for serverless deployments.

Advanced Deployment Options

Beyond basic deployment, the deploy-cloudrun action offers advanced configuration options to handle complex scenarios. One such option is the flags input, which allows developers to pass additional Cloud Run flags to the underlying gcloud run deploy or gcloud jobs deploy commands. This is useful for applying features not directly exposed by the GitHub Action, such as adding Cloud SQL instances.

yaml with: flags: '--add-cloudsql-instances=...'

When passing flags that contain other flags, the entire outer flag value must be quoted. For example, to pass arguments to the container:

yaml with: flags: '--add-cloudsql-instances=... "--args=-X=123"'

It is crucial to understand that the GitHub Action does not parse or validate these flags; the developer is responsible for ensuring compatibility with the installed gcloud version.

Another important configuration is traffic management. The no_traffic option, when set to true, ensures that the newly deployed revision does not receive traffic, effectively making it a cold deploy. This applies only to services. For more granular control, the revision_traffic input allows for comma-separated lists of revision traffic assignments. For instance, to route 10% of traffic to a specific revision:

yaml with: revision_traffic: 'my-revision=10'

To update traffic to the latest revision exclusively, the special tag LATEST can be used:

yaml with: revision_traffic: 'LATEST=100'

Note that revision_traffic is mutually exclusive with tag_traffic. For Cloud Run jobs, the wait option can be set to true to ensure the action waits for the job to complete before exiting.

Verification and Post-Deployment Steps

Once the GitHub Actions workflow completes successfully, the containerized application is deployed to Google Cloud Run. Verification is a critical step to ensure the deployment was successful and the application is functioning as expected. Developers should navigate to the Google Cloud Console, select the relevant project, and click on "Cloud Run" in the sidebar. The deployed service should be listed there with details including the service URL.

The deploy-cloudrun action also provides the service URL as a GitHub Actions output, which can be utilized in subsequent steps of the workflow for automated testing. For example:

yaml - name: 'Use output' run: 'curl "${{ steps.deploy.outputs.url }}"'

This allows for immediate health checks or integration tests to be run against the newly deployed instance. After verifying the URL in the web browser, developers can confirm that the application is live and accessible. For those who prefer GitLab CI/CD over GitHub Actions, alternative configurations exist, but the principles of containerized deployment and serverless scaling remain consistent across platforms.

Conclusion

The integration of GitHub Actions with Google Cloud Run provides a robust, automated solution for deploying stateless containerized applications. By leveraging serverless infrastructure, organizations can reduce operational overhead and optimize costs by paying only for compute resources when applications are active. The use of federated identity authentication enhances security by eliminating the need for static service account keys, while the flexibility of the deploy-cloudrun action allows for advanced traffic management and configuration options. As cloud-native development continues to evolve, mastering these automation workflows becomes essential for delivering reliable, scalable applications efficiently.

Sources

  1. Deploying to Google Cloud Run with GitHub Actions: A Step-by-Step Guide
  2. google-github-actions/deploy-cloudrun
  3. Cloud Run with GitHub Actions

Related Posts