This repository provisions the complete Azure footprint for running Vaultwarden (a lightweight Bitwarden-compatible server) on Azure Container Apps. The infrastructure is authored entirely in Bicep and can be deployed at subscription scope.
| File | Purpose |
|---|---|
infra.bicep | Main template that creates the resource group, monitoring stack, identity, storage, PostgreSQL, Key Vault, and Container Apps environment. |
vault.bicep | Deploys the Vaultwarden container app that consumes the infrastructure created by infra.bicep. |
builtin-roles.json | Stores role definition IDs (e.g., Storage Blob Data Contributor, Key Vault Secrets User). |
modules/ | Reusable Bicep modules for each resource (Log Analytics, Container Apps, Key Vault, PostgreSQL, Storage, Managed Identity, etc.). |
- Resource group – Dedicated RG per environment (default
rg-xprtzbv-vault-tst). - Monitoring – Log Analytics workspace and Application Insights for Container Apps telemetry.
- Identity – User-assigned managed identity used by the container app for Key Vault and Storage access.
- Storage – Storage account with an Azure Files share mounted as persistent
/datavolume. - PostgreSQL flexible server – Hosts the Vaultwarden database with generated admin credentials.
- Key Vault – Stores the admin token and PostgreSQL connection string, and grants the managed identity
Key Vault Secrets Useraccess. - Container Apps environment – Provides the runtime environment and connects logs to Log Analytics.
- Container App – Runs the Vaultwarden image, injects secrets from Key Vault, and exposes HTTPS ingress.
- Azure subscription with permission to deploy resource groups, role assignments, and managed identities.
- Azure CLI 2.60+ with Bicep CLI installed (
az bicep install). - Logged in via
az loginand targeting the correct subscription (az account set --subscription <SUB_ID>). - Optional: customize
builtin-roles.jsonif your tenant uses non-standard role definition IDs.
Most defaults are defined inside the Bicep files:
location: Defaults toswedencentralbut can be overridden.environment,app, anddefaultName: Compose resource names such askv-xprtzbv-vault-tst.- PostgreSQL admin login defaults to
vaultadmin; passwords and admin token values are generated at deploy time. modules/container-app-vault.bicepallows overridingimageName,imageTag, andDOMAINvia parameters.
Override parameters by supplying --parameters name=value when running az deployment commands.
Deploy shared infrastructure
az deployment sub create \ --location swedencentral \ --name vault-infra \ --template-file infra.bicep \ --parameters location=<azure-region>
This command creates the resource group and all dependent services. Capture the outputs (e.g., workspace name, storage account) if you plan to reuse them.
Deploy the Vault container app
az deployment sub create \ --location swedencentral \ --name vault-app \ --template-file vault.bicep \ --parameters location=<azure-region>
The deployment outputs
containerAppUrl, which resolves tohttps://<fqdn>.Optional validations
- Run
az deployment sub what-if ...before each deployment to preview changes. - Verify Key Vault secrets (
admin-token,pg-connectionstring) and storage role assignments after deployment.
- Run
| Module | Responsibility |
|---|---|
monitoring.bicep | Creates Log Analytics + Application Insights. |
user-managed-identity.bicep | Provisions a user-assigned managed identity for Container Apps. |
storageaccount.bicep | Builds the storage account, file share, and assigns Blob Data Contributor to the identity. |
postgresql.bicep | Deploys PostgreSQL Flexible Server, database, and firewall rule. |
keyvault.bicep | Creates Key Vault, seeds required secrets, assigns Secrets User role. |
container-app-environment.bicep | Sets up the Container Apps environment and Azure Files integration. |
container-app-vault.bicep | Deploys the Vaultwarden container with ingress, environment variables, and volume mounts. |
- Admin token and PostgreSQL connection string are generated automatically and stored in Key Vault.
- The container app reads secrets using its managed identity; no secrets are stored in source control.
- Persistent data resides in the Azure Files share (
/data). Adjust quota viamodules/storageaccount.bicepif needed. - To rotate secrets, update the Key Vault entries or redeploy the relevant module.
- Scale resources by editing module parameters (e.g., PostgreSQL SKU, Container App CPU/memory).
- Update the container image by overriding
imageTagand redeployingvault.bicep. - Use Log Analytics queries (
log-<defaultName>) to troubleshoot application logs.