From f7eedc49c73721e5ec7e5de066fac461e8247af6 Mon Sep 17 00:00:00 2001 From: Joachim Hummel Date: Tue, 4 Aug 2020 13:34:39 +0200 Subject: [PATCH] Added Templates --- template.json | 775 ++++++++++++++++++++++++++++++++++++++++++++++++++ template.yaml | 775 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1550 insertions(+) create mode 100644 template.json create mode 100644 template.yaml diff --git a/template.json b/template.json new file mode 100644 index 0000000..5aebed2 --- /dev/null +++ b/template.json @@ -0,0 +1,775 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + "Description" : "Jenkins CodeDeploy: This template creates the CodeBuild project, IAM Roles, Jenkins server with pre-installed jinkens plugins and CodeDeploy instances to deploy the application on. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template. Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0", + "Parameters" : { + "CodedeployInstanceType": { + "Description": "EC2 instance type for CodeDeploy Web Servers", + "Type": "String", + "Default": "t2.medium", + "AllowedValues": ["t1.micro", "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", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge"], + "ConstraintDescription": "must be a valid EC2 instance type." + }, + "JenkinsInstanceType": { + "Description": "EC2 instance type for Jenkins Server", + "Type": "String", + "Default": "t2.medium", + "AllowedValues": ["t1.micro", "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", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge"], + "ConstraintDescription": "must be a valid EC2 instance type." + }, + "InstanceCount" : { + "Description" : "Number of CodeDeploy Web Server EC2 instances", + "Type" : "Number", + "Default" : "3", + "ConstraintDescription" : "Must be a number between 2 and 4.", + "MinValue" : "2", + "MaxValue" : "4" + }, + "KeyName": { + "Description": "The EC2 Key Pair to allow SSH access to CodeDeploy EC2 instances and Jenkins Server", + "Type": "AWS::EC2::KeyPair::KeyName", + "ConstraintDescription": "must be the name of an existing EC2 KeyPair." + }, + "VpcId": { + "Description": "The VPC Id where the EC2 instances will be launched.", + "Type": "AWS::EC2::VPC::Id", + "ConstraintDescription": "must be the name of an existing VPC." + }, + "YourIPRange": { + "Description": "CIDR block of the network from where you will connect to the Jenkins server using HTTP and SSH", + "Type": "String", + "MinLength": "9", + "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." + }, + "PublicSubnet1": { + "Description": "The first public subnet where the Jenkins EC2 instance, ELB and CodeDeploy Web Servers will be launched", + "Type": "AWS::EC2::Subnet::Id", + "ConstraintDescription": "Must be a valid Public VPC Subnet." + }, + "PublicSubnet2": { + "Description": "The second public subnet where the ELB and CodeDeploy Web Servers will be launched", + "Type": "AWS::EC2::Subnet::Id", + "ConstraintDescription": "Must be a valid Public VPC Subnet." + }, + "CodeBuildProject" : { + "Type" : "String", + "Description" : "Enter the project name of the CodeBuild" + } + }, + + "Mappings": { + "AWSRegionArch2AMI": { + "ap-northeast-1" : { "AMI" : "ami-08847abae18baa040" }, + "ap-northeast-2" : { "AMI" : "ami-012566705322e9a8e" }, + "ap-south-1" : { "AMI" : "ami-00b6a8a2bd28daf19" }, + "ap-southeast-1" : { "AMI" : "ami-01da99628f381e50a" }, + "ap-southeast-2" : { "AMI" : "ami-00e17d1165b9dd3ec" }, + "eu-central-1" : { "AMI" : "ami-076431be05aaf8080" }, + "eu-west-1" : { "AMI" : "ami-0bdb1d6c15a40392c" }, + "eu-west-2" : { "AMI" : "ami-e1768386" }, + "eu-west-3" : { "AMI" : "ami-06340c8c12baa6a09" }, + "sa-east-1" : { "AMI" : "ami-0ad7b0031d41ed4b9" }, + "us-east-1" : { "AMI" : "ami-04681a1dbd79675a5" }, + "us-east-2" : { "AMI" : "ami-0cf31d971a3ca20d6" }, + "us-west-1" : { "AMI" : "ami-0782017a917e973e7" }, + "us-west-2" : { "AMI" : "ami-6cd6f714" } + } + }, + + "Resources": { + + "CodeBuildRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "codebuild.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + }, + "Path" : "/" + } + }, + + "CodeBuildRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "CodeBuildRole", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents", "s3:GetObject","s3:GetObjectVersion","s3:PutObject" ], + "Resource" : "*" + } ] + }, + "Roles" : [ { + "Ref" : "CodeBuildRole" + } ] + } + }, + + "CodBuildProject": { + "Type": "AWS::CodeBuild::Project", + "Properties": { + "Name": { "Ref": "CodeBuildProject"}, + "Description": "A description about my project", + "ServiceRole": { "Fn::GetAtt": [ "CodeBuildRole", "Arn" ] }, + "Artifacts": { + "EncryptionDisabled" : true, + "Location" : { "Ref" : "CodeDeployBucket" }, + "Name" : "codebuild-artifact.zip", + "Packaging" : "ZIP", + "Type" : "S3" + }, + "Environment": { + "Type": "LINUX_CONTAINER", + "ComputeType": "BUILD_GENERAL1_SMALL", + "Image": "aws/codebuild/ubuntu-base:14.04" + }, + "Source": { + "Location" : {"Fn::Join" : [ "", [ {"Ref": "CodeDeployBucket"}, "/test" ] ]}, + "Type" : "S3" + } + } + }, + + "JenkinsServer": { + "Type": "AWS::EC2::Instance", + "Metadata": { + "Comment": "Install Jenkins, nginx and the Jenkins CodeDeploy plugin", + "AWS::CloudFormation::Init": { + "configSets": { + "install_all": [ + "install_base", + "install_nginx" + ] + }, + "install_base": { + "packages": { + "yum": { + "git": [] + } + } + }, + "install_nginx": { + "packages": { + "yum": { + "nginx": [] + } + }, + "files": { + "/etc/nginx/nginx.conf": { + "content": { + "Fn::Join": [ + "", + [ + "user nginx;\n", + "worker_processes 1;\n\n", + "error_log /var/log/nginx/error.log;\n", + "pid /var/run/nginx.pid;\n\n", + "events {\n", + " worker_connections 1024;\n", + "}\n\n", + "http {\n", + " include /etc/nginx/mime.types;\n", + " default_type application/octet-stream;\n", + " log_format main '$remote_addr - $remote_user [$time_local] \"$request\" '\n", + " '$status $body_bytes_sent \"$http_referer\" '\n", + " '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n", + " access_log /var/log/nginx/access.log main;\n", + " sendfile on;\n", + " keepalive_timeout 65;\n", + " include /etc/nginx/conf.d/*.conf;\n", + " index index.html index.htm;\n", + " server {\n", + " listen 80;\n", + " server_name _;\n", + " location / {\n", + " proxy_pass http://127.0.0.1:8080;\n", + " proxy_set_header Host $host;\n", + " proxy_set_header X-Real-IP $remote_addr;\n", + " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n", + " proxy_connect_timeout 150;\n", + " proxy_send_timeout 100;\n", + " proxy_read_timeout 100;\n", + " proxy_buffers 4 32k;\n", + " client_max_body_size 8m;\n", + " client_body_buffer_size 128k;\n", + " }\n", + " location /password.txt {\n", + " alias /web/initalpass.html;\n", + " }\n", + " }\n", + "}\n" + ] + ] + } + } + }, + "mode": "000444", + "owner": "root", + "group": "root" + } + }, + "services": { + "sysvinit": { + "nginx": { + "enabled": "true", + "ensureRunning": "true", + "files": [ + "/etc/nginx/nginx.conf" + ] + } + } + } + }, + "Properties": { + "KeyName": { + "Ref": "KeyName" + }, + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "AMI"]}, + "NetworkInterfaces": [ { + "AssociatePublicIpAddress": "true", + "DeviceIndex": "0", + "GroupSet": [{ "Ref" : "JenkinsSecurityGroup" }], + "SubnetId": { "Ref" : "PublicSubnet1" } + } ], + "InstanceType": { + "Ref": "JenkinsInstanceType" + }, + "IamInstanceProfile": { + "Ref": "JenkinsInstanceProfile" + }, + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", [ + "#!/bin/bash -xe\n", + "amazon-linux-extras install epel\n", + "sudo yum install -y aws-cfn-bootstrap\n", + "sudo mkdir /web\n", + "/opt/aws/bin/cfn-init -v ", + " --stack ", { + "Ref": "AWS::StackName" + }, + " --resource JenkinsServer ", + " --configsets install_all ", + " --region ", { + "Ref": "AWS::Region" + }, "\n", + + "# Install Jenkins and Java8\n", + "sudo yum install wget -y\n", + "sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo\n", + "sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key\n", + "sudo yum install java-1.8.0-openjdk -y\n", + "sudo yum update -y\n", + "sudo yum install jenkins -y\n", + + "sudo service jenkins start\n", + "sudo chkconfig jenkins on\n", + + "# Update the AWS CLI to the latest version\n", + "sudo yum update -y aws-cli\n", + + "# Wait 30 seconds to allow Jenkins to startup\n", + "echo \"Waiting 30 seconds for Jenkins to start.....\"\n", + "sleep 30\n", + + "## Nginx setup\n", + "service nginx restart\n", + + "# Restart Jenkins Service\n", + "/etc/init.d/jenkins restart\n", + + "#Restart NGINX service\n", + "sudo service nginx restart\n", + + "sleep 90\n", + "cp /var/lib/jenkins/secrets/initialAdminPassword /web/initalpass.html \n", + "chown nginx:nginx /web/initalpass.html \n", + + "# Configure AWS CLI and GIT for jenkins user\n", + "sudo su - jenkins --shell /bin/bash -c \"aws configure set region eu-central-1\" \n", + "sudo su - jenkins --shell /bin/bash -c \"aws configure set output json\" \n", + "#until [ -f /var/lib/jenkins/jenkins.install.InstallUtil.lastExecVersion ]; do sleep 5; service jenkins restart; done\n", + "while [ ! -f /var/lib/jenkins/jenkins.install.InstallUtil.lastExecVersion ]; do echo waiting for jenkins to finish setup; sleep 10; done; service jenkins restart\n", + "\n" + ] + ] + } + }, + "Tags" : [ + { + "Key" : "Name", + "Value" : "Jenkins Server" + } + ] + } + }, + "JenkinsSecurityGroup": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable SSH and HTTP access from specific CIDR block", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "22", + "ToPort": "22", + "CidrIp": { + "Ref": "YourIPRange" + } + }, { + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "CidrIp": { + "Ref": "YourIPRange" + } + }, + { + "IpProtocol": "tcp", + "FromPort": "8080", + "ToPort": "8080", + "CidrIp": { + "Ref": "YourIPRange" + } + }], + "SecurityGroupEgress": [ + { + "IpProtocol": "tcp", + "FromPort": "0", + "ToPort": "65535", + "CidrIp": "0.0.0.0/0" + } + ] + } + }, + "ELBSG": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable HTTP access from anywhere", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "CidrIp": "0.0.0.0/0" + }] + } + }, + "WSSG": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable HTTP access from ELB", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "22", + "ToPort": "22", + "CidrIp": { + "Ref": "YourIPRange" + } + }, { + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "SourceSecurityGroupId" : { + "Ref" : "ELBSG" + } + }] + } + }, + "CodeDeployBucket" : { + "Type" : "AWS::S3::Bucket", + "Properties" : { + "VersioningConfiguration" : { + "Status" : "Enabled" + } + } + }, + + "JenkinsBucketPolicy":{ + "Type":"AWS::S3::BucketPolicy", + "Properties":{ + "Bucket":{ + "Ref":"CodeDeployBucket" + }, + "PolicyDocument":{ + "Statement":[ + { + "Sid":"IPAllow", + "Effect":"Allow", + "Action":[ + "s3:Get*","s3:List*" + ], + "Resource":{ + "Fn::Join":[ + "", + [ + "arn:aws:s3:::", + { + "Ref":"CodeDeployBucket" + }, + "/*" + ] + ] + }, + "Principal":"*", + "Condition":{ + "IpAddress":{ + "aws:SourceIp":[ + {"Fn::Join" : ["", [{"Fn::GetAtt":["JenkinsServer","PublicIp"]},"/24"]]} + ] + + } + } + } + ] + } + } + }, + + "JenkinsRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "Path" : "/", + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "ec2.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + } + } + }, + "JenkinsInstanceProfile" : { + "Type" : "AWS::IAM::InstanceProfile", + "Properties" : { + "Path" : "/", + "Roles" : [ { + "Ref" : "JenkinsRole" + } ] + } + }, + "JenkinsPolicy" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "JenkinsPolicy", + "PolicyDocument" : { + "Version" : "2012-10-17", + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "s3:GetObject","s3:GetObjectVersion","s3:PutObject", "s3:DeleteObject"], + "Resource" : "*" + }, + { + "Effect" : "Allow", + "Action" : [ "codedeploy:ListApplications","codedeploy:ListDeploymentGroups","codedeploy:RegisterApplicationRevision","codedeploy:CreateDeployment","codedeploy:GetDeploymentConfig","codedeploy:GetApplicationRevision","codedeploy:GetDeployment" ], + "Resource" : "*" + }] + }, + "Roles" : [ { + "Ref" : "JenkinsRole" + } ] + } + }, + "CodeDeployTrustRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Version" : "2008-10-17", + "Statement" : [ { + "Sid" : "1", + "Effect" : "Allow", + "Principal" : { + "Service" : "codedeploy.amazonaws.com" + }, + "Action" : "sts:AssumeRole" + } ] + }, + "Path" : "/" + } + }, + "CodeDeployRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "CodeDeployPolicy", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "ec2:Describe*" ] + }, { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "autoscaling:CompleteLifecycleAction", "autoscaling:DeleteLifecycleHook", "autoscaling:DescribeLifecycleHooks", "autoscaling:DescribeAutoScalingGroups", "autoscaling:PutLifecycleHook", "autoscaling:RecordLifecycleActionHeartbeat" ] + }, { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "Tag:getResources", "Tag:getTags", "Tag:getTagsForResource", "Tag:getTagsForResourceList" ] + } ] + }, + "Roles" : [ { + "Ref" : "CodeDeployTrustRole" + } ] + } + }, + "InstanceRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "ec2.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + }, + "Path" : "/" + } + }, + "InstanceRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "InstanceRole", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "autoscaling:Describe*", "cloudformation:Describe*", "cloudformation:GetTemplate", "s3:Get*","s3:List*" ], + "Resource" : "*" + } ] + }, + "Roles" : [ { + "Ref" : "InstanceRole" + } ] + } + }, + "CodeDeployInstanceProfile" : { + "Type" : "AWS::IAM::InstanceProfile", + "Properties" : { + "Path" : "/", + "Roles" : [ { + "Ref" : "InstanceRole" + } ] + } + }, + + "WSASG" : { + "Type" : "AWS::AutoScaling::AutoScalingGroup", + "Properties" : { + "LaunchConfigurationName" : { + "Ref" : "WSLaunchConfiguration" + }, + "VPCZoneIdentifier" : [ { + "Ref" : "PublicSubnet1" + }, { + "Ref" : "PublicSubnet2" + } ], + "MinSize" : 0, + "MaxSize" : 4, + "DesiredCapacity" : { + "Ref" : "InstanceCount" + }, + "LoadBalancerNames": [ + { + "Ref" : "ELB" + } + ], + "HealthCheckType":"ELB", + "HealthCheckGracePeriod" : 600, + "Tags" : [ { + "Key" : "Name", + "Value" : "CodeDeployDemo", + "PropagateAtLaunch" : "true" + } ] + }, + "CreationPolicy" : { + "ResourceSignal" : { + "Count": { + "Ref" : "InstanceCount" + }, + "Timeout" : "PT15M" + } + }, + "UpdatePolicy" : { + "AutoScalingRollingUpdate" : { + "MinInstancesInService" : "0", + "MaxBatchSize" : "1" + } + } + }, + "WSLaunchConfiguration" : { + "Type" : "AWS::AutoScaling::LaunchConfiguration", + "Metadata" : { + "AWS::CloudFormation::Init" : { + "services" : { + "sysvint" : { + "codedeploy-agent" : { + "enabled" : "true", + "ensureRunning" : "true" + } + } + } + } + }, + "Properties" : { + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "AMI"]}, + "InstanceType" : { + "Ref" : "CodedeployInstanceType" + }, + "SecurityGroups" : [ { + "Ref" : "WSSG" + } ], + "UserData" : { + "Fn::Base64" : { + "Fn::Join" : [ "", [ + "#!/bin/bash -ex\n", + "yum update -y aws-cfn-bootstrap\n", + "yum install -y aws-cli\n", + "# Helper function.\n", + "function error_exit\n", + "{\n", + " /opt/aws/bin/cfn-signal -e 1 ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --reason \"$1\" ", + " --resource WebServerInstance ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + " exit 1\n", + "}\n", + "# Install the AWS CodeDeploy Agent.\n", + "cd /home/ec2-user/\n", + "aws s3 cp 's3://aws-codedeploy-", { "Ref" : "AWS::Region" }, "/latest/codedeploy-agent.noarch.rpm' . || error_exit 'Failed to download AWS CodeDeploy Agent.'\n", + "yum install -y ruby || error_exit 'Failed to install AWS CodeDeploy Agent.' \n", + "yum -y install codedeploy-agent.noarch.rpm || error_exit 'Failed to install AWS CodeDeploy Agent.' \n", + + "/opt/aws/bin/cfn-init --stack ", {"Ref" : "AWS::StackId"}, " --resource WSLaunchConfiguration --region ", {"Ref" : "AWS::Region"}, " || error_exit 'Failed to run cfn-init.'\n", + "# Signal the status from cfn-init\n", + "/opt/aws/bin/cfn-signal -e 0 ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource WSASG ", + " --region ", { "Ref" : "AWS::Region" }, "\n" + ] ] + } + }, + "KeyName" : { + "Ref" : "KeyName" + }, + "IamInstanceProfile" : { + "Ref" : "CodeDeployInstanceProfile" + }, + "AssociatePublicIpAddress" : true + } + }, + "ELB" : { + "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", + "Properties" : { + "HealthCheck" : { + "HealthyThreshold" : "2", + "Interval" : "30", + "Target" : "HTTP:80/", + "Timeout" : "5", + "UnhealthyThreshold" : "5" + }, + "Listeners" : [ { + "InstancePort" : "80", + "LoadBalancerPort" : "80", + "Protocol" : "HTTP", + "InstanceProtocol" : "HTTP", + "PolicyNames" : [ ] + } ], + "Subnets" : [ { + "Ref" : "PublicSubnet1" + }, { + "Ref" : "PublicSubnet2" + } ], + "SecurityGroups" : [ { + "Ref" : "ELBSG" + } ] + } + }, + "DemoApplication" : { + "Type" : "AWS::CodeDeploy::Application" + }, + "DemoFleet" : { + "Type" : "AWS::CodeDeploy::DeploymentGroup", + "Properties" : { + "ApplicationName" : { + "Ref" : "DemoApplication" + }, + "AutoScalingGroups" : [ { + "Ref" : "WSASG" + } ], + "Deployment" : { + "Description" : "Initial deployment", + "Revision" : { + "RevisionType" : "S3", + "S3Location" : { + "Bucket" : { + "Fn::Join" : [ "", ["aws-codedeploy-", { "Ref" : "AWS::Region" }]] + }, + "BundleType" : "zip", + "Key" : "samples/latest/SampleApp_Linux.zip" + } + } + }, + "DeploymentConfigName" : "CodeDeployDefault.OneAtATime", + "ServiceRoleArn" : { + "Fn::GetAtt" : [ "CodeDeployTrustRole", "Arn" ] + } + } + } + }, + "Outputs" : { + "ELBDNSName" : { + "Description" : "DNS Name of the ELB", + "Value" : { + "Fn::GetAtt" : [ "ELB", "DNSName" ] + } + }, + "JenkinsServerDNSName" : { + "Description" : "DNS Name of Jenkins Server", + "Value" : { + "Fn::GetAtt" : [ "JenkinsServer", "PublicDnsName" ] + } + }, + "CodeDeployApplicationName" : { + "Description" : "CodeDeploy Application Name", + "Value" : { + "Ref" : "DemoApplication" + } + }, + "CodeDeployDeploymentGroup" : { + "Description" : "CodeDeploy Deployment Group Name", + "Value" : { + "Ref" : "DemoFleet" + } + }, + "S3BucketName" : { + "Description" : "S3 Bucket Name", + "Value" : { + "Ref" : "CodeDeployBucket" + } + }, + "CodeBuildProjectName" : { + "Description" : "CodeBuild Project Name", + "Value" : { + "Ref" : "CodBuildProject" + } + } + } +} + diff --git a/template.yaml b/template.yaml new file mode 100644 index 0000000..5aebed2 --- /dev/null +++ b/template.yaml @@ -0,0 +1,775 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + "Description" : "Jenkins CodeDeploy: This template creates the CodeBuild project, IAM Roles, Jenkins server with pre-installed jinkens plugins and CodeDeploy instances to deploy the application on. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template. Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0", + "Parameters" : { + "CodedeployInstanceType": { + "Description": "EC2 instance type for CodeDeploy Web Servers", + "Type": "String", + "Default": "t2.medium", + "AllowedValues": ["t1.micro", "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", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge"], + "ConstraintDescription": "must be a valid EC2 instance type." + }, + "JenkinsInstanceType": { + "Description": "EC2 instance type for Jenkins Server", + "Type": "String", + "Default": "t2.medium", + "AllowedValues": ["t1.micro", "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", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge"], + "ConstraintDescription": "must be a valid EC2 instance type." + }, + "InstanceCount" : { + "Description" : "Number of CodeDeploy Web Server EC2 instances", + "Type" : "Number", + "Default" : "3", + "ConstraintDescription" : "Must be a number between 2 and 4.", + "MinValue" : "2", + "MaxValue" : "4" + }, + "KeyName": { + "Description": "The EC2 Key Pair to allow SSH access to CodeDeploy EC2 instances and Jenkins Server", + "Type": "AWS::EC2::KeyPair::KeyName", + "ConstraintDescription": "must be the name of an existing EC2 KeyPair." + }, + "VpcId": { + "Description": "The VPC Id where the EC2 instances will be launched.", + "Type": "AWS::EC2::VPC::Id", + "ConstraintDescription": "must be the name of an existing VPC." + }, + "YourIPRange": { + "Description": "CIDR block of the network from where you will connect to the Jenkins server using HTTP and SSH", + "Type": "String", + "MinLength": "9", + "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." + }, + "PublicSubnet1": { + "Description": "The first public subnet where the Jenkins EC2 instance, ELB and CodeDeploy Web Servers will be launched", + "Type": "AWS::EC2::Subnet::Id", + "ConstraintDescription": "Must be a valid Public VPC Subnet." + }, + "PublicSubnet2": { + "Description": "The second public subnet where the ELB and CodeDeploy Web Servers will be launched", + "Type": "AWS::EC2::Subnet::Id", + "ConstraintDescription": "Must be a valid Public VPC Subnet." + }, + "CodeBuildProject" : { + "Type" : "String", + "Description" : "Enter the project name of the CodeBuild" + } + }, + + "Mappings": { + "AWSRegionArch2AMI": { + "ap-northeast-1" : { "AMI" : "ami-08847abae18baa040" }, + "ap-northeast-2" : { "AMI" : "ami-012566705322e9a8e" }, + "ap-south-1" : { "AMI" : "ami-00b6a8a2bd28daf19" }, + "ap-southeast-1" : { "AMI" : "ami-01da99628f381e50a" }, + "ap-southeast-2" : { "AMI" : "ami-00e17d1165b9dd3ec" }, + "eu-central-1" : { "AMI" : "ami-076431be05aaf8080" }, + "eu-west-1" : { "AMI" : "ami-0bdb1d6c15a40392c" }, + "eu-west-2" : { "AMI" : "ami-e1768386" }, + "eu-west-3" : { "AMI" : "ami-06340c8c12baa6a09" }, + "sa-east-1" : { "AMI" : "ami-0ad7b0031d41ed4b9" }, + "us-east-1" : { "AMI" : "ami-04681a1dbd79675a5" }, + "us-east-2" : { "AMI" : "ami-0cf31d971a3ca20d6" }, + "us-west-1" : { "AMI" : "ami-0782017a917e973e7" }, + "us-west-2" : { "AMI" : "ami-6cd6f714" } + } + }, + + "Resources": { + + "CodeBuildRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "codebuild.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + }, + "Path" : "/" + } + }, + + "CodeBuildRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "CodeBuildRole", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents", "s3:GetObject","s3:GetObjectVersion","s3:PutObject" ], + "Resource" : "*" + } ] + }, + "Roles" : [ { + "Ref" : "CodeBuildRole" + } ] + } + }, + + "CodBuildProject": { + "Type": "AWS::CodeBuild::Project", + "Properties": { + "Name": { "Ref": "CodeBuildProject"}, + "Description": "A description about my project", + "ServiceRole": { "Fn::GetAtt": [ "CodeBuildRole", "Arn" ] }, + "Artifacts": { + "EncryptionDisabled" : true, + "Location" : { "Ref" : "CodeDeployBucket" }, + "Name" : "codebuild-artifact.zip", + "Packaging" : "ZIP", + "Type" : "S3" + }, + "Environment": { + "Type": "LINUX_CONTAINER", + "ComputeType": "BUILD_GENERAL1_SMALL", + "Image": "aws/codebuild/ubuntu-base:14.04" + }, + "Source": { + "Location" : {"Fn::Join" : [ "", [ {"Ref": "CodeDeployBucket"}, "/test" ] ]}, + "Type" : "S3" + } + } + }, + + "JenkinsServer": { + "Type": "AWS::EC2::Instance", + "Metadata": { + "Comment": "Install Jenkins, nginx and the Jenkins CodeDeploy plugin", + "AWS::CloudFormation::Init": { + "configSets": { + "install_all": [ + "install_base", + "install_nginx" + ] + }, + "install_base": { + "packages": { + "yum": { + "git": [] + } + } + }, + "install_nginx": { + "packages": { + "yum": { + "nginx": [] + } + }, + "files": { + "/etc/nginx/nginx.conf": { + "content": { + "Fn::Join": [ + "", + [ + "user nginx;\n", + "worker_processes 1;\n\n", + "error_log /var/log/nginx/error.log;\n", + "pid /var/run/nginx.pid;\n\n", + "events {\n", + " worker_connections 1024;\n", + "}\n\n", + "http {\n", + " include /etc/nginx/mime.types;\n", + " default_type application/octet-stream;\n", + " log_format main '$remote_addr - $remote_user [$time_local] \"$request\" '\n", + " '$status $body_bytes_sent \"$http_referer\" '\n", + " '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n", + " access_log /var/log/nginx/access.log main;\n", + " sendfile on;\n", + " keepalive_timeout 65;\n", + " include /etc/nginx/conf.d/*.conf;\n", + " index index.html index.htm;\n", + " server {\n", + " listen 80;\n", + " server_name _;\n", + " location / {\n", + " proxy_pass http://127.0.0.1:8080;\n", + " proxy_set_header Host $host;\n", + " proxy_set_header X-Real-IP $remote_addr;\n", + " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n", + " proxy_connect_timeout 150;\n", + " proxy_send_timeout 100;\n", + " proxy_read_timeout 100;\n", + " proxy_buffers 4 32k;\n", + " client_max_body_size 8m;\n", + " client_body_buffer_size 128k;\n", + " }\n", + " location /password.txt {\n", + " alias /web/initalpass.html;\n", + " }\n", + " }\n", + "}\n" + ] + ] + } + } + }, + "mode": "000444", + "owner": "root", + "group": "root" + } + }, + "services": { + "sysvinit": { + "nginx": { + "enabled": "true", + "ensureRunning": "true", + "files": [ + "/etc/nginx/nginx.conf" + ] + } + } + } + }, + "Properties": { + "KeyName": { + "Ref": "KeyName" + }, + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "AMI"]}, + "NetworkInterfaces": [ { + "AssociatePublicIpAddress": "true", + "DeviceIndex": "0", + "GroupSet": [{ "Ref" : "JenkinsSecurityGroup" }], + "SubnetId": { "Ref" : "PublicSubnet1" } + } ], + "InstanceType": { + "Ref": "JenkinsInstanceType" + }, + "IamInstanceProfile": { + "Ref": "JenkinsInstanceProfile" + }, + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", [ + "#!/bin/bash -xe\n", + "amazon-linux-extras install epel\n", + "sudo yum install -y aws-cfn-bootstrap\n", + "sudo mkdir /web\n", + "/opt/aws/bin/cfn-init -v ", + " --stack ", { + "Ref": "AWS::StackName" + }, + " --resource JenkinsServer ", + " --configsets install_all ", + " --region ", { + "Ref": "AWS::Region" + }, "\n", + + "# Install Jenkins and Java8\n", + "sudo yum install wget -y\n", + "sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo\n", + "sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key\n", + "sudo yum install java-1.8.0-openjdk -y\n", + "sudo yum update -y\n", + "sudo yum install jenkins -y\n", + + "sudo service jenkins start\n", + "sudo chkconfig jenkins on\n", + + "# Update the AWS CLI to the latest version\n", + "sudo yum update -y aws-cli\n", + + "# Wait 30 seconds to allow Jenkins to startup\n", + "echo \"Waiting 30 seconds for Jenkins to start.....\"\n", + "sleep 30\n", + + "## Nginx setup\n", + "service nginx restart\n", + + "# Restart Jenkins Service\n", + "/etc/init.d/jenkins restart\n", + + "#Restart NGINX service\n", + "sudo service nginx restart\n", + + "sleep 90\n", + "cp /var/lib/jenkins/secrets/initialAdminPassword /web/initalpass.html \n", + "chown nginx:nginx /web/initalpass.html \n", + + "# Configure AWS CLI and GIT for jenkins user\n", + "sudo su - jenkins --shell /bin/bash -c \"aws configure set region eu-central-1\" \n", + "sudo su - jenkins --shell /bin/bash -c \"aws configure set output json\" \n", + "#until [ -f /var/lib/jenkins/jenkins.install.InstallUtil.lastExecVersion ]; do sleep 5; service jenkins restart; done\n", + "while [ ! -f /var/lib/jenkins/jenkins.install.InstallUtil.lastExecVersion ]; do echo waiting for jenkins to finish setup; sleep 10; done; service jenkins restart\n", + "\n" + ] + ] + } + }, + "Tags" : [ + { + "Key" : "Name", + "Value" : "Jenkins Server" + } + ] + } + }, + "JenkinsSecurityGroup": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable SSH and HTTP access from specific CIDR block", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "22", + "ToPort": "22", + "CidrIp": { + "Ref": "YourIPRange" + } + }, { + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "CidrIp": { + "Ref": "YourIPRange" + } + }, + { + "IpProtocol": "tcp", + "FromPort": "8080", + "ToPort": "8080", + "CidrIp": { + "Ref": "YourIPRange" + } + }], + "SecurityGroupEgress": [ + { + "IpProtocol": "tcp", + "FromPort": "0", + "ToPort": "65535", + "CidrIp": "0.0.0.0/0" + } + ] + } + }, + "ELBSG": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable HTTP access from anywhere", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "CidrIp": "0.0.0.0/0" + }] + } + }, + "WSSG": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Enable HTTP access from ELB", + "VpcId": { + "Ref": "VpcId" + }, + "SecurityGroupIngress": [{ + "IpProtocol": "tcp", + "FromPort": "22", + "ToPort": "22", + "CidrIp": { + "Ref": "YourIPRange" + } + }, { + "IpProtocol": "tcp", + "FromPort": "80", + "ToPort": "80", + "SourceSecurityGroupId" : { + "Ref" : "ELBSG" + } + }] + } + }, + "CodeDeployBucket" : { + "Type" : "AWS::S3::Bucket", + "Properties" : { + "VersioningConfiguration" : { + "Status" : "Enabled" + } + } + }, + + "JenkinsBucketPolicy":{ + "Type":"AWS::S3::BucketPolicy", + "Properties":{ + "Bucket":{ + "Ref":"CodeDeployBucket" + }, + "PolicyDocument":{ + "Statement":[ + { + "Sid":"IPAllow", + "Effect":"Allow", + "Action":[ + "s3:Get*","s3:List*" + ], + "Resource":{ + "Fn::Join":[ + "", + [ + "arn:aws:s3:::", + { + "Ref":"CodeDeployBucket" + }, + "/*" + ] + ] + }, + "Principal":"*", + "Condition":{ + "IpAddress":{ + "aws:SourceIp":[ + {"Fn::Join" : ["", [{"Fn::GetAtt":["JenkinsServer","PublicIp"]},"/24"]]} + ] + + } + } + } + ] + } + } + }, + + "JenkinsRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "Path" : "/", + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "ec2.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + } + } + }, + "JenkinsInstanceProfile" : { + "Type" : "AWS::IAM::InstanceProfile", + "Properties" : { + "Path" : "/", + "Roles" : [ { + "Ref" : "JenkinsRole" + } ] + } + }, + "JenkinsPolicy" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "JenkinsPolicy", + "PolicyDocument" : { + "Version" : "2012-10-17", + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "s3:GetObject","s3:GetObjectVersion","s3:PutObject", "s3:DeleteObject"], + "Resource" : "*" + }, + { + "Effect" : "Allow", + "Action" : [ "codedeploy:ListApplications","codedeploy:ListDeploymentGroups","codedeploy:RegisterApplicationRevision","codedeploy:CreateDeployment","codedeploy:GetDeploymentConfig","codedeploy:GetApplicationRevision","codedeploy:GetDeployment" ], + "Resource" : "*" + }] + }, + "Roles" : [ { + "Ref" : "JenkinsRole" + } ] + } + }, + "CodeDeployTrustRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Version" : "2008-10-17", + "Statement" : [ { + "Sid" : "1", + "Effect" : "Allow", + "Principal" : { + "Service" : "codedeploy.amazonaws.com" + }, + "Action" : "sts:AssumeRole" + } ] + }, + "Path" : "/" + } + }, + "CodeDeployRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "CodeDeployPolicy", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "ec2:Describe*" ] + }, { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "autoscaling:CompleteLifecycleAction", "autoscaling:DeleteLifecycleHook", "autoscaling:DescribeLifecycleHooks", "autoscaling:DescribeAutoScalingGroups", "autoscaling:PutLifecycleHook", "autoscaling:RecordLifecycleActionHeartbeat" ] + }, { + "Effect" : "Allow", + "Resource" : [ "*" ], + "Action" : [ "Tag:getResources", "Tag:getTags", "Tag:getTagsForResource", "Tag:getTagsForResourceList" ] + } ] + }, + "Roles" : [ { + "Ref" : "CodeDeployTrustRole" + } ] + } + }, + "InstanceRole" : { + "Type" : "AWS::IAM::Role", + "Properties" : { + "AssumeRolePolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Principal" : { + "Service" : [ "ec2.amazonaws.com" ] + }, + "Action" : [ "sts:AssumeRole" ] + } ] + }, + "Path" : "/" + } + }, + "InstanceRolePolicies" : { + "Type" : "AWS::IAM::Policy", + "Properties" : { + "PolicyName" : "InstanceRole", + "PolicyDocument" : { + "Statement" : [ { + "Effect" : "Allow", + "Action" : [ "autoscaling:Describe*", "cloudformation:Describe*", "cloudformation:GetTemplate", "s3:Get*","s3:List*" ], + "Resource" : "*" + } ] + }, + "Roles" : [ { + "Ref" : "InstanceRole" + } ] + } + }, + "CodeDeployInstanceProfile" : { + "Type" : "AWS::IAM::InstanceProfile", + "Properties" : { + "Path" : "/", + "Roles" : [ { + "Ref" : "InstanceRole" + } ] + } + }, + + "WSASG" : { + "Type" : "AWS::AutoScaling::AutoScalingGroup", + "Properties" : { + "LaunchConfigurationName" : { + "Ref" : "WSLaunchConfiguration" + }, + "VPCZoneIdentifier" : [ { + "Ref" : "PublicSubnet1" + }, { + "Ref" : "PublicSubnet2" + } ], + "MinSize" : 0, + "MaxSize" : 4, + "DesiredCapacity" : { + "Ref" : "InstanceCount" + }, + "LoadBalancerNames": [ + { + "Ref" : "ELB" + } + ], + "HealthCheckType":"ELB", + "HealthCheckGracePeriod" : 600, + "Tags" : [ { + "Key" : "Name", + "Value" : "CodeDeployDemo", + "PropagateAtLaunch" : "true" + } ] + }, + "CreationPolicy" : { + "ResourceSignal" : { + "Count": { + "Ref" : "InstanceCount" + }, + "Timeout" : "PT15M" + } + }, + "UpdatePolicy" : { + "AutoScalingRollingUpdate" : { + "MinInstancesInService" : "0", + "MaxBatchSize" : "1" + } + } + }, + "WSLaunchConfiguration" : { + "Type" : "AWS::AutoScaling::LaunchConfiguration", + "Metadata" : { + "AWS::CloudFormation::Init" : { + "services" : { + "sysvint" : { + "codedeploy-agent" : { + "enabled" : "true", + "ensureRunning" : "true" + } + } + } + } + }, + "Properties" : { + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "AMI"]}, + "InstanceType" : { + "Ref" : "CodedeployInstanceType" + }, + "SecurityGroups" : [ { + "Ref" : "WSSG" + } ], + "UserData" : { + "Fn::Base64" : { + "Fn::Join" : [ "", [ + "#!/bin/bash -ex\n", + "yum update -y aws-cfn-bootstrap\n", + "yum install -y aws-cli\n", + "# Helper function.\n", + "function error_exit\n", + "{\n", + " /opt/aws/bin/cfn-signal -e 1 ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --reason \"$1\" ", + " --resource WebServerInstance ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + " exit 1\n", + "}\n", + "# Install the AWS CodeDeploy Agent.\n", + "cd /home/ec2-user/\n", + "aws s3 cp 's3://aws-codedeploy-", { "Ref" : "AWS::Region" }, "/latest/codedeploy-agent.noarch.rpm' . || error_exit 'Failed to download AWS CodeDeploy Agent.'\n", + "yum install -y ruby || error_exit 'Failed to install AWS CodeDeploy Agent.' \n", + "yum -y install codedeploy-agent.noarch.rpm || error_exit 'Failed to install AWS CodeDeploy Agent.' \n", + + "/opt/aws/bin/cfn-init --stack ", {"Ref" : "AWS::StackId"}, " --resource WSLaunchConfiguration --region ", {"Ref" : "AWS::Region"}, " || error_exit 'Failed to run cfn-init.'\n", + "# Signal the status from cfn-init\n", + "/opt/aws/bin/cfn-signal -e 0 ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource WSASG ", + " --region ", { "Ref" : "AWS::Region" }, "\n" + ] ] + } + }, + "KeyName" : { + "Ref" : "KeyName" + }, + "IamInstanceProfile" : { + "Ref" : "CodeDeployInstanceProfile" + }, + "AssociatePublicIpAddress" : true + } + }, + "ELB" : { + "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", + "Properties" : { + "HealthCheck" : { + "HealthyThreshold" : "2", + "Interval" : "30", + "Target" : "HTTP:80/", + "Timeout" : "5", + "UnhealthyThreshold" : "5" + }, + "Listeners" : [ { + "InstancePort" : "80", + "LoadBalancerPort" : "80", + "Protocol" : "HTTP", + "InstanceProtocol" : "HTTP", + "PolicyNames" : [ ] + } ], + "Subnets" : [ { + "Ref" : "PublicSubnet1" + }, { + "Ref" : "PublicSubnet2" + } ], + "SecurityGroups" : [ { + "Ref" : "ELBSG" + } ] + } + }, + "DemoApplication" : { + "Type" : "AWS::CodeDeploy::Application" + }, + "DemoFleet" : { + "Type" : "AWS::CodeDeploy::DeploymentGroup", + "Properties" : { + "ApplicationName" : { + "Ref" : "DemoApplication" + }, + "AutoScalingGroups" : [ { + "Ref" : "WSASG" + } ], + "Deployment" : { + "Description" : "Initial deployment", + "Revision" : { + "RevisionType" : "S3", + "S3Location" : { + "Bucket" : { + "Fn::Join" : [ "", ["aws-codedeploy-", { "Ref" : "AWS::Region" }]] + }, + "BundleType" : "zip", + "Key" : "samples/latest/SampleApp_Linux.zip" + } + } + }, + "DeploymentConfigName" : "CodeDeployDefault.OneAtATime", + "ServiceRoleArn" : { + "Fn::GetAtt" : [ "CodeDeployTrustRole", "Arn" ] + } + } + } + }, + "Outputs" : { + "ELBDNSName" : { + "Description" : "DNS Name of the ELB", + "Value" : { + "Fn::GetAtt" : [ "ELB", "DNSName" ] + } + }, + "JenkinsServerDNSName" : { + "Description" : "DNS Name of Jenkins Server", + "Value" : { + "Fn::GetAtt" : [ "JenkinsServer", "PublicDnsName" ] + } + }, + "CodeDeployApplicationName" : { + "Description" : "CodeDeploy Application Name", + "Value" : { + "Ref" : "DemoApplication" + } + }, + "CodeDeployDeploymentGroup" : { + "Description" : "CodeDeploy Deployment Group Name", + "Value" : { + "Ref" : "DemoFleet" + } + }, + "S3BucketName" : { + "Description" : "S3 Bucket Name", + "Value" : { + "Ref" : "CodeDeployBucket" + } + }, + "CodeBuildProjectName" : { + "Description" : "CodeBuild Project Name", + "Value" : { + "Ref" : "CodBuildProject" + } + } + } +} +