{"id":30374,"date":"2015-12-07T10:44:22","date_gmt":"2015-12-07T05:14:22","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=30374"},"modified":"2015-12-15T10:05:54","modified_gmt":"2015-12-15T04:35:54","slug":"automating-deployment-using-capistrano-in-aws-auto-scaling","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/automating-deployment-using-capistrano-in-aws-auto-scaling\/","title":{"rendered":"Automating deployment using Capistrano in AWS Auto-scaling"},"content":{"rendered":"<p>Capistrano is a tool to perform tasks on multiple servers over SSH. We can <a title=\"Capistrano \u2013 Server Automation and Deployment\" href=\"http:\/\/www.tothenew.com\/blog\/capistrano-server-automation-and-deployment-tool\/\">use Capistrano<\/a> to deploy code on multiple servers running under auto-scaling. Below is one of the use cases which I solved with the help of Capistrano and bash scripts. I&#8217;ve used Capistrano for code deployment and its management using bash shell script.<\/p>\n<p><b><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-30597\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/12\/download1.jpg\" alt=\"download1\" width=\"1079\" height=\"394\" \/><\/b><\/p>\n<p><b>Use case<\/b><br \/>\nI have to deploy the code on multiple servers under AWS auto-scaling keeping in mind that no server comes up or goes down during deployment. The next task is to achieve the code integrity on all the servers at a time. All the servers must be running the same code from git repository.<\/p>\n<p><b>Note:\u00a0Before moving to the solution, please ensure that:<\/b><\/p>\n<ul>\n<li>You have already setup Capistrano on a server which can login into an application node via key-based authentication and is able to deploy the code on it.<\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You&#8217;ve used the files \u201cdeploy.rb\u201d (if single environment) or staging.rb and production.rb (If multiple environments) to insert the remote IP of the application nodes. \u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The application node is able to SSH on the master Capistrano server to read some specific purpose text files (CURRENT_REVISION &amp; PREVIOUS_REVISION) which I have used to make my solution more feasible (will be explained in the later part). <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">All the application nodes and master Capistrano server should be authenticated \u00a0to clone git repository. <\/span><\/li>\n<\/ul>\n<p><b>Solution:<br \/>\n<\/b>I followed two approaches to solve the whole use case:<\/p>\n<p><b>1st approach:<br \/>\n<\/b>There is a master Capistrano server which will be treated as the main utility server which can invoke the Capistrano\u2019s tasks on application nodes.<\/p>\n<p><b>Problems solved by this approach:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You can trigger the deployments on all the production\/staging instances from this utility server at a particular time. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You can quickly rollback the code on all the servers to the previous version, if new code fails to execute. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You need to make sure that while deploying, no new server in auto-scaling comes up or any current server goes down. For the time being, you need to pause your auto-scaling process. For this I\u2019ve used AWS CLI to make the desired number of servers same as minimum and maximum value in auto-scaling group. Now the auto-scaling has been paused for the time you are deploying on the servers using Capistrano. Once, you are finished with the deployments, you can again set the values of auto-scaling group parameters to the previous values to make auto-scaling process active again. I\u2019ve written some custom bash scripts to automate all this procedure. You can clone my git repository to use those scripts. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Also, I\u2019ve used two text files which I&#8217;ve mentioned above. The files are CURRENT_REVISION and PREVIOUS_REVISION. The CURRENT_REVISION file will store the git commit ID of the code which is currently running on the production servers. The file PREVIOUS_REVISION stores the git commit ID of the code which was previously deployed on the server. The intent of using these files is to make the rollback flow easier. I am updating the file CURRENT_REVISION after every successful deployment on all the production instances. The old value of file CURRENT_REVISION gets moved to PREVIOUS_REVISION once deployment is successful. The file CURRENT_REVISION will only get updated when you have deployed a new commit ID. If you are deploying the current commit ID again and again, the content of the files will not change. In this way, you can ensure that you always have commit ID of previous code in the file PREVIOUS_REVISION which you can use at the time of rollback. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">For quick rollback to previous version, Capistrano reads the content of the file PREVIOUS_REVISION and deploy that commit ID on all the production instances. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You can also deploy a specific commit ID on all the production instances. For this, you need to pass the parameter <\/span><b>cap -s branch=&lt;commit_id_to_be_deployed&gt; \u00a0deploy<\/b><span style=\"font-weight: 400;\">. This command will deploy the passed commit ID to all the remote servers mentioned inside ruby configuration file of Capistrano. \u00a0I&#8217;ve also made a script for the same. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">You can also shoot custom mails regarding the status of the deployment to the concerned person. I\u2019ve used the sendmail utility to send custom mails. <\/span><\/li>\n<\/ul>\n<p><b>2nd approach:<br \/>\n<\/b>Once you have setup all this and your deployment process is working fine. As auto-scaling is active now, if any new server comes up then it will be having older code which you never want to happen. \u00a0You have to maintain the code integrity on all the servers. The new server which is coming up must have the latest code which is running on all the production instances. To achieve this, I have installed Capistrano on each application node.<\/p>\n<p>Let us suppose, a new server is coming up under auto-scaling, then I\u2019ve written a custom bash script, which will perform the following tasks at the startup time of the server :-<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The new server will first SSH on the master Capistrano server to read the content of the file CURRENT_REVISION to get the commit ID of the code, which is already running on all the production instances. <\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">After getting the commit ID, the application node will deploy the code of that git commit ID on itself as each application node is also a Capistrano node in itself. To make Capistrano deploy on itself, you can mention \u201clocalhost\u201d in the remote IP in configuration file of Capistrano. <\/span><\/li>\n<\/ul>\n<p>In this way, the code integrity will be achieved. You can download all the scripts from my git repository and can use in them accordingly.<\/p>\n<p>Git repository URL : <span style=\"font-weight: 400;\">https:\/\/github.com\/tarunsaxena79\/capistrano_scripts<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Capistrano is a tool to perform tasks on multiple servers over SSH. We can use Capistrano to deploy code on multiple servers running under auto-scaling. Below is one of the use cases which I solved with the help of Capistrano and bash scripts. I&#8217;ve used Capistrano for code deployment and its management using bash shell [&hellip;]<\/p>\n","protected":false},"author":170,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":7},"categories":[1174,2348,1],"tags":[2826,1367,2828,2829,2830,2827],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/30374"}],"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\/170"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=30374"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/30374\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=30374"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=30374"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=30374"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}