-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
342 additions
and
17 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -329,6 +329,30 @@ module "invoicing" { | |
acme_account_key = module.common.acme_account_key | ||
} | ||
|
||
|
||
module "vaultwarden" { | ||
source = "./modules/vaultwarden" | ||
admin_api_key = module.keyvault.secrets["vaultwarden-api-key"] | ||
app_service_plan_id = module.common.tikweb_app_plan_id | ||
app_service_plan_location = local.resource_group_location | ||
app_service_plan_resource_group_name = module.common.resource_group_name | ||
db_password = module.common.postgres_admin_password | ||
db_username = module.common.postgres_admin_username | ||
db_name = "vaultwarden" | ||
db_host = module.common.postgres_server_fqdn | ||
location = local.resource_group_location | ||
smtp_host = "smtp.eu.mailgun.org" | ||
vaultwarden_smtp_from = "[email protected]" | ||
vaultwarden_smtp_username = module.keyvault.secrets["vaultwarden-smtp-username"] | ||
vaultwarden_smtp_password = module.keyvault.secrets["vaultwarden-smtp-password"] | ||
dns_resource_group_name = module.dns_prod.resource_group_name | ||
acme_account_key = module.common.acme_account_key | ||
root_zone_name = module.dns_prod.root_zone_name | ||
subdomain = "vaultwarden" | ||
dkim_selector = "s1" | ||
dkim_key = "k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqMtEsg4MR4gCzUovwmok+T2MsPAKfnWl9UxVHDTXyalQ4dFzgYwHi+nRHjSucAsw5WYy8arDKsJx/jEnOBOpOJECTGg6z75jXO5E9hpKFN8oWtcV/bX1KLIKZ/XlxqEsuAIbTgVUfIvZBOLzyOP0lPKsyfQw5w/0HakJFNQ1E1Zjf+NdXMQ2FSbJB1ohcWU5uMmBQagChc6IR0Lm14+Ot+EL1ZKmVoaQ2LIoNby8/Cb/5f8knUscdkeQU2HDAmHq7V+5ZJtxQZufHnUM0XaRcQw3F7sk9A9vdxa4NKTYsYd+y9AfiEM7KAd3KuPxC2wA1sxvpIq3Y+X1tr40DgyG2wIDAQAB" | ||
|
||
} | ||
# module "m0" { | ||
# source = "./modules/m0" | ||
# resource_group_location = local.resource_group_location | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
locals { | ||
fqdn = "${var.subdomain}.${var.root_zone_name}" | ||
} | ||
|
||
# MX records for Mailman | ||
resource "azurerm_dns_mx_record" "list_mx" { | ||
name = var.subdomain | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
|
||
record { | ||
preference = 20 | ||
exchange = "tietokilta.fi" | ||
} | ||
record { | ||
preference = 21 | ||
exchange = "mail.cs.hut.fi" | ||
} | ||
} | ||
|
||
# SPF record | ||
resource "azurerm_dns_txt_record" "list_spf" { | ||
name = var.subdomain | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
|
||
record { | ||
value = "v=spf1 mx include:mailgun.org ~all" | ||
} | ||
} | ||
|
||
# DKIM key for Mailgun (Mailman doesn't sign emails) | ||
resource "azurerm_dns_txt_record" "list_dkim" { | ||
name = "${var.dkim_selector}._domainkey.${var.subdomain}" | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
|
||
record { | ||
value = var.dkim_key | ||
} | ||
} | ||
|
||
# Reporting-only DMARC policy | ||
resource "azurerm_dns_txt_record" "list_dmarc" { | ||
name = "_dmarc.${var.subdomain}" | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
|
||
record { | ||
value = "v=DMARC1;p=none;sp=none;rua=mailto:[email protected]!10m;ruf=mailto:[email protected]!10m" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
terraform { | ||
required_providers { | ||
acme = { | ||
source = "vancluever/acme" | ||
version = "2.19.0" | ||
} | ||
} | ||
} | ||
resource "azurerm_resource_group" "rg" { | ||
name = "vaultwarden-rg" | ||
location = var.location | ||
} | ||
# Storage Account and File Share | ||
resource "azurerm_storage_account" "storage_account" { | ||
name = "tikvaultwardenstorage" | ||
resource_group_name = azurerm_resource_group.rg.name | ||
location = azurerm_resource_group.rg.location | ||
account_tier = "Standard" | ||
account_replication_type = "GRS" # Zone redundant https://learn.microsoft.com/en-us/azure/storage/common/storage-redundancy | ||
account_kind = "StorageV2" | ||
access_tier = "Hot" | ||
} | ||
|
||
resource "azurerm_storage_share" "file_share" { | ||
name = "vaultwarden-data" | ||
storage_account_name = azurerm_storage_account.storage_account.name | ||
quota = 10 # GB | ||
} | ||
|
||
# App Service (Linux Web App) | ||
resource "azurerm_linux_web_app" "vaultwarden_app" { | ||
name = "tik-vaultwarden-${terraform.workspace}" | ||
location = var.location | ||
resource_group_name = var.app_service_plan_resource_group_name | ||
service_plan_id = var.app_service_plan_id | ||
|
||
site_config { | ||
ftps_state = "Disabled" | ||
always_on = false | ||
|
||
application_stack { | ||
docker_registry_url = "https://docker.io" | ||
docker_image_name = "vaultwarden/server:latest" | ||
} | ||
} | ||
# Mount the Azure File Share | ||
storage_account { | ||
name = "vaultwarden-persistent-storage" | ||
account_name = azurerm_storage_account.storage_account.name | ||
access_key = azurerm_storage_account.storage_account.primary_access_key | ||
mount_path = "/data" | ||
share_name = azurerm_storage_share.file_share.name | ||
type = "AzureFiles" | ||
} | ||
|
||
app_settings = { | ||
WEBSITES_ENABLE_APP_SERVICE_STORAGE = "false" | ||
WEBSITES_PORT = "80" | ||
|
||
# Vaultwarden Environment Variables | ||
ADMIN_TOKEN = var.admin_api_key | ||
DOMAIN = "https://${local.fqdn}" | ||
SIGNUPS_ALLOWED = "false" | ||
|
||
# SMTP configuration | ||
SMTP_SECURITY = "force_tls" | ||
SMTP_HOST = var.smtp_host | ||
SMTP_FROM = var.vaultwarden_smtp_from | ||
SMTP_PORT = 465 | ||
SMTP_USERNAME = var.vaultwarden_smtp_username | ||
SMTP_PASSWORD = var.vaultwarden_smtp_password | ||
# Database configuration | ||
DATABASE_URL = "postgresql://${var.db_username}:${var.db_password}@${var.db_host}:${var.db_port}/${var.db_name}" | ||
} | ||
} | ||
|
||
|
||
# A record for the web app | ||
resource "azurerm_dns_a_record" "vaultwarden_a" { | ||
name = var.subdomain | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
records = data.dns_a_record_set.vaultwarden_dns_fetch.addrs | ||
} | ||
|
||
# Azure verification key | ||
resource "azurerm_dns_txt_record" "vaultwarden_asuid" { | ||
name = "asuid.${var.subdomain}" | ||
resource_group_name = var.dns_resource_group_name | ||
zone_name = var.root_zone_name | ||
ttl = 300 | ||
|
||
record { | ||
value = azurerm_linux_web_app.vaultwarden_app.custom_domain_verification_id | ||
} | ||
} | ||
|
||
|
||
resource "azurerm_app_service_custom_hostname_binding" "vaultwarden_hostname_binding" { | ||
hostname = local.fqdn | ||
app_service_name = azurerm_linux_web_app.vaultwarden_app.name | ||
resource_group_name = var.app_service_plan_resource_group_name | ||
|
||
# Deletion may need manual work. | ||
# https://github.com/hashicorp/terraform-provider-azurerm/issues/11231 | ||
# TODO: Add dependencies for creation | ||
depends_on = [ | ||
azurerm_dns_a_record.vaultwarden_a, | ||
azurerm_dns_txt_record.vaultwarden_asuid | ||
] | ||
} | ||
resource "random_password" "vaultwarden_cert_password" { | ||
length = 48 | ||
special = false | ||
} | ||
|
||
resource "acme_certificate" "vaultwarden_acme_cert" { | ||
account_key_pem = var.acme_account_key | ||
common_name = local.fqdn | ||
key_type = "2048" # RSA | ||
certificate_p12_password = random_password.vaultwarden_cert_password.result | ||
|
||
dns_challenge { | ||
provider = "azure" | ||
config = { | ||
AZURE_RESOURCE_GROUP = var.dns_resource_group_name | ||
AZURE_ZONE_NAME = var.root_zone_name | ||
} | ||
} | ||
} | ||
|
||
resource "azurerm_app_service_certificate" "vaultwarden_cert" { | ||
name = "tik-vaultwarden-cert-${terraform.workspace}" | ||
resource_group_name = var.app_service_plan_resource_group_name | ||
location = var.location | ||
pfx_blob = acme_certificate.vaultwarden_acme_cert.certificate_p12 | ||
password = acme_certificate.vaultwarden_acme_cert.certificate_p12_password | ||
} | ||
|
||
resource "azurerm_app_service_certificate_binding" "vaultwarden_cert_binding" { | ||
certificate_id = azurerm_app_service_certificate.vaultwarden_cert.id | ||
hostname_binding_id = azurerm_app_service_custom_hostname_binding.vaultwarden_hostname_binding.id | ||
ssl_state = "SniEnabled" | ||
} | ||
|
||
# https://github.com/hashicorp/terraform-provider-azurerm/issues/14642#issuecomment-1084728235 | ||
# Currently, the azurerm provider doesn't give us the IP address, so we need to fetch it ourselves. | ||
data "dns_a_record_set" "vaultwarden_dns_fetch" { | ||
host = azurerm_linux_web_app.vaultwarden_app.default_hostname | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
variable "admin_api_key" { | ||
description = "Vaultwarden Admin API key used to access /admin page - minLength is 20" | ||
type = string | ||
sensitive = true | ||
validation { | ||
condition = length(var.admin_api_key) >= 20 | ||
error_message = "Admin API Key must be at least 20 characters." | ||
} | ||
} | ||
variable "subdomain" { | ||
type = string | ||
} | ||
variable "root_zone_name" { | ||
type = string | ||
} | ||
variable "dns_resource_group_name" { | ||
type = string | ||
} | ||
variable "acme_account_key" { | ||
type = string | ||
} | ||
variable "dkim_selector" { | ||
type = string | ||
} | ||
variable "dkim_key" { | ||
type = string | ||
} | ||
variable "db_host" { | ||
description = "Hostname or IP address of the existing PostgreSQL database" | ||
type = string | ||
} | ||
|
||
variable "db_port" { | ||
description = "Port number of the existing PostgreSQL database" | ||
type = number | ||
default = 5432 | ||
} | ||
|
||
variable "db_name" { | ||
description = "Name of the existing PostgreSQL database" | ||
type = string | ||
} | ||
|
||
variable "db_username" { | ||
description = "Username for the existing PostgreSQL database" | ||
type = string | ||
} | ||
|
||
variable "db_password" { | ||
description = "Password for the existing PostgreSQL database" | ||
type = string | ||
sensitive = true | ||
} | ||
|
||
variable "location" { | ||
description = "Azure location" | ||
type = string | ||
} | ||
|
||
variable "app_service_plan_id" { | ||
description = "ID of the existing App Service Plan" | ||
type = string | ||
} | ||
|
||
variable "app_service_plan_resource_group_name" { | ||
description = "Resource group of the existing App Service Plan" | ||
type = string | ||
} | ||
|
||
variable "app_service_plan_location" { | ||
description = "Location of the existing App Service Plan" | ||
type = string | ||
} | ||
|
||
variable "smtp_host" { | ||
type = string | ||
} | ||
variable "vaultwarden_smtp_from" { | ||
type = string | ||
} | ||
|
||
variable "vaultwarden_smtp_username" { | ||
type = string | ||
sensitive = true | ||
} | ||
variable "vaultwarden_smtp_password" { | ||
type = string | ||
sensitive = true | ||
} |