Skip to content

Install on GCP

Admin guide

Greenlight installs into a Google Cloud project you control. Plan on about 15–20 minutes for infrastructure provisioning and another 15–20 minutes for the install wizard.

Azure Supported GCP Supported AWS Supported

This page covers Google Cloud. See Install on Azure or Install on AWS for the equivalent deployment in those clouds.

Your Shift implementation contact delivers the approved release as a private, versioned greenlight-gcp-<version>.zip archive. It opens into one versioned directory holding install.sh, a README and troubleshooting guide written for the installing administrator, the release manifest, and a deployment/ directory with the Terraform configuration, provider lock file, pinned Kubernetes assets, and the Greenlight chart. The script is part of the archive; IT does not write or download it separately. The public docs describe the resources and permissions without publishing the package or image access details.

  • A dedicated Google Cloud project with billing enabled. Enter the project ID (for example acme-greenlight), not the display name.
  • A provisioning identity with Project Owner on that project.
  • A chosen region and a non-overlapping RFC 1918 range if the Greenlight VPC will peer with an existing network.
  • Nothing for the GKE node zone — the install reads your region’s zones and pins nodes to the first one. Pass --node-zone only if you need a particular zone.
  • A domain where you can delegate one subdomain, such as greenlight.acme.com, to Cloud DNS.
  • An IT administrator who can configure the OIDC identity provider, delegate the DNS subdomain, install the Greenlight GitHub App, and become the initial Greenlight org_admin.
  • terraform, gcloud, helm, kubectl, jq, curl, and the GKE authentication plugin at the versions listed in the private package README, plus bash 4.3 or newer. The installer checks all of them before it asks for anything and tells you how to install whatever is missing. On macOS, /bin/bash is 3.2 and too old — brew install bash and run the installer with that one.

The installer enables the required Google Cloud service APIs. Your team does not enable them one at a time.

Everything below is created inside the dedicated Greenlight project.

Area Resources
Network A custom VPC, a GKE subnet with pod/service ranges, Private Service Access, Cloud Router, and Cloud NAT
Compute One GKE Standard cluster with a dedicated system node pool and an autoscaling app node pool
Databases Two private Cloud SQL for PostgreSQL instances: one for Greenlight and one for app-owned logical databases
Storage Private, versioned Cloud Storage buckets for app objects, app assets, and platform storage, plus a versioned Terraform state bucket
Registry One regional Docker Artifact Registry repository for Greenlight and app images
Secrets Secret Manager entries for platform, database, integration, and app secrets
DNS and ingress One Cloud DNS zone, a reserved external ingress IP, Traefik, and cert-manager
Identity Dedicated service accounts and Workload Identity Federation bindings for the control plane, certificates, data access, and deployed apps

The public entry points are the Greenlight/app ingress and the authenticated GKE API. Cloud SQL uses private IP, Cloud Storage blocks public access, and workloads use Workload Identity Federation instead of service-account keys.

If you want Greenlight to send notification email, provide an SMTP relay such as Google Workspace SMTP relay or another approved provider. Email remains disabled when no relay is configured.

Greenlight selects and manages the infrastructure profile in the versioned deployment package. The values below describe the standard installation footprint for cost and quota review; they are not settings the installing administrator chooses or maintains.

Resource Default
GKE system node pool 1 × e2-standard-4
GKE app node pool e2-standard-4, autoscale 0–3
Cloud SQL control plane db-custom-2-8192, 32 GB SSD with automatic growth
Cloud SQL app databases db-custom-2-8192, 32 GB SSD with automatic growth
Cloud Storage Regional, versioned, public access prevented

Greenlight manages workload autoscaling within this profile and delivers capacity changes through versioned releases. Do not edit node pools or database tiers directly; the next Greenlight infrastructure reconcile treats the versioned deployment profile as the source of truth.

Identity Access Why
Provisioning identity Project Owner on the dedicated Greenlight project Enables services, creates resources, and creates IAM bindings
gl-runner Project- or resource-scoped access to GKE, Cloud SQL, Secret Manager, Storage, Artifact Registry, and the delegated DNS zone, plus conditional project IAM administration restricted to granting a fixed set of app roles Operates the control plane, provisions app resources, and grants each app’s service account only its own resources’ roles
gl-cert-manager DNS administrator on the delegated zone only Completes DNS-01 certificate challenges
gl-data No project IAM roles by default Receives access inside a connected database only when a DBA grants it
gl-updater Infrastructure access within the dedicated Greenlight project, including the install’s own image repository Applies Greenlight releases inside the maintenance window

The installer creates the runtime service accounts and their Workload Identity bindings. Your team does not create or distribute service-account JSON keys. Delete protection guards the databases, buckets, DNS zone, and cluster, so no automatic update can remove them.

The installing administrator supplies only values specific to the customer’s environment:

Input Required Purpose
--project Yes Dedicated Google Cloud project ID
--region Yes Region identifier where Greenlight resources are created, such as us-central1 — not a zone such as us-central1-a
--control-plane-host Yes Delegated DNS zone and final Greenlight hostname
--certificate-contact No Contact address on the certificate issuer. Derived from your host name when omitted
--network-range Only when needed Replaces the package default when it overlaps a peered network
--node-zone Only when needed Pins GKE nodes to one zone instead of the region’s first zone. Must be a zone in --region

Every input above has a matching prompt: run ./install.sh with no arguments and it explains and asks for each one, so the flags are only needed for scripted runs — which must also pass --non-interactive: it requires every input up front, stops rather than prompting when one is missing, and is the only thing that skips the two confirmations. A run with no terminal that omits it stops at the first confirmation rather than proceeding on its own.

Resource names, machine sizes, database tiers, Terraform provider versions, Kubernetes chart versions, and Greenlight image digests are derived or pinned by the release package. They are not install inputs.

Extract the private release archive and run the script it contains:

Terminal window
unzip greenlight-gcp.zip
cd greenlight-gcp-v<version>
./install.sh

Run it with no arguments. If you are not signed in to Google Cloud, a browser window opens so you can sign in — Terraform needs a second credential (Application Default Credentials), and the installer records both. It then explains and asks for the project, region, and host name, and offers the standard private network 10.240.0.0/16 as a yes/no — that range cannot be changed after install and cannot be peered if it overlaps a network you will connect later; only a “no” asks for a different range. To answer up front instead, pass the flags from the table above. Scripted runs (--non-interactive) do not open a browser; they stop and name gcloud auth login and gcloud auth application-default login.

The package README pins the required CLI versions, and the installer checks all of them in one pass before anything else runs, including the gke-gcloud-auth-plugin that kubectl needs. Every region works without naming a zone, including the ones with no <region>-a zone such as us-east1: the install reads the region’s zones and pins nodes to the first one, then records it so later runs keep the same zone.

gcloud and Terraform use two separate Google credentials. An interactive ./install.sh opens a browser when either is missing. --non-interactive stops and names gcloud auth login and gcloud auth application-default login. If gcloud commands work but Terraform fails with invalid_grant or invalid_rapt, only the Terraform credential is stale — run gcloud auth application-default login and rerun the installer.

  1. Validate the target project. The installer signs you in if needed, then checks that the signed-in account can see the project ID you give it, every required tool and version in one pass, and verifies it can pull the release’s pinned public images, before it creates anything.

  2. Confirm twice. The installer shows a review screen — target, region, zone, host name, networking, node sizes, and the exact image digests — and waits for you to confirm before the Terraform state bucket is created. It then writes a Terraform plan, shows it, and asks you to confirm yes or no. Applying that saved plan file is what runs, so what executes is what you reviewed.

  3. Let the packaged script complete. It runs the plan, obtains GKE credentials, and applies the package-pinned Gateway API, Traefik, cert-manager, and Greenlight Helm releases. It prints a phase name and the matching guide section before each operation, and for each step that can run for minutes without output it shows what it is waiting for and how long it has been waiting — so a long silence is never ambiguous. It can be rerun safely after a partial failure.

    Running it from a pipeline, or prefer plain output? Pass --no-color (or set NO_COLOR) for text only, with no colour and no progress indicator. Redirected output is already plain. Set GREENLIGHT_INSTALL_VERBOSE=1 to see every command’s full output instead of a progress indicator.

  4. Open the install wizard. The install prints Finish setup in the browser: and a temporary URL on the reserved ingress IP that works before your final DNS name and certificate are ready. The wizard then shows the Cloud DNS nameservers to delegate.

  5. Delegate the zone. Create the NS records shown by the wizard in your parent DNS. Greenlight creates the control-plane, wildcard app, and certificate-challenge records inside the delegated zone, then checks on a repeating timer until delegation, the certificate, and HTTPS are live — nothing to click while you wait.

  6. Finish the wizard. Configure OIDC, test sign-in, install the GitHub App, bootstrap the plugin marketplace, name the administrator we should contact about your trial and subscription (changed later in Settings → Organization), and confirm the organization and initial administrator.

  7. Verify the installation. Open the final HTTPS URL and run the installation-health checks.

Installation health verifies that:

  1. The final URL resolves over HTTPS.
  2. SSO resolves to a real IdP user with the required role mapping.
  3. The GitHub App can reach at least one repository.
  4. A plugin marketplace repository has its initial generated commit.
  5. The policy bundle and audit log are active.
  6. A test app can register and pass the policy check.

The installer is idempotent: rerunning the same version reconciles the existing installation.

Greenlight upgrades through a customer-owned updater inside the same Google Cloud project. It applies the versioned Terraform and Helm release using customer-controlled permissions. See Upgrades.

If you enabled automatic updates on an installation whose gl-updater service account predates the image-repository access listed in the identity table above, automatic updates stop at the planning step until you rerun the installer once with the current package. The updater cannot grant itself that access; the rerun grants it, and the next scheduled update proceeds on its own. New installations already include it.