Memorystore for Redis
Runway can provision a managed Memorystore for Redis instance for your GKE workload and wire the connection details into your service automatically. Runway owns the lifecycle of the instance and its credentials: it provisions the instance in the Runway GCP projects, writes the address and auth string to Vault, and injects the connection secret into your Helm chart. You do not create or manage the secret yourself.
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 Redis touches four places. Three of them describe the instance and grant access to it; the fourth tells your deployment to consume it:
- Declare the dependency in your Fairway manifest — your chart requires (or optionally accepts) Redis.
- Define the instance in the provisioner (
memorystore.yml) — sizing, version, region, and a uniqueidentifier. - Grant your workload access in the provisioner (
workloads.yml) — references the instance by its globally uniquename. - Reference the instance from your Runway manifest (
deployment.yaml) — references it by itsidentifier.
The name and the identifier are two different handles for the same instance, used in different
files. Keep both straight: workloads.yml uses the name, the Runway manifest uses the identifier.
Step 1: Declare the dependency in your Fairway manifest
Section titled “Step 1: Declare the dependency in your Fairway manifest”In your Fairway manifest, declare that your chart needs a Redis connection. This only states whether Redis is required or optional — it does not say how to connect.
kind: FairwayManifestapiVersion: fairway/v1metadata: name: example-servicespec: # ... infrastructure: redis: presence: REQUIREDpresence accepts:
REQUIRED— Helm refuses to install the chart unless a Redis connection is configured. Use this when your service cannot run without Redis.OPTIONAL— the chart installs whether or not Redis is configured. Your application must handle the absence gracefully (see Connecting from your application).
Step 2: Define the Memorystore instance
Section titled “Step 2: Define the Memorystore instance”File an MR to add your instance to
config/runtimes/gke/memorystore.yml
in the Runway provisioner:
- name: runway-redis-example-service-gke identifier: MAIN provider: GCP engine: REDIS instance_type: CACHE redis_version: REDIS_7_2 tier: STANDARD_HA memory_size_gb: 4 regions: - us-east1 read_replicas_enabled: false labels: owner_email_handle: my-team department: eng-infra department_group: eng-infra-my-group product_category: my-categoryOne instance is provisioned per region and per environment (staging and production), all from this
single entry. The instances live in the gitlab-runway-staging and gitlab-runway-production GCP
projects.
Field reference
Section titled “Field reference”| Field | Required | Allowed values | Notes |
|---|---|---|---|
name | yes | string matching ^runway-redis-.* | Globally unique. The runway-redis- prefix is enforced. Referenced from workloads.yml and used as the type label in metrics. |
identifier | yes | ^[A-Z0-9_]{1,20}$ | Short, app-unique handle referenced from the Runway manifest. Free-form, but conventional values are MAIN, CACHE, and SIDEKIQ. |
redis_version | yes | REDIS_7_0, REDIS_7_2 | REDIS_7_2 is recommended for new instances. On the BASIC tier, upgrading incurs downtime; downgrading recreates the instance. |
regions | yes | one or more valid Runway GKE regions | Should match the regions of the workload that consumes it. See the GKE regions list. |
instance_type | yes | CACHE | Only CACHE is supported today. |
provider | yes | GCP | Only GCP is supported today. |
engine | yes | REDIS | Must be set explicitly. Only REDIS is supported today. |
memory_size_gb | yes | number (GiB) | Instance memory size. Size this for your working set plus headroom; ask in #f_runway if unsure. |
tier | no | BASIC, STANDARD_HA | Defaults to BASIC (single node, no HA). Use STANDARD_HA for a highly available primary/replica pair — recommended for anything user-facing. |
read_replicas_enabled | no | boolean | Defaults to false. Only valid on STANDARD_HA. |
replica_count | no | 1–5 | Only when read_replicas_enabled: true (default 2). Ignored when read replicas are disabled. |
labels | yes | object | Required infrastructure labels — owner_email_handle, department, department_group, product_category. See the Infrastructure Standards. |
Create the MR and assign it to a Runway team member (see
CODEOWNERS),
and ensure the pipeline passes before requesting review.
Step 3: Grant your workload access
Section titled “Step 3: Grant your workload access”In config/runtimes/gke/workloads.yml,
add a redis_instances key to your workload entry, referencing the instance by its name (not
its identifier):
- runway_service_id: example-service-gke project_id: 12345678 regions: - us-east1 redis_instances: - runway-redis-example-service-gkeThis grants the workload’s service account the access it needs to read the connection secret.
Step 4: Reference the instance from your Runway manifest
Section titled “Step 4: Reference the instance from your Runway manifest”In your Runway manifest (deployment.yaml), reference the instance by its identifier (not its
name) under spec.infrastructure.redis:
apiVersion: runway/v2kind: RunwayManifestmetadata: name: example-service-gkespec: chartRef: "oci://registry.gitlab.com/gitlab-com/gl-infra/platform/runway/example-service/chart/example-service-gke:{% .ChartVersion %}"
infrastructure: redis: - identifier: MAINThat is all that is required. On deployment, Runway resolves the identifier to the provisioned
instance for the current environment and region, and injects the connection secret into your chart
(see below).
Tuning the connection
Section titled “Tuning the connection”The manifest entry only takes identifier. Connection tuning — timeouts, pool sizing, logical db,
Prometheus metric namespace, and so on — is configured on the infrastructure.redis block of your
chart’s Helm values. The full set of tunable fields is documented in the
Fairway Redis schema.
Two fields are managed by Runway and should be left alone:
secretRefis injected by Runway. If you set it yourself, Runway overwrites it and logs a warning.clientNamedefaults to the instanceidentifier(used in logs and as a constant Prometheus label). Override it only if you have a reason to.
How credentials are delivered
Section titled “How credentials are delivered”You should not need to touch any of this, but for reference:
- The provisioner writes the connection details to Vault (mount
runway) atplatform/<runway_service_id>/redis/<identifier>/<environment>/<region>. The secret has two fields:addrs(thehost:portof the instance) andpassword(the auth string). - On deployment, Runway creates an
ExternalSecretthat syncs that Vault secret into a KubernetesSecretin your namespace. - Runway injects
infrastructure.redis.secretRefinto your Helm values, pointing at that Secret, so the generated chart reads the address and password from it at runtime.
The result is that your application receives a fully configured Redis connection without you handling any credentials directly.
Connecting from your application
Section titled “Connecting from your application”Use redis.New() from
LabKit. It reads the injected infrastructure config, resolves the address and auth from the secret,
and returns an instrumented client — you do not parse any environment variables or secret files
yourself.
import ( "errors"
"gitlab.com/gitlab-org/labkit/v2/infrastructure" "gitlab.com/gitlab-org/labkit/v2/redis")
client, err := redis.New(ctx, redis.WithRegisterer(reg), // Prometheus metrics redis.WithTracer(tracer), // OpenTelemetry spans redis.WithLogger(logger), // structured per-command logs)if err != nil { return err}
// client implements app.Component: call client.Start(ctx) during startup to// verify connectivity, and client.Shutdown(ctx) on teardown. Use// client.Redis() to obtain the underlying go-redis UniversalClient for commands.redis.New() returns a client that transparently handles single-node, Sentinel, and Cluster
topologies through one interface, so your code does not change if the underlying instance type does.
Next steps
Section titled “Next steps”- Review the Memorystore 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 sizing your instance or troubleshooting a deployment.