Vaultwarden on Google Cloud Run
This document provides a comprehensive reference for the modules/Vaultwarden_CloudRun Terraform module. It covers architecture, IAM, configuration variables, Vaultwarden-specific behaviours, and operational patterns for deploying Vaultwarden on Google Cloud Run (v2).
1. Module Overview
Vaultwarden is an unofficial, lightweight Bitwarden-compatible server written in Rust. It provides a self-hosted password manager that works with all official Bitwarden clients. Vaultwarden CloudRun is a wrapper module built on top of App CloudRun. It uses App CloudRun for all GCP infrastructure provisioning and injects Vaultwarden-specific application configuration via Vaultwarden Common.
Key Capabilities:
- Compute: Cloud Run v2 (Gen2), 1 vCPU / 512 Mi by default.
- Data Persistence: Cloud SQL PostgreSQL 15 (default; MySQL 8.0 also supported). GCS
vaultwarden-databucket auto-provisioned byVaultwarden Common. - Security: Vaultwarden serves sensitive credential data — Cloud Armor WAF is available and recommended for brute-force protection. No application-level secrets are auto-generated by
Vaultwarden Common(the database credentials are managed byApp CloudRun). - Health: Probes target
/alive, Vaultwarden's dedicated health endpoint. - Configuration: Key application settings (
SIGNUPS_ALLOWED,WEB_VAULT_ENABLED,DOMAIN) are exposed as top-level variables and injected automatically.
Project & Application Identity
| Variable | Group | Type | Default | Description |
|---|---|---|---|---|
project_id | 1 | string | — | GCP project ID. Required. |
tenant_deployment_id | 1 | string | 'demo' | Short suffix appended to all resource names. |
support_users | 1 | list(string) | [] | Email recipients for monitoring alerts. |
resource_labels | 1 | map(string) | {} | Labels applied to all provisioned resources. |
application_name | 2 | string | 'vaultwarden' | Base resource name. Do not change after initial deployment. |
display_name | 2 | string | 'Vaultwarden' | Human-readable name shown in the GCP Console. |
description | 2 | string | 'Vaultwarden password manager' | Cloud Run service description. |
application_version | 2 | string | '1.32.7' | Vaultwarden image version tag. |
Wrapper architecture: Vaultwarden CloudRun calls Vaultwarden Common to build an application_config object. The wrapper injects application-specific environment variables (ROCKET_PORT, SIGNUPS_ALLOWED, WEB_VAULT_ENABLED, DATA_FOLDER, and optionally DOMAIN) before passing the config to App CloudRun. Vaultwarden Common does not create any Secret Manager secrets — all credential management is handled by App CloudRun.
2. IAM & Access Control
Vaultwarden_CloudRun delegates all IAM provisioning to App_CloudRun. The Cloud Run SA, Cloud Build SA, IAP service agent, and password rotation role sets are identical to those in App_CloudRun §2.
No application-level secrets: Vaultwarden Common does not auto-generate application secrets. The DB_PASSWORD and ROOT_PASSWORD secrets are provisioned automatically by App CloudRun.
Database initialisation identity: The db-init Cloud Run Job runs under the Cloud Run SA. It supports both PostgreSQL (using postgres:15-alpine) and MySQL 8.0 (using mysql:8.0-debian) depending on database_type.
Cloud Armor recommendation: Vaultwarden stores passwords and sensitive credentials. Enabling enable_cloud_armor = true is strongly recommended for production deployments to protect against brute-force attacks on the login API.
CDN warning: enable_cdn = true should be used with caution. Vaultwarden serves authenticated API responses that must not be cached. Ensure Cache-Control: no-store headers are in place before enabling CDN.
For the complete role tables and IAP, password rotation, and public access details, see App_CloudRun §2.
3. Core Service Configuration
A. Compute (Cloud Run)
Vaultwarden is a lightweight Rust binary with modest resource requirements compared to other modules. The default resource allocation (1 vCPU / 512 Mi) is sufficient for small organisations.
CPU validation: cpu_limit must be at least "1000m" (1 vCPU). Cloud Run Gen2 requires a minimum of 1 vCPU for NFS and GCS Fuse. Values below "1000m" will fail validation.
| Variable | Group | Default | Description |
|---|---|---|---|
deploy_application | 3 | true | Set false for infrastructure-only deployment. |
container_image_source | 3 | 'custom' | 'custom' builds via Cloud Build. 'prebuilt' deploys an existing image URI. |
container_image | 3 | "" | Override image URI. |
cpu_limit | 3 | '1000m' | CPU per instance. Minimum 1000m enforced by validation. |
memory_limit | 3 | '512Mi' | Memory per instance. |
container_port | 3 | 80 | Vaultwarden's HTTP port. |
execution_environment | 3 | 'gen2' | Gen2 required for GCS Fuse. |
timeout_seconds | 3 | 300 | Max request duration. |
enable_cloudsql_volume | 3 | true | Connects via Unix socket. |
min_instance_count | 3 | 1 | Minimum Cloud Run instances. |
max_instance_count | 3 | 3 | Maximum Cloud Run instances. |
traffic_split | 3 | [] | Canary/blue-green traffic allocation. |
Differences from App CloudRun defaults:
| Variable | App CloudRun | Vaultwarden CloudRun | Reason |
|---|---|---|---|
container_port | 8080 | 80 | Vaultwarden's default HTTP port. |
cpu_limit | '1000m' | '1000m' | Same — validation requires ≥1000m. |
memory_limit | '512Mi' | '512Mi' | Vaultwarden is a lightweight Rust binary. |
min_instance_count | 0 | 1 | Password manager benefits from a warm instance. |
B. Database (Cloud SQL)
Vaultwarden supports both PostgreSQL 15 (default) and MySQL 8.0. The database_type variable controls which engine is used and determines the db-init job image (postgres:15-alpine for PostgreSQL, mysql:8.0-debian for MySQL).
Unix socket connection: enable_cloudsql_volume defaults to true.
| Variable | Group | Default | Description |
|---|---|---|---|
database_type | 11 | 'POSTGRES_15' | Database engine. Options: 'POSTGRES_15', 'MYSQL_8_0'. Controls the db-init image and DB_ENGINE env var. |
db_name | 11 | 'vaultwarden' | Database name. Do not change after initial deployment. |
db_user | 11 | 'vaultwarden' | Database user. Password auto-generated and stored in Secret Manager. |
database_password_length | 11 | 32 | Auto-generated password length. |
enable_auto_password_rotation | 11 | false | Automated zero-downtime password rotation. |
rotation_propagation_delay_sec | 11 | 90 | Seconds to wait after rotation before restarting. |
C. Storage (GCS)
GCS data bucket: Vaultwarden Common automatically provisions a vaultwarden-data GCS bucket.
| Variable | Group | Default | Description |
|---|---|---|---|
create_cloud_storage | 10 | true | Set false to skip GCS bucket creation. |
storage_buckets | 10 | [{ name_suffix = "data" }] | Additional GCS buckets. |
gcs_volumes | 10 | [] | GCS buckets to mount via GCS Fuse. |
enable_nfs | 10 | false | NFS storage. Disabled by default. |
D. Networking
| Variable | Group | Default | Description |
|---|---|---|---|
ingress_settings | 4 | 'all' | 'all', 'internal', or 'internal-and-cloud-load-balancing'. |
vpc_egress_setting | 4 | 'PRIVATE_RANGES_ONLY' | VPC egress routing. |
E. Application-Specific Configuration
Vaultwarden exposes application settings as top-level variables injected into environment variables by the wrapper module (vaultwarden.tf):
| Variable | Group | Default | Description |
|---|---|---|---|
domain | 3 | "" | Vaultwarden's public domain (e.g., https://vault.example.com). Required for WebAuthn, U2F, and correct email links. Injected as DOMAIN only when non-empty. |
signups_allowed | 3 | false | Allow new user registrations. Set true only for initial admin setup; disable afterwards. Injected as SIGNUPS_ALLOWED. |
web_vault_enabled | 3 | true | Enable the Vaultwarden web UI. Set false to restrict to API-only access. Injected as WEB_VAULT_ENABLED. |
Additional SMTP and logging settings are passed via environment_variables:
| Default env var | Value | Description |
|---|---|---|
LOG_LEVEL | warn | Log verbosity. Options: trace, debug, info, warn, error. |
SHOW_PASSWORD_HINT | false | Disable password hints for security. |
SMTP_HOST | "" | SMTP server hostname. |
SMTP_PORT | 587 | SMTP server port. |
SMTP_FROM | vaultwarden@example.com | Sender address for email notifications. |
SMTP_SSL | true | Enable SMTP TLS. |
| Variable | Group | Default | Description |
|---|---|---|---|
environment_variables | 5 | {} | Additional plain-text env vars merged with injected Vaultwarden defaults. |
secret_environment_variables | 5 | {} | Secret Manager references. |
F. Initialization & Bootstrap
| Variable | Group | Default | Description |
|---|---|---|---|
initialization_jobs | 12 | [] | One-shot Cloud Run Jobs. Leave empty for Vaultwarden Common to supply the default db-init job. |
cron_jobs | 12 | [] | Recurring scheduled jobs. |
4. Advanced Security
A. Cloud Armor WAF
Recommended for Vaultwarden. Protects the /api/accounts/prelogin and /api/accounts/login endpoints from brute-force attacks.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cloud_armor | 9 | false | Provisions Global HTTPS LB + Cloud Armor WAF. Recommended for production. |
admin_ip_ranges | 9 | [] | CIDR ranges exempted from WAF rules. |
B. Identity-Aware Proxy (IAP)
| Variable | Group | Default | Description |
|---|---|---|---|
enable_iap | 4 | false | Enables IAP on the Cloud Run service. Restricts access to Google-authenticated users. |
iap_authorized_users | 4 | [] | Users/service accounts granted access. |
iap_authorized_groups | 4 | [] | Google Groups granted access. |
Note: Enabling IAP on Vaultwarden requires that all Bitwarden clients authenticate through IAP, which may not be supported. IAP is more appropriate for admin-only access scenarios.
C. CDN Warning
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cdn | 9 | false | Enables Cloud CDN. Do NOT cache authenticated API responses. Ensure Cache-Control: no-store headers are configured before enabling. |
D. Backup Retention
Vaultwarden stores password vault data — backups are critical.
| Variable | Group | Default | Description |
|---|---|---|---|
backup_schedule | 6 | '0 2 * * *' | Cron expression for automated backups. |
backup_retention_days | 6 | 30 | Days to retain backup files. Default is 30 days (higher than other modules) to accommodate vault recovery scenarios. |
5. Traffic & Ingress
A. HTTPS Load Balancer
When enable_cloud_armor = true, a Global HTTPS Load Balancer is provisioned. For Vaultwarden, this is highly recommended as it enables a static IP, custom domain SSL termination, and WAF protection.
B. Custom Domains
| Variable | Group | Default | Description |
|---|---|---|---|
application_domains | 9 | [] | Custom domain names. When setting a custom domain, also set domain to the full https:// URL for correct WebAuthn and email link behaviour. |
6. CI/CD & Delivery
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cicd_trigger | 7 | false | Provisions a Cloud Build GitHub trigger. |
github_repository_url | 7 | "" | Full HTTPS URL of the GitHub repository. |
github_token | 7 | "" | GitHub PAT. Sensitive. |
enable_cloud_deploy | 7 | false | Provisions a Cloud Deploy pipeline. |
enable_binary_authorization | 7 | false | Enforces image attestation. |
7. Reliability & Scheduling
A. Health Probes
Vaultwarden exposes /alive as its dedicated health endpoint — it returns OK when the server is running.
| Variable | Group | Default | Description |
|---|---|---|---|
startup_probe | 13 | { enabled=true, type="HTTP", path="/alive", initial_delay_seconds=30, timeout_seconds=5, period_seconds=10, failure_threshold=6 } | Startup probe. |
liveness_probe | 13 | { enabled=true, type="HTTP", path="/alive", initial_delay_seconds=30, timeout_seconds=5, period_seconds=30, failure_threshold=3 } | Liveness probe. |
uptime_check_config | 13 | { enabled=true, path="/alive" } | Cloud Monitoring uptime check. |
8. Integrations
A. Redis Cache
Vaultwarden does not use Redis natively. enable_redis = false by default and is not required.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_redis | 20 | false | Not used by Vaultwarden. Disabled by default. |
B. SMTP Email
Vaultwarden uses SMTP for account verification, 2FA codes, and emergency access notifications. Configure via environment_variables:
environment_variables = {
SMTP_HOST = "smtp.example.com"
SMTP_PORT = "587"
SMTP_FROM = "vault@example.com"
SMTP_FROM_NAME = "Vaultwarden"
SMTP_SSL = "true"
SMTP_EXPLICIT_TLS = "false"
SMTP_USERNAME = "smtp-user@example.com"
}
secret_environment_variables = {
SMTP_PASSWORD = "vaultwarden-smtp-password"
}
9. Platform-Managed Behaviours
| Behaviour | Implementation | Detail |
|---|---|---|
| MySQL and PostgreSQL supported | database_type exposed as user variable | Default is POSTGRES_15; set MYSQL_8_0 for MySQL. Vaultwarden Common selects the appropriate db-init image. |
DATA_FOLDER=/data | Injected by vaultwarden.tf | Vaultwarden stores its data under /data. Hardcoded by the wrapper. |
ROCKET_PORT | Injected by vaultwarden.tf from container_port | Ensures Vaultwarden listens on the configured port. |
SIGNUPS_ALLOWED | Injected by vaultwarden.tf from var.signups_allowed | Default false. Set true for initial admin registration; disable afterwards. |
WEB_VAULT_ENABLED | Injected by vaultwarden.tf from var.web_vault_enabled | Default true. Set false for API-only. |
DOMAIN injection | Injected only when var.domain != "" | Omitted if domain is empty to avoid incorrect URL configuration. |
| 30-day backup retention | backup_retention_days = 30 | Longer retention than other modules due to vault recovery requirements. |
| No auto-generated app secrets | Vaultwarden Common creates no secrets | Vaultwarden manages its own internal token signing. |
| Unix socket by default | enable_cloudsql_volume = true | Connects to Cloud SQL via the Auth Proxy Unix socket. |
10. Variable Reference
| Variable | Group | Default | Description |
|---|---|---|---|
module_description | 0 | (Vaultwarden platform text) | Platform metadata. |
module_documentation | 0 | (docs URL) | Platform metadata. |
module_dependency | 0 | ['Services GCP'] | Required modules. |
credit_cost | 0 | 50 | Deployment credit cost. |
enable_purge | 0 | true | Permits full deletion on destroy. |
public_access | 0 | true | Platform catalogue visibility. |
project_id | 1 | — | GCP project ID. Required. |
tenant_deployment_id | 1 | 'demo' | Resource name suffix. |
support_users | 1 | [] | Monitoring alert email addresses. |
resource_labels | 1 | {} | Labels applied to all resources. |
application_name | 2 | 'vaultwarden' | Base resource name. |
display_name | 2 | 'Vaultwarden' | Human-readable name. |
description | 2 | 'Vaultwarden password manager' | Service description. |
application_version | 2 | '1.32.7' | Vaultwarden image tag. |
deploy_application | 3 | true | Infrastructure-only when false. |
container_image_source | 3 | 'custom' | 'custom' or 'prebuilt'. |
container_image | 3 | "" | Image URI override. |
cpu_limit | 3 | '1000m' | CPU per instance. Minimum 1000m enforced. |
memory_limit | 3 | '512Mi' | Memory per instance. |
container_port | 3 | 80 | Vaultwarden's HTTP port. |
domain | 3 | "" | Public domain for WebAuthn and email links. |
signups_allowed | 3 | false | Allow new user registrations. |
web_vault_enabled | 3 | true | Enable the Vaultwarden web UI. |
execution_environment | 3 | 'gen2' | Gen2 execution environment. |
timeout_seconds | 3 | 300 | Max request duration. |
enable_cloudsql_volume | 3 | true | Cloud SQL Auth Proxy sidecar. |
min_instance_count | 3 | 1 | Minimum instances. |
max_instance_count | 3 | 3 | Maximum instances. |
enable_image_mirroring | 3 | false | Image mirroring to Artifact Registry. |
ingress_settings | 4 | 'all' | Traffic source restrictions. |
vpc_egress_setting | 4 | 'PRIVATE_RANGES_ONLY' | VPC egress routing. |
enable_iap | 4 | false | Identity-Aware Proxy. |
iap_authorized_users | 4 | [] | IAP access list. |
iap_authorized_groups | 4 | [] | IAP group access. |
environment_variables | 5 | {} | Additional env vars. |
secret_environment_variables | 5 | {} | Secret Manager references. |
secret_propagation_delay | 5 | 30 | Seconds after secret creation. |
backup_schedule | 6 | '0 2 * * *' | Backup cron schedule. |
backup_retention_days | 6 | 30 | Backup retention (30 days default). |
enable_backup_import | 6 | false | One-time restore on apply. |
backup_source | 6 | 'gcs' | Backup source: 'gcs' or 'gdrive'. |
backup_uri | 6 | "" | GCS URI or Drive file ID. |
enable_cicd_trigger | 7 | false | Cloud Build GitHub trigger. |
github_repository_url | 7 | "" | GitHub repository URL. |
github_token | 7 | "" | GitHub PAT. Sensitive. |
enable_cloud_deploy | 7 | false | Cloud Deploy pipeline. |
enable_binary_authorization | 7 | false | Image attestation enforcement. |
enable_cloud_armor | 9 | false | Cloud Armor WAF. Recommended for production. |
admin_ip_ranges | 9 | [] | WAF-exempt CIDR ranges. |
application_domains | 9 | [] | Custom domains with SSL certificates. |
enable_cdn | 9 | false | Cloud CDN. Use with caution — do not cache auth responses. |
storage_buckets | 10 | [{ name_suffix = "data" }] | Additional GCS buckets. |
enable_nfs | 10 | false | NFS storage. |
gcs_volumes | 10 | [] | GCS Fuse volume mounts. |
database_type | 11 | 'POSTGRES_15' | 'POSTGRES_15' or 'MYSQL_8_0'. |
db_name | 11 | 'vaultwarden' | Database name. |
db_user | 11 | 'vaultwarden' | Database user. |
database_password_length | 11 | 32 | Auto-generated password length. |
enable_auto_password_rotation | 11 | false | Automated password rotation. |
rotation_propagation_delay_sec | 11 | 90 | Rotation restart delay. |
initialization_jobs | 12 | [] | Custom init jobs. |
cron_jobs | 12 | [] | Recurring scheduled jobs. |
startup_probe | 13 | { path="/alive", initial_delay_seconds=30, ... } | Startup probe. |
liveness_probe | 13 | { path="/alive", initial_delay_seconds=30, ... } | Liveness probe. |
uptime_check_config | 13 | { enabled=true, path="/alive" } | Uptime check. |
enable_redis | 20 | false | Redis. Not used by Vaultwarden. |
enable_vpc_sc | 22 | false | VPC Service Controls. |
enable_audit_logging | 22 | false | Cloud Audit Logs. |
Configuration Pitfalls & Sensible Defaults
Risk levels: Critical (data loss, full outage, security breach) — High (service unavailable or significant degradation) — Medium (degraded function or increased cost) — Low (minor impact).
| Variable | Sensible Default | Risk | Consequence of Incorrect Value |
|---|---|---|---|
domain | "" (empty — not injected) | High | Must be the full public URL of the Vaultwarden instance (e.g., https://vault.example.com). Without it, TOTP/2FA QR codes link to localhost, organisation invitation emails contain broken links, and attachment download URLs are invalid. Set this before any user enables 2FA. |
signups_allowed | false | Critical | The module defaults to false (registrations closed). If set to true before initial setup completes, any internet user can create an account on the vault. Lock down registrations immediately after the first admin account is created. |
admin_token (via environment_variables) | Not set (admin panel disabled) | High | When ADMIN_TOKEN is absent, the Vaultwarden admin panel at /admin is completely disabled. This is the intended secure default. If admin panel access is required, pass ADMIN_TOKEN via environment_variables using a strong Argon2 hash or a long random string — never a weak password. |
database_type | POSTGRES_15 | High | Vaultwarden supports PostgreSQL and SQLite. Changing the database type after deploy (e.g., from PostgreSQL to SQLite) abandons all existing vault data in the old database. Never change this after the first deploy. |
db_name | vaultwarden | High | Changing after first deploy causes Vaultwarden to connect to an empty database on the next restart, presenting an empty vault to all users. All credentials appear lost until the name is restored. |
min_instance_count | 1 | High | Setting to 0 enables scale-to-zero. A password manager with scale-to-zero means the vault is unavailable for 5–15 seconds after the first request following a cold start. Bitwarden clients will show connection errors until the instance is ready. |
cpu_limit | 1000m | High | Cloud Run gen2 with always-allocated CPU requires at least 1000m. Values below 1000m cause Cloud Run to reject the service definition at deploy time. Vaultwarden itself is lightweight (Rust) and 1000m is sufficient for most workloads. |
container_port | 80 | High | Must match ROCKET_PORT. A mismatch means Cloud Run's health check and load balancer route traffic to the wrong port — the service starts but all requests return connection refused or timeout. |
enable_cloudsql_volume | true | Critical | Required when database_type is not NONE. Vaultwarden connects to Cloud SQL via the Auth Proxy Unix socket. Disabling this causes all database connections to fail at startup. |
web_vault_enabled | true | Medium | Setting to false disables the Vaultwarden web UI. Users can still access the vault via native Bitwarden clients, but browser-based access is blocked. Intended for deployments where only native clients are used. |
execution_environment | "gen2" | High | Gen2 is required for NFS mounts and improved networking. Gen1 does not support Unix socket paths used by the Cloud SQL Auth Proxy in the expected location, causing database connection failures. |
enable_redis | false | Low | Redis is not required for Vaultwarden single-instance deployments. Enabling Redis without a valid redis_host causes the container to fail to start if Redis connectivity is checked at startup. |
smtp_* variables (via environment_variables) | Not set | High | SMTP for Vaultwarden is configured as a group via environment variables (SMTP_HOST, SMTP_PORT, SMTP_FROM, SMTP_USERNAME, SMTP_PASSWORD, SMTP_SECURITY). Setting some but not all SMTP variables causes silent email delivery failures — Vaultwarden will not error, but invitation emails, 2FA recovery emails, and password reset emails will not be sent. Configure all SMTP variables together or none at all. |
enable_cloud_armor | false | Medium | Enabling Cloud Armor requires application_domains to be set. Without a custom domain, the load balancer has no backend to attach the policy to, and the apply fails with a resource dependency error. |
application_domains | [] | Medium | Required when enable_cloud_armor = true or enable_iap = true. An empty list with either feature enabled causes plan-time resource reference errors. |
enable_iap | false | Medium | When IAP is enabled, iap_oauth_client_id and iap_oauth_client_secret must both be provided. Partial configuration leaves the service either fully blocked or fully unprotected depending on which value is missing. |
backup_schedule | "0 2 * * *" | Medium | An empty string disables automated backups. A password manager without backups means a Cloud SQL failure or accidental deletion results in permanent credential loss for all users. |
enable_auto_password_rotation | false | Medium | When enabled, the database password is rotated on a schedule. The Cloud Run revision must be redeployed after rotation to pick up the new Secret Manager version; otherwise Vaultwarden continues using the old (now invalid) password until connections fail. |
timeout_seconds | 300 | Low | Valid range is 0–3600. A very low value (e.g., 30) causes large vault sync operations to time out mid-request, corrupting partial sync state on the client. |
max_revisions_to_retain | platform default | Low | Cloud Run retains old revisions for rollback. Too many retained revisions increase artifact storage costs. Too few (e.g., 1) prevents any rollback if a new revision is faulty. |
11. Outputs
| Output | Description |
|---|---|
service_name | Name of the Cloud Run service. |
service_url | Public URL of the Cloud Run service. |
service_location | GCP region. |
project_id | GCP project ID. |
deployment_id | Deployment ID suffix. |
database_instance_name | Name of the Cloud SQL instance. |
database_name | Application database name. |
database_user | Application database user. |
database_password_secret | Secret Manager secret name for the database password. |
storage_buckets | Created GCS storage buckets. |
container_image | Container image used. |
cicd_enabled | Whether the CI/CD pipeline is enabled. |