Skip to content

Module Manifest

The module manifest is the runway/v3 Runway manifest of a modular feature on GitLab Dedicated. It takes the place of the runway/v2 deployment*.yaml manifest that GKE and EKS use: Dedicated doesn’t read deployment*.yaml. It sets the default configuration of the module’s infrastructure, S3 buckets, PostgreSQL instances, and Redis instances, declares the peer modules it connects to and the secrets Runway generates for it, and lists extra Helm values files. When you release the module, runwayctl catalog create checks the manifest and copies it into the Module Catalog entry. Tenants override the defaults in the Tenant Model.

Its schema is the runway.manifest.v3.Manifest message in runwayctl’s manifest.proto.

.runway/module.yaml
apiVersion: runway/v3
kind: RunwayManifest
metadata:
name: example-service-dedicated
spec:
infrastructure:
s3:
uploads:
defaultConfig:
lifecycleRules:
set:
- id: expire-tmp
expiration:
days: 30
rds:
main:
defaultConfig:
databaseName: example
instanceType: small
elasticache:
cache:
defaultConfig:
enabled: false
instanceType: xsmall
connections:
modules:
set:
- name: iam-data-dedicated
secrets:
root-key:
defaultConfig:
keyringSize: 2
extraValueFiles:
- "values-{{ .Runtime }}-features.yaml"

Field names can be in camelCase (defaultConfig) or snake_case (default_config). Unknown fields are rejected.

The module manifest is a file named module.yaml or module-<suffix>.yaml, with a .yaml or .yml extension, in the Runway directory (.runway/) or one of its subdirectories. Runway picks the one whose metadata.name is the Runway service ID, so one directory can hold a module manifest for each module.

  • Every module manifest in the directory is validated, not only the one Runway picks.
  • Two module manifests with the same metadata.name are an error.
  • The module manifest is required: without one, runwayctl catalog create fails. A module without infrastructure defaults or peers uses spec: {}.
Field Type Description
apiVersion string Required. runway/v3.
kind string Required. RunwayManifest.
metadata object Required. Metadata of the module.
spec object Required. Specification of the module.
Field Type Description
name string Required. Runway service ID, which is also the module name in the Module Catalog and the Tenant Model. Lowercase letters, digits, and hyphens, starting and ending with a letter or digit, at most 53 characters.
Field Type Description
infrastructure object Default configuration of the module’s infrastructure.
connections object Peer modules the module connects to. See Connections.
secrets object Module-private secrets that Runway generates for the module. See Secrets.
extraValueFiles array Extra Helm values files, merged after values.yaml and values-dedicated.yaml. See Extra values files.

The module’s infrastructure, keyed by the AWS service that implements it, then by a logical name of your choice. The logical names are the same as in the Tenant Model, where a tenant overrides an entry by using its name.

Field Type Description
s3 object S3 buckets. Each entry’s defaultConfig takes the S3 bucket settings.
rds object PostgreSQL (Amazon RDS) instances. Each entry’s defaultConfig takes the RDS instance settings.
elasticache object Redis (Amazon ElastiCache for Valkey) instances. Each entry’s defaultConfig takes the ElastiCache instance settings.

Each entry has one field, defaultConfig, which is required. Logical names follow the same rules as in the Tenant Model, and are at most 45 characters long:

  • s3 and rds: lowercase letters, digits, and hyphens, starting and ending with a letter or digit.
  • elasticache: lowercase letters, digits, and single hyphens, starting with a letter and not ending with a hyphen.

Whether the module needs a dependency at all is its presence in the Fairway manifest, which the module manifest doesn’t repeat. See Presence.

The peer modules the module initiates connections to, under modules.set, by their Runway service ID. The manifest must use set: modules.add is only allowed in the Tenant Model. See Connections for the rules and for what Runway creates.

Field Type Description
modules.set array Peer modules, each an object with a name, the peer’s Runway service ID.

The module-private secrets that Runway generates for the module, keyed by a logical name of your choice. The logical names are the same as in the Tenant Model, and in the name of the Kubernetes Secret, secret-<name>, that your Helm values mount. See Secrets for how the secret reaches your pods and how it is rotated.

Field Type Description
defaultConfig object Required. The secret settings. May be empty, to take every built-in default.

Logical names are lowercase letters, digits, and hyphens, starting and ending with a letter or digit, at most 45 characters. version and preventDeletion belong to the tenant: a defaultConfig that sets either of them is an error. Secrets have no presence in the Fairway manifest.

A defaultConfig must be a complete, valid configuration on its own, without any Tenant Model override. Runway checks it with the same rules as a Tenant Model entry, including required fields such as databaseName and rules that span fields, such as numCacheClusters and multiAz. This applies to disabled defaults too, so that they are sane when a tenant enables them.

Lifecycle rules must use set. add appends to the defaults, so it is only meaningful in the Tenant Model, and a module manifest that sets it is an error.

An entry is enabled unless its defaultConfig sets enabled: false. With enabled: false, you provide the defaults of an entry without turning it on: a tenant turns it on with enabled: true in its Tenant Model, without repeating the other settings. A tenant can also set enabled: false to turn off an entry that is on by default.

provision and deploy merge the defaults with the Tenant Model. Each setting of an entry comes from the first of these that sets it:

  1. The tenant’s override in the Tenant Model’s values_override.infrastructure.
  2. The entry’s defaultConfig in the module manifest.
  3. The built-in default documented on the S3, RDS, and ElastiCache pages.

Entries are merged by logical name and settings one by one, so a tenant only sets what differs. A tenant that is happy with the defaults needs no values_override.infrastructure block at all. A tenant can also add an entry that has no default; it must then be complete on its own.

The Tenant Model’s overrides are partial: they only have to parse. provision and deploy validate the merged result of every enabled entry, and check the enabled entries against the module’s presence. Disabled entries are dropped without further checks.

catalog create checks the defaults against the presence of each dependency in the Fairway manifest, and fails if they don’t match:

Fairway dependency Module manifest REQUIRED OPTIONAL UNUSED
object_store s3 Needs at least one enabled default. Any defaults, or none. Must have no defaults.
postgresql rds Needs at least one enabled default. Any defaults, or none. Must have no defaults.
redis elasticache Needs at least one enabled default. Any defaults, or none. Must have no defaults.

A required dependency can’t be off by default, and an unused one can’t have defaults, not even disabled ones.

catalog create writes the presence and the defaults into the catalog entry’s infrastructure, keyed the same way:

data/example-service-dedicated/1.26.0.yaml
infrastructure:
s3:
presence: PRESENCE_REQUIRED
entries:
uploads:
default_config:
lifecycle_rules:
set:
- id: expire-tmp
expiration:
days: 30
rds:
presence: PRESENCE_OPTIONAL
entries:
main:
default_config:
database_name: example
instance_type: small
elasticache:
presence: PRESENCE_OPTIONAL
entries:
cache:
default_config:
enabled: false
instance_type: xsmall

Catalog entries written before the infrastructure was keyed by implementation (postgresql, redis, object_store) can no longer be read. Release a new version of the module to deploy it.

runwayctl validate checks a module manifest without releasing the module:

Terminal window
runwayctl validate .runway/module.yaml