Skip to main content

Deploying to GCP from GitHub Actions

This tutorial will show you how to use the Defang GitHub Action to deploy your project to GCP from your GitHub Actions workflow.

Prerequisites

The following steps will guide you through setting up a GitHub Actions workflow that can assume a role in your GCP account using OpenID Connect (OIDC) and deploy your project using the Defang GitHub Action. The role which will be assumed must have a trust relationship with an OIDC identity provider (IdP) for GitHub Actions, and that trust relationship must be configured to allow the specific repository and branch to assume the role. This ultimately allows the GitHub Actions workflow to securely access your GCP resources without needing to store long-lived GCP credentials in your repository.

Step 1 - Identify your GCP Project ID

To configure the GitHub Action to assume a role in your GCP project, you'll need your GCP Project ID.

You can list all of the projects you have access to with the following command:

gcloud projects list --format="value(projectId)"
export PROJECT_ID="my-project-123456" # export the project ID you want to use

Identify the appropriate project ID from the list and keep it handy for the next steps.

Step 2 - Create a deployer Service Account

Using the gcloud CLI:

gcloud iam service-accounts create "deployer" \
--description="Service account used by Defang for deployment" \
--display-name="Deployer" \
--project="${PROJECT_ID}"

Step 2 - Create a Workload Identity Pool

To configure the GitHub Action to assume a role in your GCP account, you'll need to create a Workload Identity Pool and a Workload Identity Provider in your GCP project.

warning

Always add an Attribute Condition to restrict entry into the Workload Identity Pool.

We recommend replacing YOUR_REPOSITORY_OWNER and YOUR_REPOSITORY_NAME with your actual GitHub repository owner and name in the next step, and adjusting the assertion.ref condition to match your deployment branch. If you want to allow access from any branch, you can omit the assertion.ref condition.

We also recommend configuring GitHub Actions Environments. If you do not configure environments, you can omit the assertion.environment condition below.

Using the gcloud CLI:

Create a Workload Identity Pool

gcloud iam workload-identity-pools create "defang-github-actions-pool" \
--project="${PROJECT_ID}" \
--location="global" \
--display-name="Defang Github Actions Pool" \
--description="Allow Defang to deploy from Github Actions"

Add a Workload Identity Provider to the Pool

gcloud iam workload-identity-pools providers create-oidc "defang-github-actions-provider" \
--project="${PROJECT_ID}" \
--location="global" \
--workload-identity-pool="defang-github-actions-pool" \
--display-name="Defang Github Actions Provider" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner,attribute.environment=assertion.environment,attribute.ref=assertion.ref" \
--attribute-condition="assertion.repository_owner == YOUR_REPOSITORY_OWNER && assertion.repository == 'YOUR_REPOSITORY_NAME' && assertion.ref == 'refs/heads/main' && assertion.environment == 'YOUR_ENVIRONMENT'" \

Step 3 - Grant your GCP service account access to the Workload Identity Pool

Using the gcloud CLI:

Get the ID of the Workload Identity Pool we just created

WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe "defang-github-actions-pool" \
--project="${PROJECT_ID}" \
--location="global" \
--format="value(name)") | awk -F/ '{print $6}')
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:deployer@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/owner"
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"

Step 4 - Create a new GitHub Actions workflow

In your GitHub repository, create a new file at .github/workflows/deploy.yml with the following content:

name: Deploy with Defang
on:
push:
branches:
- main # Change this to your default branch if it's not 'main'
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
GCP_PROJECT_ID: # Provide your GCP Project ID

steps:
- name: Configure GCP Credentials for Prod
uses: "google-github-actions/auth@v2"
with:
service_account: "deployer@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com"
workload_identity_provider: "projects/${{ env.GCP_PROJECT_ID }}/locations/global/workloadIdentityPools/defang-github-actions-pool/providers/defang-github-actions-provider"
token_format: access_token
access_token_scopes: https://www.googleapis.com/auth/cloud-platform

- name: Checkout Repo
uses: actions/checkout@v4

- name: Deploy
uses: DefangLabs/defang-github-action@v1.2.1
with:
mode: "balanced"
provider: "gcp"

Full documentation for configuring AWS and GCP credentials can be found in the Defang GitHub Action repository.