{"id":39687,"date":"2016-08-30T10:04:33","date_gmt":"2016-08-30T04:34:33","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=39687"},"modified":"2016-08-30T12:06:45","modified_gmt":"2016-08-30T06:36:45","slug":"integration-of-aws-codedeploy-with-jenkins","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/integration-of-aws-codedeploy-with-jenkins\/","title":{"rendered":"Integration of AWS CodeDeploy with Jenkins"},"content":{"rendered":"<p>We have been working on a scenario where we want to automate testing, build, deploy and revert in one Jenkins job. Currently, we are using separate Jenkins jobs for testing, deploying and reverting the code changes. We would be automating these tasks using AWS CodeDeploy with Jenkins.<\/p>\n<p><a href=\"http:\/\/www.tothenew.com\/blog\/tag\/jenkins\/\"><em>Jenkins<\/em><\/a>\u00a0can provide us the functionality to run the test cases whenever there is a change in the application code and <em>AWS CodeDeploy <\/em>can\u00a0<a title=\"aws automation\" href=\"http:\/\/www.tothenew.com\/devops-aws\">automate the deployment process<\/a> on the servers. Integration of Jenkins and AWS CodeDeploy can automate the whole process .<\/p>\n<p><a href=\"http:\/\/www.tothenew.com\/blog\/aws-code-deploy-a-sample-walkthrough\/\"><em>AWS CodeDeploy<\/em><\/a> still doesn&#8217;t provide us the functionality to rollback if there is a deployment failure and rolling back to a successful revision is a painful task. But using a script and different plugins provided by Jenkins we can also automate this process.<\/p>\n<p><strong>Use Case<\/strong><\/p>\n<p>Integrating <strong>AWS CodeDeploy<\/strong> with <strong>Jenkins<\/strong>\u00a0for\u00a0automating testing, build, deployment as well as\u00a0<strong>Automatic Rollback<\/strong> in a case of <strong>Deployment Failure<\/strong>.<\/p>\n<p><strong>Prerequisites<\/strong><\/p>\n<ul>\n<li>At least one\u00a0AWS EC2 running instance with CodeDeploy agent configured on it<\/li>\n<li>A GitHub account with admin access and a repository where the updated code gets pushed<\/li>\n<li>A running Jenkins server that will act as a Continuous integration tool and can be accessible publicly over the internet<\/li>\n<li>A configured AWS CodeDeploy application. AWS CodeDeploy service is being used as a Continuous Deployment tool<\/li>\n<li>Necessary plugins that need to be installed in Jenkins are<strong>:<\/strong>\n<ul>\n<li>AWS CodeDeploy Plugin for Jenkins<\/li>\n<li>GitHub plugin<\/li>\n<li>Post-Build Script Plug-in<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong>Flow<\/strong><\/p>\n<ul>\n<li>Whenever a change in the application code is pushed to Github than a Jenkins job will get triggered that will run test cases on the updated code.<\/li>\n<li>If the test case fails then it will further stop the post-build actions<\/li>\n<li>If the test cases are successful then It will go to post build actions and trigger AWS CodeDeploy<\/li>\n<li>AWS CodeDeploy will deploy the new revision of the application on each server.<\/li>\n<li>After the deployment process, another post build action will get triggered that will check if the deployment status is failed then the previous successful revision gets deployed.<\/li>\n<\/ul>\n<p>In order to <strong>configure AWS CodeDeploy<\/strong> application you can refer to any of the following blogs<strong>:<\/strong><\/p>\n<ul>\n<li><a title=\"AWS CodeDeploy \u2013 A Sample Walkthrough\" href=\"http:\/\/www.tothenew.com\/blog\/aws-code-deploy-a-sample-walkthrough\/\" target=\"_blank\">AWS CodeDeploy \u2013 A Sample Walkthrough<\/a><\/li>\n<li><a title=\"AWS CodeDeploy Using S3\" href=\"http:\/\/www.tothenew.com\/blog\/aws-code-deploy-using-s3\/\" target=\"_blank\">AWS CodeDeploy Using S3<\/a><\/li>\n<li><a title=\"Deploy Code using AWS CodeDeploy and GitHub\" href=\"http:\/\/www.tothenew.com\/blog\/aws-codedeploy-and-github\/\" target=\"_blank\">Deploy Code using AWS CodeDeploy and GitHub<\/a><\/li>\n<\/ul>\n<p>In order to <strong>configure Jenkins<\/strong>\u00a0<strong>job<\/strong> for our task, follow the steps mentioned below:<\/p>\n<p>1. Now, we have to create a new Job:<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39703 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job12.png\" alt=\"job1\" width=\"825\" height=\"270\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job12.png 825w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job12-300x98.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job12-624x204.png 624w\" sizes=\"(max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>2. Then select <em>GitHub project<\/em> and provide the repo URL:<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39704 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job21.png\" alt=\"job2\" width=\"795\" height=\"369\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job21.png 795w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job21-300x139.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job21-624x289.png 624w\" sizes=\"(max-width: 795px) 100vw, 795px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>3. In SCM select <em>Git<\/em> and provide Repository URL and Login Credentials:<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39638 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job4.png\" alt=\"job4\" width=\"1366\" height=\"768\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job4.png 1366w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job4-300x168.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job4-1024x575.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job4-624x350.png 624w\" sizes=\"(max-width: 1366px) 100vw, 1366px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>4. In Build Triggers select\u00a0<em><em><em>Build when a change is pushed to GitHub:<\/em><\/em><\/em><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39646 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job61.png\" alt=\"job6\" width=\"798\" height=\"261\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job61.png 798w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job61-300x98.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job61-624x204.png 624w\" sizes=\"(max-width: 798px) 100vw, 798px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>5. In Build select <em>Add build step \u00a0&#8211;&gt; Execute Shell<\/em>\u00a0 and provide command to test the updated<br \/>\napplication code or execute a script containing test cases:<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39691 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job15.png\" alt=\"job15\" width=\"670\" height=\"297\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job15.png 670w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job15-300x132.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job15-624x276.png 624w\" sizes=\"(max-width: 670px) 100vw, 670px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>6. In Post-build Actions select <em>Add post-build action \u00a0&#8211;&gt; Deploy an application to AWS CodeDeploy:<br \/>\n<\/em><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39650 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job8.png\" alt=\"job8\" width=\"799\" height=\"363\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job8.png 799w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job8-300x136.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job8-624x283.png 624w\" sizes=\"(max-width: 799px) 100vw, 799px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>7. Then we need to provide the following<strong>:<\/strong><\/p>\n<ul>\n<li>AWS CodeDeploy Application Name<\/li>\n<li>AWS CodeDeploy Deployment Group<\/li>\n<li>AWS CodeDeploy Deployment Config<\/li>\n<li>AWS Region<\/li>\n<li>S3 Bucket <strong>: <\/strong>Provide the bucket name where you want the AWS CodeDeploy plugin to send the zip file.<\/li>\n<li>S3 Prefix <strong>:\u00a0<\/strong>Provide your directory name under the S3 bucket.<\/li>\n<li>Use Access\/Secret keys <strong>:\u00a0<\/strong>Provide\u00a0AWS Access Key and\u00a0AWS Secret Key.<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39651 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job9.png\" alt=\"job9\" width=\"798\" height=\"500\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job9.png 798w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job9-300x187.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job9-624x390.png 624w\" sizes=\"(max-width: 798px) 100vw, 798px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>8. In Post-build Actions select\u00a0<em>Add post-build action \u00a0&#8211;&gt; Execute a set of scripts \u00a0&#8211;&gt; Build steps \u00a0&#8211;&gt;<\/em><em>Execute Shell:<br \/>\n<\/em><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39654 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job111.png\" alt=\"job11\" width=\"677\" height=\"313\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job111.png 677w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job111-300x138.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job111-624x288.png 624w\" sizes=\"(max-width: 677px) 100vw, 677px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>9. Provide the path where the script is present on the server:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39655 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job13.png\" alt=\"job13\" width=\"675\" height=\"344\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job13.png 675w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job13-300x152.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job13-624x318.png 624w\" sizes=\"(max-width: 675px) 100vw, 675px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>10. The script provided here will perform rollback in case of deployment failure i.e. in a case of failure it will deploy the previous successful revision. The script is written in Python and uses boto3 so Python should be installed and boto3 package needs to be available on the server where Jenkins is installed:<\/p>\n<ul>\n<li>\n<pre>#!\/bin\/python\r\nimport boto3\r\nimport time\r\n\r\nclient = boto3.client('codedeploy', region_name='us-east-1', aws_access_key_id='xxxxxxxxxxxxxxxxxxxx', aws_secret_access_key='xxxxxxxxxxxxxxxxxxxx')\r\n# The time revision will take for deployment in seconds.\r\ntime.sleep(120)\r\nresponse5 = client.list_deployments(\r\n applicationName='codedeply-app',\r\n deploymentGroupName='codedeploy-grp',\r\n includeOnlyStatuses=[\r\n 'Created',\r\n 'Queued',\r\n 'InProgress',\r\n 'Succeeded',\r\n 'Failed',\r\n 'Stopped',\r\n ],\r\n \r\n)\r\n\r\nprint response5['deployments'][0]\r\n\r\nlast_success_Id = response5['deployments'][0]\r\nresponse3 = client.get_deployment(\r\n deploymentId=last_success_Id\r\n)\r\n\r\nprint response3['deploymentInfo']['status']\r\nStatus = response3['deploymentInfo']['status']\r\n\r\n\r\nif (Status == 'Failed'): \r\n response4 = client.create_deployment(\r\n applicationName=response3['deploymentInfo']['applicationName'],\r\n deploymentGroupName=response3['deploymentInfo']['deploymentGroupName'],\r\n revision={\r\n 'revisionType': response3['deploymentInfo']['revision']['revisionType'],\r\n 's3Location': {\r\n 'bucket': response3['deploymentInfo']['revision']['s3Location']['bucket'],\r\n 'key': response3['deploymentInfo']['revision']['s3Location']['key'],\r\n 'bundleType': response3['deploymentInfo']['revision']['s3Location']['bundleType'],\r\n 'eTag': response3['deploymentInfo']['revision']['s3Location']['eTag']\r\n },\r\n \r\n },\r\n deploymentConfigName=response3['deploymentInfo']['deploymentConfigName'],\r\n ignoreApplicationStopFailures=response3['deploymentInfo']['ignoreApplicationStopFailures']\r\n )\r\nprint response4['deploymentId']<\/pre>\n<\/li>\n<li>We have to provide <em>Access Key<\/em>,\u00a0<em>Secret Key,\u00a0<\/em><em>Application Name and<\/em>\u00a0<em>Deployment Group\u00a0<\/em>in the above script.<\/li>\n<li>The script will give the <em>Deployment Id, Status<\/em> of the current deployment revision and if in a case of deployment, \u00a0Status is Failed then previous successful revision gets deployed.<\/li>\n<\/ul>\n<p>In order to setup <strong>GitHub<\/strong> and <strong>Webhook<\/strong> follow the below-mentioned steps<strong>:<\/strong><\/p>\n<ol>\n<li>Go to <em>GitHub repo<\/em> then select <em>Settings \u00a0&#8211;&gt; Webhook and Services tab \u00a0&#8211;&gt; Add Service \u00a0&#8211;&gt; Jenkins (GitHub Plugin)<\/em><\/li>\n<li>Add the following as the <em>Jenkins hook<\/em> URL:\n<ul>\n<li>\u00a0http:\/\/JENKINS.SERVER.IP.ADDRESS:8080\/github-webhook\/<\/li>\n<li>Click <em><em>Add service:<\/em><\/em><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-39656 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job14.png\" alt=\"job14\" width=\"793\" height=\"614\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2016\/08\/job14.png 793w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job14-300x232.png 300w, \/blog\/wp-ttn-blog\/uploads\/2016\/08\/job14-624x483.png 624w\" sizes=\"(max-width: 793px) 100vw, 793px\" \/><\/p>\n<p>Integration and Deployment have been setup and now if we commit a code and push it to our repo then Jenkins will automatically get triggered and a job will start building automatically.\u00a0If the build is successful Jenkins will create a zip file of our updated application and push it to AWS S3 and further trigger AWS CodeDeploy application. If deployment is failed then it will automatically deploy the previous successful revision.<\/p>\n<p>Hence, the above procedure helps us to achieve <a title=\"docker continuous integration\" href=\"http:\/\/www.tothenew.com\/devops-chef-puppet-docker\">Continuous Integration<\/a> and Continuous Deployment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We have been working on a scenario where we want to automate testing, build, deploy and revert in one Jenkins job. Currently, we are using separate Jenkins jobs for testing, deploying and reverting the code changes. We would be automating these tasks using AWS CodeDeploy with Jenkins. Jenkins\u00a0can provide us the functionality to run the [&hellip;]<\/p>\n","protected":false},"author":968,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":15},"categories":[1174,2348,1],"tags":[3946,1676,2366,3947,3948,2845,1892,1682,1358],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/39687"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/968"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=39687"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/39687\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=39687"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=39687"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=39687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}