{"id":324,"date":"2017-12-18T23:00:54","date_gmt":"2017-12-19T01:00:54","guid":{"rendered":"http:\/\/megumijr.com\/blog\/?p=324"},"modified":"2017-12-27T12:41:08","modified_gmt":"2017-12-27T14:41:08","slug":"affordable-disaster-recovery-with-aws","status":"publish","type":"post","link":"https:\/\/megumijr.com\/blog\/2017\/12\/affordable-disaster-recovery-with-aws\/","title":{"rendered":"Affordable Disaster Recovery with AWS"},"content":{"rendered":"<h2>MUCH MORE OF THE SAME<\/h2>\n<p>I\u2019ve been working with IT for more than 30 years. When I started around the 80\u2019s, it was not even called \u201cIT\u201d. Actually, my first contact with this universe was around the 70\u2019s when I was fourteen and I took my first Cobol programing language course. At that time, computers were restricted to big corporations, universities and government and my course was entirely on \u201ccoding forms\u201d (a form with the same amount of columns of the punched cards).<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-332\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/cobol-folha-de-codifica\u00e7\u00e3o.jpg\" alt=\"\" width=\"640\" height=\"359\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/cobol-folha-de-codifica\u00e7\u00e3o.jpg 640w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/cobol-folha-de-codifica\u00e7\u00e3o-300x168.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/cobol-folha-de-codifica\u00e7\u00e3o-250x140.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/cobol-folha-de-codifica\u00e7\u00e3o-150x84.jpg 150w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>I started to work with computers before the PCs were commercially available, so I had opportunity to work with the first personal computers (TRS-80, Apple II and ZX Spectrum), microcomputers, minicomputers, mainframes and I must admit I was getting \u201cbored\u201d with IT lately. Although it has evolved a lot over time, I\u2019ve not seen anything really new for a long time.<\/p>\n<p>Take a look on the <em>storages<\/em>, for example: they increased a lot on capacity and availability but is \u201cconceptually\u201d similar to an external hard disk and makes me remember those huge \u201c<em>wardrobes<\/em>\u201d used on the mainframes.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-325\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/Mainframe.jpg\" alt=\"\" width=\"495\" height=\"250\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/Mainframe.jpg 495w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/Mainframe-300x152.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/Mainframe-250x126.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/Mainframe-150x76.jpg 150w\" sizes=\"(max-width: 495px) 100vw, 495px\" \/><\/p>\n<p>The blue cabinet on the photo was a typical hard disk housing and the CPU used another similar cabinet (<em>the tape units were really cool: you just had to put reel tape on one side, push a button and a vacuum system \u201csucks\u201d the tape tip to the other reel<\/em>).<\/p>\n<p>Talking about mainframes, the IBM&#8217;s VM-SP operating system I used to work on a 4381 mainframe on the 80\u2019s was already capable to provide several virtual machines running on a single CPU, so virtualization is not a new concept. It took more than 15 years (around 2008) for me to see the first VMWare version running on my desktop, which was very cool because I was able create test machines.<\/p>\n<p>During my career, I dedicated an expressive amount of time to study <em>Information Security<\/em> and I always became concerned about <em>Business Continuity Plan<\/em>. Even with a good backup policy, in case of a catastrophic disaster it would take several days and probably weeks to restore the IT services in most cases. Most of the companies are not prone to invest in a <em>mirror site<\/em> with all the necessary infrastructure (air conditioning, fire prevention, data links, servers, routers, etc) that maybe will never be used. However, if you don\u2019t have a mirror site, where can you deploy the applications after the disaster? How much time will be required to configure new servers? Is there a written (and updated) procedure to configure all the applications and servers?<\/p>\n<p>Let&#8217;s face the reality: <strong>the majority of the companies does not have a feasible disaster recovery plan and actually rely on lucky to survive a catastrophic disaster<\/strong>.<\/p>\n<h2>NEWS PERSPECTIVES AND FRESH AIR<\/h2>\n<p>I\u2019ve never had opportunity to work with Cloud Services and from occasional readings I had a misconception that it was all about <em>Infrastructure as a Service<\/em> (IaaS). A few days ago, I started to look the Amazon Web Services (AWS) portfolio and\u2026 \u201c<em><span style=\"color: #ff0000;\">What!?? Serverless application!!?? No need to worry about hardware capacity!?? Instant server provisioning!!?? \u201cMachine learning\u201d available to ordinary developers!!?? Internet of Things ready to use platform???<\/span><\/em>\u201d<\/p>\n<p>I got really impressed and amazed with their huge \u201cecosystem\u201d and paradigm breaking services. My feelings says that we are in front of a new revolution on IT scenario and I got really excited to take a ride on this wave, so I decided to start playing around with EC2.<\/p>\n<p>I\u2019ve always read that AWS was a good solution for occasional high demanding computer power, but I always thought of contacting some vendor to ask for some virtual machines and wait to be provisioned, and bla, bla, bla\u2026 <strong>but it\u2019s not!!<\/strong> Once you have an account, you can deploy new virtual machines in seconds using web interface or you can do it <em>programmatically<\/em>!!<\/p>\n<p>Let\u2019s say you have a nightly batch routine at your company and it is high demanding computer power process. The amount of data is growing and you\u2019re about to blow up the batch processing window. The usual approach would be considering buying new hardware, but you also have to consider the data growth for reasonable lifetime of the new hardware. To make decisions hard, once in a month there is the monthly processing batch with an even higher computer power demand. During daytime, however, the server stays almost idle.\u00a0So, you will invest a considerable amount of money in a new powerful hardware that will stay almost idle for most of the time?<\/p>\n<p>With AWS you could keep a sync copy of you database, programmatically deploy the servers before the nightly batch and decommission them right after the routine ending. This approach is very interesting because you only pay for the time of the batch routine run. <strong>You don\u2019t have to pay for idle servers<\/strong>!<\/p>\n<p>Let\u2019s consider the <em>Disaster Recovery<\/em> mentioned earlier. You can setup (and test) a whole environment to support your applications, create <em>snapshots<\/em> of servers and terminate their running instances. I case of disaster, you can bring the servers to life just running a setup script!<\/p>\n<p>Of course, you have to consider an update routine for the snapshots. Data can be kept sync either with database online replication or restoring from a backup stored at Glacier service, for example.<\/p>\n<p>You also have to take into account that it is definitively not a solution for legacy file based applications and may not be suitable for client-server applications due to network latency and bandwidth limitations.<\/p>\n<h2>PROOF OF CONCEPT<\/h2>\n<p>To learn a bit of AWS, I decided to make this small <em>proof of concept<\/em> to check how ease would be to deploy an environment programmatically. Using the web interface, I created a single LAMP server and saved as a <em>machine image<\/em> (AMI). From that image, I could start new instances of this server but I created <em>Launch Templates<\/em> for simple deployment.<\/p>\n<div id=\"attachment_326\" style=\"width: 905px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-326\" loading=\"lazy\" class=\"wp-image-326 size-full\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates.jpg\" alt=\"\" width=\"895\" height=\"330\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates.jpg 895w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates-300x111.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates-768x283.jpg 768w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates-250x92.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/LaunchTemplates-150x55.jpg 150w\" sizes=\"(max-width: 895px) 100vw, 895px\" \/><p id=\"caption-attachment-326\" class=\"wp-caption-text\"><em>Launch Templates<\/em><\/p><\/div>\n<p>I created three templates, one for each <em>availability zone<\/em> using the same image.<\/p>\n<div id=\"attachment_327\" style=\"width: 918px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-327\" loading=\"lazy\" class=\"size-full wp-image-327\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces.jpg\" alt=\"\" width=\"908\" height=\"299\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces.jpg 908w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces-300x99.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces-768x253.jpg 768w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces-250x82.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/NetworkInterfaces-150x49.jpg 150w\" sizes=\"(max-width: 908px) 100vw, 908px\" \/><p id=\"caption-attachment-327\" class=\"wp-caption-text\"><em>Network Interfaces<\/em><\/p><\/div>\n<p>Each server template is tied to its <em>availability zone<\/em> by the network interface used.<\/p>\n<p>The final configuration of this POC is just a small infrastructure with two LAMP servers behind a load balancer exposed to the Internet.<\/p>\n<p>Several different <a href=\"https:\/\/aws.amazon.com\/pt\/tools\/\">programing languages<\/a> can be used for AWS automation. I like to use Python on my scripts. It is powerful, flexible and natively available on most Linux distributions, although I have used <a href=\"https:\/\/www.python.org\/downloads\/windows\/\"><em>Python for Windows<\/em><\/a> for these tests. AWS recommends <a href=\"https:\/\/github.com\/boto\/boto3#quick-start\">BOTO3<\/a> library to provide high level API for Python on AWS management, but as far as I saw, it has a limited set of classes.<\/p>\n<p>To overcome BOTO3 limits, I decied to use Python\u2019s <em>subprocess<\/em> module for shell command calls and make use of <a href=\"http:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/index.html#cli-aws\"><em>Command Line Interface<\/em><\/a> (CLI) provided by AWS. <em>Subprocess<\/em> allows me to capture the AWS command&#8217;s output and it&#8217;s JSON format can be parsed to easily extract any information.<\/p>\n<p>The test script takes less than a minute to complete and show some data to access each server individually and the Load Balancer URL.<\/p>\n<div id=\"attachment_328\" style=\"width: 995px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-328\" loading=\"lazy\" class=\"size-full wp-image-328\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput.jpg\" alt=\"\" width=\"985\" height=\"212\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput.jpg 985w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput-300x65.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput-768x165.jpg 768w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput-250x54.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/ScriptOutput-150x32.jpg 150w\" sizes=\"(max-width: 985px) 100vw, 985px\" \/><p id=\"caption-attachment-328\" class=\"wp-caption-text\"><em>Script output<\/em><\/p><\/div>\n<p>To confirm that the solution is working fine, just copy the <em>Load Balancer DNS<\/em> name and paste on the browser.<\/p>\n<div id=\"attachment_329\" style=\"width: 955px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-329\" loading=\"lazy\" class=\"size-full wp-image-329\" src=\"http:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage.jpg\" alt=\"\" width=\"945\" height=\"507\" srcset=\"https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage.jpg 945w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage-300x161.jpg 300w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage-768x412.jpg 768w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage-250x134.jpg 250w, https:\/\/megumijr.com\/blog\/wp-content\/uploads\/2017\/12\/WebServerPage-150x80.jpg 150w\" sizes=\"(max-width: 945px) 100vw, 945px\" \/><p id=\"caption-attachment-329\" class=\"wp-caption-text\"><em>Load Balance URL<\/em><\/p><\/div>\n<p>&nbsp;<\/p>\n<h2>THE SCRIPT<\/h2>\n<p>If you wish to reproduce the test or create your own provisioning script, check the code below.<\/p>\n<pre>import subprocess\r\nimport json\r\nimport sys\r\n\r\ndef main():\r\n   #Launch Template TestServer_a (lt-049c3074a32d98ce6)\r\n   templateId = \"lt-049c3074a32d98ce6\"\r\n   print(\"Launching template: {}\".format(templateId))\r\n   instId1 = runInstance(templateId)\r\n\r\n   #Launch Template TestServer_b (lt-04d403f7cc4f71698)\r\n   templateId = \"lt-04d403f7cc4f71698\"\r\n   print(\"Launching template: {}\".format(templateId))\r\n   instId2 = runInstance(templateId)\r\n\r\n   #Get 1st Instance Data\r\n   print(\"Get instance data for: {}\".format(instId1))\r\n   DNSName1, subnetId1, vpcId = getInstanceData(instId1)\r\n   print(\"VPC Id: {} - Subnet Id: {} - DNS Name: {}\".format(vpcId, subnetId1, DNSName1))\r\n   print(\"\")\r\n\r\n   #Get 2nd Instance Data\r\n   print(\"Get instance data for: {}\".format(instId2))\r\n   DNSName2, subnetId2, vpcId = getInstanceData(instId2)\r\n   print(\"VPC Id: {} - Subnet Id: {} - DNS Name: {}\".format(vpcId, subnetId2, DNSName2))\r\n   print(\"\")\r\n \r\n   #Create Load Balancer\r\n   print(\"Creating Load Balancer...\")\r\n   lbDnsName = createLB(instId1, instId2, subnetId1, subnetId2, vpcId)\r\n   print(\"Load Balancer DNS: {}\".format(lbDnsName))\r\n   print(\"\")\r\n\r\n#end main\r\n\r\ndef runInstance(templateId):\r\n   #Start Instance\r\n   cmd = \"aws ec2 run-instances --launch-template LaunchTemplateId=\"+templateId\r\n   js = runCmd(cmd)\r\n\r\n   return js[\"Instances\"][0]['InstanceId']\r\n#End runInstance\r\n\r\ndef getInstanceData(instId):\r\n   #Wait instance to be available\r\n   cmd = \"aws ec2 wait instance-running --instance-ids \"+instId\r\n   ret=subprocess.call(cmd) # there's no output to get\r\n   if ret != 0:\r\n      sys.exit(ret)\r\n\r\n   #Get instance data\r\n   cmd = \"aws ec2 describe-instances --instance-ids \"+instId\r\n   js = runCmd(cmd)\r\n   DNSName = js[\"Reservations\"][0][\"Instances\"][0]['PublicDnsName']\r\n   subnetId = js[\"Reservations\"][0][\"Instances\"][0]['SubnetId']\r\n   vpcId = js[\"Reservations\"][0][\"Instances\"][0]['VpcId']\r\n\r\n   return DNSName, subnetId, vpcId\r\n#End getInstanceData\r\n\r\ndef createLB(instId1, instId2, subnetId1, subnetId2, vpcId):\r\n   #Create Load Balancer\r\n   cmd = \"aws elbv2 create-load-balancer --name test-lb --type network --subnets \" + \\\r\n   subnetId1 + \" \" + subnetId2\r\n   js = runCmd(cmd)\r\n   lbDnsName = js[\"LoadBalancers\"][0][\"DNSName\"]\r\n   lbArn = js[\"LoadBalancers\"][0][\"LoadBalancerArn\"]\r\n \r\n   #Create target group\r\n   cmd = \"aws elbv2 create-target-group --name test-targets --protocol TCP --port 80 --vpc-id \"+vpcId\r\n   js = runCmd(cmd)\r\n   targetArn = js[\"TargetGroups\"][0][\"TargetGroupArn\"]\r\n\r\n   #Register tags\r\n   cmd = \"aws elbv2 register-targets --target-group-arn \"+ \\\r\n   targetArn+\" --targets Id=\"+instId1+\" Id=\"+instId2\r\n   ret=subprocess.call(cmd) # there's no output to get\r\n   if ret != 0:\r\n      sys.exit(ret)\r\n \r\n   #Create listener\r\n   cmd = \"aws elbv2 create-listener --load-balancer-arn \"+ \\\r\n   lbArn+\" --protocol TCP --port 80 --default-actions Type=forward,TargetGroupArn=\"+targetArn\r\n   js = runCmd(cmd)\r\n \r\n   return lbDnsName\r\n#End createLB\r\n\r\ndef runCmd(cmd):\r\n   try:\r\n      output = subprocess.check_output(cmd)\r\n   except:\r\n      raise\r\n   return json.loads(output)\r\n#End runCmd\r\n\r\nif __name__ == \"__main__\":\r\n   main()<\/pre>\n<p>&nbsp;<\/p>\n<h2>CONCLUSION<\/h2>\n<p>AWS has an extensive set of solutions to provide a flexible infrastructure to your company. I did not dive into the economic aspects but I\u2019m pretty sure that AWS costs are considerably lower than running <em>on-premises<\/em> infrastructures if you consider the costs of hardware (servers, storage, network appliances, etc) and all the surrounding infrastructure (UPSs, air conditioning, fire prevention, physical security, power supply, data links, etc). Different availability zones is a plus providing high availability for unbeatable lower costs than building you own <em>on-premises<\/em> mirror sites.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>MUCH MORE OF THE SAME I\u2019ve been working with IT for more than 30 years. When I started around the 80\u2019s, it was not even called \u201cIT\u201d. Actually, my first contact with this universe was around the 70\u2019s when I was fourteen and I took my first Cobol programing language \u2026 <a class=\"continue-reading-link\" href=\"https:\/\/megumijr.com\/blog\/2017\/12\/affordable-disaster-recovery-with-aws\/\">Continue lendo <span class=\"meta-nav\">&rarr; <\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18,17],"tags":[23,21,20,22,19],"_links":{"self":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/posts\/324"}],"collection":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/comments?post=324"}],"version-history":[{"count":4,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions"}],"predecessor-version":[{"id":336,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions\/336"}],"wp:attachment":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/media?parent=324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/categories?post=324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/tags?post=324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}