Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Classic Load Balancer

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: ELB-011

Ensure that your HTTP(S) applications (monolithic or containerized) are using Application Load Balancers (ALBs) instead of Classic Load Balancers (ELBs) for enhanced incoming traffic distribution, better performance, and lower costs.

This rule can help you work with the AWS Well-Architected Framework.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Performance
efficiency
Cost
optimisation

Running your HTTP(S) applications behind an Amazon Application Load Balancer will provide a number of advantages over the classic load balancer such as enhanced web traffic distribution, better flexibility over routing, improved health check, monitoring and access logging, support for HTTP/2 and WebSocket protocols, and deletion protection.


Audit

To determine the type of the load balancer used by your HTTP(S) applications, perform the following operations:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/v2/.

03 In the main navigation panel, under Load Balancing, choose Load Balancers.

04 Select the load balancer used by your HTTP(S) application.

05 Select the Description tab from the console bottom panel to view the configuration information available for the selected load balancer.

06 In the Basic Configuration section, check the Type attribute value. If the Type value is set to Classic, the selected load balancer is a Classic Load Balancer, therefore your HTTP(S) application should be migrated to an Application Load Balancer (ALB).

07 Repeat steps no. 4 – 6 for each load balancer used for web applications, provisioned within the current AWS region.

08 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.

Using AWS CLI

01 Run describe-load-balancers command (OSX/Linux/UNIX) with custom query filters to list the name of each Classic Load Balancer available in the selected AWS region:

aws elb describe-load-balancers
  --region us-east-1
  --query 'LoadBalancerDescriptions[*].LoadBalancerName'

02 The command output should return an array with the requested load balancer name(s) or an empty array (i.e. []) if there are no Classic Load Balancers provisioned in the selected AWS region:

[
    "cc-project5-load-balancer",
    "cc-frontend-load-balancer"
]

If the name of the load balancer used by your HTTP(S) application is returned by the describe-load-balancers command output, your HTTP(S) application is running behind a Classic Load Balancer, therefore the application should be migrated to an Application Load Balancer (ALB).

03 Repeat steps no. 1 and 2 for each load balancer used for web applications, provisioned in the selected AWS region.

04 Change the AWS cloud region by updating the --region command parameter value and repeat the Audit process for other regions.

Remediation / Resolution

Option 1: To use the Amazon ELB migration wizard to migrate your HTTP(S) web application from a Classic Load Balancer to an Application Load Balancer, redirect the application traffic, and remove the Classic Load Balancer from your AWS account, perform the following operations:

Note: Migrating to an Application Load Balancer via the Amazon ELB migration wizard using the AWS Command Line Interface (AWS CLI) is not currently supported.

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/v2/.

03 In the main navigation panel, under Load Balancing, choose Load Balancers.

04 Click inside the Filter by tags and attributes or search by keyword box, select Type and choose classic to list the Classic Load Balancers available in the current AWS region.

05 Select the Classic Load Balancer that you want to migrate to a next generation load balancer (i.e. Application Load Balancer).

06 Select the Migration tab from the console bottom panel and choose Launch ALB Migration Wizard to initiate the migration process.

07 On the Review page, verify the configuration options selected by the migration wizard. To change an option, choose Edit. When you are finished configuring the new load balancer, choose Create to launch your Application Load Balancer (ALB). On the Load Balancer Creation Status page, choose Close to return to Amazon EC2 console.

08 After your EC2 instances are registered with the new Application Load Balancer, you can begin the process of redirecting traffic from the old load balancer to the new load balancer. To redirect traffic gradually to your new load balancer, perform the following actions:

  1. Enter the DNS name of your new load balancer into the address field of your web browser. If everything is working as expected, the browser displays the default page of your web application.
  2. Create a new DNS record that associates your domain name with your new Application Load Balancer. If your DNS service supports weighting, specify a weight of 1 in the new DNS record and a weight of 9 in the existing DNS record for your old load balancer. This directs 10% of the traffic to the new load balancer and 90% of the traffic to the old load balancer.
  3. Monitor your new Application Load Balancer to verify if it's receiving traffic and routing requests to your instances.
  4. Continue to update the weight of your DNS records until all traffic is directed to your new load balancer. Then, you can delete the DNS record for your old load balancer.

09 Once the traffic is entirely redirected to the new Application Load Balancer, navigate back to the Amazon EC2 console and remove the Classic Load Balancer. To delete the old (source) load balancer, perform the following actions:

  1. In the main navigation panel, under Load Balancing, choose Load Balancers.
  2. Select the Classic Load Balancer that you want to terminate, choose Actions, and select Delete.
  3. In the Delete Load Balancer confirmation box, choose Yes, Delete to remove the selected load balancer from your AWS cloud account.

10 Repeat steps no. 5 – 9 for each Classic Load Balancer that you want to migrate, provisioned within the current AWS region.

11 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.

Option 2: To manually migrate your HTTP(S) web application from a Classic Load Balancer to an Application Load Balancer, redirect the application traffic, and remove the Classic Load Balancer from your AWS account, perform the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Create Application Load Balancer from Classic Load Balancer",
  "Resources": {
    "ApplicationLoadBalancer": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties" : {
        "Name" : "cc-web-app-load-balancer",
        "Type" : "application",
        "Scheme" : "internet-facing",
        "IpAddressType" : "ipv4",
        "SecurityGroups" : [ "sg-0abcd1234abcd1234" ],
        "Subnets" : [ "subnet-0abcdabcdabcdabcd", "subnet-0abcd1234abcd1234", "subnet-01234abcd1234abcd" ]
      }
    },
    "HTTPSListener": {
        "Type" : "AWS::ElasticLoadBalancingV2::Listener",
        "Properties" : {
            "Protocol" : "HTTPS",
            "Port" : 443,
            "LoadBalancerArn": {
                   "Ref" : "ApplicationLoadBalancer"
            },
            "DefaultActions": [
                {
                    "Type" : "forward",
                    "TargetGroupArn" : "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd"
                }
            ],
            "Certificates" : [
              {
                  "CertificateArn" : "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
              }
            ],
            "SslPolicy" : "ELBSecurityPolicy-FS-1-2-Res-2020-10"
          }
       }
    }
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
Description: Create Application Load Balancer from Classic Load Balancer
Resources:
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: cc-web-app-load-balancer
      Type: application
      Scheme: internet-facing
      IpAddressType: ipv4
      SecurityGroups:
        - sg-0abcd1234abcd1234
      Subnets:
        - subnet-0abcdabcdabcdabcd
        - subnet-0abcd1234abcd1234
        - subnet-01234abcd1234abcd
  HTTPSListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      Protocol: HTTPS
      Port: 443
      LoadBalancerArn: !Ref 'ApplicationLoadBalancer'
      DefaultActions:
        - Type: forward
          TargetGroupArn: arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd
      Certificates:
        - CertificateArn: arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234
      SslPolicy: ELBSecurityPolicy-FS-1-2-Res-2020-10

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  region  = "us-east-1"
}

# Create Application Load Balancer from Classic Load Balancer
resource "aws_lb" "application-load-balancer" {
  name               = "cc-web-app-load-balancer"
  load_balancer_type = "application"
  internal           = false
  ip_address_type    = "ipv4"
  security_groups    = ["sg-0abcd1234abcd1234"]
  subnets            = ["subnet-0abcdabcdabcdabcd","subnet-0abcd1234abcd1234","subnet-01234abcd1234abcd"]
}

resource "aws_lb_listener" "https-listener" {

  load_balancer_arn = aws_lb.application-load-balancer.arn
  protocol          = "HTTPS"
  port              = "443"
  certificate_arn   = "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"

  default_action {
    type             = "forward"
    target_group_arn = "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd"
  }

  ssl_policy = "ELBSecurityPolicy-FS-1-2-Res-2020-10"

}

02 To delete the old (source) Classic Load Balancer, run the following Terraform command, using the Terraform name of the load balancer that you want to delete (e.g. classic-load-balancer) as the --target parameter:

terraform destroy
  --target aws_elb.classic-load-balancer

03 Type yes and press Enter to confirm the Classic Load Balancer deletion:

│ Warning: Resource targeting is in effect
│ You are creating a plan with the -target option, which means that the result of this plan may not represent all of the changes requested by the current configuration.
│ The -target option is not for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use it as part of an error message.
│

Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/v2/.

03 In the main navigation panel, under Load Balancing, choose Load Balancers.

04 Click inside the Filter by tags and attributes or search by keyword box, select Type and choose classic to list the Classic Load Balancers available in the current AWS region.

05 Select the Classic Load Balancer that you want to migrate to an Application Load Balancer and copy the configuration information available for the selected resource such as networking, security, health check, and listener information. You can use this configuration information for the Application Load Balancer (ALB) setup.

06 Click Create Load Balancer button from the console top menu to initiate the setup process.

07 On the Select load balancer type page, choose Application Load Balancer to set up a new load balancer, then select Create to start the setup process.

08 On the Create Application Load Balancer page, perform the following actions:

  1. Provide a unique name for your new ALB in the Load balancer name box.
  2. Set the Scheme configuration setting to Internet-facing. An internet-facing load balancer routes requests from clients over the internet to targets.
  3. Choose the right IP address type from the IP address type.
  4. Select the Virtual Private Cloud (VPC) for the load balancer targets from the VPC dropdown list.
  5. For Mappings, select at least one Availability Zone (AZ) and one subnet for each supported zone. AWS recommends selecting at least two Availability Zones. The load balancer will route traffic only to targets in the selected Availability Zones.
  6. Click inside the Security groups box and choose one or more security groups for the new load balancer. The security group(s) should act as a set of firewall rules that control the traffic to your load balancer.
  7. For Listeners and routing, create and configure the necessary HTTP(S) listener(s) for your new Application Load Balancer.
  8. (Optional) For AWS Global Accelerator, choose whether or not to integrate an AWS Global Accelerator with the load balancer at launch.
  9. (Optional) To attach tags to your new load balancer, use the Add tag button available in the Tags – optional section.
  10. In the Summary section, review your load balancer configuration.
  11. Choose Create load balancer to launch your new Amazon Application Load Balancer.
  12. Choose View load balancer to access your Application Load Balancer (ALB).

09 After your EC2 instances are registered with the new Application Load Balancer, you can begin the process of redirecting traffic from the old load balancer to the new load balancer. To redirect traffic gradually to your new load balancer, perform the following actions:

  1. Enter the DNS name of your new load balancer into the address field of your web browser. If everything is working as expected, the browser displays the default page of your web application.
  2. Create a new DNS record that associates your domain name with your new Application Load Balancer. If your DNS service supports weighting, specify a weight of 1 in the new DNS record and a weight of 9 in the existing DNS record for your old load balancer. This directs 10% of the traffic to the new load balancer and 90% of the traffic to the old load balancer.
  3. Monitor your new Application Load Balancer to verify if it's receiving traffic and routing requests to your instances.
  4. Continue to update the weight of your DNS records until all traffic is directed to your new load balancer. Then, you can delete the DNS record for your old load balancer.

10 Once the traffic is entirely redirected to the new Application Load Balancer, navigate back to the Amazon EC2 console and remove the Classic Load Balancer. To delete the old (source) load balancer, perform the following actions:

  1. In the main navigation panel, under Load Balancing, choose Load Balancers.
  2. Select the Classic Load Balancer that you want to terminate, choose Actions, and select Delete.
  3. In the Delete Load Balancer confirmation box, choose Yes, Delete to remove the selected load balancer from your AWS cloud account.

11 Repeat steps no. 5 – 10 for each Classic Load Balancer that you want to migrate, provisioned within the current AWS region.

12 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.

Using AWS CLI

01 Run describe-instances command (OSX/Linux/UNIX) to list the configuration information available for the Classic Load Balancer that you want to migrate to an Application Load Balancer. You can use this configuration information in the next step for the Application Load Balancer (ALB) setup:

aws elb describe-load-balancers
  --region us-east-1
  --load-balancer-name cc-frontend-load-balancer

02 The command output should return an array with the requested configuration information:

{
  "LoadBalancerDescriptions": [
      {
          "LoadBalancerName": "cc-frontend-load-balancer",
          "DNSName": "cc-frontend-load-balancer-12341234.us-east-1.elb.amazonaws.com",
          "CanonicalHostedZoneName": "cc-frontend-load-balancer-12341234.us-east-1.elb.amazonaws.com",
          "CanonicalHostedZoneNameID": "ABCDABCDABCD",
          "ListenerDescriptions": [
              {
                  "Listener": {
                      "Protocol": "HTTPS",
                      "LoadBalancerPort": 443,
                      "InstanceProtocol": "HTTP",
                      "InstancePort": 80,
                      "SSLCertificateId": "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
                  },
                  "PolicyNames": [
                      "AWSConsole-SSLNegotiationPolicy-cc-frontend-load-balancer-1656677849212"
                  ]
              },
              {
                  "Listener": {
                      "Protocol": "HTTP",
                      "LoadBalancerPort": 80,
                      "InstanceProtocol": "HTTP",
                      "InstancePort": 80
                  },
                  "PolicyNames": []
              }
          ],
          "Policies": {
              "AppCookieStickinessPolicies": [],
              "LBCookieStickinessPolicies": [],
              "OtherPolicies": [
                  "AWSConsole-SSLNegotiationPolicy-cc-frontend-load-balancer-1656675164570",
              ]
          },
          "BackendServerDescriptions": [],
          "AvailabilityZones": [
              "us-east-1d",
              "us-east-1c",
              "us-east-1b"
          ],
          "Subnets": [
              "subnet-0abcdabcdabcdabcd",
              "subnet-0abcd1234abcd1234",
              "subnet-01234abcd1234abcd"
          ],
          "VPCId": "vpc-0abcdabcdabcdabcd",
          "Instances": [
              {
                  "InstanceId": "i-0abcd1234abcd1234"
              },
              {
                  "InstanceId": "i-01234abcd1234abcd"
              }
          ],
          "HealthCheck": {
              "Target": "HTTP:80/index.html",
              "Interval": 50,
              "Timeout": 5,
              "UnhealthyThreshold": 2,
              "HealthyThreshold": 10
          },
          "SourceSecurityGroup": {
              "OwnerAlias": "123456789012",
              "GroupName": "cc-web-load-balancer"
          },
          "SecurityGroups": [
              "sg-0abcd1234abcd1234"
          ],
          "CreatedTime": "2022-05-09T15:29:20.500000+00:00",
          "Scheme": "internet-facing"
      }
  ]
}

03 Run create-load-balancer command (OSX/Linux/UNIX) to create the Amazon Application Load Balancer (ALB) that will replace your Classic Load Balancer:

aws elbv2 create-load-balancer
  --region us-east-1
  --name cc-web-app-load-balancer
  --type application
  --scheme internet-facing
  --ip-address-type ipv4
  --subnets subnet-0abcdabcdabcdabcd subnet-0abcd1234abcd1234 subnet-01234abcd1234abcd
  --security-groups sg-0abcd1234abcd1234
  --tags Key=Environment,Value=production

04 The command output should return the configuration information available for the new load balancer:

{
  "LoadBalancers": [
      {
          "VpcId": "vpc-0abcdabcdabcdabcd",
          "State": {
              "Code": "provisioning"
          },
          "LoadBalancerName": "cc-web-app-load-balancer",
          "Scheme": "internet-facing",

  ...

          "Type": "application",
          "AvailabilityZones": [
              {
                  "SubnetId": "subnet-0abcd1234abcd1234",
                  "ZoneName": "us-east-1d"
              },
              {
                  "SubnetId": "subnet-01234abcd1234abcd",
                  "ZoneName": "us-east-1c"
              },
              {
                  "SubnetId": "subnet-01234abcd1234abcd",
                  "ZoneName": "us-east-1b"
              }
          ]
      }
  ]
}

05 Run create-target-group command (OSX/Linux/UNIX) using the configuration information returned at step no. 2 to create the necessary target group for your new Application Load Balancer:

aws elbv2 create-target-group
  --region us-east-1
  --name cc-frontend-target-group
  --protocol HTTP
  --port 80
  --vpc-id vpc-0abcdabcdabcdabcd
  --health-check-protocol HTTP
  --health-check-port traffic-port
  --health-check-path /index.html
  --health-check-interval-seconds 30
  --health-check-timeout-seconds 5
  --healthy-threshold-count 10
  --unhealthy-threshold-count 2

06 The command output should return the information available for the new target group:

{
  "TargetGroups": [
      {
          "HealthCheckPath": "/index.html",
          "HealthCheckIntervalSeconds": 30,
          "VpcId": "vpc-0abcdabcdabcdabcd",
          "Protocol": "HTTP",
          "HealthCheckTimeoutSeconds": 5,
          "HealthCheckProtocol": "HTTP",
          "UnhealthyThresholdCount": 2,
          "HealthyThresholdCount": 10,
          "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd",
          "Matcher": {
              "HttpCode": "200"
          },
          "HealthCheckPort": "traffic-port",
          "Port": 80,
          "TargetGroupName": "cc-frontend-target-group"
      }
  ]
}

07 Run register-targets command (OSX/Linux/UNIX) to add your targets (i.e. the EC2 instances running behind the Classic Load Balancer) to the new target group (the command does not produce an output):

aws elbv2 register-targets
  --region us-east-1
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd"
  --targets Id=i-0abcd1234abcd1234 Id=i-01234abcd1234abcd

08 Run create-listener command (OSX/Linux/UNIX) to create, configure, and attach the necessary HTTP(S) listener to the newly created Application Load Balancer (ALB):

aws elbv2 create-listener
  --region us-east-1
  --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/cc-web-app-load-balancer/aaaabbbbccccdddd
  --protocol HTTP
  --port 80
  --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd

09 The command output should return the configuration information for the new listener:

{
  "Listeners": [
     {
        "Protocol": "HTTP",
        "DefaultActions": [
            {
               "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/cc-frontend-target-group/aaaabbbbccccdddd",
               "Type": "forward"
            }
        ],
        "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/cc-web-app-load-balancer/aaaabbbbccccdddd”,
        "Port": 80,
        "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/cc-web-app-load-balancer/aaaabbbbccccdddd/bbbbccccddddeeee"
     }
  ]
}

10 After your EC2 instances are registered with the new Application Load Balancer, you can begin the process of redirecting traffic from the old load balancer to the new load balancer. To redirect traffic gradually to your new load balancer, perform the following actions:

  1. Enter the DNS name of your new load balancer into the address field of your web browser. If everything is working as expected, the browser displays the default page of your web application.
  2. Create a new DNS record that associates your domain name with your new Application Load Balancer. If your DNS service supports weighting, specify a weight of 1 in the new DNS record and a weight of 9 in the existing DNS record for your old load balancer. This directs 10% of the traffic to the new load balancer and 90% of the traffic to the old load balancer.
  3. Monitor your new Application Load Balancer to verify if it's receiving traffic and routing requests to your instances.
  4. Continue to update the weight of your DNS records until all traffic is directed to your new load balancer. Then, you can delete the DNS record for your old load balancer.

11 Once the traffic is entirely redirected to the new Application Load Balancer, run delete-load-balancer command (OSX/Linux/UNIX) using the name of the Classic Load Balancer that you want to terminate as the identifier parameter, to remove the selected load balancer from your AWS cloud account (the command does not produce an output):

aws elb delete-load-balancer
  --load-balancer-name cc-frontend-load-balancer

12 Repeat step no. 1 – 11 for each Classic Load Balancer that you want to migrate, provisioned in the selected AWS region.

13 Change the AWS cloud region by updating the --region command parameter value and repeat the Remediation process for other regions.

References

Publication date Oct 15, 2016