Skip to content

Instantly share code, notes, and snippets.

@JosephMaxwell
Last active January 27, 2022 00:38
Show Gist options
  • Select an option

  • Save JosephMaxwell/107333cc92a4fe95e6bc2ef0efb6ff3a to your computer and use it in GitHub Desktop.

Select an option

Save JosephMaxwell/107333cc92a4fe95e6bc2ef0efb6ff3a to your computer and use it in GitHub Desktop.

Revisions

  1. JosephMaxwell renamed this gist Oct 31, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. JosephMaxwell renamed this gist Oct 31, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion jenkins.template → awslogs
    Original file line number Diff line number Diff line change
    @@ -360,7 +360,7 @@
    "installLogs": {
    "packages": {
    "yum": {
    "awslogs": []
    "awslogsd": []
    }
    },
    "commands": {
  3. JosephMaxwell revised this gist Feb 6, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -699,8 +699,8 @@
    "sudo /usr/sbin/alternatives --set javac /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/javac || true \n",
    "yum remove java-1.7 || true \n",

    "sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo\n",
    "sudo rpm --import http://pkg.jenkins.io/redhat-stable/jenkins.io.key\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",
    "yum install -y jenkins\n",
    "sudo mkdir -p /var/lib/jenkins\n",
    "sudo chown -R jenkins:jenkins /var/lib/jenkins\n",
  4. JosephMaxwell revised this gist Aug 26, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -91,6 +91,9 @@
    },
    "eu-west-1": {
    "AMI": "ami-f9dd458a"
    },
    "ap-southeast-2": {
    "AMI": "ami-10918173"
    }
    }
    },
  5. JosephMaxwell revised this gist Jul 12, 2017. No changes.
  6. JosephMaxwell revised this gist Jul 5, 2017. No changes.
  7. JosephMaxwell revised this gist Jul 5, 2017. No changes.
  8. JosephMaxwell revised this gist Jul 4, 2017. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -720,16 +720,10 @@
    "# Start Jenkins\n",
    "sudo service jenkins restart\n",
    "sudo chkconfig jenkins on\n",
    "# All is well, signal success\n",
    "cfn-signal --exit-code 0 --reason \"Stack setup complete\" --data \"$(cat /var/lib/jenkins/secrets/initialAdminPassword)\" '",
    {
    "Ref": "WaitHandle"
    },
    "'\n",
    "sleep 400\n",
    "printf \"Subject: Your Jenkins Password\n\n",
    "$(cat /var/lib/jenkins/secrets/initialAdminPassword)\n",
    "CHANGE THIS RIGHT AWAY AT: http://",
    "CHANGE THIS RIGHT AWAY AT: ",
    "http://",
    {
    "Ref": "DnsRecord"
    @@ -739,6 +733,12 @@
    "Ref": "EmailAddress"
    },
    "\n",
    "# All is well, signal success\n",
    "./opt/aws/bin/cfn-signal --exit-code 0 --reason \"Stack setup complete\" '",
    {
    "Ref": "WaitHandle"
    },
    "'\n",
    "#EOF"
    ]
    ]
  9. JosephMaxwell revised this gist Jul 4, 2017. 1 changed file with 46 additions and 11 deletions.
    57 changes: 46 additions & 11 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -31,6 +31,19 @@
    "Default": "your-ssh-key",
    "Type": "AWS::EC2::KeyPair::KeyName"
    },
    "IPWhitelist": {
    "Description": "IP Address to Whitelist (your IP address followed by /32)",
    "MinLength": "9",
    "MaxLength": "18",
    "Type": "String",
    "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."
    },
    "EmailAddress": {
    "Description": "What email address will receive the default Jenkins password",
    "Type": "String",
    "Default": ""
    },
    "DnsPrefix": {
    "Description": "Prefix for Jenkins' DNS record (<prefix>.<zone>)",
    "Type": "String",
    @@ -344,8 +357,7 @@
    "installLogs": {
    "packages": {
    "yum": {
    "awslogs": [],
    "java-1.8.0-openjdk.x86_64": []
    "awslogs": []
    }
    },
    "commands": {
    @@ -679,14 +691,16 @@
    "# Post-cfn work\n",

    "# Updating to Java 8\n",
    "sudo yum install -y java-1.8.0-openjdk.x86_64\n",
    "sudo /usr/sbin/alternatives --set java /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java\n",
    "sudo /usr/sbin/alternatives --set javac /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/javac\n",
    "sudo yum remove java-1.7\n",
    "yum install -y java-1.8.0-openjdk.x86_64 || true \n",
    "sudo /usr/sbin/alternatives --set java /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java || true\n",
    "sudo /usr/sbin/alternatives --set javac /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/javac || true \n",
    "yum remove java-1.7 || true \n",

    "sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo\n",
    "sudo rpm --import http://pkg.jenkins.io/redhat-stable/jenkins.io.key\n",
    "yum install -y jenkins\n",
    "sudo mkdir -p /var/lib/jenkins\n",
    "sudo chown -R jenkins:jenkins /var/lib/jenkins\n",
    "# Handle case where cron doesn't detect the new /etc/cron.d file\n",
    "#service cron restart\n",
    "# Attempt to restore from backup\n",
    @@ -700,16 +714,31 @@
    "Ref": "S3Prefix"
    },
    " /var/lib/jenkins || true # ignore errors\n",
    "sudo /etc/init.d/jenkins start\n",
    "sudo chkconfig jenkins on\n",
    "sudo ethtool -K eth0 sg off",
    "sudo service jenkins start\n",
    "sudo chown -R jenkins:jenkins /var/lib/jenkins\n",
    "sudo chmod -R 755 /var/lib/jenkins\n",
    "# Start Jenkins\n",
    "sudo service jenkins restart\n",
    "sudo chkconfig jenkins on\n",
    "# All is well, signal success\n",
    "cfn-signal -e 0 -r \"Stack setup complete\" '",
    "cfn-signal --exit-code 0 --reason \"Stack setup complete\" --data \"$(cat /var/lib/jenkins/secrets/initialAdminPassword)\" '",
    {
    "Ref": "WaitHandle"
    },
    "'\n",
    "sleep 400\n",
    "printf \"Subject: Your Jenkins Password\n\n",
    "$(cat /var/lib/jenkins/secrets/initialAdminPassword)\n",
    "CHANGE THIS RIGHT AWAY AT: http://",
    "http://",
    {
    "Ref": "DnsRecord"
    },
    "\" | sendmail -v ",
    {
    "Ref": "EmailAddress"
    },
    "\n",
    "#EOF"
    ]
    ]
    @@ -747,6 +776,12 @@
    "FromPort": "8080",
    "ToPort": "8080",
    "CidrIp": "0.0.0.0/0"
    },
    {
    "IpProtocol": "tcp",
    "FromPort": "22",
    "ToPort": "22",
    "CidrIp": {"Ref" : "IPWhitelist"}
    }
    ]
    }
    @@ -842,4 +877,4 @@
    }
    }
    }
    }
    }
  10. JosephMaxwell revised this gist Jul 4, 2017. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -677,6 +677,13 @@
    },
    " || error_exit 'Failed to run cfn-init'\n",
    "# Post-cfn work\n",

    "# Updating to Java 8\n",
    "sudo yum install -y java-1.8.0-openjdk.x86_64\n",
    "sudo /usr/sbin/alternatives --set java /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java\n",
    "sudo /usr/sbin/alternatives --set javac /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/javac\n",
    "sudo yum remove java-1.7\n",

    "sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo\n",
    "sudo rpm --import http://pkg.jenkins.io/redhat-stable/jenkins.io.key\n",
    "yum install -y jenkins\n",
  11. JosephMaxwell revised this gist Jul 4, 2017. 1 changed file with 33 additions and 94 deletions.
    127 changes: 33 additions & 94 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -28,23 +28,23 @@
    },
    "SshKey": {
    "Description": "Name of an existing EC2 keypair to enable SSH access to the instances",
    "Default": "SwiftOtter",
    "Default": "your-ssh-key",
    "Type": "AWS::EC2::KeyPair::KeyName"
    },
    "DnsPrefix": {
    "Description": "Prefix for Jenkins' DNS record (<prefix>.<zone>)",
    "Type": "String",
    "Default": ""
    "Default": "builds"
    },
    "DnsZone": {
    "Description": "Route53-hosted zone to use for the DNS record (<prefix>.<zone>)",
    "Type": "String",
    "Default": ""
    "Default": "your-website.com"
    },
    "S3Bucket": {
    "Description": "Existing S3 bucket to use for Jenkins backups and restores",
    "Type": "String",
    "Default": ""
    "Default": "your-s3-bucket"
    },
    "S3Prefix": {
    "Description": "[Optional] Key prefix to use for Jenkins backups",
    @@ -86,14 +86,9 @@
    "Type": "AWS::Logs::LogGroup",
    "Properties": {
    "RetentionInDays": 7
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f229fdfc-dd53-475f-8a4e-975cb52ce86f"
    }
    }
    },
    "JenkinsIamUser": {
    "SwiftOtterJenkins": {
    "Type": "AWS::IAM::User",
    "Properties": {
    "Policies": [
    @@ -145,14 +140,9 @@
    }
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9"
    }
    }
    },
    "EC2BuilderIamUser": {
    "BuildRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
    "AssumeRolePolicyDocument": {
    @@ -186,11 +176,6 @@
    }
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    }
    }
    },
    "RolePolicies": {
    @@ -238,53 +223,38 @@
    },
    "Roles": [
    {
    "Ref": "EC2BuilderIamUser"
    "Ref": "BuildRole"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "7bbe33fd-97e1-4e29-8232-12a5a347912f"
    }
    }
    },
    "Ec2BuilderProfile": {
    "BuildInstanceProfile": {
    "Type": "AWS::IAM::InstanceProfile",
    "Properties": {
    "Path": "/",
    "Roles": [
    {
    "Ref": "EC2BuilderIamUser"
    "Ref": "BuildRole"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "ef42272d-1c61-4769-a5cd-ec0f444ec408"
    }
    }
    },
    "JenkinsHostKeys": {
    "HostKeys": {
    "Type": "AWS::IAM::AccessKey",
    "Properties": {
    "UserName": {
    "Ref": "JenkinsIamUser"
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f2af5c54-7724-4e71-9845-2d5a1e903c9b"
    "Ref": "SwiftOtterJenkins"
    }
    }
    },
    "JenkinsServerGroup": {
    "ServerGroup": {
    "Type": "AWS::AutoScaling::AutoScalingGroup",
    "Properties": {
    "AvailabilityZones": {
    "Fn::GetAZs": ""
    },
    "LaunchConfigurationName": {
    "Ref": "JenkinsLaunchConfig"
    "Ref": "LaunchConfig"
    },
    "MinSize": "1",
    "MaxSize": "1",
    @@ -294,14 +264,9 @@
    "Ref": "ElasticLoadBalancer"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "5578008f-96e8-446a-9dde-96b3811f0999"
    }
    }
    },
    "JenkinsLaunchConfig": {
    "LaunchConfig": {
    "Type": "AWS::AutoScaling::LaunchConfiguration",
    "Metadata": {
    "AWS::CloudFormation::Init": {
    @@ -379,7 +344,8 @@
    "installLogs": {
    "packages": {
    "yum": {
    "awslogs": []
    "awslogs": [],
    "java-1.8.0-openjdk.x86_64": []
    }
    },
    "commands": {
    @@ -512,11 +478,11 @@
    },
    "context": {
    "access_key": {
    "Ref": "JenkinsHostKeys"
    "Ref": "HostKeys"
    },
    "secret_key": {
    "Fn::GetAtt": [
    "JenkinsHostKeys",
    "HostKeys",
    "SecretAccessKey"
    ]
    }
    @@ -624,8 +590,8 @@
    "#!/bin/bash\n",
    "AWS_CONFIG_FILE=/etc/aws.conf\n",
    "PATH=/bin:/usr/bin::/usr/local/bin\n",
    "source /usr/local/bin/jenkins-backup /var/lib/jenkins s3://{{s3_bucket}}/{{s3_prefix}}jenkins-`date +\\%Y\\%m\\%d\\%H\\%M.tar.gz` >> /var/log/jenkins-backup.log 2>&1\n",
    "echo \"ec2-terminate-instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)\" | at now + 15 min"
    "source /usr/local/bin/jenkins-backup /var/lib/jenkins s3://{{s3_bucket}}/{{s3_prefix}}jenkins-`date +\\%Y\\%m\\%d\\%H\\%M.tar.gz` >> ~/jenkins.cron.log 2>&1\n",
    "sleep 60 && /opt/aws/bin/ec2-terminate-instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
    ]
    ]
    },
    @@ -643,17 +609,14 @@
    }
    }
    }
    },
    "AWS::CloudFormation::Designer": {
    "id": "c002aae6-f2d3-41aa-909d-128327b75032"
    }
    },
    "Properties": {
    "KeyName": {
    "Ref": "SshKey"
    },
    "IamInstanceProfile": {
    "Ref": "Ec2BuilderProfile"
    "Ref": "BuildInstanceProfile"
    },
    "ImageId": {
    "Fn::FindInMap": [
    @@ -666,7 +629,7 @@
    },
    "SecurityGroups": [
    {
    "Ref": "EC2BuilderSecurityGroup"
    "Ref": "ServerSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    @@ -695,16 +658,16 @@
    {
    "Ref": "AWS::StackName"
    },
    " --resource JenkinsLaunchConfig",
    " --resource LaunchConfig",
    " --configsets install",
    " --access-key ",
    {
    "Ref": "JenkinsHostKeys"
    "Ref": "HostKeys"
    },
    " --secret-key ",
    {
    "Fn::GetAtt": [
    "JenkinsHostKeys",
    "HostKeys",
    "SecretAccessKey"
    ]
    },
    @@ -732,6 +695,7 @@
    " /var/lib/jenkins || true # ignore errors\n",
    "sudo /etc/init.d/jenkins start\n",
    "sudo chkconfig jenkins on\n",
    "sudo ethtool -K eth0 sg off",
    "# Start Jenkins\n",
    "# All is well, signal success\n",
    "cfn-signal -e 0 -r \"Stack setup complete\" '",
    @@ -746,7 +710,7 @@
    }
    }
    },
    "LoadBalancerSecurityGroup": {
    "LbSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins LBs",
    @@ -761,14 +725,9 @@
    "CidrIp": "0.0.0.0/0"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f31ffec8-0498-44e1-aae1-72f7869eed4e"
    }
    }
    },
    "EC2BuilderSecurityGroup": {
    "ServerSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins servers",
    @@ -783,19 +742,14 @@
    "CidrIp": "0.0.0.0/0"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "6b912343-a76c-49ea-a3b9-e3810e985623"
    }
    }
    },
    "ElasticLoadBalancer": {
    "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties": {
    "SecurityGroups": [
    {
    "Ref": "LoadBalancerSecurityGroup"
    "Ref": "LbSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    @@ -818,14 +772,9 @@
    "Interval": "30",
    "Timeout": "5"
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    }
    }
    },
    "JenkinsDnsRecord": {
    "DnsRecord": {
    "Type": "AWS::Route53::RecordSet",
    "Properties": {
    "HostedZoneName": {
    @@ -864,20 +813,10 @@
    ]
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f70f335b-0d40-4564-83f1-5c32db6a0d12"
    }
    }
    },
    "WaitHandle": {
    "Type": "AWS::CloudFormation::WaitConditionHandle",
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "969a3dd3-d332-4bf7-9946-836a45fda38d"
    }
    }
    "Type": "AWS::CloudFormation::WaitConditionHandle"
    }
    },
    "Outputs": {
    @@ -889,11 +828,11 @@
    [
    "http://",
    {
    "Ref": "JenkinsDnsRecord"
    "Ref": "DnsRecord"
    }
    ]
    ]
    }
    }
    }
    }
    }
  12. JosephMaxwell revised this gist Oct 17, 2016. 1 changed file with 22 additions and 211 deletions.
    233 changes: 22 additions & 211 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -93,7 +93,7 @@
    }
    }
    },
    "SwiftOtterJenkins": {
    "JenkinsIamUser": {
    "Type": "AWS::IAM::User",
    "Properties": {
    "Policies": [
    @@ -152,7 +152,7 @@
    }
    }
    },
    "BuildRole": {
    "EC2BuilderIamUser": {
    "Type": "AWS::IAM::Role",
    "Properties": {
    "AssumeRolePolicyDocument": {
    @@ -238,7 +238,7 @@
    },
    "Roles": [
    {
    "Ref": "BuildRole"
    "Ref": "EC2BuilderIamUser"
    }
    ]
    },
    @@ -248,13 +248,13 @@
    }
    }
    },
    "BuildInstanceProfile": {
    "Ec2BuilderProfile": {
    "Type": "AWS::IAM::InstanceProfile",
    "Properties": {
    "Path": "/",
    "Roles": [
    {
    "Ref": "BuildRole"
    "Ref": "EC2BuilderIamUser"
    }
    ]
    },
    @@ -264,11 +264,11 @@
    }
    }
    },
    "HostKeys": {
    "JenkinsHostKeys": {
    "Type": "AWS::IAM::AccessKey",
    "Properties": {
    "UserName": {
    "Ref": "SwiftOtterJenkins"
    "Ref": "JenkinsIamUser"
    }
    },
    "Metadata": {
    @@ -277,14 +277,14 @@
    }
    }
    },
    "ServerGroup": {
    "JenkinsServerGroup": {
    "Type": "AWS::AutoScaling::AutoScalingGroup",
    "Properties": {
    "AvailabilityZones": {
    "Fn::GetAZs": ""
    },
    "LaunchConfigurationName": {
    "Ref": "LaunchConfig"
    "Ref": "JenkinsLaunchConfig"
    },
    "MinSize": "1",
    "MaxSize": "1",
    @@ -301,7 +301,7 @@
    }
    }
    },
    "LaunchConfig": {
    "JenkinsLaunchConfig": {
    "Type": "AWS::AutoScaling::LaunchConfiguration",
    "Metadata": {
    "AWS::CloudFormation::Init": {
    @@ -512,11 +512,11 @@
    },
    "context": {
    "access_key": {
    "Ref": "HostKeys"
    "Ref": "JenkinsHostKeys"
    },
    "secret_key": {
    "Fn::GetAtt": [
    "HostKeys",
    "JenkinsHostKeys",
    "SecretAccessKey"
    ]
    }
    @@ -653,7 +653,7 @@
    "Ref": "SshKey"
    },
    "IamInstanceProfile": {
    "Ref": "BuildInstanceProfile"
    "Ref": "Ec2BuilderProfile"
    },
    "ImageId": {
    "Fn::FindInMap": [
    @@ -666,7 +666,7 @@
    },
    "SecurityGroups": [
    {
    "Ref": "ServerSecurityGroup"
    "Ref": "EC2BuilderSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    @@ -695,16 +695,16 @@
    {
    "Ref": "AWS::StackName"
    },
    " --resource LaunchConfig",
    " --resource JenkinsLaunchConfig",
    " --configsets install",
    " --access-key ",
    {
    "Ref": "HostKeys"
    "Ref": "JenkinsHostKeys"
    },
    " --secret-key ",
    {
    "Fn::GetAtt": [
    "HostKeys",
    "JenkinsHostKeys",
    "SecretAccessKey"
    ]
    },
    @@ -746,7 +746,7 @@
    }
    }
    },
    "LbSecurityGroup": {
    "LoadBalancerSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins LBs",
    @@ -768,7 +768,7 @@
    }
    }
    },
    "ServerSecurityGroup": {
    "EC2BuilderSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins servers",
    @@ -795,7 +795,7 @@
    "Properties": {
    "SecurityGroups": [
    {
    "Ref": "LbSecurityGroup"
    "Ref": "LoadBalancerSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    @@ -825,7 +825,7 @@
    }
    }
    },
    "DnsRecord": {
    "JenkinsDnsRecord": {
    "Type": "AWS::Route53::RecordSet",
    "Properties": {
    "HostedZoneName": {
    @@ -889,200 +889,11 @@
    [
    "http://",
    {
    "Ref": "DnsRecord"
    "Ref": "JenkinsDnsRecord"
    }
    ]
    ]
    }
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "969a3dd3-d332-4bf7-9946-836a45fda38d": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 270,
    "y": 90
    },
    "z": 1,
    "embeds": []
    },
    "6b912343-a76c-49ea-a3b9-e3810e985623": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 270,
    "y": 210
    },
    "z": 1,
    "embeds": []
    },
    "f31ffec8-0498-44e1-aae1-72f7869eed4e": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 60,
    "y": 300
    },
    "z": 1,
    "embeds": []
    },
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 390,
    "y": 90
    },
    "z": 1,
    "embeds": [],
    "ismemberof": [
    "f31ffec8-0498-44e1-aae1-72f7869eed4e"
    ]
    },
    "f70f335b-0d40-4564-83f1-5c32db6a0d12": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 390,
    "y": 210
    },
    "z": 1,
    "embeds": [],
    "isrelatedto": [
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    ]
    },
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 180,
    "y": 330
    },
    "z": 1,
    "embeds": []
    },
    "ef42272d-1c61-4769-a5cd-ec0f444ec408": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 300,
    "y": 330
    },
    "z": 1,
    "embeds": [],
    "isassociatedwith": [
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    ]
    },
    "7bbe33fd-97e1-4e29-8232-12a5a347912f": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 420,
    "y": 330
    },
    "z": 1,
    "embeds": [],
    "isassociatedwith": [
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    ]
    },
    "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 60,
    "y": 420
    },
    "z": 1,
    "embeds": []
    },
    "f2af5c54-7724-4e71-9845-2d5a1e903c9b": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 180,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "isrelatedto": [
    "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9"
    ]
    },
    "c002aae6-f2d3-41aa-909d-128327b75032": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 300,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "ismemberof": [
    "6b912343-a76c-49ea-a3b9-e3810e985623"
    ],
    "isrelatedto": [
    "ef42272d-1c61-4769-a5cd-ec0f444ec408",
    "969a3dd3-d332-4bf7-9946-836a45fda38d",
    "f2af5c54-7724-4e71-9845-2d5a1e903c9b"
    ]
    },
    "5578008f-96e8-446a-9dde-96b3811f0999": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 420,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "isconnectedto": [
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    ],
    "isassociatedwith": [
    "c002aae6-f2d3-41aa-909d-128327b75032"
    ]
    },
    "f229fdfc-dd53-475f-8a4e-975cb52ce86f": {
    "size": {
    "width": 150,
    "height": 150
    },
    "position": {
    "x": 60,
    "y": 90
    },
    "z": 1,
    "embeds": []
    }
    }
    }
    }
  13. JosephMaxwell created this gist Oct 17, 2016.
    1,088 changes: 1,088 additions & 0 deletions jenkins.template
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1088 @@
    {
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Launches a Jenkins server.",
    "Parameters": {
    "InstanceType": {
    "Description": "EC2 instance type",
    "Type": "String",
    "Default": "t2.small",
    "AllowedValues": [
    "t1.micro",
    "t2.small",
    "m1.small",
    "m1.medium",
    "m1.large",
    "m1.xlarge",
    "m2.xlarge",
    "m2.2xlarge",
    "m2.4xlarge",
    "m3.xlarge",
    "m3.2xlarge",
    "c1.medium",
    "c1.xlarge",
    "cc1.4xlarge",
    "cc2.8xlarge",
    "cg1.4xlarge"
    ],
    "ConstraintDescription": "must be a valid EC2 instance type."
    },
    "SshKey": {
    "Description": "Name of an existing EC2 keypair to enable SSH access to the instances",
    "Default": "SwiftOtter",
    "Type": "AWS::EC2::KeyPair::KeyName"
    },
    "DnsPrefix": {
    "Description": "Prefix for Jenkins' DNS record (<prefix>.<zone>)",
    "Type": "String",
    "Default": ""
    },
    "DnsZone": {
    "Description": "Route53-hosted zone to use for the DNS record (<prefix>.<zone>)",
    "Type": "String",
    "Default": ""
    },
    "S3Bucket": {
    "Description": "Existing S3 bucket to use for Jenkins backups and restores",
    "Type": "String",
    "Default": ""
    },
    "S3Prefix": {
    "Description": "[Optional] Key prefix to use for Jenkins backups",
    "Type": "String",
    "Default": ""
    },
    "Subnets": {
    "Description": "List of VPC subnet IDs for the cluster",
    "Type": "List<AWS::EC2::Subnet::Id>"
    },
    "VpcId": {
    "Description": "VPC associated with the provided subnets",
    "Type": "AWS::EC2::VPC::Id"
    },
    "AdminSecurityGroup": {
    "Description": "Existing security group that should be granted administrative access to Jenkins (e.g., 'sg-123456')",
    "Default": "Primary",
    "Type": "AWS::EC2::SecurityGroup::Id"
    }
    },
    "Mappings": {
    "RegionMap": {
    "us-east-1": {
    "AMI": "ami-6869aa05"
    },
    "us-west-1": {
    "AMI": "ami-7172b611"
    },
    "us-west-2": {
    "AMI": "ami-31490d51"
    },
    "eu-west-1": {
    "AMI": "ami-f9dd458a"
    }
    }
    },
    "Resources": {
    "CloudFormationLogs": {
    "Type": "AWS::Logs::LogGroup",
    "Properties": {
    "RetentionInDays": 7
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f229fdfc-dd53-475f-8a4e-975cb52ce86f"
    }
    }
    },
    "SwiftOtterJenkins": {
    "Type": "AWS::IAM::User",
    "Properties": {
    "Policies": [
    {
    "PolicyName": "S3Access",
    "PolicyDocument": {
    "Statement": [
    {
    "Effect": "Allow",
    "Action": "s3:*",
    "Resource": {
    "Fn::Join": [
    "",
    [
    "arn:aws:s3:::",
    {
    "Ref": "S3Bucket"
    },
    "/*"
    ]
    ]
    }
    }
    ]
    }
    },
    {
    "PolicyName": "IAMAccess",
    "PolicyDocument": {
    "Statement": [
    {
    "Effect": "Allow",
    "NotAction": "iam:*",
    "Resource": "*"
    }
    ]
    }
    },
    {
    "PolicyName": "EC2Access",
    "PolicyDocument": {
    "Statement": [
    {
    "Effect": "Allow",
    "Action": "ec2:*",
    "Resource": "*"
    }
    ]
    }
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9"
    }
    }
    },
    "BuildRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
    "AssumeRolePolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "Service": [
    "ec2.amazonaws.com"
    ]
    },
    "Action": [
    "sts:AssumeRole"
    ]
    }
    ]
    },
    "Policies": [
    {
    "PolicyName": "root",
    "PolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
    }
    ]
    }
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    }
    }
    },
    "RolePolicies": {
    "Type": "AWS::IAM::Policy",
    "Properties": {
    "PolicyName": "root",
    "PolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Action": "ec2:*",
    "Effect": "Allow",
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": "elasticloadbalancing:*",
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": "cloudwatch:*",
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": "autoscaling:*",
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": "s3:*",
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": [
    "iam:PassRole",
    "iam:ListInstanceProfiles",
    "ec2:*"
    ],
    "Resource": "*"
    }
    ]
    },
    "Roles": [
    {
    "Ref": "BuildRole"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "7bbe33fd-97e1-4e29-8232-12a5a347912f"
    }
    }
    },
    "BuildInstanceProfile": {
    "Type": "AWS::IAM::InstanceProfile",
    "Properties": {
    "Path": "/",
    "Roles": [
    {
    "Ref": "BuildRole"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "ef42272d-1c61-4769-a5cd-ec0f444ec408"
    }
    }
    },
    "HostKeys": {
    "Type": "AWS::IAM::AccessKey",
    "Properties": {
    "UserName": {
    "Ref": "SwiftOtterJenkins"
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f2af5c54-7724-4e71-9845-2d5a1e903c9b"
    }
    }
    },
    "ServerGroup": {
    "Type": "AWS::AutoScaling::AutoScalingGroup",
    "Properties": {
    "AvailabilityZones": {
    "Fn::GetAZs": ""
    },
    "LaunchConfigurationName": {
    "Ref": "LaunchConfig"
    },
    "MinSize": "1",
    "MaxSize": "1",
    "DesiredCapacity": "1",
    "LoadBalancerNames": [
    {
    "Ref": "ElasticLoadBalancer"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "5578008f-96e8-446a-9dde-96b3811f0999"
    }
    }
    },
    "LaunchConfig": {
    "Type": "AWS::AutoScaling::LaunchConfiguration",
    "Metadata": {
    "AWS::CloudFormation::Init": {
    "configSets": {
    "install": [
    "installConfig",
    "installApp",
    "installLogs"
    ]
    },
    "installConfig": {
    "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.WebServerInstance.Metadata.AWS::CloudFormation::Init\n",
    "action=/opt/aws/bin/cfn-init -v ",
    " --stack ",
    {
    "Ref": "AWS::StackName"
    },
    " --resource WebServerInstance ",
    " --configsets install_all ",
    " --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"
    ]
    }
    }
    }
    },
    "installLogs": {
    "packages": {
    "yum": {
    "awslogs": []
    }
    },
    "commands": {
    "01_create_state_directory": {
    "command": "mkdir -p /var/awslogs/state"
    }
    },
    "services": {
    "sysvinit": {
    "awslogs": {
    "enabled": "true",
    "ensureRunning": "true",
    "files": [
    "/etc/awslogs/awslogs.conf"
    ]
    }
    }
    },
    "files": {
    "/etc/awslogs/awslogs.conf": {
    "content": {
    "Fn::Join": [
    "",
    [
    "[general]\n",
    "state_file= /var/awslogs/state/agent-state\n",
    "[/var/log/cloud-init.log]\n",
    "file = /var/log/cloud-init.log\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/cloud-init.log\n",
    "datetime_format = \n",
    "[/var/log/cloud-init-output.log]\n",
    "file = /var/log/cloud-init-output.log\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/cloud-init-output.log\n",
    "datetime_format = \n",
    "[/var/log/cfn-init.log]\n",
    "file = /var/log/cfn-init.log\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/cfn-init.log\n",
    "datetime_format = \n",
    "[/var/log/cfn-hup.log]\n",
    "file = /var/log/cfn-hup.log\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/cfn-hup.log\n",
    "datetime_format = \n",
    "[/var/log/cfn-wire.log]\n",
    "file = /var/log/cfn-wire.log\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/cfn-wire.log\n",
    "datetime_format = \n",
    "[/var/log/httpd]\n",
    "file = /var/log/httpd/*\n",
    "log_group_name = ",
    {
    "Ref": "CloudFormationLogs"
    },
    "\n",
    "log_stream_name = {instance_id}/httpd\n",
    "datetime_format = %d/%b/%Y:%H:%M:%S\n"
    ]
    ]
    },
    "mode": "000444",
    "owner": "root",
    "group": "root"
    },
    "/etc/awslogs/awscli.conf": {
    "content": {
    "Fn::Join": [
    "",
    [
    "[plugins]\n",
    "cwlogs = cwlogs\n",
    "[default]\n",
    "region = ",
    {
    "Ref": "AWS::Region"
    },
    "\n"
    ]
    ]
    },
    "mode": "000444",
    "owner": "root",
    "group": "root"
    }
    }
    },
    "installApp": {
    "packages": {
    "python": {
    "awscli": []
    },
    "yum": {
    "git-all": []
    }
    },
    "files": {
    "/etc/aws.conf": {
    "content": {
    "Fn::Join": [
    "\n",
    [
    "[default]",
    "aws_access_key_id={{access_key}}",
    "aws_secret_access_key={{secret_key}}"
    ]
    ]
    },
    "context": {
    "access_key": {
    "Ref": "HostKeys"
    },
    "secret_key": {
    "Fn::GetAtt": [
    "HostKeys",
    "SecretAccessKey"
    ]
    }
    },
    "mode": "000700",
    "owner": "root",
    "group": "root"
    },
    "/usr/local/bin/jenkins-restore": {
    "content": {
    "Fn::Join": [
    "\n",
    [
    "#!/bin/bash -e",
    "",
    "USAGE=\"Usage: $0 S3_TARGET JENKINS_HOME\\n",
    "\\n",
    "Example:\\n",
    "$0 s3://mybucket/jenkins/jenkins-201405011901.tar.gz /var/lib/jenkins\\n",
    "\\n",
    "If S3_TARGET is a directory, restore from the newest file. Make sure to include the trailing slash:\\n",
    "$0 s3://mybucket/jenkins/ /var/lib/jenkins\"",
    "",
    "S3_TARGET=$1",
    "JENKINS_HOME=$2",
    "if [[ -z \"`echo $S3_TARGET|grep '^s3://'`\" ]]; then",
    " echo -e $USAGE",
    " exit 1",
    "fi",
    "",
    "if [[ \"$S3_TARGET\" == */ ]]; then",
    " S3_TARGET=$S3_TARGET`aws s3 ls $S3_TARGET|tail -1|awk '{print $NF}'`",
    "fi",
    "",
    "LOCAL_BACKUP=/tmp/`basename $S3_TARGET`",
    "aws s3 cp $S3_TARGET $LOCAL_BACKUP",
    "",
    "rm -rf $JENKINS_HOME",
    "#if [[ -d \"$JENKINS_HOME\" ]]; then",
    "# read -p \"Delete existing $JENKINS_HOME? (y/n) \" -n 1 -r",
    "# echo",
    "# if [[ $REPLY =~ ^[Yy]$ ]]; then",
    "# rm -rf $JENKINS_HOME",
    "# else",
    "# echo \"Bailing out\"",
    "# exit 1",
    "# fi",
    "#fi",
    "",
    "mkdir -p $JENKINS_HOME",
    "tar zxf $LOCAL_BACKUP -C $JENKINS_HOME",
    "rm -f $LOCAL_BACKUP"
    ]
    ]
    },
    "mode": "000755",
    "owner": "root",
    "group": "root"
    },
    "/usr/local/bin/jenkins-backup": {
    "content": {
    "Fn::Join": [
    "\n",
    [
    "#!/bin/bash -e",
    "",
    "USAGE=\"Usage: $0 JENKINS_HOME S3_TARGET\\n",
    "\\n",
    "Examples:\\n",
    "$0 /var/lib/jenkins s3://mybucket/jenkins/jenkins-201405011901.tar.gz\"",
    "",
    "JENKINS_HOME=$1",
    "S3_TARGET=$2",
    "if [[ -z \"`echo $S3_TARGET|grep '^s3://'`\" || ! -d \"$JENKINS_HOME\" ]]; then",
    " echo -e $USAGE",
    " exit 1",
    "fi",
    "",
    "LOCAL_BACKUP=/tmp/`basename $S3_TARGET`",
    "",
    "tar -C $JENKINS_HOME -zcf $LOCAL_BACKUP .\\",
    " --exclude \"config-history/\" \\",
    " --exclude \"config-history/*\" \\",
    " --exclude \"jobs/*/workspace*\" \\",
    " --exclude \"jobs/*/builds/*/archive\" \\",
    " --exclude \"plugins/*/*\" \\",
    " --exclude \"plugins/*.bak\" \\",
    " --exclude \"war\" \\",
    " --exclude \"cache\"",
    "",
    "aws s3 cp $LOCAL_BACKUP $S3_TARGET",
    "rm -f $LOCAL_BACKUP"
    ]
    ]
    },
    "mode": "000755",
    "owner": "root",
    "group": "root"
    },
    "/etc/cron.daily/jenkins": {
    "content": {
    "Fn::Join": [
    "\n",
    [
    "#!/bin/bash\n",
    "AWS_CONFIG_FILE=/etc/aws.conf\n",
    "PATH=/bin:/usr/bin::/usr/local/bin\n",
    "source /usr/local/bin/jenkins-backup /var/lib/jenkins s3://{{s3_bucket}}/{{s3_prefix}}jenkins-`date +\\%Y\\%m\\%d\\%H\\%M.tar.gz` >> /var/log/jenkins-backup.log 2>&1\n",
    "echo \"ec2-terminate-instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)\" | at now + 15 min"
    ]
    ]
    },
    "context": {
    "s3_bucket": {
    "Ref": "S3Bucket"
    },
    "s3_prefix": {
    "Ref": "S3Prefix"
    }
    },
    "mode": "000755",
    "owner": "root",
    "group": "root"
    }
    }
    }
    },
    "AWS::CloudFormation::Designer": {
    "id": "c002aae6-f2d3-41aa-909d-128327b75032"
    }
    },
    "Properties": {
    "KeyName": {
    "Ref": "SshKey"
    },
    "IamInstanceProfile": {
    "Ref": "BuildInstanceProfile"
    },
    "ImageId": {
    "Fn::FindInMap": [
    "RegionMap",
    {
    "Ref": "AWS::Region"
    },
    "AMI"
    ]
    },
    "SecurityGroups": [
    {
    "Ref": "ServerSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    }
    ],
    "InstanceType": {
    "Ref": "InstanceType"
    },
    "UserData": {
    "Fn::Base64": {
    "Fn::Join": [
    "",
    [
    "#!/bin/bash -xe\n",
    "# Helper function\n",
    "function error_exit\n",
    "{\n",
    " cfn-signal -e 1 -r \"$1\" '",
    {
    "Ref": "WaitHandle"
    },
    "'\n",
    " exit 1\n",
    "}\n",
    "/opt/aws/bin/cfn-init --stack ",
    {
    "Ref": "AWS::StackName"
    },
    " --resource LaunchConfig",
    " --configsets install",
    " --access-key ",
    {
    "Ref": "HostKeys"
    },
    " --secret-key ",
    {
    "Fn::GetAtt": [
    "HostKeys",
    "SecretAccessKey"
    ]
    },
    " --region ",
    {
    "Ref": "AWS::Region"
    },
    " || error_exit 'Failed to run cfn-init'\n",
    "# Post-cfn work\n",
    "sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo\n",
    "sudo rpm --import http://pkg.jenkins.io/redhat-stable/jenkins.io.key\n",
    "yum install -y jenkins\n",
    "# Handle case where cron doesn't detect the new /etc/cron.d file\n",
    "#service cron restart\n",
    "# Attempt to restore from backup\n",
    "export AWS_CONFIG_FILE=/etc/aws.conf\n",
    "sudo /usr/local/bin/jenkins-restore s3://",
    {
    "Ref": "S3Bucket"
    },
    "/",
    {
    "Ref": "S3Prefix"
    },
    " /var/lib/jenkins || true # ignore errors\n",
    "sudo /etc/init.d/jenkins start\n",
    "sudo chkconfig jenkins on\n",
    "# Start Jenkins\n",
    "# All is well, signal success\n",
    "cfn-signal -e 0 -r \"Stack setup complete\" '",
    {
    "Ref": "WaitHandle"
    },
    "'\n",
    "#EOF"
    ]
    ]
    }
    }
    }
    },
    "LbSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins LBs",
    "VpcId": {
    "Ref": "VpcId"
    },
    "SecurityGroupIngress": [
    {
    "IpProtocol": "tcp",
    "FromPort": "80",
    "ToPort": "80",
    "CidrIp": "0.0.0.0/0"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f31ffec8-0498-44e1-aae1-72f7869eed4e"
    }
    }
    },
    "ServerSecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
    "GroupDescription": "Jenkins servers",
    "VpcId": {
    "Ref": "VpcId"
    },
    "SecurityGroupIngress": [
    {
    "IpProtocol": "tcp",
    "FromPort": "8080",
    "ToPort": "8080",
    "CidrIp": "0.0.0.0/0"
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "6b912343-a76c-49ea-a3b9-e3810e985623"
    }
    }
    },
    "ElasticLoadBalancer": {
    "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties": {
    "SecurityGroups": [
    {
    "Ref": "LbSecurityGroup"
    },
    {
    "Ref": "AdminSecurityGroup"
    }
    ],
    "Subnets": {
    "Ref": "Subnets"
    },
    "Listeners": [
    {
    "LoadBalancerPort": "80",
    "InstancePort": "8080",
    "Protocol": "HTTP"
    }
    ],
    "HealthCheck": {
    "Target": "TCP:8080",
    "HealthyThreshold": "3",
    "UnhealthyThreshold": "5",
    "Interval": "30",
    "Timeout": "5"
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    }
    }
    },
    "DnsRecord": {
    "Type": "AWS::Route53::RecordSet",
    "Properties": {
    "HostedZoneName": {
    "Fn::Join": [
    "",
    [
    {
    "Ref": "DnsZone"
    },
    "."
    ]
    ]
    },
    "Name": {
    "Fn::Join": [
    "",
    [
    {
    "Ref": "DnsPrefix"
    },
    ".",
    {
    "Ref": "DnsZone"
    },
    "."
    ]
    ]
    },
    "Type": "CNAME",
    "TTL": "900",
    "ResourceRecords": [
    {
    "Fn::GetAtt": [
    "ElasticLoadBalancer",
    "DNSName"
    ]
    }
    ]
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "f70f335b-0d40-4564-83f1-5c32db6a0d12"
    }
    }
    },
    "WaitHandle": {
    "Type": "AWS::CloudFormation::WaitConditionHandle",
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "id": "969a3dd3-d332-4bf7-9946-836a45fda38d"
    }
    }
    }
    },
    "Outputs": {
    "DnsAddress": {
    "Description": "Jenkins URL",
    "Value": {
    "Fn::Join": [
    "",
    [
    "http://",
    {
    "Ref": "DnsRecord"
    }
    ]
    ]
    }
    }
    },
    "Metadata": {
    "AWS::CloudFormation::Designer": {
    "969a3dd3-d332-4bf7-9946-836a45fda38d": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 270,
    "y": 90
    },
    "z": 1,
    "embeds": []
    },
    "6b912343-a76c-49ea-a3b9-e3810e985623": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 270,
    "y": 210
    },
    "z": 1,
    "embeds": []
    },
    "f31ffec8-0498-44e1-aae1-72f7869eed4e": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 60,
    "y": 300
    },
    "z": 1,
    "embeds": []
    },
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 390,
    "y": 90
    },
    "z": 1,
    "embeds": [],
    "ismemberof": [
    "f31ffec8-0498-44e1-aae1-72f7869eed4e"
    ]
    },
    "f70f335b-0d40-4564-83f1-5c32db6a0d12": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 390,
    "y": 210
    },
    "z": 1,
    "embeds": [],
    "isrelatedto": [
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    ]
    },
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 180,
    "y": 330
    },
    "z": 1,
    "embeds": []
    },
    "ef42272d-1c61-4769-a5cd-ec0f444ec408": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 300,
    "y": 330
    },
    "z": 1,
    "embeds": [],
    "isassociatedwith": [
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    ]
    },
    "7bbe33fd-97e1-4e29-8232-12a5a347912f": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 420,
    "y": 330
    },
    "z": 1,
    "embeds": [],
    "isassociatedwith": [
    "209f1460-1e6c-4d2d-a4d5-fb6094b697ff"
    ]
    },
    "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 60,
    "y": 420
    },
    "z": 1,
    "embeds": []
    },
    "f2af5c54-7724-4e71-9845-2d5a1e903c9b": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 180,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "isrelatedto": [
    "d4e94c35-fba6-4f3b-9de8-4d3feb5579c9"
    ]
    },
    "c002aae6-f2d3-41aa-909d-128327b75032": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 300,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "ismemberof": [
    "6b912343-a76c-49ea-a3b9-e3810e985623"
    ],
    "isrelatedto": [
    "ef42272d-1c61-4769-a5cd-ec0f444ec408",
    "969a3dd3-d332-4bf7-9946-836a45fda38d",
    "f2af5c54-7724-4e71-9845-2d5a1e903c9b"
    ]
    },
    "5578008f-96e8-446a-9dde-96b3811f0999": {
    "size": {
    "width": 60,
    "height": 60
    },
    "position": {
    "x": 420,
    "y": 450
    },
    "z": 1,
    "embeds": [],
    "isconnectedto": [
    "cc5318b6-13d1-45d2-9516-f0dd3c33f540"
    ],
    "isassociatedwith": [
    "c002aae6-f2d3-41aa-909d-128327b75032"
    ]
    },
    "f229fdfc-dd53-475f-8a4e-975cb52ce86f": {
    "size": {
    "width": 150,
    "height": 150
    },
    "position": {
    "x": 60,
    "y": 90
    },
    "z": 1,
    "embeds": []
    }
    }
    }
    }