Skip to content

Commit fcecc6d

Browse files
committed
Added context path support
1 parent b731aa5 commit fcecc6d

File tree

7 files changed

+200
-68
lines changed

7 files changed

+200
-68
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# GraphDB AWS Terraform Module Changelog
22

33
## 3.0.0
4+
* Added context path support. Now you can set a custom context path for GraphDB using the `lb_context_path` variable.
45
* Upgraded terraform provider version to 6.27.0
56
* Fixed AWS Cloudwatch alarm pattern and thresholds
67
* Added support for deploying Regional NAT Gateway

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,23 @@ To switch to ALB, set the following variable:
738738
lb_type = "application"
739739
```
740740

741-
💡 Note: ALBs support idle timeouts of up to [7 days](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/edit-load-balancer-attributes.html#http-client-keep-alive-duration), which is ideal for persistent connections and long-running operations over HTTP/HTTPS.
741+
#### Deploying GraphDB behind context path with Application Load Balancer
742+
743+
If you want GraphDB to be accessible behind a context path (for example `https://example.com/graphdb/`), you can configure a context path on the Application Load Balancer (ALB).
744+
745+
Requirements:
746+
- `lb_type = "application"`
747+
- `lb_context_path` must be non-empty (e.g. `"/graphdb"`)
748+
749+
When both are set, the module will configure ALB listener rules so that:
750+
- Requests to `/<context>` and `/<context>/*` are routed to GraphDB
751+
752+
Example:
753+
754+
```hcl
755+
lb_type = "application"
756+
lb_context_path = "/graphdb"
757+
```
742758

743759
#### Transit Gateway Attachments
744760

main.tf

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -136,26 +136,26 @@ module "load_balancer" {
136136

137137
count = var.existing_lb_arn != "" ? 0 : 1
138138

139-
resource_name_prefix = var.resource_name_prefix
140-
vpc_id = var.vpc_id != "" ? var.vpc_id : module.vpc[0].vpc_id
141-
lb_subnets = local.lb_subnets
142-
lb_internal = var.lb_internal
143-
lb_type = var.lb_type
144-
lb_deregistration_delay = var.lb_deregistration_delay
145-
lb_health_check_path = var.lb_health_check_path
146-
lb_health_check_interval = var.lb_health_check_interval
147-
lb_enable_deletion_protection = var.prevent_resource_deletion
148-
lb_tls_certificate_arn = var.lb_tls_certificate_arn
149-
lb_tls_enabled = local.lb_tls_enabled
150-
lb_tls_policy = var.lb_tls_policy
151-
lb_access_logs_bucket_name = var.lb_enable_access_logs && var.deploy_logging_module ? module.logging[0].graphdb_logging_bucket_name : null
152-
lb_enable_access_logs = var.lb_enable_access_logs
153-
graphdb_node_count = var.graphdb_node_count
154-
allowed_inbound_cidrs_lb = var.allowed_inbound_cidrs_lb
155-
lb_idle_timeout = var.lb_idle_timeout
156-
lb_client_keep_alive_timeout = var.lb_client_keep_alive_timeout
157-
lb_enable_http2 = var.alb_enable_http2
158-
lb_context_path = var.lb_context_path
139+
resource_name_prefix = var.resource_name_prefix
140+
vpc_id = var.vpc_id != "" ? var.vpc_id : module.vpc[0].vpc_id
141+
lb_subnets = local.lb_subnets
142+
lb_internal = var.lb_internal
143+
lb_type = var.lb_type
144+
lb_deregistration_delay = var.lb_deregistration_delay
145+
lb_health_check_path = var.lb_health_check_path
146+
lb_health_check_interval = var.lb_health_check_interval
147+
lb_enable_deletion_protection = var.prevent_resource_deletion
148+
lb_tls_certificate_arn = var.lb_tls_certificate_arn
149+
lb_tls_enabled = local.lb_tls_enabled
150+
lb_tls_policy = var.lb_tls_policy
151+
lb_access_logs_bucket_name = var.lb_enable_access_logs && var.deploy_logging_module ? module.logging[0].graphdb_logging_bucket_name : null
152+
lb_enable_access_logs = var.lb_enable_access_logs
153+
graphdb_node_count = var.graphdb_node_count
154+
allowed_inbound_cidrs_lb = var.allowed_inbound_cidrs_lb
155+
lb_idle_timeout = var.lb_idle_timeout
156+
lb_client_keep_alive_timeout = var.lb_client_keep_alive_timeout
157+
lb_enable_http2 = var.alb_enable_http2
158+
lb_context_path = var.lb_context_path
159159
lb_enable_context_path_rewrite = var.lb_enable_context_path_rewrite
160160
}
161161

modules/graphdb/templates/04_gdb_conf_overrides.sh.tpl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ echo "#######################################"
2222

2323
LB_DNS_RECORD=${graphdb_lb_dns_name}
2424
PROTOCOL=${external_address_protocol}
25+
CONTEXT_PATH="${lb_context_path}"
26+
27+
# Construct the external URL with context path only if provided
28+
if [ -n "$CONTEXT_PATH" ]; then
29+
EXTERNAL_URL="$${PROTOCOL}://$${LB_DNS_RECORD}$${CONTEXT_PATH}"
30+
else
31+
EXTERNAL_URL="$${PROTOCOL}://$${LB_DNS_RECORD}"
32+
fi
33+
2534
# Get and store the GraphDB license
2635
aws --cli-connect-timeout 300 ssm get-parameter --region ${region} --name "/${name}/graphdb/license" --with-decryption | \
2736
jq -r .Parameter.Value | \
@@ -36,7 +45,7 @@ NODE_COUNT=$(aws autoscaling describe-auto-scaling-groups --auto-scaling-group-n
3645
if [ "$NODE_COUNT" -eq 1 ]; then
3746
cat << EOF > /etc/graphdb/graphdb.properties
3847
graphdb.connector.port=7201
39-
graphdb.external-url=$${PROTOCOL}://$${LB_DNS_RECORD}
48+
graphdb.external-url=$${EXTERNAL_URL}
4049
graphdb.external-url.enforce.transactions=true
4150
EOF
4251
else
@@ -46,16 +55,18 @@ else
4655
graphdb.auth.token.secret=$GRAPHDB_CLUSTER_TOKEN
4756
graphdb.connector.port=7201
4857
graphdb.external-url=http://$${NODE_DNS_RECORD}:7201
58+
graphdb.vhosts=$${EXTERNAL_URL},http://$${NODE_DNS_RECORD}:7201
4959
graphdb.rpc.address=$${NODE_DNS_RECORD}:7301
5060
EOF
5161

5262
cat << EOF > /etc/graphdb-cluster-proxy/graphdb.properties
5363
graphdb.auth.token.secret=$GRAPHDB_CLUSTER_TOKEN
5464
graphdb.connector.port=7200
55-
graphdb.external-url=$${PROTOCOL}://$${LB_DNS_RECORD}
56-
graphdb.vhosts=$${PROTOCOL}://$${LB_DNS_RECORD},http://$${NODE_DNS_RECORD}:7200
65+
graphdb.external-url=$${EXTERNAL_URL}
66+
graphdb.vhosts=$${EXTERNAL_URL},http://$${NODE_DNS_RECORD}:7200
5767
graphdb.rpc.address=$${NODE_DNS_RECORD}:7300
5868
graphdb.proxy.hosts=$${NODE_DNS_RECORD}:7301
69+
5970
EOF
6071
fi
6172

modules/load_balancer/alb.tf

Lines changed: 142 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ resource "aws_lb" "graphdb_alb" {
4545

4646
dynamic "access_logs" {
4747
for_each = var.lb_enable_access_logs ? [1] : []
48-
4948
content {
5049
bucket = var.lb_access_logs_bucket_name
5150
enabled = true
@@ -69,6 +68,7 @@ resource "aws_lb_target_group" "graphdb_alb_tg" {
6968
interval = var.lb_health_check_interval
7069
healthy_threshold = var.lb_healthy_threshold
7170
unhealthy_threshold = var.lb_unhealthy_threshold
71+
7272
# Prepend context path only if configured
7373
path = var.lb_context_path != "" ? "${var.lb_context_path}${var.lb_health_check_path}" : (var.graphdb_node_count > 1 ? var.lb_health_check_path : "/protocol")
7474
}
@@ -85,40 +85,44 @@ resource "aws_lb_listener" "graphdb_alb_http" {
8585
port = 80
8686
protocol = "HTTP"
8787

88+
# 1) HTTP -> HTTPS redirect (when TLS enabled)
8889
dynamic "default_action" {
89-
for_each = var.lb_tls_enabled ? ["redirect"] : (var.lb_context_path != "" ? ["fixed-response"] : ["forward"])
90-
90+
for_each = var.lb_tls_enabled ? [1] : []
9191
content {
92-
type = default_action.value == "redirect" ? "redirect" : (default_action.value == "fixed-response" ? "fixed-response" : "forward")
93-
94-
dynamic "redirect" {
95-
for_each = default_action.value == "redirect" ? [1] : []
96-
content {
97-
port = "443"
98-
protocol = "HTTPS"
99-
status_code = "HTTP_301"
100-
host = "#{host}"
101-
path = "/#{path}"
102-
query = "#{query}"
103-
}
92+
type = "redirect"
93+
redirect {
94+
port = "443"
95+
protocol = "HTTPS"
96+
status_code = "HTTP_301"
97+
host = "#{host}"
98+
path = "/#{path}"
99+
query = "#{query}"
104100
}
101+
}
102+
}
105103

106-
dynamic "fixed_response" {
107-
for_each = default_action.value == "fixed-response" ? [1] : []
108-
content {
109-
content_type = "text/plain"
110-
message_body = "Not Found"
111-
status_code = "404"
112-
}
104+
# 2) Fixed 404 (when context path is set and TLS is NOT enabled)
105+
dynamic "default_action" {
106+
for_each = (!var.lb_tls_enabled && var.lb_context_path != "") ? [1] : []
107+
content {
108+
type = "fixed-response"
109+
fixed_response {
110+
content_type = "text/plain"
111+
message_body = "Not Found"
112+
status_code = "404"
113113
}
114+
}
115+
}
114116

115-
dynamic "forward" {
116-
for_each = default_action.value == "forward" ? [1] : []
117-
content {
118-
target_group {
119-
arn = aws_lb_target_group.graphdb_alb_tg[0].arn
120-
weight = 1
121-
}
117+
# 3) Forward (when no TLS and no context path)
118+
dynamic "default_action" {
119+
for_each = (!var.lb_tls_enabled && var.lb_context_path == "") ? [1] : []
120+
content {
121+
type = "forward"
122+
forward {
123+
target_group {
124+
arn = aws_lb_target_group.graphdb_alb_tg[0].arn
125+
weight = 1
122126
}
123127
}
124128
}
@@ -129,22 +133,25 @@ resource "aws_lb_listener" "graphdb_alb_http" {
129133
}
130134
}
131135

136+
# -------------------------
137+
# HTTP (no TLS) context path rule
138+
# -------------------------
132139
resource "aws_lb_listener_rule" "graphdb_path_based_http" {
133140
count = local.is_alb && !var.lb_tls_enabled && var.lb_context_path != "" ? 1 : 0
134141

135142
listener_arn = aws_lb_listener.graphdb_alb_http[0].arn
136143
priority = 100
137144

138-
dynamic "transform" {
139-
for_each = var.lb_enable_context_path_rewrite ? [1] : []
140-
content {
141-
type = "url-rewrite"
145+
transform {
146+
type = "url-rewrite"
142147

143-
url_rewrite {
144-
rewrites = [
145-
{ regex = "^${var.lb_context_path}/(.*)$", replace = "/$1" },
146-
{ regex = "^${var.lb_context_path}$", replace = "/" }
147-
]
148+
url_rewrite_config {
149+
rewrite {
150+
# /graphdb
151+
# /graphdb/
152+
# /graphdb/anything
153+
regex = "^${var.lb_context_path}(/(.*))?$"
154+
replace = "/$2"
148155
}
149156
}
150157
}
@@ -161,6 +168,78 @@ resource "aws_lb_listener_rule" "graphdb_path_based_http" {
161168
}
162169
}
163170

171+
resource "aws_lb_listener_rule" "graphdb_root_redirect_http" {
172+
count = local.is_alb && !var.lb_tls_enabled && var.lb_context_path != "" ? 1 : 0
173+
174+
listener_arn = aws_lb_listener.graphdb_alb_http[0].arn
175+
priority = 10
176+
177+
transform {
178+
type = "url-rewrite"
179+
180+
url_rewrite_config {
181+
rewrite {
182+
regex = "^${var.lb_context_path}(/(.*))?$"
183+
replace = "/$2"
184+
}
185+
}
186+
}
187+
188+
action {
189+
type = "redirect"
190+
redirect {
191+
protocol = "HTTP"
192+
port = "80"
193+
status_code = "HTTP_301"
194+
host = "#{host}"
195+
path = "/${trim(var.lb_context_path, "/")}/"
196+
query = "#{query}"
197+
}
198+
}
199+
200+
condition {
201+
path_pattern {
202+
values = ["/"]
203+
}
204+
}
205+
}
206+
207+
resource "aws_lb_listener_rule" "graphdb_root_redirect_https" {
208+
count = local.is_alb && var.lb_tls_enabled && var.lb_context_path != "" ? 1 : 0
209+
210+
listener_arn = aws_lb_listener.graphdb_alb_https[0].arn
211+
priority = 10
212+
213+
transform {
214+
type = "url-rewrite"
215+
216+
url_rewrite_config {
217+
rewrite {
218+
regex = "^${var.lb_context_path}(/(.*))?$"
219+
replace = "/$2"
220+
}
221+
}
222+
}
223+
224+
action {
225+
type = "redirect"
226+
redirect {
227+
protocol = "HTTPS"
228+
port = "443"
229+
status_code = "HTTP_301"
230+
host = "#{host}"
231+
path = "/${trim(var.lb_context_path, "/")}/"
232+
query = "#{query}"
233+
}
234+
}
235+
236+
condition {
237+
path_pattern {
238+
values = ["/"]
239+
}
240+
}
241+
}
242+
164243
resource "aws_lb_listener" "graphdb_alb_https" {
165244
count = local.is_alb && var.lb_tls_enabled ? 1 : 0
166245

@@ -170,7 +249,8 @@ resource "aws_lb_listener" "graphdb_alb_https" {
170249
certificate_arn = var.lb_tls_certificate_arn
171250
ssl_policy = var.lb_tls_policy
172251

173-
252+
# If context path is set -> default 404 (rules will handle),
253+
# else -> default forward
174254
default_action {
175255
type = var.lb_context_path != "" ? "fixed-response" : "forward"
176256

@@ -183,20 +263,42 @@ resource "aws_lb_listener" "graphdb_alb_https" {
183263
}
184264
}
185265

186-
target_group_arn = var.lb_context_path == "" ? aws_lb_target_group.graphdb_alb_tg[0].arn : null
266+
dynamic "forward" {
267+
for_each = var.lb_context_path == "" ? [1] : []
268+
content {
269+
target_group {
270+
arn = aws_lb_target_group.graphdb_alb_tg[0].arn
271+
weight = 1
272+
}
273+
}
274+
}
187275
}
188276

189277
lifecycle {
190278
create_before_destroy = true
191279
}
192280
}
193281

282+
# -------------------------
283+
# HTTPS context path rule
284+
# -------------------------
194285
resource "aws_lb_listener_rule" "graphdb_path_based_https" {
195286
count = local.is_alb && var.lb_tls_enabled && var.lb_context_path != "" ? 1 : 0
196287

197288
listener_arn = aws_lb_listener.graphdb_alb_https[0].arn
198289
priority = 100
199290

291+
transform {
292+
type = "url-rewrite"
293+
294+
url_rewrite_config {
295+
rewrite {
296+
regex = "^${var.lb_context_path}(/(.*))?$"
297+
replace = "/$2"
298+
}
299+
}
300+
}
301+
200302
action {
201303
type = "forward"
202304
target_group_arn = aws_lb_target_group.graphdb_alb_tg[0].arn

modules/load_balancer/main.tf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ locals {
22
is_alb = var.lb_type == "application"
33
is_nlb = var.lb_type == "network"
44

5-
lb_name = "${var.resource_name_prefix}-${local.lb_flavor}"
6-
lb_flavor = local.is_alb ? "alb" : "nlb"
7-
target_group_name = "${var.resource_name_prefix}-tg-${local.lb_flavor}-${random_id.tg_name_suffix.hex}"
5+
lb_name = "${var.resource_name_prefix}-${local.lb_flavor}"
6+
lb_flavor = local.is_alb ? "alb" : "nlb"
7+
target_group_name = "${var.resource_name_prefix}-tg-${local.lb_flavor}-${random_id.tg_name_suffix.hex}"
88
graphdb_backend_health_path = var.graphdb_node_count > 1 ? var.lb_health_check_path : "/protocol"
9+
lb_context_path_norm = "/${trim(var.lb_context_path, "/")}"
10+
lb_context_path_slash = "/${trim(var.lb_context_path, "/")}/"
911

1012
effective_health_check_path = (var.lb_context_path != "" && var.lb_enable_context_path_rewrite) ? local.graphdb_backend_health_path : (var.lb_context_path != "" ? "${var.lb_context_path}${local.graphdb_backend_health_path}" : local.graphdb_backend_health_path)
1113
}

0 commit comments

Comments
 (0)