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.