Skip to content

Commit e3ce757

Browse files
authored
feat: Add listener rules support for http/tcp listeners (#216)
1 parent c8c17a5 commit e3ce757

File tree

4 files changed

+222
-2
lines changed

4 files changed

+222
-2
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ No modules.
313313
| [aws_lb_listener.frontend_http_tcp](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource |
314314
| [aws_lb_listener.frontend_https](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource |
315315
| [aws_lb_listener_certificate.https_listener](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_certificate) | resource |
316+
| [aws_lb_listener_rule.http_tcp_listener_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule) | resource |
316317
| [aws_lb_listener_rule.https_listener_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule) | resource |
317318
| [aws_lb_target_group.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource |
318319
| [aws_lb_target_group_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group_attachment) | resource |
@@ -328,8 +329,10 @@ No modules.
328329
| <a name="input_enable_deletion_protection"></a> [enable\_deletion\_protection](#input\_enable\_deletion\_protection) | If true, deletion of the load balancer will be disabled via the AWS API. This will prevent Terraform from deleting the load balancer. Defaults to false. | `bool` | `false` | no |
329330
| <a name="input_enable_http2"></a> [enable\_http2](#input\_enable\_http2) | Indicates whether HTTP/2 is enabled in application load balancers. | `bool` | `true` | no |
330331
| <a name="input_extra_ssl_certs"></a> [extra\_ssl\_certs](#input\_extra\_ssl\_certs) | A list of maps describing any extra SSL certificates to apply to the HTTPS listeners. Required key/values: certificate\_arn, https\_listener\_index (the index of the listener within https\_listeners which the cert applies toward). | `list(map(string))` | `[]` | no |
332+
| <a name="input_http_tcp_listener_rules"></a> [http\_tcp\_listener\_rules](#input\_http\_tcp\_listener\_rules) | A list of maps describing the Listener Rules for this ALB. Required key/values: actions, conditions. Optional key/values: priority, http\_tcp\_listener\_index (default to http\_tcp\_listeners[count.index]) | `any` | `[]` | no |
333+
| <a name="input_http_tcp_listener_rules_tags"></a> [http\_tcp\_listener\_rules\_tags](#input\_http\_tcp\_listener\_rules\_tags) | A map of tags to add to all http listener rules | `map(string)` | `{}` | no |
331334
| <a name="input_http_tcp_listeners"></a> [http\_tcp\_listeners](#input\_http\_tcp\_listeners) | A list of maps describing the HTTP listeners or TCP ports for this ALB. Required key/values: port, protocol. Optional key/values: target\_group\_index (defaults to http\_tcp\_listeners[count.index]) | `any` | `[]` | no |
332-
| <a name="input_http_tcp_listeners_tags"></a> [http\_tcp\_listeners\_tags](#input\_http\_tcp\_listeners\_tags) | A map of tags to add to all tcp listeners | `map(string)` | `{}` | no |
335+
| <a name="input_http_tcp_listeners_tags"></a> [http\_tcp\_listeners\_tags](#input\_http\_tcp\_listeners\_tags) | A map of tags to add to all http listeners | `map(string)` | `{}` | no |
333336
| <a name="input_https_listener_rules"></a> [https\_listener\_rules](#input\_https\_listener\_rules) | A list of maps describing the Listener Rules for this ALB. Required key/values: actions, conditions. Optional key/values: priority, https\_listener\_index (default to https\_listeners[count.index]) | `any` | `[]` | no |
334337
| <a name="input_https_listener_rules_tags"></a> [https\_listener\_rules\_tags](#input\_https\_listener\_rules\_tags) | A map of tags to add to all https listener rules | `map(string)` | `{}` | no |
335338
| <a name="input_https_listeners"></a> [https\_listeners](#input\_https\_listeners) | A list of maps describing the HTTPS listeners for this ALB. Required key/values: port, certificate\_arn. Optional key/values: ssl\_policy (defaults to ELBSecurityPolicy-2016-08), target\_group\_index (defaults to https\_listeners[count.index]) | `any` | `[]` | no |

examples/complete-alb/main.tf

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,45 @@ module "alb" {
267267
},
268268
]
269269

270+
http_tcp_listener_rules = [
271+
{
272+
http_tcp_listener_index = 0
273+
priority = 3
274+
actions = [{
275+
type = "fixed-response"
276+
content_type = "text/plain"
277+
status_code = 200
278+
message_body = "This is a fixed response"
279+
}]
280+
281+
conditions = [{
282+
http_headers = [{
283+
http_header_name = "x-Gimme-Fixed-Response"
284+
values = ["yes", "please", "right now"]
285+
}]
286+
}]
287+
},
288+
{
289+
http_tcp_listener_index = 0
290+
priority = 5000
291+
actions = [{
292+
type = "redirect"
293+
status_code = "HTTP_302"
294+
host = "www.youtube.com"
295+
path = "/watch"
296+
query = "v=dQw4w9WgXcQ"
297+
protocol = "HTTPS"
298+
}]
299+
300+
conditions = [{
301+
query_strings = [{
302+
key = "video"
303+
value = "random"
304+
}]
305+
}]
306+
},
307+
]
308+
270309
target_groups = [
271310
{
272311
name_prefix = "h1"

main.tf

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,172 @@ resource "aws_lb_listener_rule" "https_listener_rule" {
356356
)
357357
}
358358

359+
resource "aws_lb_listener_rule" "http_tcp_listener_rule" {
360+
count = var.create_lb ? length(var.http_tcp_listener_rules) : 0
361+
362+
listener_arn = aws_lb_listener.frontend_http_tcp[lookup(var.http_tcp_listener_rules[count.index], "http_tcp_listener_index", count.index)].arn
363+
priority = lookup(var.http_tcp_listener_rules[count.index], "priority", null)
364+
365+
# redirect actions
366+
dynamic "action" {
367+
for_each = [
368+
for action_rule in var.http_tcp_listener_rules[count.index].actions :
369+
action_rule
370+
if action_rule.type == "redirect"
371+
]
372+
373+
content {
374+
type = action.value["type"]
375+
redirect {
376+
host = lookup(action.value, "host", null)
377+
path = lookup(action.value, "path", null)
378+
port = lookup(action.value, "port", null)
379+
protocol = lookup(action.value, "protocol", null)
380+
query = lookup(action.value, "query", null)
381+
status_code = action.value["status_code"]
382+
}
383+
}
384+
}
385+
386+
# fixed-response actions
387+
dynamic "action" {
388+
for_each = [
389+
for action_rule in var.http_tcp_listener_rules[count.index].actions :
390+
action_rule
391+
if action_rule.type == "fixed-response"
392+
]
393+
394+
content {
395+
type = action.value["type"]
396+
fixed_response {
397+
message_body = lookup(action.value, "message_body", null)
398+
status_code = lookup(action.value, "status_code", null)
399+
content_type = action.value["content_type"]
400+
}
401+
}
402+
}
403+
404+
# forward actions
405+
dynamic "action" {
406+
for_each = [
407+
for action_rule in var.http_tcp_listener_rules[count.index].actions :
408+
action_rule
409+
if action_rule.type == "forward"
410+
]
411+
412+
content {
413+
type = action.value["type"]
414+
target_group_arn = aws_lb_target_group.main[lookup(action.value, "target_group_index", count.index)].id
415+
}
416+
}
417+
418+
# Path Pattern condition
419+
dynamic "condition" {
420+
for_each = [
421+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
422+
condition_rule
423+
if length(lookup(condition_rule, "path_patterns", [])) > 0
424+
]
425+
426+
content {
427+
path_pattern {
428+
values = condition.value["path_patterns"]
429+
}
430+
}
431+
}
432+
433+
# Host header condition
434+
dynamic "condition" {
435+
for_each = [
436+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
437+
condition_rule
438+
if length(lookup(condition_rule, "host_headers", [])) > 0
439+
]
440+
441+
content {
442+
host_header {
443+
values = condition.value["host_headers"]
444+
}
445+
}
446+
}
447+
448+
# Http header condition
449+
dynamic "condition" {
450+
for_each = [
451+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
452+
condition_rule
453+
if length(lookup(condition_rule, "http_headers", [])) > 0
454+
]
455+
456+
content {
457+
dynamic "http_header" {
458+
for_each = condition.value["http_headers"]
459+
460+
content {
461+
http_header_name = http_header.value["http_header_name"]
462+
values = http_header.value["values"]
463+
}
464+
}
465+
}
466+
}
467+
468+
# Http request method condition
469+
dynamic "condition" {
470+
for_each = [
471+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
472+
condition_rule
473+
if length(lookup(condition_rule, "http_request_methods", [])) > 0
474+
]
475+
476+
content {
477+
http_request_method {
478+
values = condition.value["http_request_methods"]
479+
}
480+
}
481+
}
482+
483+
# Query string condition
484+
dynamic "condition" {
485+
for_each = [
486+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
487+
condition_rule
488+
if length(lookup(condition_rule, "query_strings", [])) > 0
489+
]
490+
491+
content {
492+
dynamic "query_string" {
493+
for_each = condition.value["query_strings"]
494+
495+
content {
496+
key = lookup(query_string.value, "key", null)
497+
value = query_string.value["value"]
498+
}
499+
}
500+
}
501+
}
502+
503+
# Source IP address condition
504+
dynamic "condition" {
505+
for_each = [
506+
for condition_rule in var.http_tcp_listener_rules[count.index].conditions :
507+
condition_rule
508+
if length(lookup(condition_rule, "source_ips", [])) > 0
509+
]
510+
511+
content {
512+
source_ip {
513+
values = condition.value["source_ips"]
514+
}
515+
}
516+
}
517+
518+
tags = merge(
519+
var.tags,
520+
var.http_tcp_listener_rules_tags,
521+
lookup(var.http_tcp_listener_rules[count.index], "tags", {}),
522+
)
523+
}
524+
359525
resource "aws_lb_listener" "frontend_http_tcp" {
360526
count = var.create_lb ? length(var.http_tcp_listeners) : 0
361527

variables.tf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ variable "https_listener_rules" {
5252
default = []
5353
}
5454

55+
variable "http_tcp_listener_rules" {
56+
description = "A list of maps describing the Listener Rules for this ALB. Required key/values: actions, conditions. Optional key/values: priority, http_tcp_listener_index (default to http_tcp_listeners[count.index])"
57+
type = any
58+
default = []
59+
}
60+
5561
variable "idle_timeout" {
5662
description = "The time in seconds that the connection is allowed to be idle."
5763
type = number
@@ -154,14 +160,20 @@ variable "https_listener_rules_tags" {
154160
default = {}
155161
}
156162

163+
variable "http_tcp_listener_rules_tags" {
164+
description = "A map of tags to add to all http listener rules"
165+
type = map(string)
166+
default = {}
167+
}
168+
157169
variable "https_listeners_tags" {
158170
description = "A map of tags to add to all https listeners"
159171
type = map(string)
160172
default = {}
161173
}
162174

163175
variable "http_tcp_listeners_tags" {
164-
description = "A map of tags to add to all tcp listeners"
176+
description = "A map of tags to add to all http listeners"
165177
type = map(string)
166178
default = {}
167179
}

0 commit comments

Comments
 (0)