Files
richard-test/infra/cloudformation/service.yaml
T
Scaffolder 5ed58ef33c
deploy / deploy (push) Successful in 5m13s
initial commit
Change-Id: I397992a4940a47404931e3dd04dfc786c06ca51d
2026-06-08 20:42:31 +00:00

312 lines
7.8 KiB
YAML

AWSTemplateFormatVersion: '2010-09-09'
Description: |
Tool Zoo application service stack. Builds a dedicated ECS Fargate web service
with an internet-facing ALB and a stable CloudFormation-managed URL.
Parameters:
EnvironmentName:
Type: String
AllowedPattern: ^[a-zA-Z0-9-]+$
Description: Prefix used for naming resources.
ServiceName:
Type: String
AllowedPattern: ^[a-z0-9-]+$
Description: Logical service name used for the ECS service and log group.
ContainerImage:
Type: String
Description: Fully-qualified container image URI to deploy.
ContainerPort:
Type: Number
Default: 8080
MinValue: 1
MaxValue: 65535
Description: Port exposed by the web container.
HealthCheckPath:
Type: String
Default: "/"
Description: HTTP path used by the ALB health check.
DesiredCount:
Type: Number
Default: 1
MinValue: 1
MaxValue: 3
Description: Number of running tasks.
TaskCpu:
Type: Number
Default: 512
AllowedValues:
- 256
- 512
- 1024
- 2048
- 4096
Description: Fargate task CPU units.
TaskMemory:
Type: Number
Default: 1024
AllowedValues:
- 512
- 1024
- 2048
- 3072
- 4096
- 5120
- 6144
- 7168
- 8192
Description: Fargate task memory in MiB.
Mappings:
SubnetConfig:
Vpc:
CIDR: 10.52.0.0/16
PublicOne:
CIDR: 10.52.0.0/24
PublicTwo:
CIDR: 10.52.1.0/24
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !FindInMap [SubnetConfig, Vpc, CIDR]
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-vpc
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-igw
VpcGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref Vpc
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !FindInMap [SubnetConfig, PublicOne, CIDR]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-a
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !FindInMap [SubnetConfig, PublicTwo, CIDR]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-b
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-rt
PublicDefaultRoute:
Type: AWS::EC2::Route
DependsOn: VpcGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetOne
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetTwo
LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Sub ${EnvironmentName} ALB ingress
VpcId: !Ref Vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
ServiceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Sub ${EnvironmentName} ECS service ingress
VpcId: !Ref Vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
Type: application
SecurityGroups:
- !Ref LoadBalancerSecurityGroup
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
ApplicationTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: !Ref ContainerPort
Protocol: HTTP
TargetType: ip
VpcId: !Ref Vpc
HealthCheckEnabled: true
HealthCheckPath: !Ref HealthCheckPath
HealthCheckProtocol: HTTP
Matcher:
HttpCode: 200-399
ApplicationListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ApplicationTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/ecs/${EnvironmentName}/${ServiceName}
RetentionInDays: 14
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub ${EnvironmentName}-cluster
TaskExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${EnvironmentName}-task-exec-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
TaskRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${EnvironmentName}-task-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Sub ${EnvironmentName}-taskdef
Cpu: !Ref TaskCpu
Memory: !Ref TaskMemory
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !GetAtt TaskExecutionRole.Arn
TaskRoleArn: !GetAtt TaskRole.Arn
ContainerDefinitions:
- Name: web
Image: !Ref ContainerImage
Essential: true
PortMappings:
- ContainerPort: !Ref ContainerPort
Protocol: tcp
Environment:
- Name: PORT
Value: !Sub '${ContainerPort}'
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: web
Service:
Type: AWS::ECS::Service
DependsOn:
- ApplicationListener
Properties:
ServiceName: !Ref ServiceName
Cluster: !Ref Cluster
LaunchType: FARGATE
DesiredCount: !Ref DesiredCount
HealthCheckGracePeriodSeconds: 120
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !Ref ServiceSecurityGroup
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
LoadBalancers:
- TargetGroupArn: !Ref ApplicationTargetGroup
ContainerName: web
ContainerPort: !Ref ContainerPort
TaskDefinition: !Ref TaskDefinition
Outputs:
ServiceUrl:
Description: Public URL for the deployed Tool Zoo service
Value: !Sub http://${ApplicationLoadBalancer.DNSName}
ClusterName:
Description: ECS cluster name for the deployed service
Value: !Ref Cluster