1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# Load balancer ===============================================================
resource "aws_lb" "this" {
name = local.lb_name
load_balancer_type = var.load_balancer_type
internal = var.internal
subnets = var.subnet_ids
security_groups = length(var.security_group_ids) > 0 ? var.security_group_ids : null
enable_deletion_protection = var.deletion_protection
idle_timeout = local.is_alb ? var.idle_timeout : null
enable_cross_zone_load_balancing = local.is_nlb ? var.cross_zone_load_balancing : null
dynamic "access_logs" {
for_each = var.access_logs_bucket != null ? [true] : []
content {
bucket = var.access_logs_bucket
prefix = var.access_logs_prefix
enabled = true
}
}
tags = merge(var.tags, local.module_tags, {
Name = local.lb_name
resource-type = "load-balancer"
})
lifecycle {
postcondition {
condition = self.arn != ""
error_message = "Load balancer ${self.name} did not receive an ARN after apply."
}
postcondition {
condition = self.dns_name != ""
error_message = "Load balancer ${self.name} has no DNS name — check subnet and az coverage."
}
}
}
# WAF association --------------------------------------------------------------
# WAFv2 web ACLs only support ALB, API Gateway, and AppSync as targets.
resource "aws_wafv2_web_acl_association" "this" {
for_each = var.waf_web_acl_arn != null && local.is_alb ? { waf = true } : {}
resource_arn = aws_lb.this.arn
web_acl_arn = var.waf_web_acl_arn
}
# Target groups ================================================================
resource "aws_lb_target_group" "this" {
for_each = var.target_groups
name = local.target_group_names[each.key]
port = each.value.port
protocol = each.value.protocol
target_type = each.value.target_type
vpc_id = each.value.vpc_id
deregistration_delay = each.value.deregistration_delay
health_check {
enabled = each.value.health_check.enabled
path = each.value.health_check.protocol == "TCP" ? null : each.value.health_check.path
protocol = each.value.health_check.protocol
matcher = each.value.health_check.protocol == "TCP" ? null : each.value.health_check.matcher
interval = each.value.health_check.interval
timeout = each.value.health_check.protocol == "TCP" ? null : each.value.health_check.timeout
healthy_threshold = each.value.health_check.healthy_threshold
unhealthy_threshold = each.value.health_check.unhealthy_threshold
}
dynamic "stickiness" {
for_each = each.value.stickiness != null ? [each.value.stickiness] : []
content {
enabled = stickiness.value.enabled
cookie_duration = stickiness.value.type == "source_ip" ? null : stickiness.value.cookie_duration
type = stickiness.value.type
}
}
tags = merge(var.tags, each.value.tags, local.module_tags, {
Name = local.target_group_names[each.key]
resource-type = "load-balancer-target-group"
})
lifecycle {
postcondition {
condition = self.arn != ""
error_message = "Target group ${self.name} did not receive an ARN after apply."
}
}
}
# Target group attachments ========================================================
resource "aws_lb_target_group_attachment" "this" {
for_each = local.target_attachments
target_group_arn = aws_lb_target_group.this[each.value.target_group_key].arn
target_id = each.value.target_id
port = each.value.port
}
# Listeners ======================================================================
resource "aws_lb_listener" "this" {
for_each = var.listeners
load_balancer_arn = aws_lb.this.arn
port = each.value.port
protocol = each.value.protocol
certificate_arn = each.value.certificate_arn
ssl_policy = each.value.certificate_arn != null ? each.value.ssl_policy : null
dynamic "default_action" {
for_each = each.value.redirect != null ? [] : [true]
content {
type = each.value.default_action_type
target_group_arn = each.value.target_group_key != null ? aws_lb_target_group.this[each.value.target_group_key].arn : null
}
}
dynamic "default_action" {
for_each = each.value.redirect != null ? [each.value.redirect] : []
content {
type = "redirect"
redirect {
port = default_action.value.port
protocol = default_action.value.protocol
status_code = default_action.value.status_code
}
}
}
tags = merge(var.tags, local.module_tags, {
Name = local.listener_keys[each.key]
resource-type = "load-balancer-listener"
})
lifecycle {
postcondition {
condition = self.arn != ""
error_message = "Listener on port ${self.port} did not receive an ARN after apply."
}
}
}
|