Skip to content

About

Terraform module for creating an Network Load Balancer

Topics

Resources

Security policy

Stars

3 stars

Watchers

20 watching

Forks

Repository files navigation

terraform-aws-nlb

The module code moved from https://github.com/worldcoin/infrastructure/tree/main/modules/clusters/orb/nlb

Example

module "nlb" {
  source = "github.com/worldcoin/terraform-aws-nlb?ref=v0.1.0"

  cluster_name = var.name
  application  = "traefik/traefik"
  internal     = false

  acm_arn        = var.acm_arn
  acm_extra_arns = var.acm_extra_arns
  vpc_id         = var.vpc_config.vpc_id
  public_subnets = var.vpc_config.public_subnets
}

When create_default_tls_listener = false, acm_arn can be omitted:

module "nlb" {
  source = "github.com/worldcoin/terraform-aws-nlb?ref=v1.5.0"

  cluster_name                 = var.name
  application                  = "gateway-api/gateway"
  internal                     = false
  create_default_tls_listener  = false

  vpc_id         = var.vpc_config.vpc_id
  public_subnets = var.vpc_config.public_subnets
}

Dynamic listeners and target groups

Outbound security-group rules

egress_sg_rules configures the NLB's outbound rules. Omit it to retain the existing unrestricted IPv4 default. Set [] to remove all outbound rules. With a non-null default and nullable = false, Terraform uses the default when a caller passes null; null does not disable egress. Do not manage this security group's egress with separate rule resources; the module owns the complete inline rule set.

For restricted egress, allow both target traffic and health checks. For example, when both use TCP port 8080:

egress_sg_rules = [{
  description     = "Allow target traffic and health checks"
  protocol        = "tcp"
  from_port       = 8080
  to_port         = 8080
  security_groups = [aws_security_group.targets.id]
}]

Changing existing rules takes effect at apply; review target and health-check reachability before opting in. This input does not change ingress rules.

Listener configuration

Use target_groups and listeners for workloads managed outside the AWS Load Balancer Controller, such as ECS. Their map keys are stable Terraform identities. Disable the legacy listeners, set tags to avoid controller tags, and scope NLB egress to the task security group.

module "ecs_nlb" {
  source = "git@github.com:worldcoin/terraform-aws-nlb.git?ref=vX.Y.Z"

  name            = "example-ecs"
  cluster_name    = "unused-for-ecs"
  application     = "example/ecs"
  internal        = true
  vpc_id          = module.vpc.vpc_id
  private_subnets = module.vpc.private_subnets

  create_default_listeners = false
  tags                     = { service = "example" }

  target_groups = {
    api = {
      port                 = 8080
      deregistration_delay = 60
      health_check = {
        protocol = "HTTP"
        path     = "/health"
        matcher  = "200"
      }
    }
  }

  listeners = {
    http = {
      port             = 80
      target_group_key = "api"
    }
  }
}

Requirements

Name Version
terraform >= 1.2
aws >= 5.22.0

Providers

Name Version
aws 6.66.0

Modules

No modules.

Resources

Name Type
aws_lb.nlb resource
aws_lb_listener.extra resource
aws_lb_listener.plain resource
aws_lb_listener.this resource
aws_lb_listener.tls resource
aws_lb_listener_certificate.extra resource
aws_lb_target_group.extra resource
aws_lb_target_group.plain resource
aws_lb_target_group.this resource
aws_lb_target_group.tls resource
aws_security_group.nlb resource
aws_region.current data source

Inputs

Name Description Type Default Required
acm_arn ARN for ACM certificate used for TLS. Required when the default TLS listener is enabled. string null no
acm_extra_arns ARNs of ACM certificates used for TLS, attached as additional certificates to the main NLB list(string) [] no
application (namespace/app) - Name of application which will be connected to this NLB string n/a yes
cluster_name Name of the cluster will be used as suffix to all resources string n/a yes
cluster_tag Value for the elbv2.k8s.aws/cluster tag. Defaults to cluster_name. Use when the tag must differ from the name used to construct the LB name (e.g. Gateway API where the LB name prefix is trimmed but the tag must match the LBC --cluster-name). string "" no
create_default_listeners If true, default listeners will be created bool true no
create_default_plain_listener If true, default listener (80) will be created (ANDed with create_default_listeners) bool true no
create_default_tls_listener If true, tls listener (443) will be created (ANDed with create_default_listeners) bool true no
dns_record_client_routing_policy DNS client routing policy controlling which AZ's NLB node IP Route 53 returns when a client resolves the NLB hostname. any_availability_zone (default) returns IPs from any AZ. partial_availability_zone_affinity returns the local-AZ IP for ~85% of clients. availability_zone_affinity returns the local-AZ IP for 100% of clients. Combine with enable_cross_zone_load_balancing = false for end-to-end AZ affinity (client → NLB node → target all in same AZ), eliminating cross-AZ data-transfer cost. Caller must ensure each AZ has ≥1 healthy target; otherwise local-AZ clients will see failures rather than fail over. string "any_availability_zone" no
egress_sg_rules Outbound rules for the NLB security group. Defaults to unrestricted IPv4 egress; set [] to remove all outbound rules. Include target and health-check ports when restricting egress.
set(object({
description = optional(string, "")
protocol = string
from_port = number
to_port = number
security_groups = optional(list(string), [])
cidr_blocks = optional(list(string), [])
ipv6_cidr_blocks = optional(list(string), [])
}))
[
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "Allow all for egress",
"from_port": 0,
"protocol": "-1",
"to_port": 0
}
]
no
enable_cross_zone_load_balancing If true, cross-zone load balancing is enabled (NLB routes to targets in any AZ regardless of which AZ the LB node received the traffic on). Disabling can reduce cross-AZ data-transfer charges, but the NLB node in a given AZ will drop traffic when no healthy targets exist in that AZ. Defaults to true to preserve prior behavior. bool true no
enable_deletion_protection If true, deletion of the load balancer will be disabled via the AWS API bool true no
enforce_security_group_inbound_rules_on_private_link_traffic Whether the NLB security group inbound rules are enforced on traffic arriving through AWS PrivateLink (for example API Gateway VPC Links). Valid values are "on" and "off"; null keeps the AWS default ("on"). string null no
extra_listeners List with configuration for additional listeners
list(object({
name = string
port = string
protocol = optional(string, "TCP")
target_group_port = number
}))
[] no
health_check_port Port used for health check for listener number -1 no
ingress_sg_rules The security group rules to allow ingress from.
set(object({
description = optional(string, "")
protocol = optional(string, "tcp")
port = optional(number, 443)
security_groups = optional(list(string))
cidr_blocks = optional(list(string))
ipv6_cidr_blocks = optional(list(string))
}))
[
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "allow http from anywhere",
"port": 80
},
{
"description": "allow http from anywhere",
"ipv6_cidr_blocks": [
"::/0"
],
"port": 80
},
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "allow https from anywhere",
"port": 443
},
{
"description": "allow https from anywhere",
"ipv6_cidr_blocks": [
"::/0"
],
"port": 443
}
]
no
internal Set NLB to be internal (available only within VPC) bool n/a yes
listeners Additional named listeners. Each listener forwards to a target_groups key; keys are stable Terraform identities.
map(object({
port = number
protocol = optional(string, "TCP")
target_group_key = string
certificate_arn = optional(string)
ssl_policy = optional(string)
tags = optional(map(string), {})
}))
{} no
name Name of the NLB, overrides default naming string "" no
name_suffix Part of the name used to differentiate NLBs for multiple traefik instances string "" no
private_subnets List of private subnets to use list(string) [] no
public_subnets List of public subnets to use list(string) [] no
tag_prefix Tag key prefix for LBC resource/stack tags (e.g. service.k8s.aws for Service LB, gateway.k8s.aws.nlb for Gateway API) string "service.k8s.aws" no
tag_stack Override the computed stack tag value (default: var.application) string "" no
tags Tags for the NLB and its listeners/target groups (default, extra, and Gateway API). If non-empty, these fully replace the module's default tags (elbv2.k8s.aws/cluster, <tag_prefix>/resource, <tag_prefix>/stack) instead of merging with them - use this for an NLB that must not be tracked/managed by an EKS AWS Load Balancer Controller. map(string) {} no
target_groups Additional named target groups for non-controller integrations such as ECS. Keys are stable Terraform identities.
map(object({
port = number
protocol = optional(string, "TCP")
target_type = optional(string, "ip")
deregistration_delay = optional(number, 300)
health_check = optional(object({
enabled = optional(bool, true)
healthy_threshold = optional(number, 3)
interval = optional(number, 30)
matcher = optional(string)
path = optional(string)
port = optional(string, "traffic-port")
protocol = optional(string, "TCP")
timeout = optional(number)
unhealthy_threshold = optional(number, 3)
}), {})
tags = optional(map(string), {})
}))
{} no
tls_listener_version Minimum TLS version served by TLS listener string "1.3" no
vpc_id VPC ID where the NLB will be deployed string n/a yes

Outputs

Name Description
arn The ARN of the NLB.
dns_name The DNS name of the NLB.
listener_arns ARNs of listeners created from listeners, keyed by listener name.
ready Hack! Because modules with providers (cluster-apps) cannot use depends_on output value needs to be used to make sure those are provisioned in correct order.
sg_nlb_id The ID of the security group attached to NLB
ssl_policy SSL Policy attached to loadbalancer
target_group_arns ARNs of target groups created from target_groups, keyed by target group name.
zone_id The zone ID of the NLB.

About

Terraform module for creating an Network Load Balancer

Topics

Resources

Security policy

Stars

3 stars

Watchers

20 watching

Forks

Releases

Packages

Used by

Contributors

Languages