diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e173da1..7777f14 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -161,6 +161,7 @@ jobs: TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} + TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} TF_VAR_environment: staging run: terraform plan -out=tfplan @@ -171,6 +172,7 @@ jobs: TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} + TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} TF_VAR_environment: staging run: terraform apply -auto-approve tfplan @@ -280,6 +282,7 @@ jobs: TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} + TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} TF_VAR_environment: prod run: terraform plan -out=tfplan @@ -290,6 +293,7 @@ jobs: TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} + TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} TF_VAR_environment: prod run: terraform apply -auto-approve tfplan diff --git a/terraform/acm.tf b/terraform/acm.tf new file mode 100644 index 0000000..69a6d78 --- /dev/null +++ b/terraform/acm.tf @@ -0,0 +1,12 @@ +# SimpleNotes - ACM Certificate for Custom Domain +# +# NOTE: The ACM certificate should be created separately (once) in us-east-1 +# and the ARN passed via the acm_certificate_arn variable. +# +# To create a certificate manually: +# 1. Go to AWS ACM Console in us-east-1 (N. Virginia) +# 2. Request a public certificate for your domain (e.g., notes.heybub.app) +# 3. Complete DNS validation by adding the CNAME record +# 4. Copy the certificate ARN and add it to GitHub secrets as ACM_CERTIFICATE_ARN +# +# For wildcard certs (*.heybub.app), you can reuse the same cert across apps. diff --git a/terraform/cloudfront.tf b/terraform/cloudfront.tf index 9d90eea..cd5c14d 100644 --- a/terraform/cloudfront.tf +++ b/terraform/cloudfront.tf @@ -24,6 +24,9 @@ resource "aws_cloudfront_distribution" "frontend" { comment = "${local.prefix} frontend distribution" price_class = "PriceClass_100" # North America & Europe only (cheapest) + # Custom domain alias (if set) + aliases = var.domain_name != "" ? [var.domain_name] : [] + # Origin configuration - S3 bucket origin { domain_name = aws_s3_bucket.frontend.bucket_regional_domain_name @@ -113,9 +116,12 @@ resource "aws_cloudfront_distribution" "frontend" { } } - # SSL Certificate - use CloudFront default certificate + # SSL Certificate - use ACM certificate if provided, otherwise CloudFront default viewer_certificate { - cloudfront_default_certificate = true + cloudfront_default_certificate = var.acm_certificate_arn == "" ? true : false + acm_certificate_arn = var.acm_certificate_arn != "" ? var.acm_certificate_arn : null + ssl_support_method = var.acm_certificate_arn != "" ? "sni-only" : null + minimum_protocol_version = var.acm_certificate_arn != "" ? "TLSv1.2_2021" : null } tags = { diff --git a/terraform/outputs.tf b/terraform/outputs.tf index 74812c4..ffd244c 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -50,3 +50,27 @@ output "aws_region" { description = "AWS region" value = var.aws_region } + +output "custom_domain" { + description = "Custom domain name (if configured)" + value = var.domain_name != "" ? var.domain_name : null +} + +output "cloudfront_domain" { + description = "CloudFront distribution domain (for DNS CNAME)" + value = aws_cloudfront_distribution.frontend.domain_name +} + +output "custom_domain_setup" { + description = "Instructions for custom domain setup" + value = var.domain_name != "" && var.acm_certificate_arn == "" ? <<-EOT + ⚠️ Custom domain set but no ACM certificate provided! + + To enable HTTPS on ${var.domain_name}: + 1. Create ACM certificate in us-east-1 for ${var.domain_name} + 2. Add certificate ARN to GitHub secrets as ACM_CERTIFICATE_ARN + 3. Re-deploy + + DNS: Point ${var.domain_name} CNAME to ${aws_cloudfront_distribution.frontend.domain_name} + EOT : null +} diff --git a/terraform/variables.tf b/terraform/variables.tf index 310d9f8..911a87c 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -32,7 +32,13 @@ variable "supabase_jwt_secret" { } variable "domain_name" { - description = "Custom domain name (optional)" + description = "Custom domain name (optional, e.g., notes.heybub.app)" + type = string + default = "" +} + +variable "acm_certificate_arn" { + description = "ACM certificate ARN in us-east-1 for the custom domain (required if domain_name is set)" type = string default = "" }