From ce088a3663cd141eed72c50c3f5c87c0db33295b Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Thu, 28 May 2026 17:07:41 +0200 Subject: [PATCH] sec(iac): enable CloudFront OAC + AWS_IAM for all envs (#575) Flip enable_cdn = true in all three env tfvars (dev, staging, prod). The compute.tf local already derives lambda_function_url_auth_type = "AWS_IAM" when enable_cdn = true, and frontend.tf sets enable_oac = true for the Lambda compute path, so a single flag flip activates: - aws_cloudfront_origin_access_control.lambda (sigv4, always-sign) - aws_lambda_function_url.main auth_type NONE -> AWS_IAM - aws_lambda_permission.function_url_cloudfront scoped to the distribution ARN Dev: remove raw Lambda Function URL from lambda_allowed_origins (now behind CloudFront); add post-apply note to set the CF domain. Staging/prod: keep .invalid placeholders (envs not provisioned yet); replace TODO with explicit pre-apply checklist. terraform validate: Success. terraform fmt -check: clean (all envs). terraform plan (dev only): 7 to add, 3 to change, 4 to destroy (the 4 destroys are docker_build/cleanup terraform_data replaces triggered by the placeholder image URI, unrelated to OAC). Closes #575 --- terraform/environments/aws/github-dev.tfvars | 10 ++++++---- terraform/environments/aws/github-prod.tfvars | 13 ++++++++----- terraform/environments/aws/github-staging.tfvars | 11 +++++++---- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/terraform/environments/aws/github-dev.tfvars b/terraform/environments/aws/github-dev.tfvars index bef905013..cab8c7d74 100644 --- a/terraform/environments/aws/github-dev.tfvars +++ b/terraform/environments/aws/github-dev.tfvars @@ -25,11 +25,13 @@ lambda_log_retention_days = 7 # Function URL auth_type is derived from enable_cdn (local in compute.tf): # enable_cdn = false -> NONE (direct browser hits, app-layer auth) # enable_cdn = true -> AWS_IAM (CloudFront OAC signs every request) -# Current deployed dev origin (Lambda Function URL) + local Webpack dev server. +# After applying with enable_cdn = true, replace this list with: +# - the CloudFront domain from `terraform output cloudfront_domain_name` +# (e.g. "https://d1234abcd.cloudfront.net"), or the custom domain name +# set in TF_VAR_frontend_domain_names if one is configured. +# - keep http://localhost:3000 for local dev server. # Wildcard is rejected by the module (allow_credentials=true + * = any-origin CSRF). -# Update the Lambda Function URL entry when the dev environment is redeployed. lambda_allowed_origins = [ - "https://33pz7pombdqwu3bdlxp4lqxyra0bsriy.lambda-url.us-east-1.on.aws", "http://localhost:3000", ] @@ -71,7 +73,7 @@ secret_recovery_window_days = 7 # Frontend / CDN # ============================================== -enable_cdn = false +enable_cdn = true frontend_price_class = "PriceClass_100" create_subdomain_zone = false diff --git a/terraform/environments/aws/github-prod.tfvars b/terraform/environments/aws/github-prod.tfvars index 99470778c..c4d17deb8 100644 --- a/terraform/environments/aws/github-prod.tfvars +++ b/terraform/environments/aws/github-prod.tfvars @@ -25,10 +25,13 @@ lambda_log_retention_days = 30 # Function URL auth_type is derived from enable_cdn (local in compute.tf): # enable_cdn = false -> NONE (direct browser hits, app-layer auth) # enable_cdn = true -> AWS_IAM (CloudFront OAC signs every request) -# TODO(env-not-deployed): prod environment is not yet provisioned. Update this -# to the actual prod origin (e.g. the customer-facing dashboard domain) when -# the env exists. .invalid placeholder ensures any accidental apply fails fast -# on hostname resolution. +# Prod is not yet provisioned. Before the first terraform apply: +# 1. Replace the .invalid placeholder with the actual prod CloudFront domain +# (from `terraform output cloudfront_domain_name` after apply), or the +# customer-facing custom domain set in TF_VAR_frontend_domain_names. +# 2. Set TF_VAR_frontend_domain_names to the customer-facing domain (e.g. +# "app.cudly.io") so the CloudFront distribution aliases are correct. +# The .invalid TLD ensures any accidental apply fails fast on hostname resolution. lambda_allowed_origins = ["https://prod-not-yet-deployed.invalid"] # Fargate Configuration (when compute_platform = "fargate") @@ -70,7 +73,7 @@ secret_recovery_window_days = 30 # Frontend / CDN # ============================================== -enable_cdn = false +enable_cdn = true frontend_price_class = "PriceClass_200" create_subdomain_zone = false diff --git a/terraform/environments/aws/github-staging.tfvars b/terraform/environments/aws/github-staging.tfvars index 7e38b86d7..aed18425a 100644 --- a/terraform/environments/aws/github-staging.tfvars +++ b/terraform/environments/aws/github-staging.tfvars @@ -25,9 +25,12 @@ lambda_log_retention_days = 14 # Function URL auth_type is derived from enable_cdn (local in compute.tf): # enable_cdn = false -> NONE (direct browser hits, app-layer auth) # enable_cdn = true -> AWS_IAM (CloudFront OAC signs every request) -# TODO(env-not-deployed): staging environment is not yet provisioned. Update this -# to the actual staging origin when the env exists. Until then the .invalid TLD -# ensures any accidental terraform apply fails fast on hostname resolution. +# Staging is not yet provisioned. Before the first terraform apply: +# 1. Replace the .invalid placeholder with the actual staging CloudFront +# domain (from `terraform output cloudfront_domain_name` after apply), +# or the custom domain set in TF_VAR_frontend_domain_names. +# 2. Keep http://localhost:3000 for local dev server access. +# The .invalid TLD ensures any accidental apply fails fast on hostname resolution. lambda_allowed_origins = ["https://staging-not-yet-deployed.invalid"] # Fargate Configuration (when compute_platform = "fargate") @@ -69,7 +72,7 @@ secret_recovery_window_days = 14 # Frontend / CDN # ============================================== -enable_cdn = false +enable_cdn = true frontend_price_class = "PriceClass_100" create_subdomain_zone = false