Use CloudFormation to create and configure AWS Application Load Balancer

You can download this article in PDF format via the link below to support us.Download the guide in PDF formatClose

This tutorial aims to guide readers through the use of CloudFormation to create an application load balancer and its dependencies. The template will create:

  • Application load balancer
  • Target population
  • audience
  • Listener rules

AWS cloud platform uses elastic load balancer service to provide managed load balancer. An option can create applications (layer 7), networks (layer 4) or classic load balancers (layer 4 and 7). In this tutorial, we will create an application load balancer.

Load balancers are useful because:

It provides high availability for our applications. Using a load balancer in our application allows traffic to be routed to multiple backend servers. If one server fails, the traffic will be routed to other servers. This is also good for ensuring that the traffic is evenly distributed among the servers.

This is also useful for directing/filtering traffic based on configured rules. Use host-based routing, path-based routing, or a combination of the two to direct traffic to different servers.

Set up prerequisites

Users will need to have:

  • An AWS account.
  • Users who have the right to create resources on AWS.
  • A certificate was generated for its specific domain name (we generated our certificate using AWS Certificate Manager).
  • IDE for writing and editing CloudFormation templates.

N/B: Users can import certificates generated from other certificate generation entities into AWS Certificate Manager and use them.

Step 1: Create CloudFormation template

Use the following code for the CloudFormation template. Users can edit various parts of the template, as described in the next section.

AWSTemplateFormatVersion: "2010-09-09"
Description: "Create ALB, ALB security group, target groups, listeners and listener rules"
Parameters:
    VPC:
        Type: String
        Description: The vpc to launch the service
        Default: vpc-ID

    PublicSubnet1:
        Type: String
        Description: The subnet where to launch the service
        Default: subnet-ID

    PublicSubnet2:
        Type: String
        Description: the subnet where to Launch the service
        Default: subnet-ID

Resources:            
    ALBSecurityGroup:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
            GroupDescription: "security group for ALB"
            GroupName: "test-ALB-SG"
            Tags: 
              - 
                Key: "Project"
                Value: "test-blog"
              - 
                Key: "createdBy"
                Value: "Maureen Barasa"
              - 
                Key: "Environment"
                Value: "test"
              - 
                Key: "Name"
                Value: "test-ALB-SG"
            VpcId: !Ref VPC
            SecurityGroupIngress: 
              - 
                CidrIp: "0.0.0.0/0"
                FromPort: 80
                IpProtocol: "tcp"
                ToPort: 80
              - 
                CidrIp: "0.0.0.0/0"
                FromPort: 443
                IpProtocol: "tcp"
                ToPort: 443
    
    ApplicationLoadBalancer:
        Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
        Properties:
            Name: "test-Application-Load-Balancer"
            Scheme: "internet-facing"
            Type: "application"
            Subnets: 
              - !Ref PublicSubnet1
              - !Ref PublicSubnet2
            SecurityGroups: 
              - !Ref ALBSecurityGroup
            IpAddressType: "ipv4"
            LoadBalancerAttributes: 
              - 
                Key: "access_logs.s3.enabled"
                Value: "false"
              - 
                Key: "idle_timeout.timeout_seconds"
                Value: "60"
              - 
                Key: "deletion_protection.enabled"
                Value: "false"
              - 
                Key: "routing.http2.enabled"
                Value: "true"
              - 
                Key: "routing.http.drop_invalid_header_fields.enabled"
                Value: "false"

    HTTPSListener:
        Type: "AWS::ElasticLoadBalancingV2::Listener"
        Properties:
            LoadBalancerArn: !Ref ApplicationLoadBalancer
            Port: 443
            Protocol: "HTTPS"
            SslPolicy: "ELBSecurityPolicy-2016-08"
            Certificates: 
              - 
                CertificateArn: arn:aws:acm:eu-central-1:**************:certificate/*********************
                
            DefaultActions: 
              - 
                Order: 1
                TargetGroupArn: !Ref Test1TargetGroup
                Type: "forward"

    HTTPListener:
        Type: "AWS::ElasticLoadBalancingV2::Listener"
        Properties:
            LoadBalancerArn: !Ref ApplicationLoadBalancer
            Port: 80
            Protocol: "HTTP"
            DefaultActions: 
              - 
                Order: 1
                RedirectConfig: 
                    Protocol: "HTTPS"
                    Port: "443"
                    Host: "#{host}"
                    Path: "/#{path}"
                    Query: "#{query}"
                    StatusCode: "HTTP_301"
                Type: "redirect"
                
    Test1TargetGroup:
        Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
        Properties:
            HealthCheckIntervalSeconds: 30
            HealthCheckPath: "/"
            Port: 80
            Protocol: "HTTP"
            HealthCheckPort: "traffic-port"
            HealthCheckProtocol: "HTTP"
            HealthCheckTimeoutSeconds: 5
            UnhealthyThresholdCount: 2
            TargetType: "instance"
            Matcher: 
                HttpCode: "200"
            HealthyThresholdCount: 5
            VpcId: !Ref VPC
            Name: "target-group-1"
            HealthCheckEnabled: true
            TargetGroupAttributes: 
              - 
                Key: "stickiness.enabled"
                Value: "false"
              - 
                Key: "deregistration_delay.timeout_seconds"
                Value: "300"
              - 
                Key: "stickiness.type"
                Value: "lb_cookie"
              - 
                Key: "stickiness.lb_cookie.duration_seconds"
                Value: "86400"
              - 
                Key: "slow_start.duration_seconds"
                Value: "0"
              - 
                Key: "load_balancing.algorithm.type"
                Value: "round_robin"

    Test2TargetGroup:
        Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
        Properties:
            HealthCheckIntervalSeconds: 30
            HealthCheckPath: "/"
            Port: 80
            Protocol: "HTTP"
            HealthCheckPort: "traffic-port"
            HealthCheckProtocol: "HTTP"
            HealthCheckTimeoutSeconds: 5
            UnhealthyThresholdCount: 2
            TargetType: "instance"
            Matcher: 
                HttpCode: "200"
            HealthyThresholdCount: 5
            VpcId: !Ref VPC
            Name: "target-group-2"
            HealthCheckEnabled: true
            TargetGroupAttributes: 
              - 
                Key: "stickiness.enabled"
                Value: "false"
              - 
                Key: "deregistration_delay.timeout_seconds"
                Value: "300"
              - 
                Key: "stickiness.type"
                Value: "lb_cookie"
              - 
                Key: "stickiness.lb_cookie.duration_seconds"
                Value: "86400"
              - 
                Key: "slow_start.duration_seconds"
                Value: "0"
              - 
                Key: "load_balancing.algorithm.type"
                Value: "round_robin"
               
    TestListenerRule1:
        Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
        Properties:
            Priority: "1"
            ListenerArn: !Ref HTTPSListener
            Conditions: 
              - 
                Field: "host-header"
                Values: 
                  - "test1.blog.avrcr.com"
            Actions: 
              - 
                Type: "forward"
                TargetGroupArn: !Ref Test1TargetGroup
                Order: 1
                ForwardConfig: 
                    TargetGroups: 
                      - 
                        TargetGroupArn: !Ref Test1TargetGroup
                        Weight: 1
                    TargetGroupStickinessConfig: 
                        Enabled: false

    TestListenerRule2:
        Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
        Properties:
            Priority: "2"
            ListenerArn: !Ref HTTPSListener
            Conditions: 
              - 
                Field: "host-header"
                Values: 
                  - "test2.blog.com"
            Actions: 
              - 
                Type: "forward"
                TargetGroupArn: !Ref Test2TargetGroup
                Order: 1
                ForwardConfig: 
                    TargetGroups: 
                      - 
                        TargetGroupArn: !Ref Test2TargetGroup
                        Weight: 1
                    TargetGroupStickinessConfig: 
                        Enabled: false

Outputs:        
    ALB:
        Description: The created loadbalancer
        Value: !Ref ApplicationLoadBalancer

    TargetGroup1:
        Description: The created TargetGroup 1
        Value: !Ref Test1TargetGroup

    TargetGroup2:
        Description: The created TargetGroup 2
        Value: !Ref Test2TargetGroup

    LoadBalancerSecurityGroup:
        Description: the securty group for the ALB
        Value: !Ref ALBSecurityGroup

Introduction to CloudFormation templates

The template contains 3 parts. Parameters, resources and output.

Parameter part

In the parameter section, the user enters its dynamic variables. On our template, users should customize the template by entering their VPC and subnet ID. In our case, the load balancer faces the Internet, so it needs to be created in the public subnet. If the user wants to create an internal load balancer, it is best to create it in a private subnet.

Resources Section

The resources section allows users to define the AWS resources they will create.

On the template, we first create a load balancer security group. Security group creation allows inbound traffic from ports 80 and 443. Users can also customize or add more rules to the security group.

Next, the template creates a load balancer. Users can customize the name and scheme of the load balancer, or whether it is internal or Internet-facing. If it is internal, make sure to change the subnet from public to private. They can also customize the load balancer properties according to their specific needs.

Since we have opened the port 80 with 443 On the load balancer security group, this template creates two listeners for the load balancer. One listener is on port 80 (HTTP) and the other listener is on port 443 (HTTPS). Then, for the HTTP listener, configure the template to create a default action to forward all requests to the HTTPS listener by default. It can also be customized according to user needs.

For the HTTPS listener, we include the certificate we generated for the domain name. Users should change the certificate ARN to their own certificate ARN ID. In addition, we created a default action to forward traffic to the target group. This will forward all traffic that is not routed to the target group. Similarly, users can customize the default operation of the HTTPS listener according to their specific needs.

Next, the template creates two target groups. Users can customize the attributes of the target group according to their specific needs. The important thing to note is that the target type can be instance (EC2) or IP.

Finally, the template creates listener rules. For the case of host-based routing, we created listener rules, which are forwarded to specific target groups. Users can choose custom rules. Moreover, they can be changed from host-based routing to path-based routing.

Output section

The output section outputs the name of the resource you created.

Step 2: Create CodePipeline to deploy the template

Create a CodePipeline role to deploy the template to CloudFormation. Use the cloudformation template below to create the role.

AWSTemplateFormatVersion: "2010-09-09"
Description: "Template to create centos ec2 instance and install ssm on it"

Resources:
    IAMInstanceRole:
        Type: 'AWS::IAM::Role'
        Properties:
          Description: The SSM Instance Profile
          RoleName: codepipeline-test
          AssumeRolePolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Principal:
                  Service:
                  - cloudformation.amazonaws.com
                Action:
                  - 'sts:AssumeRole'
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess
            - arn:aws:iam::aws:policy/CloudWatchFullAccess
            - arn:aws:iam::aws:policy/AmazonEC2FullAccess
          Tags: 
            - 
              Key: "Project"
              Value: "test-blog"
            - 
              Key: "Environment"
              Value: "test"
            - 
              Key: "createdBy"
              Value: "Maureen Barasa"
            - 
              Key: "Name"
              Value: "codepipeline-test"

    IAMInstanceProfile:
        Type: AWS::IAM::InstanceProfile
        Properties: 
            InstanceProfileName: codepipeline-test
            Roles: 
             - !Ref IAMInstanceRole

Outputs:
  Profile:
    Description: The created Instance Profile
    Value: !Ref IAMInstanceProfile
    
  Role:
    Description: The created role
    Value: !Ref IAMInstanceRole  

Next, go to the CodeCommit console. Then create a code submission repository. Submit your alb template to the repository.

On the CodePipeline console, select “Create Pipeline”.

Create pipeline

After that, select the pipeline settings. For the service role, choose to create a new service role.

Use CloudFormation to create and configure AWS Application Load BalancerChoose pipeline settings

Also, under “Advanced Settings”, select the S3 bucket for storing artifacts. For the encryption key, select the default AWS key. Then click Next.

Use CloudFormation to create and configure AWS Application Load Balanceradvanced settings

On the Add Source stage screen, select Code Submission as your source provider.

Use CloudFormation to create and configure AWS Application Load BalancerAdd source stage

Enter your CodeCommit repository name and branch details. Also, for change detection, leave the setting as Amazon CloudWatch Events. This allows CloudWatch to detect changes made to the code and automatically start the pipeline to update those changes. When finished, click Next.

Use CloudFormation to create and configure AWS Application Load BalancerAdd source stage settings

On the Add Build Phase screen, click Skip Build Phase.

Use CloudFormation to create and configure AWS Application Load BalancerSkip the build phase

Finally, on the Add Deployment Stage screen, select CloudFormation as the deployment option.

Use CloudFormation to create and configure AWS Application Load BalancerChoose CloudFormation as the deployment option

Fill in the details of your CloudFormation deployment. N/B: For the role, please use the role created using the CloudFormation template at the beginning of this section.

Use CloudFormation to create and configure AWS Application Load BalancerAdd deployment stage details

In the next stage, users can view all completed configurations. If everything is configured correctly, click Create Pipeline.

Now you have created your first pipeline to deploy CloudFormation templates.

Use CloudFormation to create and configure AWS Application Load BalancerSuccessful deployment pipeline

More guidance on AWS:

  • Use CloudFormation to set up an AWS RDS MySQL database instance
  • Use CloudFormation to create an Amazon DocumentDB (MongoDB) database on AWS
  • Set up Elasticsearch Cluster with Kibana on AWS
  • Grant developers access to the EKS Kubernetes cluster

Happy Building! ! !

You can download this article in PDF format via the link below to support us.Download the guide in PDF formatClose

Sidebar