Created
March 26, 2019 18:03
-
-
Save hierynomus/7293e4c0d233bf50df1f50627566bfb4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Description: > | |
Sub template to setup an ECS cluster for running XebiaLabs JetPack | |
Parameters: | |
EnvironmentName: | |
AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ | |
Description: An environment name that will be prefixed to resource names. | |
Type: String | |
InstanceType: | |
Description: Which instance type should we use to build the ECS cluster? | |
Type: String | |
Default: c4.large | |
MinimumClusterSize: | |
Description: How many ECS hosts need to be deployed minimally? | |
Type: Number | |
Default: 2 | |
DesiredClusterSize: | |
Description: How many ECS hosts do you want to initially deploy? | |
Type: Number | |
Default: 2 | |
MaximumClusterSize: | |
Description: How many ECS hosts need to be deployed maximally? | |
Type: Number | |
Default: 2 | |
VPC: | |
Description: Choose which VPC this ECS cluster should be deployed to | |
Type: AWS::EC2::VPC::Id | |
Subnets: | |
Description: Choose which subnets this ECS cluster should be deployed to | |
Type: List<AWS::EC2::Subnet::Id> | |
ECSSecurityGroup: | |
Description: The security group to attach to the ECS cluster instances | |
Type: AWS::EC2::SecurityGroup::Id | |
ECSAMI: | |
Description: ECS-Optimized AMI ID | |
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> | |
Default: /aws/service/ecs/optimized-ami/amazon-linux/recommended/image_id | |
KeyPairName: | |
Description: The name of an existing public/private key pair, which allows you to securely connect to your instance after it launches | |
Type: AWS::EC2::KeyPair::KeyName | |
MountPoint: | |
Description: The Linux mount point for the EFS volume | |
Type: String | |
MinLength: '1' | |
Default: /mnt/efs | |
Filesystem: | |
Description: EFS FileSystem to be used on ECS for persistent sotrage | |
Type: String | |
Resources: | |
ECSCluster: | |
Type: AWS::ECS::Cluster | |
Properties: | |
ClusterName: !Ref EnvironmentName | |
ECSAutoScalingGroup: | |
DependsOn: ECSCluster | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
VPCZoneIdentifier: !Ref Subnets | |
LaunchConfigurationName: !Ref ECSLaunchConfiguration | |
MinSize: !Ref MinimumClusterSize | |
MaxSize: !Ref MaximumClusterSize | |
DesiredCapacity: !Ref DesiredClusterSize | |
Tags: | |
- Key: Name | |
Value: !Sub ${EnvironmentName} ECS host | |
PropagateAtLaunch: true | |
CreationPolicy: | |
ResourceSignal: | |
Timeout: PT15M | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MinInstancesInService: 1 | |
MaxBatchSize: 1 | |
PauseTime: PT15M | |
SuspendProcesses: | |
- HealthCheck | |
- ReplaceUnhealthy | |
- AZRebalance | |
- AlarmNotification | |
- ScheduledActions | |
WaitOnResourceSignals: true | |
ECSLaunchConfiguration: | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
ImageId: !Ref ECSAMI | |
InstanceType: !Ref InstanceType | |
SecurityGroups: | |
- !Ref ECSSecurityGroup | |
IamInstanceProfile: !Ref ECSInstanceProfile | |
UserData: | |
"Fn::Base64": !Sub | | |
#!/bin/bash | |
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm | |
yum install -y https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm | |
yum install -y aws-cfn-bootstrap hibagent | |
/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSLaunchConfiguration | |
/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSAutoScalingGroup | |
/usr/bin/enable-ec2-spot-hibernation | |
Metadata: | |
AWS::CloudFormation::Init: | |
config: | |
packages: | |
yum: | |
collectd: [] | |
nfs-utils: [] | |
commands: | |
01_add_instance_to_cluster: | |
command: !Sub echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config | |
02_enable_cloudwatch_agent: | |
command: !Sub /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:${ECSCloudWatchParameter} -s | |
03_createdir: | |
command: !Sub "mkdir -p /${MountPoint}" | |
04_mount: | |
command: !Sub > | |
mount -t nfs4 -o nfsvers=4.1 ${Filesystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint} | |
05_fstab: | |
command: !Sub > | |
echo ${Filesystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint} nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0 >> /etc/fstab | |
# 03_permissions: | |
# command: !Sub "chown -R ec2-user:ec2-user /${MountPoint}" | |
06_permissions_ecs_xld: | |
command: !Sub "mkdir -p /${MountPoint}/xl-deploy/repository && mkdir -p /${MountPoint}/xl-deploy/work && chmod g+w -R /${MountPoint}" | |
07_permissions_ecs_xlr: | |
command: !Sub "mkdir -p /${MountPoint}/xl-release/repository && mkdir -p /${MountPoint}/xl-release/work && chmod g+w -R /${MountPoint}" | |
# 08_restart_docker_and_ecs: | |
# command: "service docker restart && start ecs" | |
files: | |
/etc/cfn/cfn-hup.conf: | |
mode: 000400 | |
owner: root | |
group: root | |
content: !Sub | | |
[main] | |
stack=${AWS::StackId} | |
region=${AWS::Region} | |
/etc/cfn/hooks.d/cfn-auto-reloader.conf: | |
content: !Sub | | |
[cfn-auto-reloader-hook] | |
triggers=post.update | |
path=Resources.ECSLaunchConfiguration.Metadata.AWS::CloudFormation::Init | |
action=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSLaunchConfiguration | |
services: | |
sysvinit: | |
cfn-hup: | |
enabled: true | |
ensureRunning: true | |
files: | |
- /etc/cfn/cfn-hup.conf | |
- /etc/cfn/hooks.d/cfn-auto-reloader.conf | |
# This IAM Role is attached to all of the ECS hosts. It is based on the default role | |
# published here: | |
# http://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html | |
# | |
# You can add other IAM policy statements here to allow access from your ECS hosts | |
# to other AWS services. Please note that this role will be used by ALL containers | |
# running on the ECS host. | |
ECSInstanceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
Path: / | |
RoleName: !Sub ${EnvironmentName}-ECSRole-${AWS::Region} | |
AssumeRolePolicyDocument: | | |
{ | |
"Statement": [{ | |
"Action": "sts:AssumeRole", | |
"Effect": "Allow", | |
"Principal": { | |
"Service": "ec2.amazonaws.com" | |
} | |
}] | |
} | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM | |
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy | |
Policies: | |
- PolicyName: ecs-service | |
PolicyDocument: | | |
{ | |
"Statement": [{ | |
"Effect": "Allow", | |
"Action": [ | |
"ecs:CreateCluster", | |
"ecs:DeregisterContainerInstance", | |
"ecs:DiscoverPollEndpoint", | |
"ecs:Poll", | |
"ecs:RegisterContainerInstance", | |
"ecs:StartTelemetrySession", | |
"ecs:Submit*", | |
"ecr:BatchCheckLayerAvailability", | |
"ecr:BatchGetImage", | |
"ecr:GetDownloadUrlForLayer", | |
"ecr:GetAuthorizationToken" | |
], | |
"Resource": "*" | |
}] | |
} | |
ECSInstanceProfile: | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Path: / | |
Roles: | |
- !Ref ECSInstanceRole | |
ECSServiceAutoScalingRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
Action: | |
- "sts:AssumeRole" | |
Effect: Allow | |
Principal: | |
Service: | |
- application-autoscaling.amazonaws.com | |
Path: / | |
Policies: | |
- PolicyName: ecs-service-autoscaling | |
PolicyDocument: | |
Statement: | |
Effect: Allow | |
Action: | |
- application-autoscaling:* | |
- cloudwatch:DescribeAlarms | |
- cloudwatch:PutMetricAlarm | |
- ecs:DescribeServices | |
- ecs:UpdateService | |
Resource: "*" | |
ECSServiceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
Path: / | |
RoleName: !Sub ${EnvironmentName}-ECSServiceRole-${AWS::Region} | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Policies: | |
- PolicyName: !Sub ecs-service-${AWS::StackName} | |
PolicyDocument: | |
{ | |
"Version": "2012-10-17", | |
"Statement": [{ | |
"Effect": "Allow", | |
"Action": [ | |
"ec2:AuthorizeSecurityGroupIngress", | |
"ec2:Describe*", | |
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer", | |
"elasticloadbalancing:Describe*", | |
"elasticloadbalancing:RegisterInstancesWithLoadBalancer", | |
"elasticloadbalancing:DeregisterTargets", | |
"elasticloadbalancing:DescribeTargetGroups", | |
"elasticloadbalancing:DescribeTargetHealth", | |
"elasticloadbalancing:RegisterTargets" | |
], | |
"Resource": "*" | |
}] | |
} | |
ECSTaskExecutionRole: | |
Type: AWS::IAM::Role | |
Properties: | |
Path: / | |
RoleName: !Sub ${EnvironmentName}-ECSTaskExecutionRole-${AWS::Region} | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs-tasks.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
ManagedPolicyArns: | |
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy' | |
ECSCloudWatchParameter: | |
Type: AWS::SSM::Parameter | |
Properties: | |
Description: ECS | |
Name: !Sub "AmazonCloudWatch-${ECSCluster}-ECS" | |
Type: String | |
Value: !Sub | | |
{ | |
"logs": { | |
"force_flush_interval": 5, | |
"logs_collected": { | |
"files": { | |
"collect_list": [ | |
{ | |
"file_path": "/var/log/messages", | |
"log_group_name": "${ECSCluster}-/var/log/messages", | |
"log_stream_name": "{instance_id}", | |
"timestamp_format": "%b %d %H:%M:%S" | |
}, | |
{ | |
"file_path": "/var/log/dmesg", | |
"log_group_name": "${ECSCluster}-/var/log/dmesg", | |
"log_stream_name": "{instance_id}" | |
}, | |
{ | |
"file_path": "/var/log/docker", | |
"log_group_name": "${ECSCluster}-/var/log/docker", | |
"log_stream_name": "{instance_id}", | |
"timestamp_format": "%Y-%m-%dT%H:%M:%S.%f" | |
}, | |
{ | |
"file_path": "/var/log/ecs/ecs-init.log", | |
"log_group_name": "${ECSCluster}-/var/log/ecs/ecs-init.log", | |
"log_stream_name": "{instance_id}", | |
"timestamp_format": "%Y-%m-%dT%H:%M:%SZ" | |
}, | |
{ | |
"file_path": "/var/log/ecs/ecs-agent.log.*", | |
"log_group_name": "${ECSCluster}-/var/log/ecs/ecs-agent.log", | |
"log_stream_name": "{instance_id}", | |
"timestamp_format": "%Y-%m-%dT%H:%M:%SZ" | |
}, | |
{ | |
"file_path": "/var/log/ecs/audit.log", | |
"log_group_name": "${ECSCluster}-/var/log/ecs/audit.log", | |
"log_stream_name": "{instance_id}", | |
"timestamp_format": "%Y-%m-%dT%H:%M:%SZ" | |
} | |
] | |
} | |
} | |
}, | |
"metrics": { | |
"append_dimensions": { | |
"AutoScalingGroupName": "${!aws:AutoScalingGroupName}", | |
"InstanceId": "${!aws:InstanceId}", | |
"InstanceType": "${!aws:InstanceType}" | |
}, | |
"metrics_collected": { | |
"collectd": { | |
"metrics_aggregation_interval": 60 | |
}, | |
"disk": { | |
"measurement": [ | |
"used_percent" | |
], | |
"metrics_collection_interval": 60, | |
"resources": [ | |
"/" | |
] | |
}, | |
"mem": { | |
"measurement": [ | |
"mem_used_percent" | |
], | |
"metrics_collection_interval": 60 | |
}, | |
"statsd": { | |
"metrics_aggregation_interval": 60, | |
"metrics_collection_interval": 10, | |
"service_address": ":8125" | |
} | |
} | |
} | |
} | |
Outputs: | |
Cluster: | |
Description: A reference to the ECS cluster | |
Value: !Ref ECSCluster | |
ECSServiceAutoScalingRole: | |
Description: A reference to ECS service auto scaling role | |
Value: !GetAtt ECSServiceAutoScalingRole.Arn | |
ECSServiceRole: | |
Description: A reference to ECS service role | |
Value: !GetAtt ECSServiceRole.Arn | |
ECSRole: | |
Description: A reference to the ECS Role | |
Value: !GetAtt ECSInstanceRole.Arn | |
ECSTaskExecutionRole: | |
Description: A reference to the ECS Task Execution Role | |
Value: !GetAtt ECSTaskExecutionRole.Arn | |
ECSAutoScalingGroupName: | |
Description: A reference to ECS AutoScaling Group Name | |
Value: !Ref ECSAutoScalingGroup | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment