walkthroughs/howto-external-traffic/infrastructure/ecs-service.yaml (298 lines of code) (raw):
---
Parameters:
EnvironmentName:
Type: String
Description: Environment name that joins all the stacks
AppMeshMeshName:
Type: String
Description: Name of mesh
ECSServicesDomain:
Type: String
Description: DNS namespace used by services e.g. default.svc.cluster.local
EnvoyImage:
Type: String
Description: The image to use for the Envoy container
ColorTellerImageName:
Description: The name for the color teller image
Type: String
LoadBalancerPath:
Type: String
Default: "*"
Description: A path on the public load balancer that this service
should be connected to. Use * to send all load balancer
traffic to this service.
Resources:
### colorteller.default.svc.cluster.local
ColorTellerWhiteServiceDiscoveryRecord:
Type: 'AWS::ServiceDiscovery::Service'
Properties:
Name: "colorteller"
DnsConfig:
NamespaceId:
'Fn::ImportValue': !Sub "${EnvironmentName}:ECSServiceDiscoveryNamespace"
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
ColorTellerWhiteTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'white'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn:
'Fn::ImportValue': !Sub "${EnvironmentName}:TaskIamRoleArn"
ExecutionRoleArn:
'Fn::ImportValue': !Sub "${EnvironmentName}:TaskExecutionIamRoleArn"
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '80'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ColorTellerImageName}'
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group:
Fn::ImportValue: !Sub "${EnvironmentName}:ECSServiceLogGroup"
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'white'
PortMappings:
- ContainerPort: 80
Protocol: 'http'
Environment:
- Name: 'SERVER_PORT'
Value: 80
- Name: 'COLOR'
Value: 'white'
- Name: envoy
Image: !Ref EnvoyImage
Essential: true
User: '1337'
Ulimits:
- Name: "nofile"
HardLimit: 15000
SoftLimit: 15000
PortMappings:
- ContainerPort: 9901
Protocol: 'tcp'
- ContainerPort: 15000
Protocol: 'tcp'
- ContainerPort: 15001
Protocol: 'tcp'
HealthCheck:
Command:
- 'CMD-SHELL'
- 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE'
Interval: 5
Timeout: 2
Retries: 3
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group:
Fn::ImportValue: !Sub "${EnvironmentName}:ECSServiceLogGroup"
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'white-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/ColorTellerWhite'
- Name: 'ENVOY_LOG_LEVEL'
Value: 'debug'
ColorTellerWhiteService:
Type: 'AWS::ECS::Service'
Properties:
Cluster:
'Fn::ImportValue': !Sub "${EnvironmentName}:ECSCluster"
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: FARGATE
ServiceRegistries:
- RegistryArn:
'Fn::GetAtt': ColorTellerWhiteServiceDiscoveryRecord.Arn
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- 'Fn::ImportValue': !Sub "${EnvironmentName}:ECSServiceSecurityGroup"
Subnets:
- 'Fn::ImportValue': !Sub "${EnvironmentName}:PrivateSubnet1"
- 'Fn::ImportValue': !Sub "${EnvironmentName}:PrivateSubnet2"
TaskDefinition: { Ref: ColorTellerWhiteTaskDefinition }
### colorgateway.default.svc.cluster.local
ColorGatewayServiceDiscoveryRecord:
Type: 'AWS::ServiceDiscovery::Service'
Properties:
Name: "colorgateway"
DnsConfig:
NamespaceId:
'Fn::ImportValue': !Sub "${EnvironmentName}:ECSServiceDiscoveryNamespace"
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
ColorGatewayTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'gateway'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn:
'Fn::ImportValue': !Sub "${EnvironmentName}:TaskIamRoleArn"
ExecutionRoleArn:
'Fn::ImportValue': !Sub "${EnvironmentName}:TaskExecutionIamRoleArn"
ContainerDefinitions:
- Name: envoy
Image: !Ref EnvoyImage
Essential: true
Ulimits:
- Name: "nofile"
HardLimit: 15000
SoftLimit: 15000
PortMappings:
- ContainerPort: 9901
Protocol: 'tcp'
- ContainerPort: 15000
Protocol: 'tcp'
- ContainerPort: 15001
Protocol: 'tcp'
- ContainerPort: 80
Protocol: 'tcp'
HealthCheck:
Command:
- 'CMD-SHELL'
- 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE'
Interval: 5
Timeout: 2
Retries: 3
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group:
Fn::ImportValue: !Sub "${EnvironmentName}:ECSServiceLogGroup"
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'gateway-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${AppMeshMeshName}/virtualGateway/ColorGateway'
- Name: 'ENVOY_LOG_LEVEL'
Value: 'debug'
ColorGatewayService:
Type: 'AWS::ECS::Service'
DependsOn:
- WebLoadBalancerRule
Properties:
Cluster:
'Fn::ImportValue': !Sub "${EnvironmentName}:ECSCluster"
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: FARGATE
ServiceRegistries:
- RegistryArn:
'Fn::GetAtt': ColorGatewayServiceDiscoveryRecord.Arn
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- 'Fn::ImportValue': !Sub "${EnvironmentName}:ECSServiceSecurityGroup"
Subnets:
- 'Fn::ImportValue': !Sub "${EnvironmentName}:PrivateSubnet1"
- 'Fn::ImportValue': !Sub "${EnvironmentName}:PrivateSubnet2"
TaskDefinition: { Ref: ColorGatewayTaskDefinition }
HealthCheckGracePeriodSeconds: 300
LoadBalancers:
- ContainerName: envoy
ContainerPort: 80
TargetGroupArn: !Ref WebTargetGroup
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId:
'Fn::ImportValue': !Sub "${EnvironmentName}:VPC"
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
FromPort: 80
ToPort: 80
# public ALB for color gateway
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
- { 'Fn::ImportValue': !Sub "${EnvironmentName}:PublicSubnet1" }
- { 'Fn::ImportValue': !Sub "${EnvironmentName}:PublicSubnet2" }
SecurityGroups: [!Ref 'PublicLoadBalancerSG']
WebTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /ready
HealthCheckPort: 9901
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
TargetType: ip
Name: !Sub "${EnvironmentName}-web"
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 120
VpcId:
'Fn::ImportValue': !Sub "${EnvironmentName}:VPC"
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PublicLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref WebTargetGroup
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: HTTP
WebLoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref WebTargetGroup
Type: 'forward'
Conditions:
- Field: path-pattern
Values: [!Ref 'LoadBalancerPath']
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 1
Outputs:
ColorAppEndpoint:
Description: Public endpoint for Color App service
Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']]