Bootstrap FreeKB - Amazon Web Services (AWS) - Create Network Load Balancer (NLB) TLS Listener using Terraform
Amazon Web Services (AWS) - Create Network Load Balancer (NLB) TLS Listener using Terraform

Updated:   |  Amazon Web Services (AWS) articles

An Elastic Load Balancer (ELB) is typically used to load balance requests across two (or more) different EC2 instances. 

 

This assumes you have setup Terraform with the Amazon Web Services (AWS) provider. If not, check out my article Amazon Web Services (AWS) Getting Started with Terraform.

Let's say you have the following files on your Terraform server.

├── required_providers.tf
├── network_load_balancers (directory)
│   ├── acm_certificate.tf
│   ├── elastic_ips.tf
│   ├── listener.tf
│   ├── load_balancer.tf
│   ├── provider.tf
│   ├── target_group.tf
│   ├── virtual_private_clouds.tf

 

required_providers.tf will almost always have this.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
    }
  }
}

 

Let's say provider.tf has the following. In this example, the "default" profile in /home/username/.aws/config and /home/username/.aws/credentials is being used. This assumes you have setup Terraform as described in Amazon Web Services (AWS) - Getting Started with Terraform.

provider "aws" {
  alias   = "default"
  profile = "default"
  region  = "default"
}

 

And virtual_private_clouds.tf could have the following. Replace "my-vpc" with the name of your Virtual Private Cloud. Check out my articles list Virtual Private Cloud (VPC) using Terraform and list Virtual Private Cloud (VPC) Subnets using Terraform for more details on this.

data "aws_vpc" "my_vpc" {
  filter {
    name = "tag:Name"
    values = ["my-vpc"]
  }
}

data "aws_subnet" "my_aws_subnet" {
  filter {
    name = "tag:Name"
    values = ["us-east-1a"]
  }
}

 

And elastic_ip.tf could have the following to get your Elastic IPs. Check out my article list Elastic IP Addresses (EIP) using Terraform for more details on this.

data "aws_eips" "staging_eips" {
  tags = {
    environment = "staging"
  }
}

 

And load_balancer.tf could have the following to create a Network Load Balancer.

resource "aws_lb" "my-network-load-balancer" {
  name               = "my-network-load-balancer"
  internal           = false
  load_balancer_type = "network"

  subnet_mapping {
    subnet_id     = data.aws_subnet.my_aws_subnet.id
    allocation_id = data.aws_eips.staging_eips.elastic_ip_allocation_id
  }

  tags = {
    Environment = "staging"
    Name = "my-network-load-balancer"
  }
}

 

And target_group.tf could have the following to create the network load balancer target group.

resource "aws_lb_target_group" "my-target-group" {
  name     = "my-target-group"
  port     = 80
  protocol = "HTTP"
  vpc_id   = data.aws_vpc.my_vpc.id

  tags = {
    Name = "my-target-group"
  }
}

 

And acm_certificate.tf could have the following to create a SSL certificate with Subject Alternative Names (SAN) example.com and *.example.com. Check out my article create SSL certificate using Terraform for more details on this.

resource "aws_acm_certificate" "example_com_certificate" {
  domain_name               = "example.com"
  validation_method         = "DNS"
  subject_alternative_names = ["example.com", "*.example.com"]

  tags = {
    environment = "staging"
  }

  lifecycle {
    create_before_destroy = true
  }
}

 

The List Elastic Load Balancer (ELB) SSL Policies using the AWS CLI command can be used to list the SSL policies that can be used by a Network Load Balancer.

~]# aws elbv2 describe-ssl-policies
[
    {
        "Name": "ELBSecurityPolicy-2016-08",
        "SupportedLoadBalancerTypes": [
            "application",
            "network"
        ]
    }
]

 

And listener.tf could have the following to create the TCP port 443 listener, where ssl_policy is one of the SSL policies where SupportedLoadBalancerTypes includes network.

resource "aws_lb_listener" "tls-listener" {

  load_balancer_arn = aws_lb.my-network-load-balancer.arn
  port              = 443
  protocol          = "TCP"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate.example_com_certificate.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.my-target-group.arn
  }

  tags = {
    Name = "tls-listener"
  }
}

 

The terraform plan command can be used to see what Terraform will try to do.

terraform plan

 

And the terraform apply command can be used to create the Elastic Load balancer Target Group.

terraform apply

 

It's a good idea to verify that the SSL certificate has been validated. If validation has failed, you'll probably run into problems. Check out my article List certificates using the AWS CLI. The status should be ISSUED, not FAILED.

]$ aws acm list-certificates
{
    "CertificateSummaryList": [
        {
            "DomainName": "example.com",
            "Status": "ISSUED"

 

openssl s_client connect can be used to verify that the Network Load Balancer is now listening on port TLS over port 443.

~]$ openssl s_client -connect network-load-balancer-123456789abcdefg.elb.us-east-1.amazonaws.com:443
CONNECTED(00000003)
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M02
verify return:1
depth=0 CN = example.com
verify return:1
---
Certificate chain
 0 s:CN = example.com
   i:C = US, O = Amazon, CN = Amazon RSA 2048 M02
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Oct 17 00:00:00 2023 GMT; NotAfter: Nov 15 23:59:59 2024 GMT
 1 s:C = US, O = Amazon, CN = Amazon RSA 2048 M02
   i:C = US, O = Amazon, CN = Amazon Root CA 1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Aug 23 22:25:30 2022 GMT; NotAfter: Aug 23 22:25:30 2030 GMT
 2 s:C = US, O = Amazon, CN = Amazon Root CA 1
   i:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: May 25 12:00:00 2015 GMT; NotAfter: Dec 31 01:00:00 2037 GMT
 3 s:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
   i:C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  2 00:00:00 2009 GMT; NotAfter: Jun 28 17:39:16 2034 GMT

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 84754f in the box below so that we can be sure you are a human.