YAML mode
Reis supports declarative infrastructure management through YAML files. Define your resources in YAML, commit them to version control, and apply them with reis apply -f for repeatable, auditable deployments.
Reis supports declarative infrastructure management through YAML files. Define your resources in YAML, commit them to version control, and apply them with reis apply -f for repeatable, auditable deployments.
This article is the orientation map — the file format, multi-document layout, and per-asset links. For the field-by-field reference of each asset type, jump straight to its dedicated page below.
Per-asset deployment guides
Each deployable asset has its own YAML walkthrough with the full set of fields that apply to it:
- Deploy an HTTP container
- Deploy a worker
- Deploy a cron job
- Deploy a Memcached instance
- Deploy a TLS bundle
- Deploy an X.509 certificate
- Deploy a GPG keypair
- Deploy an SSH keypair
- Deploy an encryption key
- Deploy a YAML config
- Deploy a JSON config
- Deploy a plain config
- Deploy an env file
Projects, registries, and secrets are simpler and covered inline at the end of this article.
Prerequisites
Before applying resources, set an organisation context. Reis needs to know which organisation to apply resources to:
# Set your default organisation (interactive)
reis org:switch
# Or pass it explicitly on each apply
reis apply -f infrastructure.yml --org 550e8400-e29b-41d4-a716-446655440000See Authentication for setting up credentials and your default organisation.
File format
Every YAML resource document carries a kind, an identity, and then the resource-specific fields. Fields are organised into named groups under top-level keys like workload, scaling, and networking:
kind: <resource-type>
project: <project-handle> # required for project-scoped resources
handle: <resource-handle>
name: <display-name>
regions:
- <region-id>
# resource-specific groups follow
workload:
cpu: "500"Supported kinds
| Kind | Per-asset guide |
|---|---|
container (type http) | HTTP container |
container (type worker) | Worker |
container (type cronjob) | Cron job |
memcached | Memcached |
tls_bundle | TLS bundle |
x509_cert | X.509 certificate |
gpg_keypair | GPG keypair |
ssh_keypair | SSH keypair |
encryption_key | Encryption key |
yaml_config | YAML config |
json_config | JSON config |
plain_config | Plain config |
env_file | Env file |
registry | inline below |
secret | inline below |
project | inline below |
Multi-document files
Combine multiple resources in a single file using the YAML document separator ---:
kind: secret
project: my-project
handle: db-password
name: Database Password
value: s3cret-value-here
---
kind: registry
project: my-project
handle: ghcr
name: GitHub Registry
server: ghcr.io
username: myuser
password: ghp_xxxxxxxxxxxx
---
kind: container
project: my-project
handle: web-api
name: Web API
image: ghcr.io/myorg/api:v1.0.0
type: http
registry: ghcr
regions:
- falkenstein-1
- virginia-1
workload:
cpu: "500"
memory: "512"
port: "8080"
healthcheck: /healthz
env:
NODE_ENV: production
secrets:
DB_PASSWORD: db-passwordResources are applied in the order they appear. Define secrets and registries before the containers that reference them.
Container group structure
Every container — HTTP, worker, or cron job — uses the same group structure. Per-asset articles show which groups apply to which type.
| Group | What it controls |
|---|---|
| (top level) | name, handle, image, project, registry, regions, type — identity and routing |
workload | CPU/memory, port, health check, env vars, secrets, ENTRYPOINT/CMD overrides |
scaling | Manual replicas, autoscaling caps and targets |
storage | Ephemeral storage size, persistent volumes |
networking | Hostnames, DNS, external networking |
observability | Prometheus scraping |
security | Basic auth, rate limiting, IP allow/deny lists |
proxy_cache | Managed proxy cache settings |
schedule | Cron expression, timezone, retry limits (cron jobs only) |
Project fields
kind: project
handle: my-project
name: My Project
regions:
- falkenstein-1
- virginia-1A project is the namespace inside an organisation that owns containers, registries, secrets, vault items, configs, and Memcached instances. Members and roles are managed via the console or the API directly — they're not editable from YAML.
Attachments (which org-level registry, secret, TLS bundle, config, etc. are usable inside the project) are not managed from the project YAML. Use the dedicated project:attach, project:detach, and project:attachments commands instead — see Commands Reference: Projects.
Project quotas (read-only display)
When you reis get an existing project, you'll also see a quotas: block showing the namespace quotas the platform has applied. These values are display-only — Reis silently ignores any edits you make under quotas: when you re-apply the file, so you can round-trip without manual cleanup.
kind: project
handle: my-project
name: My Project
regions: [falkenstein-1, virginia-1]
quotas: # read-only — set by the platform
request:
cpu: 1000m
memory: 1G
limit:
cpu: 2000m
memory: 2GRegistry fields
kind: registry
project: my-project
handle: ghcr
name: GitHub Registry
server: ghcr.io
username: myuser
password: ghp_xxxxxxxxxxxxRegistries hold the credentials used to pull private images. Reference one from a container via the top-level registry: <handle> field.
Secret fields
kind: secret
project: my-project
handle: db-password
name: Database Password
value: s3cret-value-hereSecrets are encrypted at rest and injected into containers as environment variables — see the HTTP container guide for the workload.secrets mapping shape.
Create-or-update semantics
reis apply -f looks up each resource by its handle:
- If the resource does not exist, it is created.
- If the resource already exists, it is updated with the values from the YAML file.
That makes reis apply idempotent — running it multiple times with the same file produces the same result.
Dry run
Validate a YAML file without making any changes:
reis apply -f infrastructure.yml --dry-runDry run does not require authentication. It parses the file, validates the structure, and shows what would be created or updated.
Exporting resources
Export any existing resource to YAML format:
# Export to stdout
reis export container web-api --project my-project
# Export to file
reis export container web-api --project my-project --file web-api.ymlThe exported YAML uses the same format that reis apply expects, so you can export, modify, and re-apply.
Tips
- Order matters in multi-document files. Define secrets and registries before the containers that reference them.
- Use handles, not UUIDs. Handles are immutable in Bahriya and are the primary identifier in YAML files.
- Environment variables can be specified as a YAML map (
KEY: value). Reis converts them to the API format automatically. - Commit your YAML files to version control for an audit trail of infrastructure changes.
- Use dry run to validate changes before applying them, especially in CI/CD pipelines.
YAML mode vs flag mode
| You're doing… | Reach for… |
|---|---|
| Managing a stack of related resources together | YAML mode |
| Onboarding a new project under version control | YAML mode |
| Restoring a previously exported config | YAML mode |
| A one-off deploy from your laptop | flag mode |
| A scripted CI job that builds the same container | flag mode |
| Quick edits to a field or two | flag mode |
Both modes produce identical results.