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.
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
Visit the GitHub repo for this pattern.
git clone https://github.com/aws-samples/serverless-patterns/ cd serverless-patterns/alb-ecs-java-sam
mvn clean packagebash buildsam deploy --guided
sam delete
.bash delete-ecr-repo.sh
.