Skip to content

Instantly share code, notes, and snippets.

@arturo-c
Created February 12, 2017 16:42
Show Gist options
  • Save arturo-c/d920614818f87ba26b84fdab2752ddbe to your computer and use it in GitHub Desktop.
Save arturo-c/d920614818f87ba26b84fdab2752ddbe to your computer and use it in GitHub Desktop.
JenkinsStack
{
"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."
},
"VpcId":{
"Type":"AWS::EC2::VPC::Id",
"Description":"Select a VPC that allows instances to access the Internet."
},
"Domain": {
"Type": "String",
"Description": "Root domain where to put the db, like bookshout.aws",
"Default": "bookshout.aws"
},
"Subdomain": {
"Type": "String",
"Description": "Subdomain of FQDN like jenkins, resulting in something like jenkins.bookshout.aws",
"Default": "jenkins"
},
"ZoneID": {
"Type": "AWS::Route53::HostedZone::Id",
"Description": "Zone ID where to place jenkins."
},
"EC2InstanceProfile": {
"Type":"String",
"Description": "Valid iam role to assign instances.",
"Default": "eb-ec2-role"
},
"SubnetID":{
"Type":"List<AWS::EC2::Subnet::Id>",
"Description":"Select at two subnets in your selected VPC."
},
"VOLID":{
"Type": "AWS::EC2::Volume::Id",
"Description":"Volume that holds jenkins data."
},
"SSHSG":{
"Type": "AWS::EC2::SecurityGroup::Id",
"Description": "Source of valid ssh connection."
},
"AppsSG":{
"Type": "AWS::EC2::SecurityGroup::Id",
"Description": "Apps security group to connect to jenkins on port 443"
},
"InstanceType":{
"Description":"EC2 instance type",
"Type":"String",
"Default":"t2.small",
"AllowedValues":[
"t2.micro",
"t2.small",
"t2.medium",
"t2.large",
"m3.medium",
"m3.large",
"m3.xlarge",
"m3.2xlarge",
"m4.large"
],
"ConstraintDescription":"Please choose a valid instance type."
}
},
"Mappings":{
"AWSRegionToAMI":{
"us-east-1":{
"AMIID":"ami-d69c74c0"
},
"us-east-2":{
"AMIID":"ami-446f3521"
},
"us-west-1":{
"AMIID":"ami-9fadf8ff"
},
"us-west-2":{
"AMIID":"ami-7abc111a"
}
}
},
"Resources":{
"ECSCluster":{
"Type":"AWS::ECS::Cluster"
},
"EcsSecurityGroup":{
"Type":"AWS::EC2::SecurityGroup",
"Properties":{
"GroupDescription":"ECS Security Group",
"VpcId":{
"Ref":"VpcId"
}
}
},
"EcsSecurityGroupSolrinbound":{
"Type":"AWS::EC2::SecurityGroupIngress",
"Properties":{
"GroupId":{
"Ref":"EcsSecurityGroup"
},
"IpProtocol":"tcp",
"FromPort":"8983",
"ToPort":"8983",
"SourceSecurityGroupId": { "Ref" : "AppsSG" }
}
},
"EcsSecurityGroupSSHinbound":{
"Type":"AWS::EC2::SecurityGroupIngress",
"Properties":{
"GroupId":{
"Ref":"EcsSecurityGroup"
},
"IpProtocol":"tcp",
"FromPort":"22",
"ToPort":"22",
"SourceSecurityGroupId": { "Ref" : "SSHSG" }
}
},
"JenkinsSG":{
"Type":"AWS::EC2::SecurityGroupIngress",
"Properties":{
"GroupId":{
"Ref":"EcsSecurityGroup"
},
"IpProtocol":"tcp",
"FromPort":"5000",
"ToPort":"5000",
"CidrIp": "0.0.0.0/0"
}
},
"JenkinsSGWeb":{
"Type":"AWS::EC2::SecurityGroupIngress",
"Properties":{
"GroupId":{
"Ref":"EcsSecurityGroup"
},
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp": "0.0.0.0/0"
}
},
"taskdefinition":{
"Type":"AWS::ECS::TaskDefinition",
"Properties":{
"Family":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"jenkins"
]
]
},
"ContainerDefinitions":[
{
"Name":"mysql",
"Cpu":"200",
"Memory":"500",
"Essential":"true",
"Image":"mysql",
"Environment": [
{
"Name": "MYSQL_ROOT_PASSWORD",
"Value": "jenkins"
}
],
"MountPoints":[
{
"ContainerPath": "/var/lib/mysql",
"SourceVolume": "mysql-vol"
}
],
"PortMappings":[
{
"ContainerPort":3306
}
]
},
{
"Name":"jenkins",
"Cpu":"1024",
"Essential":"true",
"Image": "jenkins",
"Memory":"4000",
"Links":[
"mysql:mysql"
],
"MountPoints":[
{
"ContainerPath": "/var/jenkins_home",
"SourceVolume":"jenkins-vol"
},
{
"ContainerPath": "/var/run/docker.sock",
"SourceVolume":"dockersock"
}
],
"Environment":[
{
"Name": "MYSQL_HOST",
"Value": "mysql"
},
{
"Name": "MYSQL_PASSWORD",
"Value": "jenkins"
},
{
"Name": "MYSQL_USERNAME",
"Value": "root"
}
],
"PortMappings":[
{
"ContainerPort":8080,
"HostPort":80
},
{
"ContainerPort":5000,
"HostPort":5000
}
]
}],
"Volumes":[
{
"Name":"jenkins-vol",
"Host": {
"SourcePath": "/mnt/container-data/jenkins"
}
},
{
"Name":"mysql-vol",
"Host": {
"SourcePath": "/mnt/container-data/mysql"
}
},
{
"Name":"dockersock",
"Host": {
"SourcePath": "/var/run/docker.sock"
}
}
]
}
},
"ECSAutoScalingGroup":{
"Type":"AWS::AutoScaling::AutoScalingGroup",
"Properties":{
"VPCZoneIdentifier":{
"Ref":"SubnetID"
},
"LaunchConfigurationName":{
"Ref":"ContainerInstances"
},
"MinSize":"1",
"MaxSize":"1",
"DesiredCapacity":"1"
},
"CreationPolicy":{
"ResourceSignal":{
"Timeout":"PT15M"
}
},
"UpdatePolicy":{
"AutoScalingReplacingUpdate":{
"WillReplace":"true"
}
}
},
"ContainerInstances":{
"Type":"AWS::AutoScaling::LaunchConfiguration",
"Properties":{
"ImageId":{
"Fn::FindInMap":[
"AWSRegionToAMI",
{
"Ref":"AWS::Region"
},
"AMIID"
]
},
"SecurityGroups":[
{
"Ref":"EcsSecurityGroup"
}
],
"InstanceType":{
"Ref":"InstanceType"
},
"AssociatePublicIpAddress":"true",
"IamInstanceProfile":{
"Ref":"EC2InstanceProfile"
},
"KeyName":{
"Ref":"KeyName"
},
"UserData":{
"Fn::Base64":{
"Fn::Join":[
"",
[
"#!/bin/bash -xe\n",
"echo ECS_CLUSTER=",
{
"Ref":"ECSCluster"
},
" >> /etc/ecs/ecs.config\n",
"yum install -y aws-cfn-bootstrap\n",
"yum install -y R-core python27 python-boto aws-apitools-ec2 ec2-utils rsync aws-cli\n",
"ln -s /usr/lib/python2.6/site-packages/boto/ /usr/lib/python2.7/site-packages/\n",
". /etc/profile.d/aws-apitools-common.sh\n",
"REGION=us-east-1\n",
"ZONE=`ec2-metadata -z | cut -d\\ -f2`\n",
"INSTANCEID=`ec2-metadata -i | cut -d\\ -f2`\n",
"VOLID=",
{
"Ref":"VOLID"
},
"\n",
"ec2-attach-volume --region $REGION $VOLID -i $INSTANCEID -d /dev/sdf\n",
"while [ ! -e /dev/sdf ]\n",
"do\n",
"echo 'Waiting for disk to appear..'\n",
"sleep 30\n",
"done\n",
"mkdir /mnt/container-data\n",
"chown ec2-user:ec2-user /mnt/container-data\n",
"cat >>/etc/fstab <<EOF\n",
"/dev/sdf /mnt/container-data ext4 defaults 1 1\n",
"EOF\n",
"cat >>/etc/rc.local <<EOF\n",
"su ec2-user -c 'cd /mnt/container-data; nohup ./updater.py >>log/updater.log 2>&1 &'\n",
"EOF\n",
"HOSTED_ZONE_ID=",
{
"Ref": "ZoneID"
},
"\n",
"json='{ \"Comment\": \"Update the A record set\", \"Changes\": [ { \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\": \"",
{
"Fn::Join": [ "", [ {"Ref": "Subdomain"}, ".", {"Ref": "Domain"} ] ]
},
"\", \"Type\": \"A\", \"TTL\": 300, \"ResourceRecords\": [ { \"Value\": \"127.0.0.1\" } ] } } ] }'\n",
"echo $json > update-route-53-A.json\n",
"IP=$( curl http:\/\/169.254.169.254\/latest\/meta-data\/local-ipv4 )\n",
"INPUT_JSON=$( cat update-route-53-A.json | sed \"s\/127\\.0\\.0\\.1\/$IP\/\" )\n",
"INPUT_JSON=\"{ \\\"ChangeBatch\\\": $INPUT_JSON }\"\n",
"aws route53 change-resource-record-sets --hosted-zone-id \"$HOSTED_ZONE_ID\" --cli-input-json \"$INPUT_JSON\"\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ",
{
"Ref":"AWS::StackName"
},
" --resource ECSAutoScalingGroup ",
" --region ",
{
"Ref":"AWS::Region"
},
"\n",
"reboot"
]
]
}
}
}
},
"service": {
"Type": "AWS::ECS::Service",
"Properties" : {
"Cluster": { "Ref": "ECSCluster" },
"DesiredCount": "1",
"TaskDefinition" : { "Ref": "taskdefinition" }
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment