walkthroughs/howto-http-headers/app.yaml (1,332 lines of code) (raw):
Parameters:
ProjectName:
Type: String
Description: Project name to link stacks
AppMeshXdsEndpoint:
Type: String
Description: App Mesh XDS Endpoint Override
Default: ""
EnvoyImage:
Type: String
Description: Envoy container image
FrontAppImage:
Type: String
Description: Front app container image
ColorAppImage:
Type: String
Description: Color app container image
Resources:
Mesh:
Type: AWS::AppMesh::Mesh
Properties:
MeshName: !Ref ProjectName
ColorRouter:
Type: AWS::AppMesh::VirtualRouter
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
ColorService:
Type: AWS::AppMesh::VirtualService
DependsOn:
- ColorRouter
Properties:
MeshName: !Ref ProjectName
VirtualServiceName: !Sub 'color.${ProjectName}.local'
Spec:
Provider:
VirtualRouter:
VirtualRouterName: 'color-router'
FrontNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- ColorRouter
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'front-node'
Spec:
Backends:
- VirtualService:
VirtualServiceName: !Sub 'color.${ProjectName}.local'
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'front'
BlueNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'blue-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'blue'
ColorRouteBlue:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- BlueNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-blue'
Spec:
Priority: 900
HttpRoute:
Match:
Prefix: '/'
Headers:
- Name: "color_header"
Match:
Range:
Start: 100
End: 150
Action:
WeightedTargets:
- VirtualNode: 'blue-node'
Weight: 100
GreenNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'green-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'green'
ColorRouteGreen:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- GreenNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-green'
Spec:
Priority: 2
HttpRoute:
Match:
Prefix: '/'
Headers:
- Name: "color_header"
Match:
Regex: "redor.*"
Action:
WeightedTargets:
- VirtualNode: 'green-node'
Weight: 100
RedNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'red-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'red'
ColorRouteRed:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- RedNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-red'
Spec:
Priority: 5
HttpRoute:
Match:
Prefix: '/'
Headers:
- Name: "color_header"
Match:
Prefix: "redorgreen"
Action:
WeightedTargets:
- VirtualNode: 'red-node'
Weight: 100
YellowNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'yellow-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'yellow'
ColorRouteYellow:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- YellowNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-yellow'
Spec:
Priority: 990
HttpRoute:
Match:
Prefix: '/'
Headers:
- Name: "color_header"
Action:
WeightedTargets:
- VirtualNode: 'yellow-node'
Weight: 100
PurpleNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'purple-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'purple'
ColorRoutePurple:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- PurpleNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-purple'
Spec:
Priority: 1000
HttpRoute:
Match:
Prefix: '/'
Headers:
- Name: "color_header"
Invert: true
Action:
WeightedTargets:
- VirtualNode: 'purple-node'
Weight: 100
WhiteNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'white-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'white'
ColorRouteWhite:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- WhiteNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-white'
Spec:
Priority: 995
HttpRoute:
Match:
Prefix: '/'
Method: "GET"
Action:
WeightedTargets:
- VirtualNode: 'white-node'
Weight: 100
BlackNode:
Type: AWS::AppMesh::VirtualNode
DependsOn:
- Mesh
Properties:
MeshName: !Ref ProjectName
VirtualNodeName: 'black-node'
Spec:
Listeners:
- PortMapping:
Port: 8080
Protocol: http
HealthCheck:
Protocol: http
Path: '/ping'
HealthyThreshold: 2
UnhealthyThreshold: 2
TimeoutMillis: 2000
IntervalMillis: 5000
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Sub '${ProjectName}.local'
ServiceName: 'color'
Attributes:
- Key: 'ECS_TASK_DEFINITION_FAMILY'
Value: 'black'
ColorRouteBlack:
Type: AWS::AppMesh::Route
DependsOn:
- ColorRouter
- BlackNode
Properties:
MeshName: !Ref ProjectName
VirtualRouterName: 'color-router'
RouteName: 'color-route-black'
Spec:
Priority: 300
HttpRoute:
Match:
Prefix: '/'
Action:
WeightedTargets:
- VirtualNode: 'black-node'
Weight: 100
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ProjectName
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for the instances"
VpcId:
Fn::ImportValue: !Sub '${ProjectName}:VPC'
SecurityGroupIngress:
- CidrIp:
Fn::ImportValue: !Sub '${ProjectName}:VpcCIDR'
IpProtocol: -1
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '${ProjectName}-log-group'
RetentionInDays: 30
TaskIamRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "ecs-tasks.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchFullAccess
- arn:aws:iam::aws:policy/AWSAppMeshEnvoyAccess
TaskExecutionIamRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "ecs-tasks.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
CloudMapNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Name: !Sub '${ProjectName}.local'
Vpc:
Fn::ImportValue:
!Sub "${ProjectName}:VPC"
ColorServiceRegistry:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: 'color'
DnsConfig:
NamespaceId: !GetAtt 'CloudMapNamespace.Id'
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
FrontServiceRegistry:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: 'front'
DnsConfig:
NamespaceId: !GetAtt 'CloudMapNamespace.Id'
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
PublicLoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'Access to the public facing load balancer'
VpcId:
Fn::ImportValue:
!Sub "${ProjectName}:VPC"
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 80
ToPort: 80
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PublicSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PublicSubnet2'
SecurityGroups:
- !Ref PublicLoadBalancerSecurityGroup
WebTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: '/ping'
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
TargetType: ip
Name: !Sub '${ProjectName}-webtarget'
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 120
VpcId:
Fn::ImportValue:
!Sub "${ProjectName}:VPC"
PublicLoadBalancerListener:
DependsOn:
- PublicLoadBalancer
Type: AWS::ElasticLoadBalancingV2::Listener
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:
- '*'
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 1
FrontTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'front'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref FrontAppImage
Essential: true
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'feapp'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR_HOST'
Value: !Sub 'color.${ProjectName}.local:8080'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'feapp-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/front-node'
- Name: 'ENVOY_LOG_LEVEL'
Value: 'debug'
BlueTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'blue'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub ${ProjectName}-log-group
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'blue'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'blue'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'blue-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/blue-node'
GreenTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'green'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'green'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'green'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'green-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/green-node'
RedTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'red'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'red'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'red'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'red-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/red-node'
YellowTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'yellow'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'yellow'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'yellow'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'yellow-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/yellow-node'
PurpleTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'purple'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'purple'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'purple'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'purple-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/purple-node'
WhiteTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'white'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'white'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'white-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/white-node'
BlackTaskDef:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'black'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !Ref TaskIamRole
ExecutionRoleArn: !Ref TaskExecutionIamRole
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '8080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Ref ColorAppImage
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'black'
PortMappings:
- ContainerPort: 8080
Protocol: 'tcp'
Environment:
- Name: 'COLOR'
Value: 'black'
- 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: !Sub '${ProjectName}-log-group'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'black-envoy'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${ProjectName}/virtualNode/black-node'
FrontService:
Type: AWS::ECS::Service
DependsOn:
- WebLoadBalancerRule
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'FrontServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref FrontTaskDef
LoadBalancers:
- ContainerName: app
ContainerPort: 8080
TargetGroupArn: !Ref WebTargetGroup
BlueService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref BlueTaskDef
GreenService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref GreenTaskDef
RedService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref RedTaskDef
YellowService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref YellowTaskDef
PurpleService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref PurpleTaskDef
WhiteService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref WhiteTaskDef
BlackService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: 'FARGATE'
ServiceRegistries:
- RegistryArn: !GetAtt 'ColorServiceRegistry.Arn'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet1'
- Fn::ImportValue:
!Sub '${ProjectName}:PrivateSubnet2'
TaskDefinition: !Ref BlackTaskDef
Outputs:
FrontendEndpoint:
Description: 'Public endpoint for Frontend service'
Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']]
Export:
Name: !Sub '${ProjectName}:FrontendEndpoint'