Finalize self hosted with self certificate, resolve webhook issues.

This commit is contained in:
Patrick Fic
2026-04-20 09:49:48 -07:00
parent 969dd8be8d
commit cc48448a07
12 changed files with 236 additions and 44 deletions

View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID9zCCAt+gAwIBAgIUTB4OhIqfXvT0mBKHwYAwDPq79ygwDQYJKoZIhvcNAQEL
BQAwgYoxCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJCQzESMBAGA1UEBwwJVmFuY291
dmVyMRowGAYDVQQKDBFJbUVYIFN5c3RlbXMgSW5jLjEXMBUGA1UEAwwOaW1leHN5
c3RlbXMuY2ExJTAjBgkqhkiG9w0BCQEWFmNvbnRhY3RAaW1leHN5c3RlbXMuY2Ew
HhcNMjYwNDEzMjAxMDIzWhcNMzYwNDEwMjAxMDIzWjCBijELMAkGA1UEBhMCQ0Ex
CzAJBgNVBAgMAkJDMRIwEAYDVQQHDAlWYW5jb3V2ZXIxGjAYBgNVBAoMEUltRVgg
U3lzdGVtcyBJbmMuMRcwFQYDVQQDDA5pbWV4c3lzdGVtcy5jYTElMCMGCSqGSIb3
DQEJARYWY29udGFjdEBpbWV4c3lzdGVtcy5jYTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAPE+5bcnfYsMyLzJr50bzpHHP8I+cdSkvu7lwGysPZCCxi4Z
vkIDq4Q5xDa3ZZCeNZ9feELqm9ZjWpnaZj4CMbXMDpIucZHQJC9USCGavYhzNYu2
G3IU7D834jd8GkwGMQuXkGiuQmQssIZIKfX+MaZ0KKrh8gJbxXZOfCp3fdYOnFPq
BFCR0N/gTbeRboq36dG4vo1FanDLGroMS7FycGjyUTQv3CTWkGAOAPGQVrGZgvYM
DtFr+7M2J/KCbUMobK0uc1scAjLgetXknzVPU3qA66F3Hi7oWykoFX8m9oX/OJnK
/Gt8rIjRMOyQSK7dKT7qXCxgQVQnqHbyUCX4WUkCAwEAAaNTMFEwHQYDVR0OBBYE
FIRKLjeI+adC7yNg6cSDj72Kej11MB8GA1UdIwQYMBaAFIRKLjeI+adC7yNg6cSD
j72Kej11MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAHCSjlG
bo5miEfisKffPyfzufBIhOLLORasuFQ3gVKBU32JytuoflABfcqy3prgZxbFLMB2
fDcSImKuOtt79OMeMlA+ptfkWuOpFMqL2j6BilzjJ/MAlPAZlZmmuLh/fPj3lbMD
QQds/YhSmZcTdRX8seQslnYq1AT7629BDbpCjjL3pRkntnePR7u8tgb28Pm8Vl3S
uCnGS/mMxrS/7z+QnaDi1N/nyIwa2bQtGmsoMn+CzuUUjyMD4TYbdUJv+fca8/tR
zezNEHcpBCKGGgZRowhifJwEoel0M1iEo8UYy5eFPDF8CoRGRIH7QSaduCfnej06
KLtevL/vyhUpTMA=
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -9,7 +9,7 @@ This Terraform stack deploys Documenso to AWS in `ca-central-1` using:
- Route53 DNS for `esignature.imex.online`
- Optional SES domain identity and DKIM management for outbound email
- Secrets Manager for generated application secrets, SMTP credentials, and the optional Documenso signing certificate
- AWS WAF with a basic managed rule set and rate limiting
- AWS WAF with a basic managed rule set, rate limiting, and an allowlist for trusted IPv4 CIDRs
- CloudWatch alarms for ALB, ECS, and RDS health indicators
## Why this shape
@@ -47,9 +47,10 @@ This is the most practical fit for your Docker Compose workload if you want a ba
2. If you want Documenso signing enabled, add `signing_certificate_base64` and `signing_certificate_passphrase`.
3. Optionally set `upload_bucket_name` if you want a specific S3 bucket name.
4. Set `manage_ses_resources = true` only if you want this stack to own SES identity verification and DKIM records.
5. Run `terraform init`.
6. Run `terraform plan`.
7. Run `terraform apply`.
5. Set `waf_bypass_ipv4_cidrs` with any public `/32` addresses that should bypass WAF inspection. The VPC CIDR is already allowlisted automatically.
6. Run `terraform init`.
7. Run `terraform plan`.
8. Run `terraform apply`.
## Recommended first production adjustments

View File

@@ -26,6 +26,10 @@ locals {
smtp_host = "email-smtp.${var.aws_region}.amazonaws.com"
s3_bucket_name = coalesce(var.upload_bucket_name, "${local.name_prefix}-${data.aws_caller_identity.current.account_id}-${var.aws_region}")
app_secret_name = coalesce(var.app_secret_name, "${local.name_prefix}/${replace(var.domain_name, ".", "-")}/app")
waf_bypass_ipv4_cidrs = distinct(concat(
[var.vpc_cidr],
var.waf_bypass_ipv4_cidrs
))
common_tags = merge(var.tags, {
Application = var.project_name
ManagedBy = "Terraform"
@@ -44,6 +48,7 @@ locals {
NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS = var.allowed_signup_domains
NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID = aws_iam_access_key.documenso_upload.id
NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY = aws_iam_access_key.documenso_upload.secret
NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY = var.documenso_license_key
},
trimspace(var.signing_certificate_base64) != "" ? {
NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS = var.signing_certificate_base64
@@ -66,7 +71,8 @@ locals {
"NEXT_PRIVATE_SMTP_FROM_ADDRESS",
"NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS",
"NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID",
"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY"
"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY",
"NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY"
] : {
name = secret_name
valueFrom = "${aws_secretsmanager_secret.app.arn}:${secret_name}::"
@@ -634,6 +640,16 @@ resource "aws_lb_listener" "https" {
depends_on = [aws_acm_certificate_validation.this]
}
resource "aws_wafv2_ip_set" "trusted_ipv4" {
name = "${local.name_prefix}-trusted-ipv4"
description = "IPv4 CIDRs that bypass the Documenso WAF rules"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = local.waf_bypass_ipv4_cidrs
tags = local.common_tags
}
resource "aws_wafv2_web_acl" "this" {
name = "${local.name_prefix}-web-acl"
description = "WAF protection for Documenso"
@@ -643,6 +659,27 @@ resource "aws_wafv2_web_acl" "this" {
allow {}
}
rule {
name = "AllowTrustedIpv4"
priority = 0
action {
allow {}
}
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.trusted_ipv4.arn
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AllowTrustedIpv4"
sampled_requests_enabled = true
}
}
rule {
name = "AWSManagedRulesCommonRuleSet"
priority = 1
@@ -1004,4 +1041,4 @@ resource "aws_cloudwatch_metric_alarm" "rds_free_storage_low" {
}
tags = local.common_tags
}
}

File diff suppressed because one or more lines are too long

View File

@@ -229,7 +229,7 @@ variable "smtp_password" {
variable "smtp_from_name" {
description = "Display name used in outbound email."
type = string
default = "ImEX E-Signature"
default = "ImEX Sign"
}
variable "smtp_from_address" {
@@ -269,6 +269,12 @@ variable "waf_rate_limit" {
default = 2000
}
variable "waf_bypass_ipv4_cidrs" {
description = "Additional IPv4 CIDR blocks that bypass the WAF. The VPC CIDR is always included automatically."
type = list(string)
default = []
}
variable "alarm_actions" {
description = "Optional list of SNS topic ARNs or other alarm actions to invoke when CloudWatch alarms fire."
type = list(string)
@@ -303,4 +309,10 @@ variable "rds_free_storage_alarm_threshold_bytes" {
description = "Alarm threshold for low RDS free storage, in bytes."
type = number
default = 5368709120
}
variable "documenso_license_key" {
description = "Documenso license key. Not required for the free community edition, but required for enterprise features and support."
type = string
default = ""
}