Created
March 28, 2016 18:41
-
-
Save murillodigital/b3aea3d5593e313c727b to your computer and use it in GitHub Desktop.
This file contains 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
{ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Description": "ECS Cluster Stack - Version 0.1.0", | |
"Parameters": { | |
"ParameterNetworkStackName": { | |
"Type": "String", | |
"Description": "Name for networks stack", | |
"Default": "QwinixNetworkStack" | |
}, | |
"ParameterDesiredClusterSize": { | |
"Type": "String", | |
"Description": "Number of instances to bring up", | |
"Default": "2" | |
} | |
}, | |
"Resources": { | |
"LambdaExecutionRole": { | |
"Type": "AWS::IAM::Role", | |
"Properties": { | |
"AssumeRolePolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [{ | |
"Effect": "Allow", | |
"Principal": {"Service": ["lambda.amazonaws.com"]}, | |
"Action": ["sts:AssumeRole"] | |
}] | |
}, | |
"Path": "/", | |
"Policies": [{ | |
"PolicyName": "root", | |
"PolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [{ | |
"Effect": "Allow", | |
"Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"], | |
"Resource": "arn:aws:logs:*:*:*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": ["cloudformation:DescribeStacks"], | |
"Resource": "*" | |
}] | |
} | |
}] | |
} | |
}, | |
"LookupStackOutputs": { | |
"Type": "AWS::Lambda::Function", | |
"DependsOn": "LambdaExecutionRole", | |
"Properties": { | |
"Description": "Retrieve stack network information", | |
"Code": { | |
"ZipFile": { "Fn::Join": ["\n", [ | |
"var response = require('cfn-response');", | |
"exports.handler = function(event, context) {", | |
" console.log('REQUEST RECEIVED:\\n', JSON.stringify(event));", | |
" if (event.RequestType == 'Delete') {", | |
" response.send(event, context, response.SUCCESS);", | |
" return;", | |
" }", | |
" var stackName = event.ResourceProperties.StackName;", | |
" var responseData = {};", | |
" if (stackName) {", | |
" var aws = require('aws-sdk');", | |
" var cfn = new aws.CloudFormation();", | |
" cfn.describeStacks({StackName: stackName}, function(err, data) {", | |
" if (err) {", | |
" responseData = {Error: 'DescribeStacks call failed'};", | |
" console.log(responseData.Error + ':\\n', err);", | |
" response.send(event, context, response.FAILED, responseData);", | |
" }", | |
" else {", | |
" data.Stacks[0].Outputs.forEach(function(output) {", | |
" responseData[output.OutputKey] = output.OutputValue;", | |
" });", | |
" response.send(event, context, response.SUCCESS, responseData);", | |
" }", | |
" });", | |
" } else {", | |
" responseData = {Error: 'Stack name not specified'};", | |
" console.log(responseData.Error);", | |
" response.send(event, context, response.FAILED, responseData);", | |
" }", | |
"};" | |
]]} | |
}, | |
"Handler": "index.handler", | |
"Runtime": "nodejs", | |
"Timeout": "45", | |
"Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] } | |
} | |
}, | |
"NetworkInfo": { | |
"Type": "Custom::NetworkInfo", | |
"Properties": { | |
"ServiceToken": { "Fn::GetAtt": ["LookupStackOutputs", "Arn"] }, | |
"StackName": { "Ref": "ParameterNetworkStackName" } | |
} | |
}, | |
"ECSCluster": { | |
"Type": "AWS::ECS::Cluster" | |
}, | |
"ECSAutoScalingGroup": { | |
"Type": "AWS::AutoScaling::AutoScalingGroup", | |
"Properties": { | |
"DesiredCapacity": "2", | |
"LaunchConfigurationName": {"Ref": "ECSLaunchConfiguration"}, | |
"MinSize": "1", | |
"MaxSize": "10", | |
"VPCZoneIdentifier": [{"Fn::GetAtt": ["NetworkInfo", "PrivateSubnet"]}] | |
} | |
}, | |
"ECSLaunchConfiguration": { | |
"Type": "AWS::AutoScaling::LaunchConfiguration", | |
"Properties": { | |
"AssociatePublicIpAddress": "false", | |
"ImageId": "ami-63b25203", | |
"InstanceType": "c4.large", | |
"KeyName": "ops-cr", | |
"SecurityGroups": [{"Ref": "ECSPrivateSecurityGroup"}], | |
"IamInstanceProfile": {"Ref": "ECSInstanceProfile"}, | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": ["", [ | |
"#!/bin/bash\n", | |
"ifconfig eth0 mtu 1500 up\n", | |
"yum install -y ecs-init\n", | |
"usermod -a -G docker ec2-user\n", | |
"echo ECS_CLUSTER=", {"Ref": "ECSCluster"}, " > /etc/ecs/ecs.config\n", | |
"service docker start\n", | |
"start ecs\n" | |
]] | |
} | |
} | |
} | |
}, | |
"ECSInstanceProfile": { | |
"Type": "AWS::IAM::InstanceProfile", | |
"Properties": { | |
"Path": "/", | |
"Roles": [{"Ref": "ECSInstanceRole"}] | |
} | |
}, | |
"ECSInstanceRole": { | |
"Type": "AWS::IAM::Role", | |
"Properties": { | |
"AssumeRolePolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Principal": { | |
"Service": [ | |
"ec2.amazonaws.com" | |
] | |
}, | |
"Action": [ | |
"sts:AssumeRole" | |
] | |
} | |
] | |
}, | |
"Path": "/", | |
"Policies": [ | |
{ | |
"PolicyName": "ECSClusterPolicy", | |
"PolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"ec2:AuthorizeSecurityGroupIngress", | |
"ec2:Describe*", | |
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer", | |
"elasticloadbalancing:Describe*", | |
"elasticloadbalancing:RegisterInstancesWithLoadBalancer", | |
"ecs:*", | |
"ecr:*" | |
], | |
"Resource": "*" | |
} | |
] | |
} | |
} | |
] | |
} | |
}, | |
"ECSServiceRole": { | |
"Type": "AWS::IAM::Role", | |
"Properties": { | |
"AssumeRolePolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Principal": { | |
"Service": [ | |
"ecs.amazonaws.com" | |
] | |
}, | |
"Action": [ | |
"sts:AssumeRole" | |
] | |
} | |
] | |
}, | |
"Path": "/", | |
"Policies": [ | |
{ | |
"PolicyName": "ECSServicePolicy", | |
"PolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"ec2:AuthorizeSecurityGroupIngress", | |
"ec2:Describe*", | |
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer", | |
"elasticloadbalancing:Describe*", | |
"elasticloadbalancing:RegisterInstancesWithLoadBalancer", | |
"ecs:*", | |
"ecr:*" | |
], | |
"Resource": "*" | |
} | |
] | |
} | |
} | |
] | |
} | |
}, | |
"ECSPrivateSecurityGroup": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"GroupDescription": "ECS Cluster - Private", | |
"VpcId": {"Fn::GetAtt": ["NetworkInfo", "VPC"]}, | |
"SecurityGroupIngress": [ | |
{ | |
"CidrIp": "0.0.0.0/0", | |
"FromPort": "0", | |
"ToPort": "65535", | |
"IpProtocol": "tcp" | |
} | |
] | |
} | |
}, | |
"ECSNatIngressRule": { | |
"Type": "AWS::EC2::SecurityGroupIngress", | |
"Properties": { | |
"FromPort": "0", | |
"ToPort": "65535", | |
"IpProtocol": "tcp", | |
"SourceSecurityGroupId": {"Ref": "ECSPrivateSecurityGroup"}, | |
"GroupId": {"Fn::GetAtt": ["NetworkInfo", "NATSecurityGroup"]} | |
} | |
}, | |
"ECSPublicSecurityGroup": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"GroupDescription": "ECS Cluster - Public", | |
"VpcId": {"Fn::GetAtt": ["NetworkInfo", "VPC"]}, | |
"SecurityGroupIngress": [ | |
{ | |
"CidrIp": "0.0.0.0/0", | |
"FromPort": "80", | |
"ToPort": "80", | |
"IpProtocol": "tcp" | |
} | |
] | |
} | |
}, | |
"ECSPublicLoadBalancer": { | |
"Type": "AWS::ElasticLoadBalancing::LoadBalancer", | |
"Properties": { | |
"Listeners": [ | |
{ | |
"InstancePort": "80", | |
"InstanceProtocol": "HTTP", | |
"LoadBalancerPort": "80", | |
"Protocol": "HTTP" | |
} | |
], | |
"SecurityGroups": [ | |
{"Ref": "ECSPublicSecurityGroup"} | |
], | |
"Subnets": [ | |
{"Fn::GetAtt": ["NetworkInfo", "PublicSubnet"]} | |
] | |
} | |
}, | |
"ECSTaskDefinition": { | |
"Type": "AWS::ECS::TaskDefinition", | |
"Properties": { | |
"ContainerDefinitions": [ | |
{ | |
"Cpu": "1024", | |
"Image": "571780515387.dkr.ecr.us-east-1.amazonaws.com/empower_retirement:latest", | |
"Memory": "256", | |
"Name": "empower_retirement", | |
"PortMappings": [ | |
{ | |
"ContainerPort": "80", | |
"HostPort": "80" | |
} | |
] | |
} | |
], | |
"Volumes": [ | |
{ | |
"Name": "my-vol" | |
} | |
] | |
} | |
}, | |
"ECSService": { | |
"Type": "AWS::ECS::Service", | |
"Properties": { | |
"Cluster": {"Ref": "ECSCluster"}, | |
"DesiredCount": "1", | |
"LoadBalancers": [ | |
{ | |
"ContainerName": "empower_retirement", | |
"ContainerPort": "80", | |
"LoadBalancerName": {"Ref": "ECSPublicLoadBalancer"} | |
} | |
], | |
"Role": {"Ref": "ECSServiceRole"}, | |
"TaskDefinition": {"Ref": "ECSTaskDefinition"} | |
} | |
} | |
}, | |
"Outputs": { | |
"ECSClusterName": { | |
"Description": "Name of created ECS Cluster", | |
"Value": {"Ref": "ECSCluster"} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment