Skip to content

Instantly share code, notes, and snippets.

@kenjimiyao
Created May 21, 2017 06:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenjimiyao/433e2d19c823857cca3ed7f7398d11aa to your computer and use it in GitHub Desktop.
Save kenjimiyao/433e2d19c823857cca3ed7f7398d11aa to your computer and use it in GitHub Desktop.
Sample of CloudFormation templates
AWSTemplateFormatVersion: '2010-09-09'
Description: ECS Cluster Settings
Parameters:
ClusterName:
Description: Cluster
Type: String
ClusterSize:
Description: Number of instances for valid cluster
Type: String
SecurityGroup:
Type: AWS::EC2::SecurityGroup::Id
Description: Select at public security group in your selected VPC.
SubnetID:
Type: List<AWS::EC2::Subnet::Id>
Description: Select at two public subnets in your selected VPC.
InstanceType:
Description: EC2 instance type
Type: String
Default: t2.micro
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.
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS instances.
Resources:
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ClusterName
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier: !Ref 'SubnetID'
LaunchConfigurationName: !Ref 'ContainerInstances'
MinSize: !Ref ClusterSize
MaxSize: !Ref ClusterSize
DesiredCapacity: !Ref ClusterSize
MetricsCollection:
- Granularity: 1Minute
Metrics:
- GroupInServiceInstances
Tags:
- Key: Name
Value: !Join ['-', ['ecs', !Ref ClusterName]]
PropagateAtLaunch: 'true'
CreationPolicy:
ResourceSignal:
Timeout: PT15M
UpdatePolicy:
AutoScalingReplacingUpdate:
WillReplace: 'true'
ContainerInstances:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
AssociatePublicIpAddress: 'true'
ImageId: ami-f63f6f91
SecurityGroups: [!Ref 'SecurityGroup']
InstanceType: !Ref 'InstanceType'
IamInstanceProfile: !Ref 'EC2InstanceProfile'
KeyName: !Ref 'KeyName'
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}
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*', 'ecr:Get*', 'ecr:BatchGetImage', 'logs:CreateLogStream', 'logs:PutLogEvents', 'cloudwatch:PutMetricData', 'cloudwatch:GetMetricStatistics', 'cloudwatch:ListMetrics', 'ec2:DescribeTags']
Resource: '*'
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']
AWSTemplateFormatVersion: '2010-09-09'
Description: ECS task and service definitions
Parameters:
# Taskによって変わる内容
TaskMemory:
Type: String
Description: Soft limit in task definition
TaskMaxMemory:
Type: String
Description: Hard limit of task definition
ImageRepositoryUrl:
Type: String
Description: Image repository url
JavaOpts:
Type: String
Description: JAVA_OPTS
ServiceDesiredCount:
Type: String
Description: Task size of a service
ClusterName:
Description: Cluster name
Type: String
# Jenkinsから入力
ServiceName:
Type: String
Description: Used as domain name, task name, service name, and cloudwatch log group name.
Tag:
Type: String
Description: Docker registry tag
BuildNumber:
Type: String
Description: Build number
VpcId:
Type: AWS::EC2::VPC::Id
Description: Select a VPC that allows instances access to the Internet.
SubnetID:
Type: List<AWS::EC2::Subnet::Id>
Description: Select at two public subnets in your selected VPC.
SecurityGroup:
Type: AWS::EC2::SecurityGroup::Id
Description: Select at elb security group in your selected VPC.
Resources:
# Task
taskdefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref ServiceName
ContainerDefinitions:
- Name: app
Essential: 'true'
Image: !Join [':', [!Ref ImageRepositoryUrl, !Ref Tag]]
MemoryReservation: !Ref TaskMemory
Memory: !Ref TaskMaxMemory
PortMappings:
- ContainerPort: 9000
Environment:
- Name: JAVA_OPTS
Value: !Ref JavaOpts
- Name: BUILD_NUMBER # デプロイ時に毎回Taskを更新するため
Value: !Ref BuildNumber
# IAM
ServiceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['-', ['ecs-service', !Ref ServiceName]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ecs.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action: ['elasticloadbalancing:DeregisterInstancesFromLoadBalancer', 'elasticloadbalancing:DeregisterTargets', 'elasticloadbalancing:Describe*', 'elasticloadbalancing:RegisterInstancesWithLoadBalancer', 'elasticloadbalancing:RegisterTargets', 'ec2:Describe*', 'ec2:AuthorizeSecurityGroupIngress']
Resource: '*'
service:
Type: AWS::ECS::Service
Condition: External
DependsOn: ALBListener
Properties:
Cluster: !Ref 'ClusterName'
DesiredCount: !Ref ServiceDesiredCount
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
LoadBalancers:
- ContainerName: app
ContainerPort: 9000
TargetGroupArn: !Ref 'ECSTG'
Role: !Ref 'ServiceRole'
TaskDefinition: !Ref 'taskdefinition'
# ALB
ecsalb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Condition: External
Properties:
Scheme: internet-facing
Name: !Ref ServiceName
Subnets: !Ref SubnetID
SecurityGroups: [!Ref 'SecurityGroup']
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
- Key: deletion_protection.enabled
Value: 'true'
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Condition: External
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref 'ECSTG'
LoadBalancerArn: !Ref 'ecsalb'
Port: '80'
Protocol: HTTP
ECSTG:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Condition: External
DependsOn: ecsalb
Properties:
HealthCheckIntervalSeconds: 10
HealthCheckPath: /healthcheck
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Name: !Ref ServiceName
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: !Ref VpcId
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: '20'
# RecordSet
ALBDNSRecord:
Type: AWS::Route53::RecordSet
Condition: External
Properties:
HostedZoneName: example.com.
Comment: "alb dns record"
Name:
Fn::Join:
- '.'
- - !Ref ServiceName
- 'example.com.'
Type: A
AliasTarget:
HostedZoneId: !GetAtt ecsalb.CanonicalHostedZoneID
DNSName: !GetAtt ecsalb.DNSName
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment