AWS Elastic Load Balancing Connecting Internet-Facing Load Balancer to Private IP Address Targets

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

The essential configuration pieces that puts an Application Load Balancer in the position to take publicly issued requests and forward them to targets running in private subnets is to:

  1. Declare the application load balancer as internet-facing
  2. Associate the application balancer with two public subnets. We need two, deployed in different availability zones, for high availability purposes:
Resources:
  ...
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${Color}-public-alb
      Scheme: internet-facing
      Type: application
      IpAddressType: ipv4
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      SecurityGroups:
        - !Ref ApplicationLoadBalancerSecurityGroup
      LoadBalancerAttributes:
        - Key: access_logs.s3.enabled
          Value: false

After being declared as such, the Application Load Balancer gets a dynamically generated publicly routable IP address, and the packets sent to the load balancer are routed to it by the virtue of the fact it is associated with public subnets.

The association between the Application Load Balancer and its target processes is done via a Target Group:

Resources:
  ...
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    #
    # the "DependsOn" is important, I've seen race conditions
    # 
    DependsOn: ApplicationLoadBalancer
    Properties:
      Name: !Sub ${Color}-themyscira-tg
      VpcId: !Ref VPC
      Protocol: HTTP
      Port: !Ref ApplicationPort
      TargetType: ip
      HealthCheckProtocol: HTTP
      HealthCheckIntervalSeconds: 60
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 3
      UnhealthyThresholdCount: 3
      HealthCheckPath: '/actuator/health'

The Target Group is referred by the Service definition, which is the configuration element that specifies the fact that the target tasks will be deployed in private subnets, in its Network Configuration section.

Resources:
  ...
  ServiceDefinition:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: !Sub ${Color}-themyscira
      LaunchType: FARGATE
      Cluster: !Ref Cluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 1
      HealthCheckGracePeriodSeconds: 60
      LoadBalancers:
        - ContainerName: !Sub themyscira-container
          ContainerPort: !Ref ApplicationPort
          TargetGroupArn: !Ref TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: DISABLED
          SecurityGroups:
            - !Ref ServiceSecurityGroup
          Subnets:
            - !Ref PrivateSubnet1
            - !Ref PrivateSubnet2

The full CloudFormation stack that can be used to experiment with this is available here:

CloudFormation Network Experimentation Stack

Note that if the application load balancer is "internal" and not "internet-facing", the "Subnets" configuration element can be used to specify the private subnets, directly.