Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1794 lines (1791 sloc) 43.9 KB
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description":"Builds a S3 bucket, a VPC w/ 1 public subnet, an IGW, route tables, ACL, 1 EC2 instance for Jenkins, and CodePipeline.",
"Parameters":{
"KeyName":{
"Description":"Name of an existing EC2 KeyPair for SSH access to the instances.",
"Type":"AWS::EC2::KeyPair::KeyName"
},
"AppName":{
"Type":"String",
"Description":"Name of the application.",
"MinLength":"2",
"MaxLength":"15",
"Default":"app-name",
"AllowedPattern":"[a-z0-9][-. a-z0-9]*",
"ConstraintDescription":"Must be between 2 and 15 characters long, lowercase and may contain alphanumeric characters, hyphens (-), and dots (.), but must start with alphanumeric."
},
"S3ArtifactObject":{
"Type":"String",
"Default":"public/jenkins/aws-codepipeline-s3-aws-codedeploy-linux-pmd.zip",
"Description":"Application artfiact name in S3."
},
"S3ArtifactBucket":{
"Type":"String",
"Default":"stelligent-training-public",
"Description":"Name of the bucket that the application artifact will be based in."
},
"YourIP":{
"Description":"IP address to connect to SSH from. Check http://checkip.amazonaws.com/ to find yours.",
"Type":"String",
"Default":"999.999.999.999/32",
"MinLength":"10",
"MaxLength":"18",
"AllowedPattern":"(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription":"must be a valid IP CIDR range of the form x.x.x.x/x."
},
"RepositoryName":{
"Description":"The name of the CodeCommit repo",
"Type":"String",
"AllowedPattern":"[\\x20-\\x7E]*",
"ConstraintDescription":"Can contain only ASCII characters."
},
"RepositoryBranch":{
"Description":"The name of the branch for the CodeCommit repo",
"Type":"String",
"Default":"master",
"AllowedPattern":"[\\x20-\\x7E]*",
"ConstraintDescription":"Can contain only ASCII characters."
},
"ECSRepoName":{
"Type":"String",
"Description":"The name of the ECR Repo"
},
"ECSCFNURL":{
"Type":"String",
"Default":"NOURL",
"Description":"The URL for this CloudFormation Template"
},
"ImageTag":{
"Type":"String",
"Description":"The version of the image tag",
"Default":"latest"
},
"DesiredCapacity":{
"Type":"Number",
"Default":"1",
"Description":"Number of instances to launch in your ECS cluster"
},
"MaxSize":{
"Type":"Number",
"Default":"1",
"Description":"Maximum number of instances that can be launched in your ECS cluster"
},
"InstanceType":{
"Description":"The EC2 instance type",
"Type":"String",
"Default":"t2.micro",
"AllowedValues":[
"t2.micro",
"t2.small",
"t2.medium",
"m3.medium",
"m3.large",
"m3.xlarge",
"m3.2xlarge",
"c3.large",
"c3.xlarge",
"c3.2xlarge",
"c3.4xlarge",
"c3.8xlarge",
"c4.large",
"c4.xlarge",
"c4.2xlarge",
"c4.4xlarge",
"c4.8xlarge",
"r3.large",
"r3.xlarge",
"r3.2xlarge",
"r3.4xlarge",
"r3.8xlarge",
"i2.xlarge",
"i2.2xlarge",
"i2.4xlarge",
"i2.8xlarge",
"d2.xlarge",
"d2.2xlarge",
"d2.4xlarge",
"d2.8xlarge",
"hi1.4xlarge",
"hs1.8xlarge",
"cr1.8xlarge",
"cc2.8xlarge"
],
"ConstraintDescription":"must be a valid EC2 instance type."
},
"SSHLocation":{
"Description":" The IP address range that can be used to SSH to the EC2 instances",
"Type":"String",
"MinLength":"9",
"MaxLength":"18",
"Default":"0.0.0.0/0",
"AllowedPattern":"(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription":"must be a valid IP CIDR range of the form x.x.x.x/x."
}
},
"Metadata":{
"AWS::CloudFormation::Interface":{
"ParameterGroups":[
{
"Label":{
"default":"Dynamic Configuration"
},
"Parameters":[
"KeyName",
"YourIP",
"ECSRepoName",
"RepositoryName"
]
},
{
"Label":{
"default":"ECS Configuration"
},
"Parameters":[
"DesiredCapacity",
"ImageTag",
"MaxSize"
]
},
{
"Label":{
"default":"CodeCommit Configuration"
},
"Parameters":[
"RepositoryBranch"
]
}
]
}
},
"Mappings":{
"VPCIpSpace":{
"us-east-1":{
"RANGE":"10.52"
},
"us-west-2":{
"RANGE":"10.53"
}
},
"SubnetTypeIpRanges":{
"public":{
"RANGE":"0.0/17"
}
},
"publicSubnetConfig":{
"publicSubnet01":{
"CIDR":"10.0/24"
},
"publicSubnet02":{
"CIDR":"2.0/24"
}
},
"instancesTypes":{
"Demo":{
"INST":"t2.small"
}
},
"AWSInstanceType2Virt":{
"t2.micro":{
"Virt":"HVM"
},
"t2.small":{
"Virt":"HVM"
},
"t2.medium":{
"Virt":"HVM"
},
"t2.large":{
"Virt":"HVM"
}
},
"AWSInstanceType2EBSOpt":{
"t2.micro":{
"EBSOpt":"false"
},
"t2.small":{
"EBSOpt":"false"
},
"t2.medium":{
"EBSOpt":"false"
},
"t2.large":{
"EBSOpt":"false"
}
},
"AWSRegionVirt2AMI":{
"us-east-1":{
"HVM":"ami-8fcee4e5"
},
"us-west-2":{
"HVM":"ami-63b25203"
}
},
"AWSRegionToAMI":{
"us-east-1":{
"AMIID":"ami-2b3b6041"
},
"us-west-2":{
"AMIID":"ami-ac6872cd"
},
"eu-west-1":{
"AMIID":"ami-03238b70"
},
"ap-northeast-1":{
"AMIID":"ami-fb2f1295"
},
"ap-southeast-2":{
"AMIID":"ami-43547120"
},
"us-west-1":{
"AMIID":"ami-bfe095df"
},
"ap-southeast-1":{
"AMIID":"ami-c78f43a4"
},
"eu-central-1":{
"AMIID":"ami-e1e6f88d"
}
}
},
"Resources":{
"MyVPC":{
"Type":"AWS::EC2::VPC",
"Properties":{
"CidrBlock":{
"Fn::Join":[
"",
[
{
"Fn::FindInMap":[
"VPCIpSpace",
{
"Ref":"AWS::Region"
},
"RANGE"
]
},
".",
"0.0/16"
]
]
},
"EnableDnsSupport":"true",
"EnableDnsHostnames":"true",
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-VPC"
]
]
}
}
]
}
},
"publicSubnet01":{
"Type":"AWS::EC2::Subnet",
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"CidrBlock":{
"Fn::Join":[
"",
[
{
"Fn::FindInMap":[
"VPCIpSpace",
{
"Ref":"AWS::Region"
},
"RANGE"
]
},
".",
{
"Fn::FindInMap":[
"publicSubnetConfig",
"publicSubnet01",
"CIDR"
]
}
]
]
},
"AvailabilityZone":{
"Fn::Select":[
"2",
{
"Fn::GetAZs":{
"Ref":"AWS::Region"
}
}
]
},
"Tags":[
{
"Key":"SubnetType",
"Value":"Public"
},
{
"Key":"Name",
"Value":"publicSubnet01"
}
]
}
},
"publicSubnet02":{
"Type":"AWS::EC2::Subnet",
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"MapPublicIpOnLaunch":"true",
"CidrBlock":{
"Fn::Join":[
"",
[
{
"Fn::FindInMap":[
"VPCIpSpace",
{
"Ref":"AWS::Region"
},
"RANGE"
]
},
".",
{
"Fn::FindInMap":[
"publicSubnetConfig",
"publicSubnet02",
"CIDR"
]
}
]
]
},
"AvailabilityZone":{
"Fn::Select":[
"3",
{
"Fn::GetAZs":{
"Ref":"AWS::Region"
}
}
]
},
"Tags":[
{
"Key":"SubnetType",
"Value":"Public"
},
{
"Key":"Name",
"Value":"publicSubnet02"
}
]
}
},
"InternetGateway":{
"Type":"AWS::EC2::InternetGateway",
"Properties":{
"Tags":[
{
"Key":"Name",
"Value":"DemoVPCIGW"
}
]
}
},
"AttachGateway":{
"Type":"AWS::EC2::VPCGatewayAttachment",
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"InternetGatewayId":{
"Ref":"InternetGateway"
}
}
},
"PublicRouteTable":{
"Type":"AWS::EC2::RouteTable",
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"Tags":[
{
"Key":"Name",
"Value":"PublicRouteTable"
}
]
}
},
"PublicRoute":{
"Type":"AWS::EC2::Route",
"Properties":{
"RouteTableId":{
"Ref":"PublicRouteTable"
},
"DestinationCidrBlock":"0.0.0.0/0",
"GatewayId":{
"Ref":"InternetGateway"
}
}
},
"PublicSubnetRTAssociation01":{
"Type":"AWS::EC2::SubnetRouteTableAssociation",
"Properties":{
"SubnetId":{
"Ref":"publicSubnet01"
},
"RouteTableId":{
"Ref":"PublicRouteTable"
}
}
},
"PublicSubnetRTAssociation02":{
"Type":"AWS::EC2::SubnetRouteTableAssociation",
"Properties":{
"SubnetId":{
"Ref":"publicSubnet02"
},
"RouteTableId":{
"Ref":"PublicRouteTable"
}
}
},
"PublicNetworkAcl":{
"Type":"AWS::EC2::NetworkAcl",
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"Tags":[
{
"Key":"Name",
"Value":"NetworkAcl"
}
]
}
},
"InboundPublicNAclEntry":{
"Type":"AWS::EC2::NetworkAclEntry",
"Properties":{
"NetworkAclId":{
"Ref":"PublicNetworkAcl"
},
"RuleNumber":"2000",
"Protocol":"-1",
"RuleAction":"allow",
"Egress":"false",
"CidrBlock":"0.0.0.0/0",
"PortRange":{
"From":"0",
"To":"65535"
}
}
},
"OutboundPublicNetworkAclEntry":{
"Type":"AWS::EC2::NetworkAclEntry",
"Properties":{
"NetworkAclId":{
"Ref":"PublicNetworkAcl"
},
"RuleNumber":"2000",
"Protocol":"-1",
"RuleAction":"allow",
"Egress":"true",
"CidrBlock":"0.0.0.0/0",
"PortRange":{
"From":"0",
"To":"65535"
}
}
},
"publicSubnetNetworkAclAssociation01":{
"Type":"AWS::EC2::SubnetNetworkAclAssociation",
"Properties":{
"SubnetId":{
"Ref":"publicSubnet01"
},
"NetworkAclId":{
"Ref":"PublicNetworkAcl"
}
}
},
"publicSubnetNetworkAclAssociation02":{
"Type":"AWS::EC2::SubnetNetworkAclAssociation",
"Properties":{
"SubnetId":{
"Ref":"publicSubnet02"
},
"NetworkAclId":{
"Ref":"PublicNetworkAcl"
}
}
},
"SourceSG":{
"Type":"AWS::EC2::SecurityGroup",
"DependsOn":[
"MyVPC"
],
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"GroupDescription":"Sample source security group",
"SecurityGroupIngress":[
{
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp":"0.0.0.0/0"
}
],
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-SourceSG"
]
]
}
}
]
}
},
"TargetSG":{
"Type":"AWS::EC2::SecurityGroup",
"DependsOn":[
"MyVPC"
],
"Properties":{
"VpcId":{
"Ref":"MyVPC"
},
"GroupDescription":"ALL Inbound TCP - Source Restricted to SourceSG",
"SecurityGroupIngress":[
{
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp":"0.0.0.0/0"
}
],
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-TargetSG"
]
]
}
}
]
}
},
"OutboundRule":{
"Type":"AWS::EC2::SecurityGroupEgress",
"DependsOn":[
"MyVPC"
],
"Properties":{
"IpProtocol":"tcp",
"FromPort":"0",
"ToPort":"65535",
"DestinationSecurityGroupId":{
"Fn::GetAtt":[
"TargetSG",
"GroupId"
]
},
"GroupId":{
"Fn::GetAtt":[
"SourceSG",
"GroupId"
]
}
}
},
"InboundRule":{
"Type":"AWS::EC2::SecurityGroupIngress",
"DependsOn":[
"MyVPC"
],
"Properties":{
"IpProtocol":"tcp",
"FromPort":"0",
"ToPort":"65535",
"SourceSecurityGroupId":{
"Fn::GetAtt":[
"TargetSG",
"GroupId"
]
},
"GroupId":{
"Fn::GetAtt":[
"TargetSG",
"GroupId"
]
}
}
},
"EcsCluster":{
"Type":"AWS::ECS::Cluster",
"DependsOn":[
"MyVPC"
]
},
"PhpTaskDefinition":{
"Type":"AWS::ECS::TaskDefinition",
"DependsOn":[
"MyVPC"
],
"Properties":{
"ContainerDefinitions":[
{
"Name":"php-simple-app",
"Cpu":"10",
"Essential":"true",
"Image":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::AccountId"
},
".dkr.ecr.us-east-1.amazonaws.com/",
{
"Ref":"ECSRepoName"
},
":",
{
"Ref":"ImageTag"
}
]
]
},
"Memory":"300",
"PortMappings":[
{
"HostPort":80,
"ContainerPort":80
}
]
}
],
"Volumes":[
{
"Name":"my-vol"
}
]
}
},
"EcsElb":{
"Type":"AWS::ElasticLoadBalancing::LoadBalancer",
"DependsOn":[
"MyVPC"
],
"Properties":{
"Subnets":[
{
"Ref":"publicSubnet01"
},
{
"Ref":"publicSubnet02"
}
],
"Listeners":[
{
"LoadBalancerPort":"80",
"InstancePort":"80",
"Protocol":"HTTP"
}
],
"SecurityGroups":[
{
"Ref":"SourceSG"
},
{
"Ref":"TargetSG"
}
],
"HealthCheck":{
"Target":"HTTP:80/",
"HealthyThreshold":"2",
"UnhealthyThreshold":"10",
"Interval":"30",
"Timeout":"5"
}
}
},
"ECSAutoScalingGroup":{
"Type":"AWS::AutoScaling::AutoScalingGroup",
"DependsOn":[
"MyVPC"
],
"Properties":{
"VPCZoneIdentifier":[
{
"Ref":"publicSubnet01"
},
{
"Ref":"publicSubnet02"
}
],
"LaunchConfigurationName":{
"Ref":"ContainerInstances"
},
"MinSize":"1",
"MaxSize":{
"Ref":"MaxSize"
},
"DesiredCapacity":{
"Ref":"DesiredCapacity"
}
},
"CreationPolicy":{
"ResourceSignal":{
"Timeout":"PT15M"
}
},
"UpdatePolicy":{
"AutoScalingRollingUpdate":{
"MinInstancesInService":"1",
"MaxBatchSize":"1",
"PauseTime":"PT15M",
"WaitOnResourceSignals":"true"
}
}
},
"ContainerInstances":{
"Type":"AWS::AutoScaling::LaunchConfiguration",
"DependsOn":[
"MyVPC"
],
"Metadata":{
"AWS::CloudFormation::Init":{
"config":{
"commands":{
"01_add_instance_to_cluster":{
"command":{
"Fn::Join":[
"",
[
"#!/bin/bash\n",
"echo ECS_CLUSTER=",
{
"Ref":"EcsCluster"
},
" >> /etc/ecs/ecs.config"
]
]
}
}
},
"files":{
"/etc/cfn/cfn-hup.conf":{
"content":{
"Fn::Join":[
"",
[
"[main]\n",
"stack=",
{
"Ref":"AWS::StackId"
},
"\n",
"region=",
{
"Ref":"AWS::Region"
},
"\n"
]
]
},
"mode":"000400",
"owner":"root",
"group":"root"
},
"/etc/cfn/hooks.d/cfn-auto-reloader.conf":{
"content":{
"Fn::Join":[
"",
[
"[cfn-auto-reloader-hook]\n",
"triggers=post.update\n",
"path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init\n",
"action=/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref":"AWS::StackName"
},
" --resource ContainerInstances ",
" --region ",
{
"Ref":"AWS::Region"
},
"\n",
"runas=root\n"
]
]
}
}
},
"services":{
"sysvinit":{
"cfn-hup":{
"enabled":"true",
"ensureRunning":"true",
"files":[
"/etc/cfn/cfn-hup.conf",
"/etc/cfn/hooks.d/cfn-auto-reloader.conf"
]
}
}
}
}
}
},
"Properties":{
"ImageId":{
"Fn::FindInMap":[
"AWSRegionToAMI",
{
"Ref":"AWS::Region"
},
"AMIID"
]
},
"SecurityGroups":[
{
"Ref":"SourceSG"
},
{
"Ref":"TargetSG"
}
],
"InstanceType":{
"Ref":"InstanceType"
},
"IamInstanceProfile":{
"Ref":"EC2InstanceProfile"
},
"KeyName":{
"Ref":"KeyName"
},
"UserData":{
"Fn::Base64":{
"Fn::Join":[
"",
[
"#!/bin/bash -xe\n",
"yum install -y aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref":"AWS::StackName"
},
" --resource ContainerInstances ",
" --region ",
{
"Ref":"AWS::Region"
},
"\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ",
{
"Ref":"AWS::StackName"
},
" --resource ECSAutoScalingGroup ",
" --region ",
{
"Ref":"AWS::Region"
},
"\n"
]
]
}
}
}
},
"EcsService":{
"Type":"AWS::ECS::Service",
"DependsOn":[
"MyVPC",
"ECSAutoScalingGroup"
],
"Properties":{
"Cluster":{
"Ref":"EcsCluster"
},
"DesiredCount":"1",
"DeploymentConfiguration":{
"MaximumPercent":100,
"MinimumHealthyPercent":0
},
"LoadBalancers":[
{
"ContainerName":"php-simple-app",
"ContainerPort":"80",
"LoadBalancerName":{
"Ref":"EcsElb"
}
}
],
"Role":{
"Ref":"EcsServiceRole"
},
"TaskDefinition":{
"Ref":"PhpTaskDefinition"
}
}
},
"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:Describe*",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"ec2:Describe*",
"ec2:AuthorizeSecurityGroupIngress"
],
"Resource":"*"
}
]
}
}
]
}
},
"EC2Role":{
"Type":"AWS::IAM::Role",
"DependsOn":[
"MyVPC"
],
"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:RegisterContainerInstance",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Submit*",
"ecr:*",
"ecs:Poll"
],
"Resource":"*"
}
]
}
}
]
}
},
"EC2InstanceProfile":{
"Type":"AWS::IAM::InstanceProfile",
"DependsOn":[
"MyVPC"
],
"Properties":{
"Path":"/",
"Roles":[
{
"Ref":"EC2Role"
}
]
}
},
"JenkinsRole":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Statement":[
{
"Sid":"",
"Effect":"Allow",
"Principal":{
"Service":"ec2.amazonaws.com"
},
"Action":"sts:AssumeRole"
}
]
},
"Path":"/"
}
},
"JenkinsRolePolicies":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"JenkinsRole",
"PolicyDocument":{
"Statement":[
{
"Action":[
"*"
],
"Effect":"Allow",
"Resource":"*"
}
]
},
"Roles":[
{
"Ref":"JenkinsRole"
}
]
}
},
"JenkinsInstanceProfile":{
"Type":"AWS::IAM::InstanceProfile",
"Properties":{
"Path":"/",
"Roles":[
{
"Ref":"JenkinsRole"
}
]
}
},
"JenkinsSG":{
"Type":"AWS::EC2::SecurityGroup",
"Properties":{
"GroupDescription":"Enable HTTP access on port 80",
"VpcId":{
"Ref":"MyVPC"
},
"SecurityGroupIngress":[
{
"IpProtocol":"tcp",
"FromPort":"22",
"ToPort":"22",
"CidrIp":{
"Ref":"YourIP"
}
},
{
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp":{
"Ref":"YourIP"
}
}
],
"SecurityGroupEgress":[
{
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"tcp",
"FromPort":"443",
"ToPort":"443",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"udp",
"FromPort":"123",
"ToPort":"123",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"udp",
"FromPort":"9418",
"ToPort":"9418",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"icmp",
"FromPort":"-1",
"ToPort":"-1",
"CidrIp":"0.0.0.0/0"
}
],
"Tags":[
{
"Key":"Name",
"Value":"JenkinsSG"
}
]
}
},
"JenkinsServer":{
"Type":"AWS::EC2::Instance",
"DependsOn":[
"EcsService",
"JenkinsSG",
"JenkinsRole",
"ECSAutoScalingGroup"
],
"Metadata":{
"AWS::CloudFormation::Init":{
"config":{
"packages":{
"yum":{
"java-1.7.0-openjdk":[
],
"java-1.7.0-openjdk-devel":[
]
}
},
"files":{
"/tmp/config.xml":{
"source":"https://s3.amazonaws.com/aws-codedeploy-samples-us-east-1/templates/latest/Jenkins_Helper_Scripts/config.xml",
"mode":"644"
},
"/tmp/hudson.tasks.Maven.xml":{
"source":"https://s3.amazonaws.com/aws-codedeploy-samples-us-east-1/templates/latest/Jenkins_Helper_Scripts/hudson.tasks.Maven.xml",
"mode":"644"
},
"/tmp/jenkins.mvn.GlobalMavenConfig.xml":{
"source":"https://s3.amazonaws.com/aws-codedeploy-samples-us-east-1/templates/latest/Jenkins_Helper_Scripts/jenkins.mvn.GlobalMavenConfig.xml",
"mode":"644"
}
}
}
}
},
"Properties":{
"KeyName":{
"Ref":"KeyName"
},
"ImageId":{
"Fn::FindInMap":[
"AWSRegionVirt2AMI",
{
"Ref":"AWS::Region"
},
{
"Fn::FindInMap":[
"AWSInstanceType2Virt",
"t2.large",
"Virt"
]
}
]
},
"NetworkInterfaces":[
{
"SubnetId":{
"Ref":"publicSubnet01"
},
"GroupSet":[
{
"Ref":"JenkinsSG"
}
],
"AssociatePublicIpAddress":"true",
"DeviceIndex":"0"
}
],
"EbsOptimized":{
"Fn::FindInMap":[
"AWSInstanceType2EBSOpt",
"t2.large",
"EBSOpt"
]
},
"InstanceType":"t2.large",
"IamInstanceProfile":{
"Ref":"JenkinsInstanceProfile"
},
"UserData":{
"Fn::Base64":{
"Fn::Join":[
"",
[
"#!/bin/bash -ex\n",
"yum update -y aws-cfn-bootstrap\n",
"# Update the AWS CLI to the latest version\n",
"yum install -y aws-cli\n",
"function error_exit\n",
"{\n",
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '",
{
"Ref":"JenkinsHostWaitHandle"
},
"'\n",
" exit 1\n",
"}\n",
"/opt/aws/bin/cfn-init -v -s ",
{
"Ref":"AWS::StackName"
},
" -r JenkinsServer --region ",
{
"Ref":"AWS::Region"
},
"\n",
"# Install Docker\n",
"cd /tmp/\n",
"yum install -y docker\n",
"service docker start\n",
"chkconfig docker on\n",
"# Wait 30 seconds to allow Docker to startup\n",
"echo \"Waiting 30 seconds for Docker to start.....\"\n",
"sleep 30\n",
"yum -y install git*\n",
"# Install Maven\n",
"cd /tmp/\n",
"wget http://mirror.cogentco.com/pub/apache/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz\n",
"tar xzvf apache-maven-3.3.3-bin.tar.gz -C /opt/\n",
"rm /tmp/apache-maven-3.3.3-bin.tar.gz\n",
"# Install Jenkins\n",
"wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo\n",
"rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key\n",
"yum install -y jenkins-1.658-1.1\n",
"service jenkins start\n",
"chkconfig jenkins on\n",
"# Wait 30 seconds to allow Jenkins to startup\n",
"echo \"Waiting 30 seconds for Jenkins to start.....\"\n",
"sleep 30\n",
"usermod -a -G docker jenkins\n",
"# Install the required plugins\n",
"cd /var/lib/jenkins/plugins\n",
"curl -O -L https://updates.jenkins-ci.org/latest/aws-codepipeline.hpi\n",
"chown jenkins:jenkins *.hpi\n",
"mv /tmp/hudson.tasks.Maven.xml /var/lib/jenkins/\n",
"mv /tmp/jenkins.mvn.GlobalMavenConfig.xml /var/lib/jenkins/\n",
"chown jenkins:jenkins /var/lib/jenkins/*.xml\n",
"# Restarting Jenkins\n",
"service jenkins restart\n",
"echo \"Waiting 30 seconds for Jenkins to start.....\"\n",
"sleep 30\n",
"# configure our job\n",
"wget -P /tmp https://s3.amazonaws.com/stelligent-training-public/public/jenkins/config-template.xml\n",
"/bin/sed -i \"s/APPNAME/",
{
"Ref":"AWS::StackName"
},
"/g\" /tmp/config-template.xml\n",
"/bin/sed -i \"s/MY_STACK/",
{
"Ref":"AWS::StackName"
},
"/g\" /tmp/config-template.xml\n",
"/bin/sed -i \"s/MY_ACCTID/",
{
"Ref":"AWS::AccountId"
},
"/g\" /tmp/config-template.xml\n",
"/bin/sed -i \"s/MY_ECR/",
{
"Ref":"ECSRepoName"
},
"/g\" /tmp/config-template.xml\n",
"/bin/sed -i \"s/REGION/",
{
"Ref":"AWS::Region"
},
"/g\" /tmp/config-template.xml\n",
"/usr/bin/java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080 create-job ",
{
"Ref":"AWS::StackName"
},
"< /tmp/config-template.xml\n",
"# Set up port forwarding\n",
"iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080\n",
"iptables-save > /etc/sysconfig/iptables\n",
"# If all went well, signal success\n",
"/opt/aws/bin/cfn-signal -e $? -r 'Instance configuration complete' '",
{
"Ref":"JenkinsHostWaitHandle"
},
"'\n",
"\n"
]
]
}
},
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-Jenkins"
]
]
}
}
]
}
},
"JenkinsHostWaitHandle":{
"Type":"AWS::CloudFormation::WaitConditionHandle"
},
"JenkinsHostWaitCondition":{
"Type":"AWS::CloudFormation::WaitCondition",
"DependsOn":"JenkinsServer",
"Properties":{
"Handle":{
"Ref":"JenkinsHostWaitHandle"
},
"Timeout":"600"
}
},
"CodePipelineTrustRole":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Statement":[
{
"Sid":"1",
"Effect":"Allow",
"Principal":{
"Service":[
"codepipeline.amazonaws.com"
]
},
"Action":"sts:AssumeRole"
}
]
},
"Path":"/"
}
},
"CodePipelineRolePolicies":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"CodePipelinePolicy",
"PolicyDocument":{
"Statement":[
{
"Action":[
"s3:*"
],
"Resource":[
"*"
],
"Effect":"Allow"
},
{
"Action":[
"s3:PutBucketPolicy",
"s3:PutObject"
],
"Resource":[
{
"Fn::Join":[
"",
[
"arn:aws:s3:::demo-",
{
"Ref":"AWS::Region"
},
"-",
{
"Ref":"AWS::AccountId"
},
"-",
{
"Ref":"AWS::StackName"
}
]
]
}
],
"Effect":"Allow"
},
{
"Action":[
"codecommit:GetBranch",
"codecommit:GetCommit",
"codecommit:UploadArchive",
"codecommit:GetUploadArchiveStatus",
"codecommit:CancelUploadArchive"
],
"Resource":"*",
"Effect":"Allow"
},
{
"Action":[
"codepipeline:*",
"iam:ListRoles",
"iam:PassRole",
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:RegisterApplicationRevision",
"elasticbeanstalk:DescribeApplications",
"elasticbeanstalk:DescribeEnvironments",
"lambda:GetFunctionConfiguration",
"lambda:ListFunctions"
],
"Resource":"*",
"Effect":"Allow"
}
]
},
"Roles":[
{
"Ref":"CodePipelineTrustRole"
}
]
}
},
"CustomJenkinsActionType":{
"Type":"AWS::CodePipeline::CustomActionType",
"DependsOn":"JenkinsHostWaitCondition",
"Properties":{
"Category":"Build",
"Provider":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-Jenkins"
]
]
},
"Version":"1",
"ConfigurationProperties":[
{
"Key":"true",
"Name":"ProjectName",
"Queryable":"true",
"Required":"true",
"Secret":"false",
"Type":"String"
}
],
"InputArtifactDetails":{
"MaximumCount":5,
"MinimumCount":0
},
"OutputArtifactDetails":{
"MaximumCount":5,
"MinimumCount":0
},
"Settings":{
"EntityUrlTemplate":{
"Fn::Join":[
"",
[
"http://",
{
"Fn::GetAtt":[
"JenkinsServer",
"PublicIp"
]
},
"/job/{Config:ProjectName}"
]
]
},
"ExecutionUrlTemplate":{
"Fn::Join":[
"",
[
"http://",
{
"Fn::GetAtt":[
"JenkinsServer",
"PublicIp"
]
},
"/job/{Config:ProjectName}/{ExternalExecutionId}"
]
]
}
}
}
},
"MyPipeline":{
"Type":"AWS::CodePipeline::Pipeline",
"DependsOn":[
"CustomJenkinsActionType",
"ECSAutoScalingGroup"
],
"Properties":{
"Name":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-Pipeline"
]
]
},
"RoleArn":{
"Fn::GetAtt":[
"CodePipelineTrustRole",
"Arn"
]
},
"Stages":[
{
"Name":"Source",
"Actions":[
{
"InputArtifacts":[
],
"Name":"Source",
"ActionTypeId":{
"Category":"Source",
"Owner":"AWS",
"Version":"1",
"Provider":"CodeCommit"
},
"OutputArtifacts":[
{
"Name":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-SourceArtifact"
]
]
}
}
],
"Configuration":{
"BranchName":{
"Ref":"RepositoryBranch"
},
"RepositoryName":{
"Ref":"RepositoryName"
}
},
"RunOrder":1
}
]
},
{
"Name":"Build",
"Actions":[
{
"Name":"PmdBuild",
"InputArtifacts":[
{
"Name":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-SourceArtifact"
]
]
}
}
],
"ActionTypeId":{
"Category":"Build",
"Owner":"Custom",
"Version":"1",
"Provider":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-Jenkins"
]
]
}
},
"OutputArtifacts":[
{
"Name":{
"Fn::Join":[
"",
[
{
"Ref":"AWS::StackName"
},
"-BuiltArtifact"
]
]
}
}
],
"Configuration":{
"ProjectName":{
"Ref":"AWS::StackName"
}
},
"RunOrder":1
}
]
}
],
"ArtifactStore":{
"Type":"S3",
"Location":{
"Fn::Join":[
"",
[
"codepipeline-",
{
"Ref":"AWS::Region"
},
"-",
{
"Ref":"AWS::AccountId"
}
]
]
}
}
}
}
},
"Outputs":{
"AppURL":{
"Value":{
"Fn::Join":[
"",
[
"http://",
{
"Fn::GetAtt":[
"EcsElb",
"DNSName"
]
},
"/"
]
]
},
"Description":"URL to the working application running on ECS"
},
"PipelineUrl":{
"Value":{
"Fn::Join":[
"",
[
"https://console.aws.amazon.com/codepipeline/home?region=",
{
"Ref":"AWS::Region"
},
"#/view/",
{
"Ref":"MyPipeline"
}
]
]
},
"Description":"Pipeline Url"
},
"VpcId":{
"Value":{
"Ref":"MyVPC"
},
"Description":"VPC ID of newly created VPC"
},
"IGWId":{
"Value":{
"Ref":"InternetGateway"
},
"Description":"Internet Gateway ID"
},
"PublicSubnetA":{
"Value":{
"Ref":"publicSubnet01"
},
"Description":"Public Subnet in AZ A"
},
"JenkinsInstanceID":{
"Value":{
"Ref":"JenkinsServer"
},
"Description":"Jenkins Instance ID"
},
"JenkinsPublicIP":{
"Value":{
"Fn::GetAtt":[
"JenkinsServer",
"PublicIp"
]
},
"Description":"Jenkins Public IP Address"
}
}
}