Last updated on 26th February 2026

Deploy to Google Cloud with gcloud

This guide walks you through deploying to Google Cloud Platform using DeployHQ's Custom Action protocol. Custom Actions run CLI tools inside Docker containers during your deployment pipeline, letting you use the gcloud CLI to deploy to App Engine, Cloud Run, GKE, and other GCP services.

Prerequisites

Before you begin, ensure you have:

  • Beta Features Enabled: Custom Actions require beta features to be enabled in your account settings
  • A GCP Project: An active Google Cloud project with billing enabled
  • Service Account Credentials: A service account JSON key file with permissions for your target services
  • Application Code in Repository: Your application source code with any required configuration files (e.g., app.yaml for App Engine, Dockerfile for Cloud Run)

Setting Up the Server

  1. Open your project in DeployHQ and navigate to Servers.
  2. Click New Server and select Custom Action as the protocol.
  3. Under Image Source, select Curated Template.
  4. Choose Google Cloud SDK from the template dropdown. This sets the Docker image to google/cloud-sdk:slim.
  5. Enter your deployment commands in the Commands field:
   echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
   gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
   gcloud config set project my-gcp-project
   gcloud app deploy /data/app.yaml --quiet
  1. Set Halt on error to stop the deployment if any command fails.
  2. Click Create Server.

Configuring Credentials

Google Cloud authentication uses a service account key. Create a service account in the GCP Console with the necessary roles, then download the JSON key file.

Add the following environment variables to your DeployHQ server:

Variable Value
GCP_SERVICE_ACCOUNT_KEY The full contents of your service account JSON key file
GCP_PROJECT_ID Your Google Cloud project ID

Your commands should authenticate before running any gcloud operations:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID

Required IAM Roles

The roles needed depend on the services you are deploying to:

Service Required Roles
App Engine roles/appengine.deployer, roles/appengine.serviceAdmin
Cloud Run roles/run.developer, roles/iam.serviceAccountUser
GKE roles/container.developer
Cloud Functions roles/cloudfunctions.developer
Cloud Storage roles/storage.admin

Example Commands

Deploy to App Engine

Deploy a standard or flexible App Engine application:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud app deploy /data/app.yaml --quiet

The --quiet flag suppresses interactive prompts, which is required for non-interactive environments.

Deploy to Cloud Run

Deploy a container to Cloud Run from source:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud run deploy my-service \
  --source /data \
  --region us-central1 \
  --platform managed \
  --allow-unauthenticated \
  --quiet

Or deploy a pre-built container image:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud run deploy my-service \
  --image gcr.io/$GCP_PROJECT_ID/my-service:%revision% \
  --region us-central1 \
  --platform managed \
  --quiet

Deploy to GKE

Connect to a GKE cluster and apply Kubernetes manifests:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud container clusters get-credentials my-cluster --zone us-central1-a
kubectl apply -f /data/k8s/
kubectl rollout status deployment/my-app -n production --timeout=300s

Note that the google/cloud-sdk:slim image includes kubectl, so no additional image is needed for GKE deployments.

Deploy Cloud Functions

Deploy a Cloud Function from your repository:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud functions deploy my-function \
  --source /data \
  --runtime nodejs20 \
  --trigger-http \
  --entry-point handler \
  --region us-central1 \
  --quiet

Sync to Cloud Storage

Upload static files to a Cloud Storage bucket:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gsutil -m rsync -r -d /data/public/ gs://my-bucket/

Multi-Environment Usage

Separate Projects per Environment

Use different GCP projects for staging and production by setting different GCP_PROJECT_ID values on each DeployHQ server:

Staging server:

Variable Value
GCP_PROJECT_ID my-app-staging
GCP_SERVICE_ACCOUNT_KEY Staging service account key

Production server:

Variable Value
GCP_PROJECT_ID my-app-production
GCP_SERVICE_ACCOUNT_KEY Production service account key

Dynamic Configuration

Use DeployHQ text variables for environment-specific settings:

echo "$GCP_SERVICE_ACCOUNT_KEY" > /tmp/gcp-key.json
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
gcloud config set project $GCP_PROJECT_ID
gcloud run deploy my-service-%server% \
  --source /data \
  --region us-central1 \
  --platform managed \
  --quiet

Troubleshooting

"ERROR: (gcloud.auth.activate-service-account) Could not read json file":

  • Ensure the GCP_SERVICE_ACCOUNT_KEY environment variable contains the full JSON key, not a file path
  • Check that the value is not truncated. Service account keys are typically around 2,400 characters.

"ERROR: (gcloud.app.deploy) Permissions error":

  • Verify the service account has the required IAM roles listed above
  • Check that the service account belongs to the correct GCP project

"Cloud Build has not been used in this project before":

  • Cloud Run source deployments require Cloud Build. Enable it in the GCP Console under APIs and Services.
  • Also enable the Container Registry or Artifact Registry API

"The user-provided container failed to start":

  • For Cloud Run, check that your application listens on the PORT environment variable
  • Review Cloud Run logs in the GCP Console for startup errors

"Unable to connect to the server" (GKE):

  • Ensure the GKE cluster is running and the API server is accessible
  • Verify the cluster name and zone in your get-credentials command

Timeout errors:

  • Custom Actions have a 30-minute timeout per command
  • App Engine and Cloud Run deployments can take several minutes. If builds are slow, consider deploying a pre-built container image instead of building from source.