| AWSTemplateFormatVersion: '2010-09-09' |
| Description: A stack for deploying instance to run load tests |
| Parameters: |
| DesiredCapacity: |
| Type: Number |
| Default: 3 |
| Description: Number of EC2 instances to launch in your ECS cluster. |
| MaxSize: |
| Type: Number |
| Default: 10 |
| Description: Maximum number of EC2 instances that can be launched in your ECS cluster. |
| ECSAMI: |
| Description: AMI ID |
| Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> |
| Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id |
| InstanceType: |
| Description: EC2 instance type |
| Type: String |
| Default: m4.xlarge |
| AllowedValues: [t2.micro, t2.small, t2.medium, t2.large, m3.medium, m3.large, |
| m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, |
| c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, |
| c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, |
| r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] |
| ConstraintDescription: Please choose a valid instance type. |
| ECSKeyName: |
| Type: String |
| Default: gerrit-cluster-keys |
| Description: EC2 key pair name the cluter's instances |
| EntryPoint: |
| Type: String |
| Default: "docker info" |
| Description: Command to run when startinig the load tests |
| 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 is the subnet which cover the ranges: |
| # |
| # 10.0.0.0 - 10.0.0.255 |
| SubnetConfig: |
| VPC: |
| CIDR: '10.0.0.0/16' |
| PublicOne: |
| CIDR: '10.0.0.0/24' |
| Resources: |
| VPC: |
| Type: AWS::EC2::VPC |
| Properties: |
| EnableDnsSupport: true |
| EnableDnsHostnames: true |
| CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] |
| |
| 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 |
| |
| 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 |
| |
| # ECS Resources |
| ECSCluster: |
| Type: AWS::ECS::Cluster |
| |
| EcsHostSecurityGroup: |
| Type: AWS::EC2::SecurityGroup |
| Properties: |
| GroupDescription: Access to the ECS hosts that run containers |
| VpcId: !Ref 'VPC' |
| SecurityGroupIngress: |
| # Allow access to NLB from anywhere on the internet |
| - CidrIp: 0.0.0.0/0 |
| IpProtocol: -1 |
| |
| CloudWatchLogsGroup: |
| Type: AWS::Logs::LogGroup |
| Properties: |
| LogGroupName: !Ref AWS::StackName |
| RetentionInDays: 1 |
| |
| # Autoscaling group. This launches the actual EC2 instances that will register |
| # themselves as members of the cluster, and run the docker containers. |
| ECSAutoScalingGroup: |
| Type: AWS::AutoScaling::AutoScalingGroup |
| Properties: |
| VPCZoneIdentifier: |
| - !Ref PublicSubnetOne |
| LaunchConfigurationName: !Ref 'ContainerInstances' |
| MinSize: '1' |
| MaxSize: !Ref 'MaxSize' |
| DesiredCapacity: !Ref 'DesiredCapacity' |
| CreationPolicy: |
| ResourceSignal: |
| Timeout: PT15M |
| UpdatePolicy: |
| AutoScalingReplacingUpdate: |
| WillReplace: 'true' |
| ContainerInstances: |
| Type: AWS::AutoScaling::LaunchConfiguration |
| Properties: |
| ImageId: !Ref 'ECSAMI' |
| SecurityGroups: [!Ref 'EcsHostSecurityGroup'] |
| InstanceType: !Ref 'InstanceType' |
| IamInstanceProfile: !Ref 'EC2InstanceProfile' |
| KeyName: !Ref ECSKeyName |
| UserData: |
| Fn::Base64: !Sub | |
| #!/bin/bash -xe |
| echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config |
| yum install -y aws-cfn-bootstrap |
| # Signal to CloudFormation aws-cfn-bootstrap has been correctly updated |
| /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region} |
| ${EntryPoint} |
| AutoscalingRole: |
| Type: AWS::IAM::Role |
| Properties: |
| AssumeRolePolicyDocument: |
| Statement: |
| - Effect: Allow |
| Principal: |
| Service: [application-autoscaling.amazonaws.com] |
| Action: ['sts:AssumeRole'] |
| Path: / |
| Policies: |
| - PolicyName: service-autoscaling |
| PolicyDocument: |
| Statement: |
| - Effect: Allow |
| Action: |
| - 'application-autoscaling:*' |
| - 'cloudwatch:DescribeAlarms' |
| - 'cloudwatch:PutMetricAlarm' |
| - 'ecs:DescribeServices' |
| - 'ecs:UpdateService' |
| Resource: '*' |
| EC2InstanceProfile: |
| Type: AWS::IAM::InstanceProfile |
| Properties: |
| Path: / |
| Roles: [!Ref 'EC2Role'] |
| |
| # Role for the EC2 hosts. This allows the ECS agent on the EC2 hosts |
| # to communciate with the ECS control plane, as well as download the docker |
| # images from ECR to run on your host. |
| EC2Role: |
| Type: AWS::IAM::Role |
| Properties: |
| AssumeRolePolicyDocument: |
| Statement: |
| - Effect: Allow |
| Principal: |
| Service: [ec2.amazonaws.com] |
| Action: ['sts:AssumeRole'] |
| Path: / |
| Policies: |
| - PolicyName: ecs-service |
| PolicyDocument: |
| Statement: |
| - Effect: Allow |
| Action: |
| - 'ecs:CreateCluster' |
| - 'ecs:DeregisterContainerInstance' |
| - 'ecs:DiscoverPollEndpoint' |
| - 'ecs:Poll' |
| - 'ecs:RegisterContainerInstance' |
| - 'ecs:StartTelemetrySession' |
| - 'ecs:Submit*' |
| - 'logs:CreateLogStream' |
| - 'logs:PutLogEvents' |
| - 'ecr:GetAuthorizationToken' |
| - 'ecr:BatchGetImage' |
| - 'ecr:GetDownloadUrlForLayer' |
| Resource: '*' |
| - PolicyName: s3-bucket |
| PolicyDocument: |
| Statement: |
| - Effect: Allow |
| Action: |
| - 's3:ListBucket' |
| Resource: '*' |
| - Effect: Allow |
| Action: |
| - 's3:PutObject' |
| - 's3:GetObject' |
| - 's3:DeleteObject' |
| Resource: '*' |
| |
| Outputs: |
| ClusterName: |
| Description: The name of the ECS cluster |
| Value: !Ref 'ECSCluster' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ] |
| VPCId: |
| Description: The ID of the VPC that this stack is deployed in |
| Value: !Ref 'VPC' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'VPCId' ] ] |
| PublicSubnetOne: |
| Description: Public subnet one |
| Value: !Ref 'PublicSubnetOne' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetOne' ] ] |