Terraform - A detailed guide on setting up ALB(Application Load Balancer) and SSL?

Why do we need an SSL Certificate for an Application Load Balancer (ALB) in AWS?

SSL certificates are used to establish secure connections between clients and servers over the internet. They are particularly important for protecting sensitive information, such as login credentials or financial data, when it is transmitted between the client and the server.

In the context of an Application Load Balancer (ALB) in AWS, SSL certificates are used to terminate SSL connections to the ALB. This means that the ALB decrypts incoming SSL connections from clients, and then sends the decrypted traffic to the target group. By terminating SSL connections at the ALB, you can offload the SSL processing from the targets, which can improve the performance and scalability of your application.

Using SSL certificates with an ALB is also important for security reasons. By encrypting the traffic between the client and the ALB, you can protect sensitive information from being intercepted or modified by malicious actors. SSL certificates also help to establish trust between the client and the server by verifying the identity of the server using a trusted third-party certificate authority (CA).

1. Create VPC(aws_vpc) and Subnet(aws_subnet)

To begin with, you need to create a subnet in AWS using Terraform, you can use the [aws_subnet][14] resource.

Refer to the following terraform code -

 1# aws_vpc.tf
 2
 3# Create a VPC
 4resource "aws_vpc" "my-vpc" {
 5  cidr_block = "10.0.0.0/16"
 6
 7  tags = {
 8    Name = "my-vpc"
 9  }
10}
11
12# Create a public subnet
13resource "aws_subnet" "public-a" {
14  vpc_id                  = aws_vpc.my-vpc.id
15  cidr_block              = "10.0.0.0/24"
16  availability_zone       = "us-east-1a"
17  map_public_ip_on_launch = true
18
19  tags = {
20    Name = "public-a"
21  }
22}
23
24# Create a private subnet
25resource "aws_subnet" "private-a" {
26  vpc_id                  = aws_vpc.my-vpc.id
27  cidr_block              = "10.0.1.0/24"
28  availability_zone       = "us-east-1a"
29  map_public_ip_on_launch = false
30
31  tags = {
32    Name = "private-a"
33  }
34}

2. Create Security Group(aws_security_group)

After creating the VPC, Subnet you need to create Security Group. In the security group you can specify the Ingress as well Egress rules based on the ports which you need to open.

For this example, I am allowing SSH and enabling PORT 22`.

 1# security_group.tf
 2
 3# Create a security group
 4resource "aws_security_group" "my-sg" {
 5  name        = "my-sg"
 6  description = "Security group for my resources"
 7  vpc_id      = aws_vpc.my-vpc.id
 8
 9  ingress {
10    description = "SSH"
11    from_port   = 22
12    to_port     = 22
13    protocol    = "tcp"
14    cidr_blocks = ["0.0.0.0/0"]
15  }
16
17  egress {
18    from_port   = 0
19    to_port     = 0
20    protocol    = "-1"
21    cidr_blocks = ["0.0.0.0/0"]
22  }
23
24  tags = {
25    Name = "my-sg"
26  }
27} 

The above terraform configuration will create a security group that allows inbound SSH traffic from any IP address and allows all outbound traffic. The security group is placed in the specified VPC using the aws_vpc resource.

You can customize the security group by specifying different options for the aws_security_group resource. For example, you can add additional ingress or egress rules to allow or block specific traffic, or specify different IP ranges or protocols. You can also add tags to the security group to organize and identify it.


3. Create Application Load Balancer (aws_lb) and Load Balancer Listener (aws_lb_listener)

The third step would be to create an ALB with a listener that listens for HTTP traffic on port 80. The ALB is placed in the specified security group and subnets and is configured to forward traffic to a target group using the aws_lb_target_group resource.

 1# aws_lb_listner.tf
 2
 3# Create an ALB
 4resource "aws_lb" "my-alb" {
 5  name            = "my-alb"
 6  internal        = false
 7  load_balancer_type = "application"
 8  security_groups = [aws_security_group.my-sg.id]
 9  subnets         = [aws_subnet.public-a.id, aws_subnet.private-a.id]
10
11  tags = {
12    Name = "my-alb"
13  }
14}
15
16# Create a listener for the ALB
17resource "aws_lb_listener" "my-listener" {
18  load_balancer_arn = aws_lb.my-alb.arn
19  protocol          = "HTTP"
20  port              = 80
21  default_action {
22    type = "forward"
23    target_group_arn = aws_lb_target_group.my-tg.arn
24  }
25} 

You can specify a different protocol (e.g. HTTPS), port, or default action for the listener. You can also add additional listeners for different protocols or ports.


4. Add an AWS SSL Certificate(aws_acm_certificate) to an ALB listener in AWS

To add an SSL certificate to an Application Load Balancer (ALB) in AWS using Terraform, you can use the aws_acm_certificate resource to request and validate the certificate, and the aws_lb_listener_certificate resource to associate the certificate with the ALB listener.

Here are the things which you need to do -

  1. Request and validate an SSL certificate from AWS Certificate Manager (ACM)
  2. Associate the SSL certificate with the ALB listener
 1# certificate_config.tf
 2
 3# Request and validate an SSL certificate from AWS Certificate Manager (ACM)
 4resource "aws_acm_certificate" "my-certificate" {
 5  domain_name       = "example.com"
 6  validation_method = "DNS"
 7
 8  tags = {
 9    Name = "example.com SSL certificate"
10  }
11}
12
13# Associate the SSL certificate with the ALB listener
14resource "aws_lb_listener_certificate" "my-certificate" {
15  listener_arn = aws_lb_listener.my-listener.arn
16  certificate_arn = aws_acm_certificate.my-certificate.arn
17}

The aws_acm_certificate resource requests an SSL certificate for the specified domain name and validation method. In this example, the certificate is validated using the DNS validation method, which means that you will need to create DNS records to prove that you own the domain. The aws_lb_listener_certificate resource associates the SSL certificate with the ALB listener, which means that the ALB will use the certificate to terminate SSL connections.

Note that the SSL certificate will only be available for use after it has been successfully validated. This can take some time, depending on the validation method used. You can use the aws_acm_certificate_validation resource to check the validation status of the certificate.

5. How to run the complete ALB(Application Load Balancer) and SSL?

In the previous 4 steps, you will end up creating the following terraform files -

  1. aws_vpc.tf
  2. security_group.tf
  3. aws_lb_listner.tf
  4. certificate_config.tf

Save all the above files inside a directory and name the project. After that you also need to create the following file -

  1. main.tf
  2. backend.tf (for storing the state file remotely)
1# main.tf
2
3 provider "aws" {
4   region     = "eu-central-1"
5   shared_credentials_files = ["/Users/rahulwagh/.aws/credentials"]
6} 
1#backend.tf
2
3terraform {
4    backend "s3" {
5        bucket = "aws_ssl_setup"
6        key    = "jhooq/terraform/remote/s3/terraform.tfstate"
7        region     = "eu-central-1"
8    }
9} 

Run the following commands-

You can save the above terraform configuration inside a terraform file . e.g. security_group.tf and after that run the following commands

  1. terraform init
  2. terraform plan
  3. terrafrom apply

Conclusion

using SSL certificates with an ALB in AWS is important for improving the security and performance of your application. It is a best practice to use SSL certificates for any application that handles sensitive information or that requires a secure connection.

Posts in this series