13 Commits
master ... ecs

Author SHA1 Message Date
Cedric Ziel
093b9b27a6 Use service registry for discovery 2020-05-12 09:51:23 +02:00
Cedric Ziel
8c6ee60e36 Add dispatch service 2020-05-11 16:30:58 +02:00
Cedric Ziel
f97fa7a455 Add payment service 2020-05-11 15:51:35 +02:00
Cedric Ziel
a9206d7479 Add ratings service 2020-05-11 15:40:22 +02:00
Cedric Ziel
4422db5072 Add shipping service 2020-05-11 15:32:16 +02:00
Cedric Ziel
5967945d58 Add mysql service 2020-05-11 15:19:32 +02:00
Cedric Ziel
c58432972c Add cart service 2020-05-11 15:05:55 +02:00
Cedric Ziel
6a638b4d6a Add user service 2020-05-11 14:56:09 +02:00
Cedric Ziel
96f8ef8be8 Add catalogue service 2020-05-11 14:16:44 +02:00
Cedric Ziel
e95b14892f Add RabbitMQ service 2020-05-11 13:57:47 +02:00
Cedric Ziel
c7e6b9d252 Add redis service 2020-05-11 13:51:10 +02:00
Cedric Ziel
f3f350409c Add web & mongodb service 2020-05-11 13:42:42 +02:00
Cedric Ziel
b3ee2880d9 Add cluster descriptor
* add template for instana-agent
2020-05-11 13:42:08 +02:00
4 changed files with 1451 additions and 0 deletions

571
aws-ecs-ec2/cluster.yaml Normal file
View File

@@ -0,0 +1,571 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: A stack for deploying containerized applications onto a cluster of EC2
hosts using Elastic Container Service. This stack runs containers on
hosts that are in a private VPC subnet. Outbound network traffic from the
hosts must go out through a NAT gateway. There are two load balancers, one
inside the public subnet, which can be used to send traffic to the
containers in the private subnet, and one in the private subnet, which can
be used for private internal traffic between internal services.
Parameters:
DesiredCapacity:
Type: Number
Default: '3'
Description: Number of EC2 instances to launch in your ECS cluster.
MaxSize:
Type: Number
Default: '6'
Description: Maximum number of EC2 instances that can be launched in your ECS cluster.
ECSAMI:
Description: AMI ID
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id
InstanceType:
Description: EC2 instance type
Type: String
Default: c4.xlarge
AllowedValues: [t2.micro, t2.small, t2.medium, t2.large, m3.medium, m3.large,
m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge,
c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge,
c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge,
r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge]
ConstraintDescription: Please choose a valid instance type.
Mappings:
# Hard values for the subnet masks. These masks define
# the range of internal IP addresses that can be assigned.
# The VPC can have all IP's from 10.0.0.0 to 10.0.255.255
# There are four subnets which cover the ranges:
#
# 10.0.0.0 - 10.0.0.255
# 10.0.1.0 - 10.0.1.255
# 10.0.2.0 - 10.0.2.255
# 10.0.3.0 - 10.0.3.255
#
# If you need more IP addresses (perhaps you have so many
# instances that you run out) then you can customize these
# ranges to add more
SubnetConfig:
VPC:
CIDR: '10.0.0.0/16'
PublicOne:
CIDR: '10.0.0.0/24'
PublicTwo:
CIDR: '10.0.1.0/24'
PrivateOne:
CIDR: '10.0.2.0/24'
PrivateTwo:
CIDR: '10.0.3.0/24'
Resources:
# VPC in which containers will be networked.
# It has two public subnets, and two private subnets.
# We distribute the subnets across the first two available subnets
# for the region, for high availability.
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
# Two public subnets, where containers can have public IP addresses
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
MapPublicIpOnLaunch: true
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
MapPublicIpOnLaunch: true
# Two private subnets where containers will only have private
# IP addresses, and will only be reachable by other members of the
# VPC
PrivateSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PrivateOne', 'CIDR']
PrivateSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PrivateTwo', 'CIDR']
# Setup networking resources for the public subnets. Containers
# in the public subnets have public IP addresses and the routing table
# sends network traffic via the internet gateway.
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachement:
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: GatewayAttachement
Properties:
RouteTableId: !Ref 'PublicRouteTable'
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetOne
RouteTableId: !Ref PublicRouteTable
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTwo
RouteTableId: !Ref PublicRouteTable
# Setup networking resources for the private subnets. Containers
# in these subnets have only private IP addresses, and must use a NAT
# gateway to talk to the internet. We launch two NAT gateways, one for
# each private subnet.
NatGatewayOneAttachment:
Type: AWS::EC2::EIP
DependsOn: GatewayAttachement
Properties:
Domain: vpc
NatGatewayTwoAttachment:
Type: AWS::EC2::EIP
DependsOn: GatewayAttachement
Properties:
Domain: vpc
NatGatewayOne:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGatewayOneAttachment.AllocationId
SubnetId: !Ref PublicSubnetOne
NatGatewayTwo:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGatewayTwoAttachment.AllocationId
SubnetId: !Ref PublicSubnetTwo
PrivateRouteTableOne:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PrivateRouteOne:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTableOne
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGatewayOne
PrivateRouteTableOneAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTableOne
SubnetId: !Ref PrivateSubnetOne
PrivateRouteTableTwo:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PrivateRouteTwo:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTableTwo
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGatewayTwo
PrivateRouteTableTwoAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTableTwo
SubnetId: !Ref PrivateSubnetTwo
# OPTIONAL: VPC Endpoint for DynamoDB
# If a container needs to access DynamoDB this allows a container in the private subnet
# to talk to DynamoDB directly without needing to go via the NAT gateway. This reduces
# the amount of bandwidth through the gateway, meaning that the gateway is free to serve
# your other traffic.
DynamoDBEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "*"
Principal: "*"
Resource: "*"
RouteTableIds:
- !Ref 'PrivateRouteTableOne'
- !Ref 'PrivateRouteTableTwo'
ServiceName: !Join [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".dynamodb" ] ]
VpcId: !Ref 'VPC'
# ECS Resources
ECSCluster:
Type: AWS::ECS::Cluster
# A security group for the EC2 hosts that will run the containers.
# Two rules, allowing network traffic from a public facing load
# balancer and from other hosts in the security group.
#
# Remove any of the following ingress rules that are not needed.
# If you want to make direct requests to a container using its
# public IP address you'll need to add a security group rule
# to allow traffic from all IP addresses.
EcsHostSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the ECS hosts that run containers
VpcId: !Ref 'VPC'
EcsSecurityGroupIngressFromPublicALB:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from the public ALB
GroupId: !Ref 'EcsHostSecurityGroup'
IpProtocol: -1
SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'
EcsSecurityGroupIngressFromPrivateALB:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from the private ALB
GroupId: !Ref 'EcsHostSecurityGroup'
IpProtocol: -1
SourceSecurityGroupId: !Ref 'PrivateLoadBalancerSG'
EcsSecurityGroupIngressFromSelf:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from other containers in the same security group
GroupId: !Ref 'EcsHostSecurityGroup'
IpProtocol: -1
SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup'
# Autoscaling group. This launches the actual EC2 instances that will register
# themselves as members of the cluster, and run the docker containers.
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnetOne
- !Ref PrivateSubnetTwo
LaunchConfigurationName: !Ref 'ContainerInstances'
MinSize: '1'
MaxSize: !Ref 'MaxSize'
DesiredCapacity: !Ref 'DesiredCapacity'
CreationPolicy:
ResourceSignal:
Timeout: PT15M
UpdatePolicy:
AutoScalingReplacingUpdate:
WillReplace: 'true'
ContainerInstances:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref 'ECSAMI'
SecurityGroups: [!Ref 'EcsHostSecurityGroup']
InstanceType: !Ref 'InstanceType'
IamInstanceProfile: !Ref 'EC2InstanceProfile'
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
yum install -y aws-cfn-bootstrap curl
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region}
AutoscalingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [application-autoscaling.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: service-autoscaling
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'application-autoscaling:*'
- 'cloudwatch:DescribeAlarms'
- 'cloudwatch:PutMetricAlarm'
- 'ecs:DescribeServices'
- 'ecs:UpdateService'
Resource: '*'
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles: [!Ref 'EC2Role']
# Role for the EC2 hosts. This allows the ECS agent on the EC2 hosts
# to communciate with the ECS control plane, as well as download the docker
# images from ECR to run on your host.
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ec2.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'ecs:CreateCluster'
- 'ecs:DeregisterContainerInstance'
- 'ecs:DiscoverPollEndpoint'
- 'ecs:Poll'
- 'ecs:RegisterContainerInstance'
- 'ecs:StartTelemetrySession'
- 'ecs:Submit*'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'ecr:GetAuthorizationToken'
- 'ecr:BatchGetImage'
- 'ecr:GetDownloadUrlForLayer'
Resource: '*'
# Load balancers for getting traffic to containers.
# This sample template creates two load balancers:
#
# - One public load balancer, hosted in public subnets that is accessible
# to the public, and is intended to route traffic to one or more public
# facing services.
# - One private load balancer, hosted in private subnets, that only
# accepts traffic from other containers in the cluster, and is
# intended for private services that should not be accessed directly
# by the public.
# A public facing load balancer, this is used for accepting traffic from the public
# internet and directing it to public facing microservices
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId: !Ref 'VPC'
SecurityGroupIngress:
# Allow access to ALB from anywhere on the internet
- CidrIp: 0.0.0.0/0
IpProtocol: -1
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
# The load balancer is placed into the public subnets, so that traffic
# from the internet can reach the load balancer directly via the internet gateway
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups: [!Ref 'PublicLoadBalancerSG']
# A dummy target group is used to setup the ALB to just drop traffic
# initially, before any real service target groups have been added.
DummyTargetGroupPublic:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-1']]
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PublicLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref 'DummyTargetGroupPublic'
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: HTTP
# An internal load balancer, this would be used for a service that is not
# directly accessible to the public, but instead should only receive traffic
# from your other services.
PrivateLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the internal load balancer
VpcId: !Ref 'VPC'
PrivateLoadBalancerIngressFromECS:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Only accept traffic from a container in the container host security group
GroupId: !Ref 'PrivateLoadBalancerSG'
IpProtocol: -1
SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup'
PrivateLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internal
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
# This load balancer is put into the private subnet, so that there is no
# route for the public to even be able to access the private load balancer.
- !Ref PrivateSubnetOne
- !Ref PrivateSubnetTwo
SecurityGroups: [!Ref 'PrivateLoadBalancerSG']
# This dummy target group is used to setup the ALB to just drop traffic
# initially, before any real service target groups have been added.
DummyTargetGroupPrivate:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-2']]
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
PrivateLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PrivateLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref 'DummyTargetGroupPrivate'
Type: 'forward'
LoadBalancerArn: !Ref 'PrivateLoadBalancer'
Port: 80
Protocol: HTTP
# This is an IAM role which authorizes ECS to manage resources on your
# account on your behalf, such as updating your load balancer with the
# details of where your containers are, so that traffic can reach your
# containers.
ECSRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ecs.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action:
# Rules which allow ECS to attach network interfaces to instances
# on your behalf in order for awsvpc networking mode to work right
- 'ec2:AttachNetworkInterface'
- 'ec2:CreateNetworkInterface'
- 'ec2:CreateNetworkInterfacePermission'
- 'ec2:DeleteNetworkInterface'
- 'ec2:DeleteNetworkInterfacePermission'
- 'ec2:Describe*'
- 'ec2:DetachNetworkInterface'
# Rules which allow ECS to update load balancers on your behalf
# with the information sabout how to send traffic to your containers
- 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer'
- 'elasticloadbalancing:DeregisterTargets'
- 'elasticloadbalancing:Describe*'
- 'elasticloadbalancing:RegisterInstancesWithLoadBalancer'
- 'elasticloadbalancing:RegisterTargets'
Resource: '*'
# These are the values output by the CloudFormation template. Be careful
# about changing any of them, because of them are exported with specific
# names so that the other task related CF templates can use them.
Outputs:
ClusterName:
Description: The name of the ECS cluster
Value: !Ref 'ECSCluster'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ]
InternalUrl:
Description: The url of the internal load balancer
Value: !Join ['', ['http://', !GetAtt 'PrivateLoadBalancer.DNSName']]
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'InternalUrl' ] ]
ExternalUrl:
Description: The url of the external load balancer
Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']]
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ExternalUrl' ] ]
ECSRole:
Description: The ARN of the ECS role
Value: !GetAtt 'ECSRole.Arn'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSRole' ] ]
PublicListener:
Description: The ARN of the public load balancer's Listener
Value: !Ref PublicLoadBalancerListener
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicListener' ] ]
PrivateListener:
Description: The ARN of the public load balancer's Listener
Value: !Ref PrivateLoadBalancerListener
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateListener' ] ]
VPCId:
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'VPCId' ] ]
PublicSubnetOne:
Description: Public subnet one
Value: !Ref 'PublicSubnetOne'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetOne' ] ]
PublicSubnetTwo:
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetTwo' ] ]
PrivateSubnetOne:
Description: Private subnet one
Value: !Ref 'PrivateSubnetOne'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetOne' ] ]
PrivateSubnetTwo:
Description: Private subnet two
Value: !Ref 'PrivateSubnetTwo'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetTwo' ] ]
EcsHostSecurityGroup:
Description: A security group used to allow containers to receive traffic
Value: !Ref 'EcsHostSecurityGroup'
Export:
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'EcsHostSecurityGroup' ] ]

View File

@@ -0,0 +1,120 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy the instana agent on ECS as a daemon service
Parameters:
StackName:
Type: String
Default: production
Description: The name of the parent cluster stack that you created. Necessary
to locate and reference resources created by that stack.
ServiceName:
Type: String
Default: instana-agent
Description: A name for the service
ImageUrl:
Type: String
Default: instana/agent
Description: The url of a docker image that contains the application process that
will handle the traffic for this service
ContainerCpu:
Type: Number
Default: 1024
Description: How much CPU to give the container. 1024 is 1 CPU
ContainerMemory:
Type: Number
Default: 2048
Description: How much memory in megabytes to give the container
Role:
Type: String
Default: ""
Description: (Optional) An IAM role to give the service's containers if the code within needs to
access other AWS resources like S3 buckets, DynamoDB tables, etc
InstanaAgentKey:
Type: String
InstanaAgentEndpoint:
Type: String
Default: "ingress-red-saas.instana.io"
InstanaAgentEndpointPort:
Type: Number
Default: '443'
Conditions:
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
Resources:
# The task definition. This is a simple metadata description of what
# container to run, and what resource requirements it has.
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'ServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
NetworkMode: host
IpcMode: host
PidMode: host
Volumes:
- Host:
SourcePath: "/var/run"
Name: "host-var-run"
- Host:
SourcePath: "/run"
Name: "host-run"
- Host:
SourcePath: "/dev"
Name: "host-dev"
- Host:
SourcePath: "/sys"
Name: "host-sys"
- Host:
SourcePath: "/var/log"
Name: "host-var-log"
ContainerDefinitions:
- Name: !Ref 'ServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: !Ref 'ImageUrl'
Privileged: true
MountPoints:
- ContainerPath: /var/run
SourceVolume: "host-var-run"
ReadOnly: false
- ContainerPath: /run
SourceVolume: "host-run"
ReadOnly: false
- ContainerPath: /dev
SourceVolume: "host-dev"
ReadOnly: false
- ContainerPath: /sys
SourceVolume: "host-sys"
ReadOnly: false
- ContainerPath: /var/log
SourceVolume: "host-var-log"
ReadOnly: false
Environment:
- Name: INSTANA_ZONE
Value: !Ref 'StackName'
- Name: INSTANA_AGENT_ENDPOINT
Value: !Ref 'InstanaAgentEndpoint'
- Name: INSTANA_AGENT_ENDPOINT_PORT
Value: !Ref 'InstanaAgentEndpointPort'
- Name: INSTANA_AGENT_KEY
Value: !Ref 'InstanaAgentKey'
# The service. The service is a resource which allows you to run multiple
# copies of a type of task, and gather up their logs and metrics, as well
# as monitor the number of running tasks and replace any that have crashed
Service:
Type: AWS::ECS::Service
Properties:
ServiceName: !Ref 'ServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
TaskDefinition: !Ref 'TaskDefinition'
SchedulingStrategy: DAEMON

752
aws-ecs-ec2/services.yaml Normal file
View File

@@ -0,0 +1,752 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy robot shop services to a given ECS cluster
Parameters:
StackName:
Type: String
Default: ecs-ec2-robotshop
Description: The name of the parent cluster stack that you created. Necessary
to locate and reference resources created by that stack.
WebServiceName:
Type: String
Default: web
Description: The web service name
MongoDbServiceName:
Type: String
Default: mongodb
Description: The mongodb service name
RedisServiceName:
Type: String
Default: redis
Description: The redis service name
RabbitMqServiceName:
Type: String
Default: rabbitmq
Description: The rabbitmq service name
CatalogueServiceName:
Type: String
Default: catalogue
Description: The catalogue service name
UserServiceName:
Type: String
Default: user
Description: The user service name
CartServiceName:
Type: String
Default: cart
Description: The cart service name
MySqlServiceName:
Type: String
Default: mysql
Description: The cart service name
ShippingServiceName:
Type: String
Default: shipping
Description: The cart service name
RatingsServiceName:
Type: String
Default: ratings
Description: The cart service name
PaymentServiceName:
Type: String
Default: payment
Description: The payment service name
DispatchServiceName:
Type: String
Default: dispatch
Description: The payment service name
ImageUrl:
Type: String
Default: nginx
Description: The url of a docker image that contains the application process that
will handle the traffic for this service
WebContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
MongoDbContainerPort:
Type: Number
Default: 27017
Description: What port number the application inside the docker container is binding to
RedisContainerPort:
Type: Number
Default: 6379
Description: What port number the application inside the docker container is binding to
RabbitMqContainerPort:
Type: Number
Default: 5672
Description: What port number the application inside the docker container is binding to
CatalogueContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
UserContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
CartContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
MySqlContainerPort:
Type: Number
Default: 3306
Description: What port number the application inside the docker container is binding to
ShippingContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
RatingsContainerPort:
Type: Number
Default: 80
Description: What port number the application inside the docker container is binding to
PaymentContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
DispatchContainerPort:
Type: Number
Default: 8080
Description: What port number the application inside the docker container is binding to
ContainerCpu:
Type: Number
Default: 256
Description: How much CPU to give the container. 1024 is 1 CPU
ContainerMemory:
Type: Number
Default: 512
Description: How much memory in megabytes to give the container
Path:
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.
Priority:
Type: Number
Default: 1
Description: The priority for the routing rule added to the load balancer.
This only applies if your have multiple services which have been
assigned to different paths on the load balancer.
DesiredCount:
Type: Number
Default: 2
Description: How many copies of the service task to run
Role:
Type: String
Default: ""
Description: (Optional) An IAM role to give the service's containers if the code within needs to
access other AWS resources like S3 buckets, DynamoDB tables, etc
WebLogGroup:
Type: String
Default: "rs-web"
Conditions:
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
Resources:
Registry:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Description: RobotShop registry for ecs
Name: robot-shop
Vpc:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'VPCId']]
# MongoDB service
MongoDbTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'MongoDbServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'MongoDbServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-mongodb:0.4.17
PortMappings:
- ContainerPort: !Ref 'MongoDbContainerPort'
LogConfiguration:
LogDriver: json-file
MongoDbService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'MongoDbServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'MongoDbTaskDefinition'
# Redis service
RedisTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'RedisServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'RedisServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: redis:4.0.6
PortMappings:
- ContainerPort: !Ref 'RedisContainerPort'
LogConfiguration:
LogDriver: json-file
RedisService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'RedisServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'RedisTaskDefinition'
# rabbitmq service
RabbitMqTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'RabbitMqServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'RabbitMqServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: rabbitmq:3.7-management-alpine
PortMappings:
- ContainerPort: !Ref 'RabbitMqContainerPort'
LogConfiguration:
LogDriver: json-file
RabbitMqService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'RabbitMqServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'RabbitMqTaskDefinition'
# catalogue service
CatalogueTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['MongoDbService']
Properties:
Family: !Ref 'CatalogueServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'CatalogueServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-catalogue:0.4.17
PortMappings:
- ContainerPort: !Ref 'CatalogueContainerPort'
LogConfiguration:
LogDriver: json-file
CatalogueService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, CatalogueRegistryService]
Properties:
ServiceName: !Ref 'CatalogueServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'CatalogueServiceName'
ContainerPort: !Ref 'CatalogueContainerPort'
RegistryArn: !GetAtt CatalogueRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'CatalogueTaskDefinition'
CatalogueRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'CatalogueServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# user service
UserTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['MongoDbService', 'RedisService']
Properties:
Family: !Ref 'UserServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'UserServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-user:0.4.17
PortMappings:
- ContainerPort: !Ref 'UserContainerPort'
LogConfiguration:
LogDriver: json-file
UserService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, UserRegistryService]
Properties:
ServiceName: !Ref 'UserServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'UserServiceName'
ContainerPort: !Ref 'UserContainerPort'
RegistryArn: !GetAtt UserRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'UserTaskDefinition'
UserRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'UserServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# cart service
CartTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['RedisService']
Properties:
Family: !Ref 'CartServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'CartServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-cart:0.4.17
PortMappings:
- ContainerPort: !Ref 'CartContainerPort'
LogConfiguration:
LogDriver: json-file
CartService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, CartRegistryService]
Properties:
ServiceName: !Ref 'CartServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'CartServiceName'
ContainerPort: !Ref 'CartContainerPort'
RegistryArn: !GetAtt CartRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'CartTaskDefinition'
CartRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'CartServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# mysql service
MySqlTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'MySqlServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'MySqlServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
LinuxParameters:
Capabilities:
Add:
- NET_ADMIN
Image: robotshop/rs-mysql-db:0.4.17
PortMappings:
- ContainerPort: !Ref 'MySqlContainerPort'
LogConfiguration:
LogDriver: json-file
MySqlService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'MySqlServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'MySqlTaskDefinition'
# shipping service
ShippingTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['MySqlService']
Properties:
Family: !Ref 'ShippingServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'ShippingServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-shipping:0.4.17
PortMappings:
- ContainerPort: !Ref 'ShippingContainerPort'
LogConfiguration:
LogDriver: json-file
ShippingService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, ShippingRegistryService]
Properties:
ServiceName: !Ref 'ShippingServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'ShippingServiceName'
ContainerPort: !Ref 'ShippingContainerPort'
RegistryArn: !GetAtt ShippingRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'ShippingTaskDefinition'
ShippingRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'ShippingServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# ratings service
RatingsTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['MySqlService']
Properties:
Family: !Ref 'RatingsServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'RatingsServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-ratings:0.4.17
PortMappings:
- ContainerPort: !Ref 'RatingsContainerPort'
LogConfiguration:
LogDriver: json-file
RatingsService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, RatingsRegistryService]
Properties:
ServiceName: !Ref 'RatingsServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'RatingsServiceName'
ContainerPort: !Ref 'RatingsContainerPort'
RegistryArn: !GetAtt RatingsRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'RatingsTaskDefinition'
RatingsRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'RatingsServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# payment service
PaymentTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['RabbitMqService']
Properties:
Family: !Ref 'PaymentServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
NetworkMode: awsvpc
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'PaymentServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-payment:0.4.17
PortMappings:
- ContainerPort: !Ref 'PaymentContainerPort'
LogConfiguration:
LogDriver: json-file
PaymentService:
Type: AWS::ECS::Service
DependsOn: [LoadBalancerRule, PaymentRegistryService]
Properties:
ServiceName: !Ref 'PaymentServiceName'
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetOne']]
- Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PrivateSubnetTwo']]
ServiceRegistries:
- ContainerName: !Ref 'PaymentServiceName'
ContainerPort: !Ref 'PaymentContainerPort'
RegistryArn: !GetAtt PaymentRegistryService.Arn
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'PaymentTaskDefinition'
PaymentRegistryService:
Type: AWS::ServiceDiscovery::Service
DependsOn: Registry
Properties:
Name: !Ref 'PaymentServiceName'
DnsConfig:
NamespaceId: !GetAtt Registry.Id
DnsRecords:
- TTL: 10
Type: SRV
- TTL: 10
Type: A
RoutingPolicy: WEIGHTED
# dispatch service
DispatchTaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn: ['RabbitMqService']
Properties:
Family: !Ref 'DispatchServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'DispatchServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-dispatch:0.4.17
PortMappings:
- ContainerPort: !Ref 'DispatchContainerPort'
LogConfiguration:
LogDriver: json-file
DispatchService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerRule
Properties:
ServiceName: !Ref 'DispatchServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DesiredCount: 1
TaskDefinition: !Ref 'DispatchTaskDefinition'
WebTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref 'WebServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
TaskRoleArn:
Fn::If:
- 'HasCustomRole'
- !Ref 'Role'
- !Ref "AWS::NoValue"
ContainerDefinitions:
- Name: !Ref 'WebServiceName'
Cpu: !Ref 'ContainerCpu'
Memory: !Ref 'ContainerMemory'
Image: robotshop/rs-web:0.4.17
Environment:
- Name: CATALOGUE_HOST
Value: catalogue.robot-shop
- Name: USER_HOST
Value: user.robot-shop
- Name: CART_HOST
Value: cart.robot-shop
- Name: SHIPPING_HOST
Value: shipping.robot-shop
- Name: PAYMENT_HOST
Value: payment.robot-shop
- Name: RATINGS_HOST
Value: ratings.robot-shop
PortMappings:
- ContainerPort: !Ref 'WebContainerPort'
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-create-group: true
awslogs-region: !Ref AWS::Region
awslogs-group: !Ref WebLogGroup
awslogs-stream-prefix: ecs
WebService:
Type: AWS::ECS::Service
DependsOn: ['LoadBalancerRule', 'CatalogueService']
Properties:
ServiceName: !Ref 'WebServiceName'
Cluster:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'ClusterName']]
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 75
DesiredCount: !Ref 'DesiredCount'
TaskDefinition: !Ref 'WebTaskDefinition'
LoadBalancers:
- ContainerName: !Ref 'WebServiceName'
ContainerPort: !Ref 'WebContainerPort'
TargetGroupArn: !Ref 'WebTargetGroup'
WebTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Name: !Ref 'WebServiceName'
Port: !Ref 'WebContainerPort'
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'VPCId']]
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'WebTargetGroup'
Type: 'forward'
Conditions:
- Field: path-pattern
Values: [!Ref 'Path']
ListenerArn:
Fn::ImportValue:
!Join [':', [!Ref 'StackName', 'PublicListener']]
Priority: !Ref 'Priority'

View File

@@ -0,0 +1,8 @@
# Robot-Shop on AWS ECS with Fargate
## Prerequisites
The `ecs-cli` tool has to be on your `$PATH`.
[Read more on installing it](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html)