Cloud Storage (GCS)
Runway can provision a managed Cloud Storage bucket for your GKE workload and grant the workload’s service account object access to it. Runway owns the lifecycle of the bucket: it creates one bucket per environment in the Runway GCP projects, attaches a bucket-scoped IAM grant to your workload, and publishes the bucket name and project to Vault.
This guide assumes you already have a working Runway for Kubernetes deployment. If you do not, start with Getting Started first.
Overview
Section titled “Overview”Provisioning a bucket touches two files in the provisioner:
- Define the bucket in
config/runtimes/gke/gcs.yml— name, location, lifecycle, and labels. - Grant your workload access in
config/runtimes/gke/workloads.yml— references the bucket by itsnamevia agcs_bucketslist.
A bucket belongs to a single service: each bucket may be referenced by at most one workload. One
bucket is provisioned per environment (staging and production), in the gitlab-runway-staging and
gitlab-runway-production GCP projects. The physical bucket is named <name>-<environment> — the
-<environment> suffix is appended in code so the bucket name is globally unique.
Step 1: Define the bucket
Section titled “Step 1: Define the bucket”File an MR to add your bucket to
config/runtimes/gke/gcs.yml
in the Runway provisioner:
- name: runway-example-service location: US-EAST1 versioning: true soft_delete_retention_days: 7 retention_policy: retention_days: 30 is_locked: false lifecycle_rules: - action: type: Delete condition: age: 90 labels: gl_service: example-service-gke # required owner_email_handle: my-team department: eng-infra department_group: eng-infra-my-group product_category: my-categoryField reference
Section titled “Field reference”| Field | Required | Default | Notes |
|---|---|---|---|
name | yes | — | Must match ^runway-[a-z0-9]([a-z0-9-]*[a-z0-9])?$ (max 52 chars). The runway- prefix is enforced. The physical bucket is <name>-<environment>; the -<environment> suffix is appended for GCS global uniqueness. Must be unique across all buckets. |
labels | yes | — | Required infrastructure labels. gl_service is required; owner_email_handle, department, department_group, and product_category are optional. See the Infrastructure Standards. |
location | no | US-EAST1 | Any valid GCS bucket location (region, dual-region, or multi-region). |
versioning | no | true | Enable object versioning. |
soft_delete_retention_days | no | GCS default (7 days) | Soft-delete retention in days. Omit for the GCS default; 0 disables soft delete. |
retention_policy | no | none | Object: retention_days (required, ≥ 1) and is_locked (default false). Omit for no retention policy. |
lifecycle_rules | no | [] | Bucket lifecycle rules, passed through unchanged. Each rule has an action (Delete, SetStorageClass, or AbortIncompleteMultipartUpload) and a condition. |
Uniform bucket-level access is always enabled and legacy ACLs are disabled — this is fixed and not configurable.
Create the MR and assign it to a Runway team member (see
CODEOWNERS),
and ensure the pipeline passes before requesting review.
Step 2: Grant your workload access
Section titled “Step 2: Grant your workload access”In config/runtimes/gke/workloads.yml,
add a gcs_buckets key to your workload entry, referencing the bucket by its name:
- runway_service_id: example-service-gke project_id: 12345678 regions: - us-east1 gcs_buckets: - runway-example-serviceThis grants the workload’s service account roles/storage.objectUser on the bucket — read, write,
and delete objects, scoped to this bucket only. Remember that each bucket may be referenced by only
one workload; the inventory validation fails if two workloads claim the same bucket or if you
reference a bucket that is not defined in gcs.yml.
What gets created
Section titled “What gets created”On apply, the provisioner creates, for each environment:
-
The bucket
<name>-<environment>in the environment’s Runway GCP project, with uniform bucket-level access enabled. -
An IAM grant of
roles/storage.objectUserto the workload service accountgke-<runway_service_id>@<project>.iam.gserviceaccount.com, condition-scoped to the exact bucket (an exact resource match plus its object prefix). -
A Vault secret (mount
runway) atplatform/<runway_service_id>/gcs/<bucket>/<environment>, containing:{"bucket_name": "runway-example-service-production","project": "gitlab-runway-production"}
Consuming the bucket
Section titled “Consuming the bucket”Your workload’s service account already has object access to the bucket through Workload Identity, so
you do not need to handle any storage credentials — you only need to know the bucket name. Read it
from the Vault secret the provisioner publishes (see What gets created), for
example with an ExternalSecret that points at
platform/<runway_service_id>/gcs/<bucket>/<environment> on the runway mount and surfaces
bucket_name (and project) into your namespace. See
Secrets management for how Runway wires Vault into your
deployment. Your application then talks to GCS using its ambient Workload Identity credentials and the
bucket name from that secret.
Next steps
Section titled “Next steps”- Review the GCS schema for the authoritative field definitions.
- See Secrets management for other secret needs your service may have.
- Ask the Runway team in
#f_runwayfor help or to track deploy-time GCS support.