Skip to content

Setup

Terminal window
pnpm add https://pkg.alchemy.run/alchemy/pr:2930:51c662a https://pkg.alchemy.run/@alchemy.run/gcp/pr:2930:51c662a effect @effect/platform-bun @effect/platform-node
  • Node.js 24.11.1+ or Bun.
  • A GCP project and its id.
  • Credentials with enough IAM to create what you deploy: your own Google account through gcloud, or a service-account key. A working starting point is Cloud Run Admin, Storage Admin, Pub/Sub Admin, Service Account Admin (Alchemy creates an alch-* service account for each runtime), and Project IAM Admin (it grants roles to that account). Add the admin role for anything else you declare — Firestore, BigQuery, Secret Manager.
  • Docker running locally. GCP.Function, GCP.Run.Service, GCP.Run.Job, and GCP.Run.WorkerPool bundle your code and build a container image before pushing it to Artifact Registry.
  • The APIs enabled on the project for whatever you use: run.googleapis.com, artifactregistry.googleapis.com, iam.googleapis.com, cloudresourcemanager.googleapis.com, plus the service-specific ones (firestore.googleapis.com, secretmanager.googleapis.com, pubsub.googleapis.com, bigquery.googleapis.com, redis.googleapis.com).
Terminal window
gcloud services enable run.googleapis.com artifactregistry.googleapis.com \
iam.googleapis.com cloudresourcemanager.googleapis.com

Run alchemy profile edit --add GCP and choose gcloud login, then pick a gcloud configuration. Alchemy signs in to it with gcloud auth login if it has no login yet, and deploys as its account into its project and compute/region. It never activates the configuration, so each Alchemy profile can use a different Google account while your gcloud stays as it is.

Terminal window
alchemy profile edit --add GCP
# when the login expires or is revoked:
alchemy profile refresh --provider GCP

The profile names the configuration and nothing else, so no token is copied into it:

// ~/.alchemy/profiles/<name>/gcp.json
{ "method": "gcloud", "configuration": "work" }

To set it up without prompts, create the configuration with gcloud first:

Terminal window
gcloud config configurations create work --no-activate
gcloud auth login --configuration=work
gcloud config set project my-project --configuration=work
alchemy profile edit --add GCP --method gcloud --set configuration=work

A project or region in the profile overrides the configuration’s.

This needs the Google Cloud CLI. Creating projects without an organization or folder also needs it: Google only lets user accounts do that.

To deploy as a service account instead, choose Service account JSON and point at the key file. Alchemy stores the path in the profile.

Environment variables need no profile. When a token or key file is set, Alchemy uses it instead of the profile, and in CI (CI=true) the environment is the only source:

  • GOOGLE_PROJECT_ID — project id (GOOGLE_CLOUD_PROJECT is accepted as an alias).
  • GOOGLE_APPLICATION_CREDENTIALS — path to the key file.

Or GOOGLE_ACCESS_TOKEN plus GOOGLE_PROJECT_ID for a short-lived token. On GKE with Workload Identity, neither is needed — the metadata server is the last link in the chain.

See Profiles for how credentials are stored and switched.

alchemy.run.ts
import * as Alchemy from "alchemy";
import * as GCP from "@alchemy.run/gcp";
import * as Effect from "effect/Effect";
export default Alchemy.Stack(
"App",
{ providers: GCP.providers(), state: GCP.state() },
Effect.gen(function* () {
return {};
}),
);

GCP.providers() merges next to any other cloud’s providers, so a single stack can span GCP and Cloudflare or AWS.

Regional resources created without a location / region prop land in the default region. It comes with the credential (the profile’s region, which alchemy profile asks for), else us-central1. To pin a stack to a region regardless of the credential, provide GCP.Region(...):

export default Alchemy.Stack(
"App",
{
providers: GCP.providers().pipe(
Layer.provideMerge(GCP.Region("europe-west1")),
),
state: GCP.state(),
},
program,
);

A resource that should live elsewhere takes an explicit location. Changing the stack region never moves a deployed resource: its recorded location wins.

Requests for regional resources that Google only serves from a regional endpoint (Secret Manager, Parameter Manager) go to {service}.{region}.rep.googleapis.com automatically. For data residency, send every regional request to its regional endpoint:

GCP.providers().pipe(
Layer.provideMerge(GCP.RegionalEndpoints("prefer")),
);

alchemy destroy removes what a stack created, including the per-host service accounts and their role grants. For a test project that has drifted, pnpm nuke:gcp deletes Alchemy-managed resources across the whole project — including every service account stamped alchemy-host. Do not point it at a project you care about.

  • Tutorial — deploy your first Stack.
  • Cloud Run — the runtime the rest of these docs build on.