Last active
September 6, 2017 21:01
-
-
Save irvingpop/a8bb9e3fa4563e82bf4a3d8ee701136d to your computer and use it in GitHub Desktop.
Automate on Habitat on ECS, phase 1
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
AWSTemplateFormatVersion: '2010-09-09' | |
Parameters: | |
KeyName: | |
Type: AWS::EC2::KeyPair::KeyName | |
Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS instances. | |
VPC: | |
Type: AWS::EC2::VPC::Id | |
Description: Select a VPC that allows instances access to the Internet. | |
SubnetIds: | |
Type: List<AWS::EC2::Subnet::Id> | |
Description: Select at least two subnets in your selected VPC. | |
DesiredCapacity: | |
Type: Number | |
Default: '1' | |
Description: Number of instances to launch in your ECS cluster. | |
MaxSize: | |
Type: Number | |
Default: '2' | |
Description: Maximum number of instances that can be launched in your ECS cluster. | |
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. | |
ContactDept: | |
Description: Contact department for billing purposes | |
Type: String | |
ContactEmail: | |
Description: Contact email for Cloudwatch notifications and instance tagging | |
Type: String | |
Mappings: | |
AWSRegionToAMI: | |
us-east-1: | |
AMIID: ami-04351e12 | |
us-east-2: | |
AMIID: ami-207b5a45 | |
us-west-1: | |
AMIID: ami-7d664a1d | |
us-west-2: | |
AMIID: ami-57d9cd2e | |
Resources: | |
################################################################################ | |
# Combo Service - runs all of the containers in a single task definition (1 host), so linking can work | |
################################################################################ | |
AutomateService: | |
Type: AWS::ECS::Service | |
DependsOn: ALBListener | |
Properties: | |
Cluster: !Ref ECSCluster | |
DesiredCount: 1 | |
LoadBalancers: | |
- ContainerName: automate-nginx | |
ContainerPort: 80 | |
TargetGroupArn: !Ref ECSTG | |
Role: !Ref ECSServiceRole | |
TaskDefinition: !Ref AutomateTask | |
AutomateTask: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
Family: !Sub ${AWS::StackName}-automate | |
ContainerDefinitions: | |
- Name: postgresql-data | |
Cpu: '10' | |
Essential: 'false' | |
Image: chefdemo/postgresql-data:stable | |
Memory: 300 | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
MountPoints: | |
- ContainerPath: /hab/svc/postgresql/data | |
SourceVolume: postgresql-data | |
- Name: postgresql | |
Hostname: postgresql | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/postgresql:stable | |
Memory: 300 | |
Environment: | |
- Name: HAB_POSTGRESQL | |
Value: | | |
[superuser] | |
name = 'hab' | |
password = 'chefrocks' | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
MountPoints: | |
- ContainerPath: /hab/svc/postgresql/data | |
SourceVolume: postgresql-data | |
VolumesFrom: | |
- SourceContainer: postgresql-data | |
ReadOnly: false | |
- Name: rabbitmq | |
Hostname: rabbitmq | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/rabbitmq:stable | |
Memory: 512 | |
Links: | |
- postgresql | |
Command: | |
- --peer | |
- postgresql | |
Environment: | |
- Name: HAB_RABBITMQ | |
Value: | | |
[rabbitmq] | |
default_vhost = '/insights' | |
default_user = 'insights' | |
default_pass = 'chefrocks' | |
[rabbitmq.management] | |
enabled = true | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: elasticsearch | |
Hostname: elasticsearch | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/elasticsearch:stable | |
Memory: 2048 | |
Links: | |
- postgresql | |
Command: | |
- --peer | |
- postgresql | |
Ulimits: | |
- Name: nofile | |
HardLimit: 262144 | |
SoftLimit: 262144 | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: logstash | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/logstash:stable | |
Memory: 2048 | |
Links: | |
- rabbitmq | |
- elasticsearch | |
Command: | |
- --peer | |
- rabbitmq | |
- --bind | |
- elasticsearch:elasticsearch.default | |
- --bind | |
- rabbitmq:rabbitmq.default | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: workflow | |
Hostname: workflow | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/workflow-server:stable | |
Memory: 768 | |
Links: | |
- postgresql | |
- rabbitmq | |
- elasticsearch | |
Command: | |
- --peer | |
- postgresql | |
- --bind | |
- database:postgresql.default | |
- --bind | |
- elasticsearch:elasticsearch.default | |
- --bind | |
- rabbitmq:rabbitmq.default | |
MountPoints: | |
- ContainerPath: /var/opt/delivery/delivery/etc | |
SourceVolume: maintenance | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: notifications | |
Hostname: notifications | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/notifications:stable | |
Memory: 768 | |
Links: | |
- postgresql | |
- rabbitmq | |
- elasticsearch | |
Command: | |
- --peer | |
- postgresql | |
- --bind | |
- database:postgresql.default | |
- --bind | |
- elasticsearch:elasticsearch.default | |
- --bind | |
- rabbitmq:rabbitmq.default | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: compliance | |
Hostname: compliance | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/compliance:stable | |
Memory: 768 | |
Links: | |
- postgresql | |
Command: | |
- --peer | |
- postgresql | |
- --bind | |
- elasticsearch:elasticsearch.default | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
- Name: automate-nginx | |
Hostname: automate-nginx | |
Cpu: 10 | |
Essential: 'true' | |
Image: chefdemo/automate-nginx:stable | |
Memory: 300 | |
PortMappings: | |
- ContainerPort: 80 | |
- ContainerPort: 443 | |
Links: | |
- postgresql | |
- rabbitmq | |
- elasticsearch | |
- compliance | |
Command: | |
- --peer | |
- postgresql | |
- --bind | |
- elasticsearch:elasticsearch.default | |
- --bind | |
- workflow:workflow-server.default | |
- --bind | |
- compliance:compliance.default | |
- --bind | |
- notifications:notifications.default | |
MountPoints: | |
- ContainerPath: /var/opt/delivery/delivery/etc | |
SourceVolume: maintenance | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref 'CloudwatchLogsGroup' | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-stream-prefix: !Sub ${AWS::StackName} | |
Volumes: | |
- Name: postgresql-data | |
- Name: maintenance | |
ECSALB: | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Properties: | |
Name: ECSALB | |
Scheme: internet-facing | |
LoadBalancerAttributes: | |
- Key: idle_timeout.timeout_seconds | |
Value: '30' | |
Subnets: !Ref SubnetIds | |
SecurityGroups: [!Ref 'EcsSecurityGroup'] | |
ALBListener: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
DependsOn: ECSServiceRole | |
Properties: | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'ECSTG' | |
LoadBalancerArn: !Ref 'ECSALB' | |
Port: '80' | |
Protocol: HTTP | |
ECSALBListenerRule: | |
Type: AWS::ElasticLoadBalancingV2::ListenerRule | |
DependsOn: ALBListener | |
Properties: | |
Actions: | |
- Type: forward | |
TargetGroupArn: !Ref 'ECSTG' | |
Conditions: | |
- Field: path-pattern | |
Values: [/] | |
ListenerArn: !Ref 'ALBListener' | |
Priority: 1 | |
ECSTG: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
DependsOn: ECSALB | |
Properties: | |
HealthCheckIntervalSeconds: 10 | |
HealthCheckPath: /viz/ | |
HealthCheckProtocol: HTTP | |
HealthCheckTimeoutSeconds: 5 | |
HealthyThresholdCount: 2 | |
Name: ECSTG | |
Port: 80 | |
Protocol: HTTP | |
UnhealthyThresholdCount: 2 | |
VpcId: !Ref VPC | |
ECSServiceRole: | |
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: ['elasticloadbalancing:DeregisterInstancesFromLoadBalancer', 'elasticloadbalancing:DeregisterTargets', | |
'elasticloadbalancing:Describe*', 'elasticloadbalancing:RegisterInstancesWithLoadBalancer', | |
'elasticloadbalancing:RegisterTargets', 'ec2:Describe*', 'ec2:AuthorizeSecurityGroupIngress'] | |
Resource: '*' | |
################################################################################ | |
# ECS Cluster - the EC2 instances (docker hosts) in an Autoscale group that make up the cluster | |
################################################################################ | |
ECSCluster: | |
Type: AWS::ECS::Cluster | |
ECSAutoScalingGroup: | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
VPCZoneIdentifier: !Ref SubnetIds | |
LaunchConfigurationName: !Ref 'DockerHosts' | |
MinSize: '1' | |
MaxSize: !Ref 'MaxSize' | |
DesiredCapacity: !Ref 'DesiredCapacity' | |
Tags: | |
- Key: Name | |
Value: !Sub ${AWS::StackName}-dockerhost | |
PropagateAtLaunch: true | |
- Key: X-Dept | |
Value: !Ref ContactDept | |
PropagateAtLaunch: true | |
- Key: X-Contact | |
Value: !Ref ContactEmail | |
PropagateAtLaunch: true | |
CreationPolicy: | |
ResourceSignal: | |
Timeout: PT15M | |
UpdatePolicy: | |
AutoScalingReplacingUpdate: | |
WillReplace: 'true' | |
DockerHosts: | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
ImageId: !FindInMap [AWSRegionToAMI, !Ref 'AWS::Region', AMIID] | |
SecurityGroups: [!Ref 'EcsSecurityGroup'] | |
InstanceType: !Ref 'InstanceType' | |
IamInstanceProfile: !Ref 'EC2InstanceProfile' | |
KeyName: !Ref 'KeyName' | |
EbsOptimized: true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: 200 | |
VolumeType: gp2 | |
DeleteOnTermination: true | |
UserData: | |
Fn::Base64: !Sub | | |
#!/bin/bash -xe | |
echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config | |
yum install -y aws-cfn-bootstrap | |
# up the vm.max_map_count for elasticsearch | |
sysctl -w vm.max_map_count=262144 | |
/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*', 'logs:CreateLogStream', 'logs:PutLogEvents'] | |
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'] | |
EcsSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: ECS Security Group | |
VpcId: !Ref VPC | |
EcsSecurityGroupHTTPinbound: | |
Type: AWS::EC2::SecurityGroupIngress | |
Properties: | |
GroupId: !Ref 'EcsSecurityGroup' | |
IpProtocol: tcp | |
FromPort: '80' | |
ToPort: '80' | |
CidrIp: 0.0.0.0/0 | |
EcsSecurityGroupSSHinbound: | |
Type: AWS::EC2::SecurityGroupIngress | |
Properties: | |
GroupId: !Ref 'EcsSecurityGroup' | |
IpProtocol: tcp | |
FromPort: '22' | |
ToPort: '22' | |
CidrIp: 0.0.0.0/0 | |
EcsSecurityGroupALBports: | |
Type: AWS::EC2::SecurityGroupIngress | |
Properties: | |
GroupId: !Ref 'EcsSecurityGroup' | |
IpProtocol: tcp | |
FromPort: '31000' | |
ToPort: '61000' | |
SourceSecurityGroupId: !Ref 'EcsSecurityGroup' | |
CloudwatchLogsGroup: | |
Type: AWS::Logs::LogGroup | |
Properties: | |
LogGroupName: !Join ['-', [ECSLogGroup, !Ref 'AWS::StackName']] | |
RetentionInDays: 14 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment