Wednesday, February 17, 2016

Speaking at RVA AWS Meetup on 2016-02-17 about Jenkins and AWS Integration for CI/CD

Central VA AWS User Group - 2016-02-17

I will be speaking on Jenkins integration to AWS EC2, CodeCommit, CodeDeploy, and CodePipeline.  The talk location is:

Tuckahoe Library
1901 Starling Dr., Henrico, VA (map)

Jimmy Ray with AuthX Consulting will present Jenkins usage with AWS.

•  Jenkins concepts

•  Options for Jenkins in AWS (yum, AWS Marketplace, etc.)

•  Configuring Jenkins in AWS (Setup, Plugins, Proxies(NGINX), Route 53/ELB, Security (Jenkins, Groups, SSL, etc.))

•  EC2 Roles

•  Jenkins Slaves

•  AWS CodeDeploy

•  AWS CodeCommit

•  AWS CodePipeline





Jenkins has it own Pipeline plugin (formerly know as Workflow).  Information can be found here:


Below is an example pipeline Groovy script that I wrote to build and deploy a CMS application from code in GitHub.  Maven builds the project, and then shell scripts perform the deployment to AWS EC2 instances.  Without Jenkins Pipeline, this would have been more complex involving multiple jobs.  Though it still can be broken down into multiple jobs, this particular example was done in a single Jenkins job.

stage 'build'
node {
  git url: 'git@github.com:co/XYZ.git', credentialsId: 'co-XYZ-jenkins', branch: 'develop'

  def v = version()
  if (v) {
    echo "Building version ${v}"
  }

  def mvnHome = tool 'Maven 3.3.3'
  sh "export JAVA_HOME=/opt/jdk1.8.0_60/ && ${mvnHome}/bin/mvn -f hippo/pom.xml clean verify -Dbuild.number=" + env.BUILD_NUMBER
  step([$class: 'ArtifactArchiver', artifacts: '**/target/site.war,**/target/cms.war', fingerprint: true])
}

stage 'tag'
node {
    echo "Build-" + env.BUILD_TAG
    dir(env.HOME + '/workspace/XYZ-CMS/TEST/TestWF/hippo') {
        sh 'git tag -a ' + env.BUILD_TAG + ' -m "Auto-tagging build number ' + env.BUILD_TAG + ' from Jenkins."'
        sh 'git push origin ' + env.BUILD_TAG
    }
}

stage 'undeploy'
node {
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo rm -rf /usr/share/tomcat8/webapps/cms.war'"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo rm -rf /usr/share/tomcat8/webapps/cms'"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo rm -rf /usr/share/tomcat8/webapps/site.war'"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo rm -rf /usr/share/tomcat8/webapps/site'"
}

stage 'restartTomcat8'
node {
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo service tomcat8 restart'"
}

stage 'restartNGINX'
node {
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo nginx -s reload'"
}


stage 'deployCms'
node {
    sh "scp -i " + env.G_BUILD_TEST_KEY + " " + env.HOME + "/workspace/XYZ-CMS/TEST/TestWF/hippo/cms/target/cms.war " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + ":~"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo chmod 755 ~ec2-user/cms.war'"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo cp ~ec2-user/cms.war /usr/share/tomcat8/webapps'"
    sleep 120
}

stage 'deploySite'
node {
    sh "scp -i " + env.G_BUILD_TEST_KEY + " " + env.HOME + "/workspace/XYZ-CMS/TEST/TestWF/hippo/site/target/site.war " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + ":~"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo chmod 755 ~ec2-user/site.war'"
    sh "ssh -i " + env.G_BUILD_TEST_KEY + " " + env.G_EC2_USER + "@" + env.G_XYZ_CMS_TEST_IP + " 'sudo cp ~ec2-user/site.war /usr/share/tomcat8/webapps'"
}

stage 'testCms'
node {
    def sout = new StringBuilder(), serr = new StringBuilder()
    def proc = "curl -s -o /dev/null -I -w '%{http_code}' http://cms-test.xyz.com/cms".execute()
    proc.consumeProcessOutput(sout, serr)
    proc.waitForOrKill(30000)
    //println "out> $sout err> $serr"
    echo sout.toString()
}

stage 'testSite'
node {
    def sout = new StringBuilder(), serr = new StringBuilder()
    def proc = "curl -s -o /dev/null -I -w '%{http_code}' http://site-test.xyz.com".execute()
    proc.consumeProcessOutput(sout, serr)
    proc.waitForOrKill(30000)
    //println "out> $sout err> $serr"
    echo sout.toString()
}

def version() {
  def matcher = readFile('hippo/pom.xml') =~ '<version>(.+)</version>'
  matcher ? matcher[1][1] : null
}