You've already forked microservices
mirror of
https://github.com/ebosas/microservices.git
synced 2025-08-24 20:08:55 +02:00
Deployment to Amazon ECS/AWS Fargate
This commit is contained in:
@@ -74,7 +74,7 @@ To access the back end service, attach to its docker container from a separate t
|
|||||||
docker attach microservices_backend
|
docker attach microservices_backend
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deployment on Amazon ECS/AWS Fargate
|
## Deployment to Amazon ECS/AWS Fargate
|
||||||
|
|
||||||
### ECR
|
### ECR
|
||||||
|
|
||||||
|
80
deployments/alb.yml
Normal file
80
deployments/alb.yml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: External, public facing load balancer, for forwarding public traffic to containers.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this load balancer to
|
||||||
|
Resources:
|
||||||
|
EcsSecurityGroupIngressFromPublicALB:
|
||||||
|
Type: AWS::EC2::SecurityGroupIngress
|
||||||
|
Properties:
|
||||||
|
Description: Ingress from the public ALB
|
||||||
|
GroupId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
IpProtocol: -1
|
||||||
|
SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'
|
||||||
|
|
||||||
|
# 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. 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:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
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
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}: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
|
||||||
|
Port: 80
|
||||||
|
Protocol: HTTP
|
||||||
|
UnhealthyThresholdCount: 2
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
PublicLoadBalancerListener:
|
||||||
|
Type: AWS::ElasticLoadBalancingV2::Listener
|
||||||
|
Properties:
|
||||||
|
DefaultActions:
|
||||||
|
- TargetGroupArn: !Ref 'DummyTargetGroupPublic'
|
||||||
|
Type: 'forward'
|
||||||
|
LoadBalancerArn: !Ref 'PublicLoadBalancer'
|
||||||
|
Port: 80
|
||||||
|
Protocol: HTTP
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
PublicListener:
|
||||||
|
Description: The ARN of the public load balancer's Listener
|
||||||
|
Value: !Ref PublicLoadBalancerListener
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:PublicListener
|
||||||
|
ExternalUrl:
|
||||||
|
Description: The url of the external load balancer
|
||||||
|
Value: !Sub http://${PublicLoadBalancer.DNSName}
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:ExternalUrl
|
214
deployments/cluster-ec2.yml
Normal file
214
deployments/cluster-ec2.yml
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: EC2 ECS cluster running containers in public or private subnets.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: "A friendly environment name that will be used for namespacing all cluster resources. Example: staging, qa, or production"
|
||||||
|
InstanceType:
|
||||||
|
Type: String
|
||||||
|
Default: t2.micro
|
||||||
|
Description: Class of EC2 instance used to host containers. Choose t2 for testing, m5 for general purpose, c5 for CPU intensive services, and r5 for memory intensive services
|
||||||
|
AllowedValues: [ t2.micro, t2.small, t2.medium, t2.large, t2.xlarge, t2.2xlarge,
|
||||||
|
m5.large, m5.xlarge, m5.2xlarge, m5.4xlarge, m5.12xlarge, m5.24xlarge,
|
||||||
|
c5.large, c5.xlarge, c5.2xlarge, c5.4xlarge, c5.9xlarge, c5.18xlarge,
|
||||||
|
r5.large, r5.xlarge, r5.2xlarge, r5.4xlarge, r5.12xlarge, r5.24xlarge ]
|
||||||
|
ConstraintDescription: Please choose a valid instance type.
|
||||||
|
DesiredCapacity:
|
||||||
|
Type: Number
|
||||||
|
Default: '1'
|
||||||
|
Description: Number of EC2 instances to launch in your ECS cluster.
|
||||||
|
MaxSize:
|
||||||
|
Type: Number
|
||||||
|
Default: '3'
|
||||||
|
Description: Maximum number of EC2 instances that can be launched in your ECS cluster.
|
||||||
|
ECSAMI:
|
||||||
|
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
|
||||||
|
Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id
|
||||||
|
Description: The Amazon Machine Image ID used for the cluster, leave it as the default value to get the latest AMI
|
||||||
|
Resources:
|
||||||
|
# ECS Resources
|
||||||
|
ECSCluster:
|
||||||
|
Type: AWS::ECS::Cluster
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
# Protection from scale-in is required with capacity providers but
|
||||||
|
# the auto scaling group will have to be manually removed when deleting
|
||||||
|
# the ec2 cluster stack in cloudformation.
|
||||||
|
NewInstancesProtectedFromScaleIn: true
|
||||||
|
VPCZoneIdentifier:
|
||||||
|
# Choose private subnets if using NAT gateways
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetTwo
|
||||||
|
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:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
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
|
||||||
|
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region}
|
||||||
|
EC2InstanceProfile:
|
||||||
|
Type: AWS::IAM::InstanceProfile
|
||||||
|
Properties:
|
||||||
|
Path: /
|
||||||
|
Roles: [!Ref 'EC2Role']
|
||||||
|
|
||||||
|
# Capacity provider. Automatically manages the scaling of the EC2 instances.
|
||||||
|
ECSCapacityProvider:
|
||||||
|
Type: AWS::ECS::CapacityProvider
|
||||||
|
Properties:
|
||||||
|
AutoScalingGroupProvider:
|
||||||
|
AutoScalingGroupArn: !Ref ECSAutoScalingGroup
|
||||||
|
ManagedScaling:
|
||||||
|
MaximumScalingStepSize: 2
|
||||||
|
MinimumScalingStepSize: 1
|
||||||
|
Status: ENABLED
|
||||||
|
TargetCapacity: 100
|
||||||
|
ManagedTerminationProtection: ENABLED
|
||||||
|
ECSClusterCapProvAssoc:
|
||||||
|
Type: AWS::ECS::ClusterCapacityProviderAssociations
|
||||||
|
Properties:
|
||||||
|
Cluster: !Ref ECSCluster
|
||||||
|
CapacityProviders:
|
||||||
|
- !Ref ECSCapacityProvider
|
||||||
|
DefaultCapacityProviderStrategy:
|
||||||
|
- CapacityProvider: !Ref ECSCapacityProvider
|
||||||
|
Weight: 100
|
||||||
|
|
||||||
|
# A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets
|
||||||
|
# on your AWS account
|
||||||
|
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: '*'
|
||||||
|
|
||||||
|
# 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: '*'
|
||||||
|
|
||||||
|
# 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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
AutoscalingRole:
|
||||||
|
Description: The ARN of the role used for autoscaling
|
||||||
|
Value: !GetAtt 'AutoscalingRole.Arn'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
ECSRole:
|
||||||
|
Description: The ARN of the ECS role
|
||||||
|
Value: !GetAtt 'ECSRole.Arn'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:ECSRole
|
128
deployments/cluster-fargate.yml
Normal file
128
deployments/cluster-fargate.yml
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: AWS Fargate cluster that can span public and private subnets.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: "A friendly environment name that will be used for namespacing all cluster resources. Example: staging, qa, or production"
|
||||||
|
Resources:
|
||||||
|
# ECS Resources
|
||||||
|
ECSCluster:
|
||||||
|
Type: AWS::ECS::Cluster
|
||||||
|
|
||||||
|
# A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets
|
||||||
|
# on your AWS account
|
||||||
|
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: '*'
|
||||||
|
|
||||||
|
# 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: '*'
|
||||||
|
|
||||||
|
# This is a role which is used by the ECS tasks themselves.
|
||||||
|
ECSTaskExecutionRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Principal:
|
||||||
|
Service: [ecs-tasks.amazonaws.com]
|
||||||
|
Action: ['sts:AssumeRole']
|
||||||
|
Path: /
|
||||||
|
Policies:
|
||||||
|
- PolicyName: AmazonECSTaskExecutionRolePolicy
|
||||||
|
PolicyDocument:
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
# Allow the ECS Tasks to download images from ECR
|
||||||
|
- 'ecr:GetAuthorizationToken'
|
||||||
|
- 'ecr:BatchCheckLayerAvailability'
|
||||||
|
- 'ecr:GetDownloadUrlForLayer'
|
||||||
|
- 'ecr:BatchGetImage'
|
||||||
|
|
||||||
|
# Allow the ECS tasks to upload logs to CloudWatch
|
||||||
|
- 'logs:CreateLogStream'
|
||||||
|
- 'logs:PutLogEvents'
|
||||||
|
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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
AutoscalingRole:
|
||||||
|
Description: The ARN of the role used for autoscaling
|
||||||
|
Value: !GetAtt 'AutoscalingRole.Arn'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
ECSRole:
|
||||||
|
Description: The ARN of the ECS role
|
||||||
|
Value: !GetAtt 'ECSRole.Arn'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:ECSRole
|
||||||
|
ECSTaskExecutionRole:
|
||||||
|
Description: The ARN of the ECS role
|
||||||
|
Value: !GetAtt 'ECSTaskExecutionRole.Arn'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:ECSTaskExecutionRole
|
220
deployments/network.yml
Normal file
220
deployments/network.yml
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: The network stack for the ECS cluster.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: "A friendly environment name that will be used for namespacing all cluster resources. Example: staging, qa, or production"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# A security group for either the EC2 hosts that will run the containers
|
||||||
|
# or the containers we will run in Fargate. Rules are added based on
|
||||||
|
# what ingress you choose to add to the cluster.
|
||||||
|
ContainerSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
GroupDescription: Access to the ECS hosts that run containers
|
||||||
|
VpcId: !Ref 'VPC'
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
VpcId:
|
||||||
|
Description: The ID of the VPC that this stack is deployed in
|
||||||
|
Value: !Ref 'VPC'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:VpcId
|
||||||
|
PublicSubnetOne:
|
||||||
|
Description: Public subnet one
|
||||||
|
Value: !Ref 'PublicSubnetOne'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
PublicSubnetTwo:
|
||||||
|
Description: Public subnet two
|
||||||
|
Value: !Ref 'PublicSubnetTwo'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:PublicSubnetTwo
|
||||||
|
PrivateSubnetOne:
|
||||||
|
Description: Private subnet one
|
||||||
|
Value: !Ref 'PrivateSubnetOne'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:PrivateSubnetOne
|
||||||
|
PrivateSubnetTwo:
|
||||||
|
Description: Private subnet two
|
||||||
|
Value: !Ref 'PrivateSubnetTwo'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:PrivateSubnetTwo
|
||||||
|
ContainerSecurityGroup:
|
||||||
|
Description: A security group used to allow containers to receive traffic
|
||||||
|
Value: !Ref 'ContainerSecurityGroup'
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
179
deployments/resources.yml
Normal file
179
deployments/resources.yml
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: The RabbitMQ, Redis, and PostgreSQL resources.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: "A friendly environment name that will be used for namespacing all cluster resources. Example: staging, qa, or production"
|
||||||
|
RabbitUsername:
|
||||||
|
Type: String
|
||||||
|
Default: rabbit
|
||||||
|
Description: A RabbitMQ username
|
||||||
|
PostgresUsername:
|
||||||
|
Type: String
|
||||||
|
Default: postgres
|
||||||
|
Description: A Postgres username
|
||||||
|
RabbitPassword:
|
||||||
|
NoEcho: true
|
||||||
|
Type: String
|
||||||
|
Default: Secret123456 # remove
|
||||||
|
AllowedPattern: "^[a-zA-Z0-9]{12,20}$"
|
||||||
|
Description: The RabbitMQ password
|
||||||
|
PostgresPassword:
|
||||||
|
NoEcho: true
|
||||||
|
Type: String
|
||||||
|
Default: Secret123456 # remove
|
||||||
|
AllowedPattern: "^[a-zA-Z0-9]{12,20}$"
|
||||||
|
Description: The Postgres password
|
||||||
|
Resources:
|
||||||
|
# A RabbitMQ broker
|
||||||
|
RabbitMQ:
|
||||||
|
Type: AWS::AmazonMQ::Broker
|
||||||
|
Properties:
|
||||||
|
AutoMinorVersionUpgrade: false
|
||||||
|
BrokerName: RabbitBroker
|
||||||
|
DeploymentMode: SINGLE_INSTANCE
|
||||||
|
EngineType: RABBITMQ
|
||||||
|
EngineVersion: 3.8.22
|
||||||
|
HostInstanceType: mq.t3.micro
|
||||||
|
PubliclyAccessible: false
|
||||||
|
SecurityGroups: [!Ref RabbitSecurityGroup]
|
||||||
|
SubnetIds:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PrivateSubnetOne
|
||||||
|
Users:
|
||||||
|
- Password: !Ref RabbitPassword
|
||||||
|
Username: !Ref RabbitUsername
|
||||||
|
RabbitSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
GroupDescription: Access to RabbitMQ
|
||||||
|
SecurityGroupIngress:
|
||||||
|
- SourceSecurityGroupId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 5671
|
||||||
|
ToPort: 5671
|
||||||
|
|
||||||
|
# A Redis cluster
|
||||||
|
Redis:
|
||||||
|
Type: AWS::ElastiCache::CacheCluster
|
||||||
|
DeletionPolicy: Delete
|
||||||
|
Properties:
|
||||||
|
Engine: redis
|
||||||
|
ClusterName: RedisCluster
|
||||||
|
CacheNodeType: cache.t2.micro
|
||||||
|
NumCacheNodes: 1
|
||||||
|
CacheSubnetGroupName: !Ref RedisSubnetGroup
|
||||||
|
VpcSecurityGroupIds: [!Ref RedisSecurityGroup]
|
||||||
|
RedisSubnetGroup:
|
||||||
|
Type: AWS::ElastiCache::SubnetGroup
|
||||||
|
Properties:
|
||||||
|
Description: !Sub ${EnvironmentName}-Redis
|
||||||
|
SubnetIds:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PrivateSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PrivateSubnetTwo
|
||||||
|
RedisSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
GroupDescription: Access to Redis
|
||||||
|
SecurityGroupIngress:
|
||||||
|
- SourceSecurityGroupId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 6379
|
||||||
|
ToPort: 6379
|
||||||
|
|
||||||
|
# A Postgres database
|
||||||
|
Postgres:
|
||||||
|
Type: AWS::RDS::DBInstance
|
||||||
|
DeletionPolicy: Delete
|
||||||
|
Properties:
|
||||||
|
DBInstanceIdentifier: postgresinstance
|
||||||
|
DBName: microservices
|
||||||
|
DBInstanceClass: db.t2.micro
|
||||||
|
StorageType: gp2
|
||||||
|
AllocatedStorage: 20
|
||||||
|
MaxAllocatedStorage: 21
|
||||||
|
Engine: postgres
|
||||||
|
EngineVersion: 12.8
|
||||||
|
MasterUsername: !Ref PostgresUsername
|
||||||
|
MasterUserPassword: !Ref PostgresPassword
|
||||||
|
MultiAZ: false
|
||||||
|
PubliclyAccessible: false
|
||||||
|
VPCSecurityGroups: [!Ref PostgresSecurityGroup]
|
||||||
|
DBSubnetGroupName: !Ref PostgresSubnetGroup
|
||||||
|
PostgresSubnetGroup:
|
||||||
|
Type: AWS::RDS::DBSubnetGroup
|
||||||
|
Properties:
|
||||||
|
DBSubnetGroupDescription: !Sub ${EnvironmentName}-Postgres
|
||||||
|
SubnetIds:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PrivateSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PrivateSubnetTwo
|
||||||
|
PostgresSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
GroupDescription: Access to Postgres
|
||||||
|
SecurityGroupIngress:
|
||||||
|
- SourceSecurityGroupId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 5432
|
||||||
|
ToPort: 5432
|
||||||
|
# - CidrIp: 0.0.0.0/0
|
||||||
|
# IpProtocol: tcp
|
||||||
|
# FromPort: 5432
|
||||||
|
# ToPort: 5432
|
||||||
|
|
||||||
|
# # An example showing how to use Secrets Manager to generate login credentials.
|
||||||
|
# # Refer in templates like this '{{resolve:secretsmanager:RabbitSecrets::password}}'
|
||||||
|
# RabbitSecrets:
|
||||||
|
# Type: AWS::SecretsManager::Secret
|
||||||
|
# Properties:
|
||||||
|
# Name: RabbitSecrets
|
||||||
|
# Description: This secret has a dynamically generated password
|
||||||
|
# GenerateSecretString:
|
||||||
|
# SecretStringTemplate: '{"username": "rabbit"}'
|
||||||
|
# GenerateStringKey: "password"
|
||||||
|
# PasswordLength: 15
|
||||||
|
# ExcludeCharacters: ',:='
|
||||||
|
|
||||||
|
# Connection strings for the resources created in this stack, will be passed to
|
||||||
|
# services as environmental variables. This will expose passwords in SSM Parameter
|
||||||
|
# Store as well as the ECS tasks definitions interface. Instead, use Secrets
|
||||||
|
# Manager to generate passwords and retrieve directly in applicaton code as shown
|
||||||
|
# in the commented example above.
|
||||||
|
RabbitURLParameter:
|
||||||
|
Type: AWS::SSM::Parameter
|
||||||
|
Properties:
|
||||||
|
Name: !Sub /microservices/${EnvironmentName}/rabbiturl
|
||||||
|
Type: String
|
||||||
|
Description: A connection string for RabbitMQ
|
||||||
|
Value:
|
||||||
|
Fn::Join:
|
||||||
|
- ''
|
||||||
|
- - !Sub amqps://${RabbitUsername}:${RabbitPassword}@
|
||||||
|
- !Select [1, !Split ['://', !Select [0, !GetAtt RabbitMQ.AmqpEndpoints]]]
|
||||||
|
PostgresURLParameter:
|
||||||
|
Type: AWS::SSM::Parameter
|
||||||
|
Properties:
|
||||||
|
Name: !Sub /microservices/${EnvironmentName}/postgresurl
|
||||||
|
Type: String
|
||||||
|
Description: A connection string for Postgres
|
||||||
|
Value:
|
||||||
|
Fn::Join:
|
||||||
|
- ''
|
||||||
|
- - !Sub postgres://${PostgresUsername}:${PostgresPassword}@
|
||||||
|
- !Sub ${Postgres.Endpoint.Address}:${Postgres.Endpoint.Port}
|
||||||
|
RedisURLParameter:
|
||||||
|
Type: AWS::SSM::Parameter
|
||||||
|
Properties:
|
||||||
|
Name: !Sub /microservices/${EnvironmentName}/redisurl
|
||||||
|
Type: String
|
||||||
|
Description: A connection string for Redis
|
||||||
|
Value: !Sub ${Redis.RedisEndpoint.Address}:${Redis.RedisEndpoint.Port}
|
232
deployments/services-ec2/cache.yml
Normal file
232
deployments/services-ec2/cache.yml
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service into an ECS cluster behind a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: cache
|
||||||
|
Description: A name for the service
|
||||||
|
ContainerCpu:
|
||||||
|
Type: Number
|
||||||
|
Default: 256
|
||||||
|
Description: How much CPU to give the container. 1024 is 1 CPU
|
||||||
|
ContainerMemory:
|
||||||
|
Type: Number
|
||||||
|
Default: 230
|
||||||
|
Description: How much memory in megabytes to give the container
|
||||||
|
DesiredCount:
|
||||||
|
Type: Number
|
||||||
|
Default: 1
|
||||||
|
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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: REDIS_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/redisurl}}'
|
||||||
|
|
||||||
|
# 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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
PlacementStrategies:
|
||||||
|
- Field: memory
|
||||||
|
Type: binpack
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
232
deployments/services-ec2/database.yml
Normal file
232
deployments/services-ec2/database.yml
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service into an ECS cluster behind a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: database
|
||||||
|
Description: A name for the service
|
||||||
|
ContainerCpu:
|
||||||
|
Type: Number
|
||||||
|
Default: 256
|
||||||
|
Description: How much CPU to give the container. 1024 is 1 CPU
|
||||||
|
ContainerMemory:
|
||||||
|
Type: Number
|
||||||
|
Default: 230
|
||||||
|
Description: How much memory in megabytes to give the container
|
||||||
|
DesiredCount:
|
||||||
|
Type: Number
|
||||||
|
Default: 1
|
||||||
|
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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: POSTGRES_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/postgresurl}}'
|
||||||
|
|
||||||
|
# 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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
PlacementStrategies:
|
||||||
|
- Field: memory
|
||||||
|
Type: binpack
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
294
deployments/services-ec2/server.yml
Normal file
294
deployments/services-ec2/server.yml
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service into an ECS cluster behind a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: server
|
||||||
|
Description: A name for the service
|
||||||
|
ContainerPort:
|
||||||
|
Type: Number
|
||||||
|
Default: 80
|
||||||
|
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: 230
|
||||||
|
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: 1
|
||||||
|
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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
PortMappings:
|
||||||
|
- ContainerPort: !Ref 'ContainerPort'
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: REDIS_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/redisurl}}'
|
||||||
|
- Name: SERVER_ADDR
|
||||||
|
Value: 0.0.0.0:80
|
||||||
|
|
||||||
|
# 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
|
||||||
|
DependsOn: LoadBalancerRule
|
||||||
|
Properties:
|
||||||
|
ServiceName: !Ref 'ServiceName'
|
||||||
|
Cluster:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
PlacementStrategies:
|
||||||
|
- Field: memory
|
||||||
|
Type: binpack
|
||||||
|
LoadBalancers:
|
||||||
|
- ContainerName: !Ref 'ServiceName'
|
||||||
|
ContainerPort: !Ref 'ContainerPort'
|
||||||
|
TargetGroupArn: !Ref 'TargetGroup'
|
||||||
|
|
||||||
|
# A target group. This is used for keeping track of all the tasks, and
|
||||||
|
# what IP addresses / port numbers they have. You can query it yourself,
|
||||||
|
# to use the addresses yourself, but most often this target group is just
|
||||||
|
# connected to an application load balancer, or network load balancer, so
|
||||||
|
# it can automatically distribute traffic across all the targets.
|
||||||
|
TargetGroup:
|
||||||
|
Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
||||||
|
Properties:
|
||||||
|
HealthCheckIntervalSeconds: 6
|
||||||
|
HealthCheckPath: /
|
||||||
|
HealthCheckProtocol: HTTP
|
||||||
|
HealthCheckTimeoutSeconds: 5
|
||||||
|
HealthyThresholdCount: 2
|
||||||
|
Name: !Ref 'ServiceName'
|
||||||
|
Port: 80
|
||||||
|
Protocol: HTTP
|
||||||
|
UnhealthyThresholdCount: 2
|
||||||
|
TargetGroupAttributes:
|
||||||
|
- Key: deregistration_delay.timeout_seconds
|
||||||
|
Value: 60
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
|
||||||
|
# Create a rule on the load balancer for routing traffic to the target group
|
||||||
|
LoadBalancerRule:
|
||||||
|
Type: AWS::ElasticLoadBalancingV2::ListenerRule
|
||||||
|
Properties:
|
||||||
|
Actions:
|
||||||
|
- TargetGroupArn: !Ref 'TargetGroup'
|
||||||
|
Type: 'forward'
|
||||||
|
Conditions:
|
||||||
|
- Field: path-pattern
|
||||||
|
Values: [!Ref 'Path']
|
||||||
|
ListenerArn:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:PublicListener
|
||||||
|
Priority: !Ref 'Priority'
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
244
deployments/services-fargate/cache.yml
Normal file
244
deployments/services-fargate/cache.yml
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service on AWS Fargate, accessible via a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: cache
|
||||||
|
Description: A name for the service
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
NetworkMode: awsvpc
|
||||||
|
RequiresCompatibilities:
|
||||||
|
- FARGATE
|
||||||
|
ExecutionRoleArn:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ECSTaskExecutionRole
|
||||||
|
TaskRoleArn:
|
||||||
|
Fn::If:
|
||||||
|
- 'HasCustomRole'
|
||||||
|
- !Ref 'Role'
|
||||||
|
- !Ref "AWS::NoValue"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: REDIS_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/redisurl}}'
|
||||||
|
|
||||||
|
# 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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
LaunchType: FARGATE
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
NetworkConfiguration:
|
||||||
|
AwsvpcConfiguration:
|
||||||
|
AssignPublicIp: ENABLED
|
||||||
|
SecurityGroups:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
Subnets:
|
||||||
|
# Choose private subnets if using NAT gateways
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetTwo
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
244
deployments/services-fargate/database.yml
Normal file
244
deployments/services-fargate/database.yml
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service on AWS Fargate, accessible via a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: database
|
||||||
|
Description: A name for the service
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
NetworkMode: awsvpc
|
||||||
|
RequiresCompatibilities:
|
||||||
|
- FARGATE
|
||||||
|
ExecutionRoleArn:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ECSTaskExecutionRole
|
||||||
|
TaskRoleArn:
|
||||||
|
Fn::If:
|
||||||
|
- 'HasCustomRole'
|
||||||
|
- !Ref 'Role'
|
||||||
|
- !Ref "AWS::NoValue"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: POSTGRES_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/postgresurl}}'
|
||||||
|
|
||||||
|
# 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: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
LaunchType: FARGATE
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
NetworkConfiguration:
|
||||||
|
AwsvpcConfiguration:
|
||||||
|
AssignPublicIp: ENABLED
|
||||||
|
SecurityGroups:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
Subnets:
|
||||||
|
# Choose private subnets if using NAT gateways
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetTwo
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
307
deployments/services-fargate/server.yml
Normal file
307
deployments/services-fargate/server.yml
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
|
Description: Deploy a service on AWS Fargate, accessible via a public load balancer.
|
||||||
|
Parameters:
|
||||||
|
EnvironmentName:
|
||||||
|
Type: String
|
||||||
|
Default: production
|
||||||
|
Description: The name of the environment to add this service to
|
||||||
|
ServiceName:
|
||||||
|
Type: String
|
||||||
|
Default: server
|
||||||
|
Description: A name for the service
|
||||||
|
ContainerPort:
|
||||||
|
Type: Number
|
||||||
|
Default: 80
|
||||||
|
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 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
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ]
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
# A log group for storing the stdout logs from this service's containers
|
||||||
|
LogGroup:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
LogGroupName: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
NetworkMode: awsvpc
|
||||||
|
RequiresCompatibilities:
|
||||||
|
- FARGATE
|
||||||
|
ExecutionRoleArn:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ECSTaskExecutionRole
|
||||||
|
TaskRoleArn:
|
||||||
|
Fn::If:
|
||||||
|
- 'HasCustomRole'
|
||||||
|
- !Ref 'Role'
|
||||||
|
- !Ref "AWS::NoValue"
|
||||||
|
ContainerDefinitions:
|
||||||
|
- Name: !Ref 'ServiceName'
|
||||||
|
Cpu: !Ref 'ContainerCpu'
|
||||||
|
Memory: !Ref 'ContainerMemory'
|
||||||
|
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/microservices/${ServiceName}:latest
|
||||||
|
PortMappings:
|
||||||
|
- ContainerPort: !Ref 'ContainerPort'
|
||||||
|
LogConfiguration:
|
||||||
|
LogDriver: 'awslogs'
|
||||||
|
Options:
|
||||||
|
awslogs-group: !Sub ${EnvironmentName}-service-${ServiceName}
|
||||||
|
awslogs-region: !Ref 'AWS::Region'
|
||||||
|
awslogs-stream-prefix: !Ref 'ServiceName'
|
||||||
|
Environment:
|
||||||
|
- Name: RABBIT_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/rabbiturl}}'
|
||||||
|
- Name: REDIS_URL
|
||||||
|
Value: !Sub '{{resolve:ssm:/microservices/${EnvironmentName}/redisurl}}'
|
||||||
|
- Name: SERVER_ADDR
|
||||||
|
Value: 0.0.0.0:80
|
||||||
|
|
||||||
|
# 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
|
||||||
|
DependsOn: LoadBalancerRule
|
||||||
|
Properties:
|
||||||
|
ServiceName: !Ref 'ServiceName'
|
||||||
|
Cluster:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
LaunchType: FARGATE
|
||||||
|
DeploymentConfiguration:
|
||||||
|
MaximumPercent: 200
|
||||||
|
MinimumHealthyPercent: 75
|
||||||
|
DesiredCount: !Ref 'DesiredCount'
|
||||||
|
NetworkConfiguration:
|
||||||
|
AwsvpcConfiguration:
|
||||||
|
AssignPublicIp: ENABLED
|
||||||
|
SecurityGroups:
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ContainerSecurityGroup
|
||||||
|
Subnets:
|
||||||
|
# Choose private subnets if using NAT gateways
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetOne
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:PublicSubnetTwo
|
||||||
|
TaskDefinition: !Ref 'TaskDefinition'
|
||||||
|
LoadBalancers:
|
||||||
|
- ContainerName: !Ref 'ServiceName'
|
||||||
|
ContainerPort: !Ref 'ContainerPort'
|
||||||
|
TargetGroupArn: !Ref 'TargetGroup'
|
||||||
|
|
||||||
|
# A target group. This is used for keeping track of all the tasks, and
|
||||||
|
# what IP addresses / port numbers they have. You can query it yourself,
|
||||||
|
# to use the addresses yourself, but most often this target group is just
|
||||||
|
# connected to an application load balancer, or network load balancer, so
|
||||||
|
# it can automatically distribute traffic across all the targets.
|
||||||
|
TargetGroup:
|
||||||
|
Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
||||||
|
Properties:
|
||||||
|
HealthCheckIntervalSeconds: 6
|
||||||
|
HealthCheckPath: /
|
||||||
|
HealthCheckProtocol: HTTP
|
||||||
|
HealthCheckTimeoutSeconds: 5
|
||||||
|
HealthyThresholdCount: 2
|
||||||
|
TargetType: ip
|
||||||
|
Name: !Ref 'ServiceName'
|
||||||
|
Port: !Ref 'ContainerPort'
|
||||||
|
Protocol: HTTP
|
||||||
|
UnhealthyThresholdCount: 2
|
||||||
|
TargetGroupAttributes:
|
||||||
|
- Key: deregistration_delay.timeout_seconds
|
||||||
|
Value: 60
|
||||||
|
VpcId:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:VpcId
|
||||||
|
|
||||||
|
# Create a rule on the load balancer for routing traffic to the target group
|
||||||
|
LoadBalancerRule:
|
||||||
|
Type: AWS::ElasticLoadBalancingV2::ListenerRule
|
||||||
|
Properties:
|
||||||
|
Actions:
|
||||||
|
- TargetGroupArn: !Ref 'TargetGroup'
|
||||||
|
Type: 'forward'
|
||||||
|
Conditions:
|
||||||
|
- Field: path-pattern
|
||||||
|
Values: [!Ref 'Path']
|
||||||
|
ListenerArn:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:PublicListener
|
||||||
|
Priority: !Ref 'Priority'
|
||||||
|
|
||||||
|
# Enable autoscaling for this service
|
||||||
|
ScalableTarget:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||||
|
DependsOn: Service
|
||||||
|
Properties:
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
MinCapacity: 1
|
||||||
|
MaxCapacity: 10
|
||||||
|
RoleARN:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:AutoscalingRole
|
||||||
|
|
||||||
|
# Create scaling policies for the service
|
||||||
|
ScaleDownPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- down
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalUpperBound: 0
|
||||||
|
ScalingAdjustment: -1
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
ScaleUpPolicy:
|
||||||
|
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||||
|
DependsOn: ScalableTarget
|
||||||
|
Properties:
|
||||||
|
PolicyName:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - scale
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- up
|
||||||
|
PolicyType: StepScaling
|
||||||
|
ResourceId:
|
||||||
|
Fn::Join:
|
||||||
|
- '/'
|
||||||
|
- - service
|
||||||
|
- Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
ScalableDimension: 'ecs:service:DesiredCount'
|
||||||
|
ServiceNamespace: 'ecs'
|
||||||
|
StepScalingPolicyConfiguration:
|
||||||
|
AdjustmentType: 'ChangeInCapacity'
|
||||||
|
StepAdjustments:
|
||||||
|
- MetricIntervalLowerBound: 0
|
||||||
|
MetricIntervalUpperBound: 15
|
||||||
|
ScalingAdjustment: 1
|
||||||
|
- MetricIntervalLowerBound: 15
|
||||||
|
MetricIntervalUpperBound: 25
|
||||||
|
ScalingAdjustment: 2
|
||||||
|
- MetricIntervalLowerBound: 25
|
||||||
|
ScalingAdjustment: 3
|
||||||
|
MetricAggregationType: 'Average'
|
||||||
|
Cooldown: 60
|
||||||
|
|
||||||
|
# Create alarms to trigger these policies
|
||||||
|
LowCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - low-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "Low CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 20
|
||||||
|
ComparisonOperator: LessThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleDownPolicy
|
||||||
|
|
||||||
|
HighCpuUsageAlarm:
|
||||||
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
Properties:
|
||||||
|
AlarmName:
|
||||||
|
Fn::Join:
|
||||||
|
- '-'
|
||||||
|
- - high-cpu
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
AlarmDescription:
|
||||||
|
Fn::Join:
|
||||||
|
- ' '
|
||||||
|
- - "High CPU utilization for service"
|
||||||
|
- !Ref 'ServiceName'
|
||||||
|
- "in environment"
|
||||||
|
- !Ref 'EnvironmentName'
|
||||||
|
MetricName: CPUUtilization
|
||||||
|
Namespace: AWS/ECS
|
||||||
|
Dimensions:
|
||||||
|
- Name: ServiceName
|
||||||
|
Value: !Ref 'ServiceName'
|
||||||
|
- Name: ClusterName
|
||||||
|
Value:
|
||||||
|
Fn::ImportValue: !Sub ${EnvironmentName}:ClusterName
|
||||||
|
Statistic: Average
|
||||||
|
Period: 60
|
||||||
|
EvaluationPeriods: 1
|
||||||
|
Threshold: 70
|
||||||
|
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||||
|
AlarmActions:
|
||||||
|
- !Ref ScaleUpPolicy
|
Reference in New Issue
Block a user