From dec269815721100b478b1630e1e08c316eca1285 Mon Sep 17 00:00:00 2001 From: ebosas Date: Wed, 3 Nov 2021 08:36:06 +0200 Subject: [PATCH] Pipeline deployment type --- README.md | 20 +- deployments/cluster-ec2.yml | 214 ------------------ deployments/services-ec2/cache.yml | 237 -------------------- deployments/services-ec2/database.yml | 237 -------------------- deployments/services-ec2/server.yml | 299 -------------------------- 5 files changed, 19 insertions(+), 988 deletions(-) delete mode 100644 deployments/cluster-ec2.yml delete mode 100644 deployments/services-ec2/cache.yml delete mode 100644 deployments/services-ec2/database.yml delete mode 100644 deployments/services-ec2/server.yml diff --git a/README.md b/README.md index a97aae6..96e1dd1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,25 @@ A basic example of microservice architecture which demonstrates communication be ![](demo.gif) -## Usage +## Deployment on AWS Fargate + +`cd deployments` and create the pipeline stack: + +```bash +aws cloudformation create-stack \ + --stack-name MicroservicesPipeline \ + --template-body file://pipeline.yml \ + --parameters \ + ParameterKey=DeploymentType,ParameterValue=fargate \ + ParameterKey=EnvironmentName,ParameterValue=microservices \ + ParameterKey=GitHubRepo,ParameterValue= \ + ParameterKey=GitHubBranch,ParameterValue= \ + ParameterKey=GitHubToken,ParameterValue= \ + ParameterKey=GitHubUser,ParameterValue= \ + --capabilities CAPABILITY_NAMED_IAM +``` + +## Local use To run the example, clone the Github repository and start the services using Docker Compose. Once Docker finishes downloading and building images, the front end is accessible by visiting `localhost:8080`. diff --git a/deployments/cluster-ec2.yml b/deployments/cluster-ec2.yml deleted file mode 100644 index aac68d8..0000000 --- a/deployments/cluster-ec2.yml +++ /dev/null @@ -1,214 +0,0 @@ -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 - 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 diff --git a/deployments/services-ec2/cache.yml b/deployments/services-ec2/cache.yml deleted file mode 100644 index 20db679..0000000 --- a/deployments/services-ec2/cache.yml +++ /dev/null @@ -1,237 +0,0 @@ -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 - # ImageUrl: - # Type: String - # Description: The url of a docker image that contains the application process that - # will handle the traffic for this 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 - # Image: !Ref ImageUrl - 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 diff --git a/deployments/services-ec2/database.yml b/deployments/services-ec2/database.yml deleted file mode 100644 index 66d147e..0000000 --- a/deployments/services-ec2/database.yml +++ /dev/null @@ -1,237 +0,0 @@ -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 - # ImageUrl: - # Type: String - # Description: The url of a docker image that contains the application process that - # will handle the traffic for this 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 - # Image: !Ref ImageUrl - 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 diff --git a/deployments/services-ec2/server.yml b/deployments/services-ec2/server.yml deleted file mode 100644 index c7f206e..0000000 --- a/deployments/services-ec2/server.yml +++ /dev/null @@ -1,299 +0,0 @@ -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 - # ImageUrl: - # Type: String - # Description: The url of a docker image that contains the application process that - # will handle the traffic for this 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 - # Image: !Ref ImageUrl - 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