Create Sorry content for ALB and Fargate(ECS) pattern

TOC

Create Sorry content for ALB and Fargate(ECS) pattern

If your system is configured with ALB and Fargate (ECS), Fargate may be temporarily stopped for system maintenance or other reasons.
If a user accesses the system during maintenance, you need to inform the user.

In this case, we will prepare Sorry content in a Lambda function and associate this with ALB.
Then, during maintenance, we will configure it so that traffic from users will be routed here.

Environment

Diagram of create Sorry contents for ALB and Fargate system

We will associate two contents with ALB.

The first is Fargate.
It pulls images from the ECR repository and creates a container.

The second is a Lambda function.
It acts as Sorry content.

CloudFormation template files

The above configuration is built with CloudFormation.
The CloudFormation templates are located at the following URL

https://github.com/awstut-an-r/awstut-fa/tree/main/086

Explanation of key points of the template files

This page covers how to deploy Sorry content in the ALB/Fargate configuration.

For information on how to attach Fargate (ECS) in a private subnet to ALB, please refer to the following page

あわせて読みたい
Attach Fargate in private subnet to ALB 【Configure Fargate containers in private subnet to attach to ALB】 I checked the following page for the three target types of ALB. https://awstut.com/en/202...

For information on how to forward traffic to multiple target groups with path-based routing in ALB, please check the following page

あわせて読みたい
Forwarding traffic to multiple target groups with path-based routing in ALB 【Configuration of ALB for path-based routing】 ALB supports path-based routing. If you have a listener with a default rule that forwards requests to one tar...

For information on how to attach Lambda or other content to ALB, please refer to the following page

あわせて読みたい
Three target types of ALB (Instance, IP, Lambda) and Auto Scaling 【Configuration to check all target types of ALB】 There are three types of resources that can be specified as ALB targets. instanceThe targets are specified...

Lambda Functions

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - !Ref Architecture
      Code:
        ZipFile: |
          import json

          def lambda_handler(event, context):
            return {
              'statusCode': 503,
              'isBase64Encoded': False,
              'headers': {
                'Content-Type': 'text/html; charset=utf-8'
              },
              'body': 'Sorry Contents from Lambda Function.'
            }
      FunctionName: !Sub "${Prefix}-function"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

No special configuration is required.
It is a simple function that returns “Sorry Contents from Lambda Function.” with status code 503.

The key point is the resource-based policy of the Lambda function.

Resources:
  Permission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref Function
      Action: lambda:InvokeFunction
      Principal: elasticloadbalancing.amazonaws.com
Code language: YAML (yaml)

This is the content that permits the ELB to invoke this function.
This setting is for the ALB to return Sorry content as described below.

ALB

Target Groups

Resources:
  ALBTargetGroupFargate:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      ...

  ALBTargetGroupLambda:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckEnabled: false
      Name: !Sub "${Prefix}-ALBTargetGroupLambda"
      Targets:
        - Id: !Ref FunctionArn
      TargetType: lambda
Code language: YAML (yaml)

Define target groups as resources for the ALB relationship.

Two target groups are required.

The first is the group for Fargate.
This explanation is omitted.

The second group is for Lambda functions.
Specify the ARN of the aforementioned Lambda function in the Targets property and “lambda” in the TargetType property.
Now you can set the Lambda function as the routing destination for incoming traffic to the ALB.

Listener Rules

Resources:
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref ALBTargetGroupFargate
          Type: forward
      LoadBalancerArn: !Ref ALB
      Port: !Ref HTTPPort
      Protocol: HTTP

  ALBListenerRule1:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref ALBTargetGroupFargate
          Type: forward
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values:
              - /*
      ListenerArn: !Ref ALBListener
      Priority: 1

  ALBListenerRule2:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref ALBTargetGroupLambda
          Type: forward
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values:
              - /*
      ListenerArn: !Ref ALBListener
      Priority: 2
Code language: YAML (yaml)

Create two rules.

The first is for Fargate.
Set it to match all paths and specify “1” for the Priority property.
This will make this rule the preferred one.

The second is for Lambda functions.
Here, too, set the rule to match all paths and specify “2” for the Priority property.
Due to the priority, the first rule for Fargate is applied during normal operation.
During maintenance, manually adjust these priorities to route traffic to the Lambda function, which is Sorry content.

(Reference) Application Container

index.html

<html>
  <head>
  </head>
  <body>
    <h1>fa-086 index.html</h1>
  </body>
</html>
Code language: HTML, XML (xml)

A simple HTML file.

Dockerfile

FROM nginx:latest

COPY index.html /usr/share/nginx/html

EXPOSE 80
Code language: Dockerfile (dockerfile)

Create an image based on nginx, with the root HTML file replaced with the one mentioned above.

Architecting

Use CloudFormation to build this environment and check the actual behavior.

Create CloudFormation stacks and check resources in stacks

First, create a CloudFormation stack for the ECR repository and push a Docker image to the created ECR.
For more information on this procedure, please refer to the following page

あわせて読みたい
Introduction to Fargate with CloudFormation 【Configuration for Getting Started with Fargate with CloudFormation】 AWS Fargate is a serverless service that allows you to run Docker containers.In this i...

After the image is ready, create the rest of the stacks.
For information on how to create nested stacks and check each stack, please refer to the following page

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

After checking the resources of each stack, information on the main resources created this time is as follows

  • ALB DNS name: fa-086-alb-2131954533.ap-northeast-1.elb.amazonaws.com
  • ECR repository: fa-086
  • ECS Cluster: fa-086-cluster
  • ECS service: fa-086-service
  • Lambda function: fa-086-lambda

Check each resource from the AWS Management Console.
Check the ALB.

Detail of ALB 1.

You can see that ALB has been successfully created.

Also check the ALB target groups.

Detail of ALB 2.
Detail of ALB 3.

You can see that two target groups have been created.
These groups are for Fargate and Lambda functions respectively.

Check the listener rules.

Detail of ALB 4.

You can see that the rule for Fargate has the highest priority, followed by the rule for Lambda functions.

Check Action

Normal

Now that everything is ready, access the ALB.
Access the domain name of the ALB that you have just confirmed.

Detail of ALB 5.

The container on Fargate can be accessed via ALB.
This means that the rule for the highest priority Fargate has been applied.

Maintenance

Next, we will display Sorry content for maintenance.

First, from the AWS Management Console, we manually change the ALB listener rules.

Detail of ALB 6.

We have changed the priority order.
We set the rule for the Lambda function to the highest priority.

Access the domain name of the ALB again.

Detail of ALB 7.

The string for the Sorry content Lambda function is returned.
By changing the listener rule in this way, the Sorry content can be output during maintenance.

Summary

We have confirmed how to deploy Sorry content using Lambda functions in ALB and Fargate configurations.
By changing the priority of the listener rule, we confirmed that the Sorry contents can be displayed during maintenance.

TOC