Pull request previews on Google Cloud

Run each pull request's stagelet on its own Compute Engine instance in your Google Cloud project. See what stagely setup creates and the roles it needs.

Stagely gives each GitHub pull request a stagelet: a private, running copy of your app. On Google Cloud, each stagelet runs on its own Compute Engine instance in your project. You run stagely setup gcp once. After that, the customer agent creates an instance when a pull request deploys, and deletes it when the stagelet ends.

What setup creates

Setup applies a Terraform module with OpenTofu or Terraform. It creates these resources in the region and zone that you choose:

Resource Details
Network <environment>-stagely, in custom mode, with one subnetwork, 10.42.0.0/20
Agent host Instance of type e2-small, Ubuntu 24.04
Gateway host Instance of type e2-small, Ubuntu 24.04, with a static external address
Firewall rules Rules on network tags: one set for the agent host, one for the gateway host, and one for stagelet machines and build workers
Artifact Registry repository A Docker repository in the region, with the ID in -registry
Service accounts <environment>-push can push to the repository and pull from it. <environment>-pull can only pull from it. Your service account can impersonate both.

The hosts get setup’s SSH key for root, and they block the project-wide SSH keys.

Credentials

Setup needs a service account key in GOOGLE_APPLICATION_CREDENTIALS, or in the file that -credentials names. The service account needs these roles in the project:

  • Compute Admin (roles/compute.admin)
  • Artifact Registry Administrator (roles/artifactregistry.admin)
  • Service Account Admin (roles/iam.serviceAccountAdmin)

The project needs these APIs turned on: Compute Engine, Artifact Registry, IAM, and IAM Service Account Credentials.

The key stays on your computer and on the agent host. On the agent host, it is in /etc/stagely/stagely-agent.env, which only root can read. Machines never get the key.

Stagelet machines and build workers

  • The agent creates one instance for each stagelet, in the zone in -zone. Its type is e2-medium. Setup has no flag to change this type.
  • The agent keeps two build workers, also of type e2-medium. They stay when stagelets come and go.
  • Each instance starts from Ubuntu 24.04, and cloud-init installs Docker at the first boot. With -golden-image, instances start from an image that already has Docker. The stagely repository has the Packer template for this image.
  • Each instance joins the environment’s subnetwork. The agent connects to it over SSH, and accepts only the host key that it gave the instance.
  • The agent names its machines stagely-<environment>-..., so several environments can share one project and zone.

Registry

Build workers push images to the Artifact Registry repository. Before each build and each start, the agent impersonates one of the two service accounts and gets a token that lasts one hour:

  • A build worker gets a token of the push account.
  • A stagelet machine gets a token of the pull account.

A token works only with the repository. Your service account key never goes to a machine.

Isolation

  • Stagelet machines and build workers accept connections only from instances with the agent’s or the gateway’s network tag.
  • The network has no rule that lets in its own address range. So a stagelet does not accept connections from another stagelet, and it cannot reach the agent host.
  • The agent host accepts only SSH, and only from your -operator-cidr ranges.
  • The gateway host accepts ports 80 and 443 from anywhere, and SSH from your ranges.
  • On each instance, containers cannot open new connections to the metadata server at 169.254.169.254, except on port 53. The metadata server is also the instance’s DNS server.

Run setup

export GOOGLE_APPLICATION_CREDENTIALS=key.json
stagely login
stagely setup gcp \
  -environment production \
  -region us-central1 \
  -zone us-central1-a \
  -stagelet-domain stagelets.example.com \
  -registry stagely \
  -operator-cidr 203.0.113.7/32 \
  -binaries bin/linux-amd64 \
  -acme-email ops@example.com
Flag Meaning
-region Region of the network, the address and the repository, required
-zone Zone in the region for the hosts and stagelet machines, required
-registry ID of the Artifact Registry Docker repository that setup creates, required
-project Project ID. The default is the project of the service account key.
-credentials Service account key file. The default is the file in GOOGLE_APPLICATION_CREDENTIALS.
-golden-image Image for stagelet machines and build workers, built from the golden image template

Setup also takes the flags that every cloud takes. At the end, it prints the gateway’s static address. Point DNS at the gateway with an A record.

After setup

  1. Add .stagely.yml to your repository.
  2. Add config values and secrets.
  3. Read the Security model before you add real secrets.