AWS Application and Network Load Balancer (ALB & NLB) Terraform module
Terraform module which creates Application and Network Load Balancer resources on AWS.
Usage
Application Load Balancer
HTTP and HTTPS listeners with default actions:
module "alb" {
source = "terraform-aws-modules/alb/aws"
version = "~> 8.0"
name = "my-alb"
load_balancer_type = "application"
vpc_id = "vpc-abcde012"
subnets = ["subnet-abcde012", "subnet-bcde012a"]
security_groups = ["sg-edcd9784", "sg-edcd9785"]
access_logs = {
bucket = "my-alb-logs"
}
target_groups = [
{
name_prefix = "pref-"
backend_protocol = "HTTP"
backend_port = 80
target_type = "instance"
targets = {
my_target = {
target_id = "i-0123456789abcdefg"
port = 80
}
my_other_target = {
target_id = "i-a1b2c3d4e5f6g7h8i"
port = 8080
}
}
}
]
https_listeners = [
{
port = 443
protocol = "HTTPS"
certificate_arn = "arn:aws:iam::123456789012:server-certificate/test_cert-123456789012"
target_group_index = 0
}
]
http_tcp_listeners = [
{
port = 80
protocol = "HTTP"
target_group_index = 0
}
]
tags = {
Environment = "Test"
}
}
HTTP to HTTPS redirect and HTTPS cognito authentication:
module "alb" {
source = "terraform-aws-modules/alb/aws"
version = "~> 8.0"
name = "my-alb"
load_balancer_type = "application"
vpc_id = "vpc-abcde012"
subnets = ["subnet-abcde012", "subnet-bcde012a"]
security_groups = ["sg-edcd9784", "sg-edcd9785"]
access_logs = {
bucket = "my-alb-logs"
}
target_groups = [
{
name_prefix = "pref-"
backend_protocol = "HTTPS"
backend_port = 443
target_type = "instance"
}
]
https_listeners = [
{
port = 443
protocol = "HTTPS"
certificate_arn = "arn:aws:iam::123456789012:server-certificate/test_cert-123456789012"
action_type = "authenticate-cognito"
target_group_index = 0
authenticate_cognito = {
user_pool_arn = "arn:aws:cognito-idp::123456789012:userpool/test-pool"
user_pool_client_id = "6oRmFiS0JHk="
user_pool_domain = "test-domain-com"
}
}
]
http_tcp_listeners = [
{
port = 80
protocol = "HTTP"
action_type = "redirect"
redirect = {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
]
tags = {
Environment = "Test"
}
}
Cognito Authentication only on certain routes, with redirects for other routes:
module "alb" {
source = "terraform-aws-modules/alb/aws"
version = "~> 8.0"
name = "my-alb"
load_balancer_type = "application"
vpc_id = "vpc-abcde012"
subnets = ["subnet-abcde012", "subnet-bcde012a"]
security_groups = ["sg-edcd9784", "sg-edcd9785"]
access_logs = {
bucket = "my-alb-logs"
}
target_groups = [
{
name_prefix = "default"
backend_protocol = "HTTPS"
backend_port = 443
target_type = "instance"
}
]
https_listeners = [
{
port = 443
certificate_arn = "arn:aws:iam::123456789012:server-certificate/test_cert-123456789012"
}
]
https_listener_rules = [
{
https_listener_index = 0
priority = 5000
actions = [{
type = "redirect"
status_code = "HTTP_302"
host = "www.youtube.com"
path = "/watch"
query = "v=dQw4w9WgXcQ"
protocol = "HTTPS"
}]
conditions = [{
path_patterns = ["/onboarding", "/docs"]
}]
},
{
https_listener_index = 0
priority = 2
actions = [
{
type = "authenticate-cognito"
user_pool_arn = "arn:aws:cognito-idp::123456789012:userpool/test-pool"
user_pool_client_id = "6oRmFiS0JHk="
user_pool_domain = "test-domain-com"
},
{
type = "forward"
target_group_index = 0
}
]
conditions = [{
path_patterns = ["/protected-route", "private/*"]
}]
}
]
}
When you're using ALB Listener rules, make sure that every rule's actions
block ends in a forward
, redirect
, or fixed-response
action so that every rule will resolve to some sort of an HTTP response. Checkout the AWS documentation for more information.
Network Load Balancer (TCP_UDP, UDP, TCP and TLS listeners)
module "nlb" {
source = "terraform-aws-modules/alb/aws"
version = "~> 8.0"
name = "my-nlb"
load_balancer_type = "network"
vpc_id = "vpc-abcde012"
subnets = ["subnet-abcde012", "subnet-bcde012a"]
access_logs = {
bucket = "my-nlb-logs"
}
target_groups = [
{
name_prefix = "pref-"
backend_protocol = "TCP"
backend_port = 80
target_type = "ip"
}
]
https_listeners = [
{
port = 443
protocol = "TLS"
certificate_arn = "arn:aws:iam::123456789012:server-certificate/test_cert-123456789012"
target_group_index = 0
}
]
http_tcp_listeners = [
{
port = 80
protocol = "TCP"
target_group_index = 0
}
]
tags = {
Environment = "Test"
}
}
Assumptions
It's recommended you use this module with terraform-aws-vpc, terraform-aws-security-group, and terraform-aws-autoscaling.
Notes
- Terraform AWS provider version v2.39.0 and newer has issue #16674 related to "Provider produced inconsistent final plan". It means that S3 bucket has to be created before referencing it as an argument inside
access_logs = { bucket = "my-already-created-bucket-for-logs" }
, so this won't work:access_logs = { bucket = module.log_bucket.s3_bucket_id }
.
Conditional creation
Sometimes you need to have a way to create ALB resources conditionally but Terraform does not allow to use count
inside module
block, so the solution is to specify argument create_lb
.
# This LB will not be created
module "lb" {
source = "terraform-aws-modules/alb/aws"
create_lb = false
# ... omitted
}
Examples
Requirements
Name | Version |
---|---|
terraform | >= 1.0 |
aws | >= 4.59 |
Providers
Name | Version |
---|---|
aws | >= 4.59 |
Modules
No modules.
Resources
Name | Type |
---|---|
aws_lambda_permission.lb | resource |
aws_lb.this | resource |
aws_lb_listener.frontend_http_tcp | resource |
aws_lb_listener.frontend_https | resource |
aws_lb_listener_certificate.https_listener | resource |
aws_lb_listener_rule.http_tcp_listener_rule | resource |
aws_lb_listener_rule.https_listener_rule | resource |
aws_lb_target_group.main | resource |
aws_lb_target_group_attachment.this | resource |
aws_security_group.this | resource |
aws_security_group_rule.this | resource |
aws_wafv2_web_acl_association.this | resource |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
access_logs | Map containing access logging configuration for load balancer. | map(string) |
{} |
no |
create_lb | Controls if the Load Balancer should be created | bool |
true |
no |
create_security_group | Determines if a security group is created | bool |
true |
no |
desync_mitigation_mode | Determines how the load balancer handles requests that might pose a security risk to an application due to HTTP desync. | string |
"defensive" |
no |
drop_invalid_header_fields | Indicates whether invalid header fields are dropped in application load balancers. Defaults to false. | bool |
false |
no |
enable_cross_zone_load_balancing | Indicates whether cross zone load balancing should be enabled in application load balancers. | bool |
false |
no |
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 |
enable_http2 | Indicates whether HTTP/2 is enabled in application load balancers. | bool |
true |
no |
enable_tls_version_and_cipher_suite_headers | Indicates whether the two headers (x-amzn-tls-version and x-amzn-tls-cipher-suite), which contain information about the negotiated TLS version and cipher suite, are added to the client request before sending it to the target. | bool |
false |
no |
enable_waf_fail_open | Indicates whether to route requests to targets if lb fails to forward the request to AWS WAF | bool |
false |
no |
enable_xff_client_port | Indicates whether the X-Forwarded-For header should preserve the source port that the client used to connect to the load balancer in application load balancers. | bool |
true |
no |
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 |
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 |
http_tcp_listener_rules_tags | A map of tags to add to all http listener rules | map(string) |
{} |
no |
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 |
http_tcp_listeners_tags | A map of tags to add to all http listeners | map(string) |
{} |
no |
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 |
https_listener_rules_tags | A map of tags to add to all https listener rules | map(string) |
{} |
no |
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 |
https_listeners_tags | A map of tags to add to all https listeners | map(string) |
{} |
no |
idle_timeout | The time in seconds that the connection is allowed to be idle. | number |
60 |
no |
internal | Boolean determining if the load balancer is internal or externally facing. | bool |
false |
no |
ip_address_type | The type of IP addresses used by the subnets for your load balancer. The possible values are ipv4 and dualstack. | string |
"ipv4" |
no |
lb_tags | A map of tags to add to load balancer | map(string) |
{} |
no |
listener_ssl_policy_default | The security policy if using HTTPS externally on the load balancer. See. | string |
"ELBSecurityPolicy-2016-08" |
no |
load_balancer_create_timeout | Timeout value when creating the ALB. | string |
"10m" |
no |
load_balancer_delete_timeout | Timeout value when deleting the ALB. | string |
"10m" |
no |
load_balancer_type | The type of load balancer to create. Possible values are application or network. | string |
"application" |
no |
load_balancer_update_timeout | Timeout value when updating the ALB. | string |
"10m" |
no |
name | The resource name and Name tag of the load balancer. | string |
null |
no |
name_prefix | The resource name prefix and Name tag of the load balancer. Cannot be longer than 6 characters | string |
null |
no |
preserve_host_header | Indicates whether Host header should be preserve and forward to targets without any change. Defaults to false. | bool |
false |
no |
putin_khuylo | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | bool |
true |
no |
security_group_description | Description of the security group created | string |
null |
no |
security_group_name | Name to use on security group created | string |
null |
no |
security_group_rules | Security group rules to add to the security group created | any |
{} |
no |
security_group_tags | A map of additional tags to add to the security group created | map(string) |
{} |
no |
security_group_use_name_prefix | Determines whether the security group name (security_group_name ) is used as a prefix |
bool |
true |
no |
security_groups | The security groups to attach to the load balancer. e.g. ["sg-edcd9784","sg-edcd9785"] | list(string) |
[] |
no |
subnet_mapping | A list of subnet mapping blocks describing subnets to attach to network load balancer | list(map(string)) |
[] |
no |
subnets | A list of subnets to associate with the load balancer. e.g. ['subnet-1a2b3c4d','subnet-1a2b3c4e','subnet-1a2b3c4f'] | list(string) |
null |
no |
tags | A map of tags to add to all resources | map(string) |
{} |
no |
target_group_tags | A map of tags to add to all target groups | map(string) |
{} |
no |
target_groups | A list of maps containing key/value pairs that define the target groups to be created. Order of these maps is important and the index of these are to be referenced in listener definitions. Required key/values: name, backend_protocol, backend_port | any |
[] |
no |
vpc_id | VPC id where the load balancer and other resources will be deployed. | string |
null |
no |
web_acl_arn | WAF ARN to associate this LB with. | string |
null |
no |
xff_header_processing_mode | Determines how the load balancer modifies the X-Forwarded-For header in the HTTP request before sending the request to the target. | string |
"append" |
no |
Outputs
Name | Description |
---|---|
http_tcp_listener_arns | The ARN of the TCP and HTTP load balancer listeners created |
http_tcp_listener_ids | The IDs of the TCP and HTTP load balancer listeners created |
https_listener_arns | The ARNs of the HTTPS load balancer listeners created |
https_listener_ids | The IDs of the load balancer listeners created |
lb_arn | The ID and ARN of the load balancer we created |
lb_arn_suffix | ARN suffix of our load balancer - can be used with CloudWatch |
lb_dns_name | The DNS name of the load balancer |
lb_id | The ID and ARN of the load balancer we created |
lb_zone_id | The zone_id of the load balancer to assist with creating DNS records |
security_group_arn | Amazon Resource Name (ARN) of the security group |
security_group_id | ID of the security group |
target_group_arn_suffixes | ARN suffixes of our target groups - can be used with CloudWatch |
target_group_arns | ARNs of the target groups. Useful for passing to your Auto Scaling group |
target_group_attachments | ARNs of the target group attachment IDs |
target_group_names | Name of the target group. Useful for passing to your CodeDeploy Deployment Group |
Authors
Module is maintained by Anton Babenko with help from these awesome contributors.
License
Apache 2 Licensed. See LICENSE for full details.
Additional information for users from Russia and Belarus
- Russia has illegally annexed Crimea in 2014 and brought the war in Donbas followed by full-scale invasion of Ukraine in 2022.
- Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee.
- Putin khuylo!