Skip to content

AWS Network Load Balancer TCP and TLS with Terraform

Step-01: Introduction

Image

Image

Image

Step-02: c5-04-securitygroup-privatesg.tf

  • NLB requires private security group EC2 Instances to have the ingress_cidr_blocks as 0.0.0.0/0
# Before
  ingress_cidr_blocks = [module.vpc.vpc_cidr_block]

# After
  ingress_cidr_blocks = ["0.0.0.0/0"] # Required for NLB

Step-03: c10-01-NLB-network-loadbalancer-variables.tf

  • Place holder file for NLB variables.

Step-04: c10-02-NLB-network-loadbalancer.tf

# Terraform AWS Network Load Balancer (NLB)
module "nlb" {
  source  = "terraform-aws-modules/alb/aws"
  version = "6.0.0"
  name_prefix = "mynlb-"
  #name = "nlb-basic"
  load_balancer_type = "network"
  vpc_id = module.vpc.vpc_id
  subnets = module.vpc.public_subnets
  #security_groups = [module.loadbalancer_sg.this_security_group_id] # Security Groups not supported for NLB
  # TCP Listener 
    http_tcp_listeners = [
    {
      port               = 80
      protocol           = "TCP"
      target_group_index = 0
    }  
  ]  

  #  TLS Listener
  https_listeners = [
    {
      port               = 443
      protocol           = "TLS"
      certificate_arn    = module.acm.acm_certificate_arn
      target_group_index = 0
    },
  ]


  # Target Group
  target_groups = [
    {
      name_prefix      = "app1-"
      backend_protocol = "TCP"
      backend_port     = 80
      target_type      = "instance"
      deregistration_delay = 10
      health_check = {
        enabled             = true
        interval            = 30
        path                = "/app1/index.html"
        port                = "traffic-port"
        healthy_threshold   = 3
        unhealthy_threshold = 3
        timeout             = 6
      }      
    },
  ]
  tags = local.common_tags 
}

Step-05: c10-03-NLB-network-loadbalancer-outputs.tf

# Terraform AWS Network Load Balancer (NLB) Outputs
output "lb_id" {
  description = "The ID and ARN of the load balancer we created."
  value       = module.nlb.lb_id
}

output "lb_arn" {
  description = "The ID and ARN of the load balancer we created."
  value       = module.nlb.lb_arn
}

output "lb_dns_name" {
  description = "The DNS name of the load balancer."
  value       = module.nlb.lb_dns_name
}

output "lb_arn_suffix" {
  description = "ARN suffix of our load balancer - can be used with CloudWatch."
  value       = module.nlb.lb_arn_suffix
}

output "lb_zone_id" {
  description = "The zone_id of the load balancer to assist with creating DNS records."
  value       = module.nlb.lb_zone_id
}

output "http_tcp_listener_arns" {
  description = "The ARN of the TCP and HTTP load balancer listeners created."
  value       = module.nlb.http_tcp_listener_arns
}

output "http_tcp_listener_ids" {
  description = "The IDs of the TCP and HTTP load balancer listeners created."
  value       = module.nlb.http_tcp_listener_ids
}

output "https_listener_arns" {
  description = "The ARNs of the HTTPS load balancer listeners created."
  value       = module.nlb.https_listener_arns
}

output "https_listener_ids" {
  description = "The IDs of the load balancer listeners created."
  value       = module.nlb.https_listener_ids
}

output "target_group_arns" {
  description = "ARNs of the target groups. Useful for passing to your Auto Scaling group."
  value       = module.nlb.target_group_arns
}

output "target_group_arn_suffixes" {
  description = "ARN suffixes of our target groups - can be used with CloudWatch."
  value       = module.nlb.target_group_arn_suffixes
}

output "target_group_names" {
  description = "Name of the target group. Useful for passing to your CodeDeploy Deployment Group."
  value       = module.nlb.target_group_names
}

Step-06: c12-route53-dnsregistration.tf

  • Change-1: Update DNS Name
  • Change-2: Update alias name
  • Change-3: Update alias zone_id
# DNS Registration 
resource "aws_route53_record" "apps_dns" {
  zone_id = data.aws_route53_zone.mydomain.zone_id 
  name    = "nlb1.devopsincloud.com"
  type    = "A"
  alias {
    name                   = module.nlb.lb_dns_name
    zone_id                = module.nlb.lb_zone_id
    evaluate_target_health = true
  }  
}

Step-07: c13-03-autoscaling-resource.tf

  • Change the module name for target_group_arns to nlb
# Before
  target_group_arns = module.alb.target_group_arns
# After
  target_group_arns = module.nlb.target_group_arns

Step-08: c13-06-autoscaling-ttsp.tf

  • Comment TTSP ALB policy which is not applicable to NLB
# TTS - Scaling Policy-2: Based on ALB Target Requests
# THIS POLICY IS SPECIFIC TO ALB and NOT APPLICABLE TO NLB
/*
resource "aws_autoscaling_policy" "alb_target_requests_greater_than_yy" {
  name                   = "alb-target-requests-greater-than-yy"
  policy_type = "TargetTrackingScaling" # Important Note: The policy type, either "SimpleScaling", "StepScaling" or "TargetTrackingScaling". If this value isn't provided, AWS will default to "SimpleScaling."    
  autoscaling_group_name = aws_autoscaling_group.my_asg.id 
  estimated_instance_warmup = 120 # defaults to ASG default cooldown 300 seconds if not set  
  # Number of requests > 10 completed per target in an Application Load Balancer target group.
  target_tracking_configuration {
    predefined_metric_specification {
      predefined_metric_type = "ALBRequestCountPerTarget"
      resource_label =  "${module.alb.lb_arn_suffix}/${module.alb.target_group_arn_suffixes[0]}"    
    }  
    target_value = 10.0
  }    
}
*/

Step-09: Execute Terraform Commands

# Terraform Initialize
terraform init

# Terrafom Validate
terraform validate

# Terraform Plan
terraform plan

# Terraform Apply
terraform apply -auto-approve

Step-10: Verify the AWS resources created

  1. Confirm SNS Subscription in your email
  2. Verify EC2 Instances
  3. Verify Launch Templates (High Level)
  4. Verify Autoscaling Group (High Level)
  5. Verify Network Load Balancer
  6. TCP Listener
  7. TLS Listener
  8. Verify Network Load Balancer Target Group
  9. Health Checks - both nodes should be healthy
  10. Access and Test
# Access and Test with Port 80 - TCP Listener
http://nlb.devopsincloud.com
http://nlb.devopsincloud.com/app1/index.html
http://nlb.devopsincloud.com/app1/metadata.html

# Access and Test with Port 443 - TLS Listener
https://nlb.devopsincloud.com
https://nlb.devopsincloud.com/app1/index.html
https://nlb.devopsincloud.com/app1/metadata.html

Step-11: Clean-Up

# Terraform Destroy
terraform destroy -auto-approve

# Clean-Up Files
rm -rf .terraform*
rm -rf terraform.tfstate*

References

-Complete NLB - Example