Select your cookie preferences

We use cookies and similar tools to enhance your experience, provide our services, deliver relevant advertising, and make improvements. Approved third parties also use these tools to help us deliver advertising and provide certain site features.

Deploying Spring Boot App on Amazon ECS/AWS Fargate with Application Load Balancer

Created with SnapApplication Load BalancerAWS Fargate

This sample project deploys a Java 21 Spring Boot App on Amazon ECS Fargate with Application Load Balancer to route traffic between two ECS Tasks.

The Amazon ECR The repository of the container image of the Spring Boot Application.
Application Load Balancer receives the HTTP request which routes the traffic to one of the Amazon ECS Tasks.
Amazon ECS Cluster is configured with one service having 2 Tasks. The 2 Tasks runs the Spring Boot application as container. The container image is retrieved from the Amazon Elastic Container Registry. The application uses in-memory database to store the data.

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: This template deploys ALB with ECS Fargate cluster to deploy a containerised Spring Boot Application

Parameters:
  ImageURI:
    Type: String
    Description: The URI of the image to deploy

Resources:
  VPC: 
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
  
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
  
  PublicSubnet2: 
    Type: AWS::EC2::Subnet
    Properties: 
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [1, !GetAZs '']

  InternetGateway:
    Type: AWS::EC2::InternetGateway
  
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  
  PublicRoute: 
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow incoming HTTP traffic
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0 
          IpProtocol: tcp
          FromPort: 80
          ToPort: 80
  MicroServiceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow incoming HTTP traffic
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0 
          IpProtocol: tcp
          FromPort: 8081
          ToPort: 8081
          Description: Allow incoming HTTP traffic from ALB
        - CidrIpv6: ::/0
          IpProtocol: tcp
          FromPort: 8081
          ToPort: 8081
          Description: Allow incoming HTTP traffic from ALB
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: my-ecs-cluster

  ECSService:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSCluster
      DesiredCount: 2 
      TaskDefinition: !Ref ECSTaskDef
      LaunchType: FARGATE
      ServiceName: books-microservice-lb-service
      SchedulingStrategy: REPLICA
      LoadBalancers:
        - ContainerName: books-microservice
          ContainerPort: 8081
          TargetGroupArn: !Ref ECSALBTargetGroup
      HealthCheckGracePeriodSeconds: 29
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref MicroServiceSecurityGroup
          Subnets:
            - !Ref PublicSubnet1
            - !Ref PublicSubnet2
      PlatformVersion: LATEST
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 100
        DeploymentCircuitBreaker:
          Enable: true
          Rollback: true
      DeploymentController:
        Type: ECS
      ServiceConnectConfiguration:
        Enabled: false
      Tags: []
      EnableECSManagedTags: true
    DependsOn:
      - ALBListener        

  ECSALBTargetGroup:  
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckPath: /actuator/health
      Name: books-microservice-alb-tg
      Port: 80
      Protocol: HTTP
      TargetType: ip
      HealthCheckProtocol: HTTP 
      HealthCheckIntervalSeconds: 10
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 5
      VpcId: !Ref VPC
      TargetGroupAttributes:
        - Key: deregistration_delay.timeout_seconds
          Value: '300'      

  ECSALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: books-microservice-alb
      Type: application
      Scheme: internet-facing
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      SecurityGroups:
        - !Ref ALBSecurityGroup
  
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ECSALBTargetGroup
      LoadBalancerArn: !Ref ECSALB
      Port: 80
      Protocol: HTTP

  ECSExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ecs-tasks.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: ecs-service-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ecr:GetAuthorizationToken
                  - ecr:BatchCheckLayerAvailability
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
        - PolicyName: cloudwatch-logs-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:DescribeLogStreams
                Resource: "*"

  ECSTaskDef:
    Type: AWS::ECS::TaskDefinition
    Properties:
      RequiresCompatibilities:
        - FARGATE
      Cpu: "1024"
      Memory: "2048"
      NetworkMode: awsvpc
      Family: books-microservice-task-definition
      ExecutionRoleArn: !GetAtt ECSExecutionRole.Arn
      ContainerDefinitions:
        - Name: books-microservice
          Image: !Ref ImageURI 
          PortMappings:
            - ContainerPort: 8081
              Protocol: tcp
              HostPort: 8081
              AppProtocol: http
              Name: books-microservice-8081-tcp
          Essential: true
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-create-group: true
              awslogs-group: "/ecs/books-microservice-task-definition"
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: ecs


Outputs:
  ECSCluster: 
    Description: A reference to the ECS cluster
    Value: !Ref ECSCluster
  
  ECSALBDNSName:
    Description: The DNS name of the ALB
    Value: !GetAtt ECSALB.DNSName

< Back to all patterns


GitHub icon Visit the GitHub repo for this pattern.

Download

git clone https://github.com/aws-samples/serverless-patterns/ cd serverless-patterns/alb-ecs-java-sam

Deploy

mvn clean packagebash buildsam deploy --guided


Testing

See the GitHub repo for detailed testing instructions.

Cleanup

Delete the stack: sam delete.
Delete the ECR repository: bash delete-ecr-repo.sh.

Biswanath Mukherjee

Presented by Biswanath Mukherjee

Sr. Solutions Architect working at AWS India.

Follow on LinkedIn