Skip to content

Commit 3e03217

Browse files
Add CORS support (#45)
* Add CORS support * Replace naked domain logic * Fix security header * Make change backwards compatible * Make new argument optional * Use A record with alias for CF * Fix default logic * Fix target record name * Add back missing fix * Add path option to reverse proxy * Attempt to fix path * Use regex extraction instead
1 parent cc15dfd commit 3e03217

File tree

3 files changed

+83
-19
lines changed

3 files changed

+83
-19
lines changed

aws-cf-reverse-proxy/main.tf

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,19 @@ resource "random_string" "id" {
66
}
77

88
locals {
9+
10+
origin_domain = try(regex("^https?://([^/]+)", var.origin_url)[0], null)
11+
origin_path = try(regex("^https?://[^/]+(/.*)", var.origin_url)[0], null)
12+
913
random_id = var.random_identifier == "" ? random_string.id[0].result : var.random_identifier
14+
15+
app_route53_zone_name = var.app_route53_zone_name != "" ? var.app_route53_zone_name : var.app_naked_domain
16+
17+
target_record_name = (
18+
var.app_target_domain == local.app_route53_zone_name
19+
? ""
20+
: replace(var.app_target_domain, ".${local.app_route53_zone_name}", "")
21+
)
1022
}
1123

1224
module "luthername_site" {
@@ -22,7 +34,7 @@ module "luthername_site" {
2234
}
2335

2436
data "aws_route53_zone" "site" {
25-
name = "${var.app_naked_domain}."
37+
name = "${local.app_route53_zone_name}."
2638
private_zone = false
2739
}
2840

@@ -59,14 +71,14 @@ resource "aws_acm_certificate_validation" "site" {
5971

6072
resource "aws_route53_record" "site" {
6173
zone_id = data.aws_route53_zone.site.zone_id
62-
name = var.app_target_domain
63-
type = "CNAME"
64-
ttl = "300"
65-
records = [aws_cloudfront_distribution.site.domain_name]
66-
}
74+
name = local.target_record_name
75+
type = "A"
6776

68-
locals {
69-
origin_domain = replace(var.origin_url, "/(https?://)|(/)/", "")
77+
alias {
78+
name = aws_cloudfront_distribution.site.domain_name
79+
zone_id = aws_cloudfront_distribution.site.hosted_zone_id
80+
evaluate_target_health = false
81+
}
7082
}
7183

7284
resource "aws_cloudfront_distribution" "site" {
@@ -78,6 +90,8 @@ resource "aws_cloudfront_distribution" "site" {
7890
origin_id = "origin-site"
7991
domain_name = local.origin_domain
8092

93+
origin_path = local.origin_path
94+
8195
custom_origin_config {
8296
origin_protocol_policy = "https-only"
8397
http_port = "80"
@@ -111,6 +125,8 @@ resource "aws_cloudfront_distribution" "site" {
111125
viewer_protocol_policy = "redirect-to-https"
112126
compress = true
113127

128+
response_headers_policy_id = length(var.cors_allowed_origins) > 0 ? aws_cloudfront_response_headers_policy.allow_specified_origins[0].id : null
129+
114130
dynamic "lambda_function_association" {
115131
for_each = var.use_302 ? [1] : []
116132

@@ -139,3 +155,33 @@ resource "aws_cloudfront_distribution" "site" {
139155

140156
tags = module.luthername_site.tags
141157
}
158+
159+
resource "aws_cloudfront_response_headers_policy" "allow_specified_origins" {
160+
count = length(var.cors_allowed_origins) > 0 ? 1 : 0
161+
162+
name = "allow-specified-cors-origins"
163+
164+
cors_config {
165+
access_control_allow_credentials = false
166+
167+
access_control_allow_headers {
168+
items = ["*"]
169+
}
170+
171+
access_control_allow_methods {
172+
items = ["GET", "HEAD", "OPTIONS"]
173+
}
174+
175+
access_control_allow_origins {
176+
items = var.cors_allowed_origins
177+
}
178+
179+
origin_override = true
180+
}
181+
182+
security_headers_config {
183+
content_type_options {
184+
override = true
185+
}
186+
}
187+
}

aws-cf-reverse-proxy/tests/test1/test.tf

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ provider "aws" {
1414
}
1515

1616
module "test" {
17-
source = "../../"
18-
luther_env = "env"
19-
luther_project = "project"
20-
app_naked_domain = "example.com"
21-
app_target_domain = "target.example.com"
22-
origin_url = "origin.example.com"
23-
use_302 = true
17+
source = "../../"
18+
luther_env = "env"
19+
luther_project = "project"
20+
21+
app_target_domain = "target.example.com"
22+
app_route53_zone_name = "app.luthersystems.com"
23+
24+
origin_url = "origin.example.com"
25+
use_302 = true
26+
27+
cors_allowed_origins = ["https://app.luthersystems.com"]
2428

2529
providers = {
2630
aws = aws

aws-cf-reverse-proxy/vars.tf

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ variable "luther_env" {
1212
type = string
1313
}
1414

15-
variable "app_naked_domain" {
16-
type = string
17-
}
18-
1915
variable "app_target_domain" {
2016
type = string
2117
}
@@ -38,3 +34,21 @@ variable "random_identifier" {
3834
type = string
3935
default = ""
4036
}
37+
38+
variable "cors_allowed_origins" {
39+
type = list(string)
40+
description = "List of allowed origins for CORS"
41+
default = []
42+
}
43+
44+
variable "app_route53_zone_name" {
45+
type = string
46+
description = "The exact Route53 zone name (e.g., app.luthersystems.com) to use for DNS validation and record creation"
47+
default = ""
48+
}
49+
50+
variable "app_naked_domain" {
51+
type = string
52+
description = "Renamed to `app_route53_zone`"
53+
default = ""
54+
}

0 commit comments

Comments
 (0)