<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python on Technology Enlightened</title>
    <link>https://pprakash.me/tags/python/</link>
    <description>Recent content in Python on Technology Enlightened</description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>&amp;copy; &lt;a href=&#34;https://github.com/p-prakash/&#34;&gt;Prakash P&lt;/a&gt; 2015 - 2023</copyright>
    <lastBuildDate>Tue, 14 Mar 2017 17:39:24 +0000</lastBuildDate>
    <atom:link href="https://pprakash.me/tags/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Monitor AWS Trusted Advisor Checks</title>
      <link>https://pprakash.me/tech/2017/03/14/monitor-aws-trusted-advisor-checks/</link>
      <pubDate>Tue, 14 Mar 2017 17:39:24 +0000</pubDate>
      <guid>https://pprakash.me/tech/2017/03/14/monitor-aws-trusted-advisor-checks/</guid>
      <description>&lt;p&gt;AWS Trusted Advisor is an important tool which provides more than 50 checks across four different categories Cost Optimization, Performance, Security &amp;amp; Fault Tolerance (at the moment of writing this post).&lt;/p&gt;&#xA;&lt;p&gt;But I have noticed that this is not being used more extensively considering the importance of it. Hence I created couple of lambda functions which shall be configured to run on daily basis to refresh the checks and create summary of all the checks and send an email.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Scheduling automated EBS snapshots serverless using AWS Lambda</title>
      <link>https://pprakash.me/tech/2016/06/09/automated-ebs-snapshots/</link>
      <pubDate>Thu, 09 Jun 2016 11:46:37 +0000</pubDate>
      <guid>https://pprakash.me/tech/2016/06/09/automated-ebs-snapshots/</guid>
      <description>&lt;p&gt;EBS snapshot as backup mechanism is a very common practice and it also has been defined in &lt;a href=&#34;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-best-practices.html&#34;&gt;Backup and Recovery&lt;/a&gt; section of EC2 best practices. If you have read my another article &lt;a href=&#34;https://pprakash.me/tech/2015/11/15/save-aws-costs-by-scheduled-start-and-stop-of-ec2-instances/&#34;&gt;Save AWS costs by scheduled start and stop of EC2 instances&lt;/a&gt;, similar approach will be used in creating Snapshots too.&lt;/p&gt;&#xA;&lt;p&gt;Using JSON in EC2 Tags enables us to provide granular configuration details. Create an EC2 tag with name as &lt;em&gt;backup&lt;/em&gt; and value with details containing time to take backup and retention period. Obtaining these details from Tags will enable us to configure different schedule &amp;amp; retention period for different EC2 instance. If no backup is needed on a particular day, that day shall be removed from the value.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sync S3 bucket to multiple S3 buckets in different region</title>
      <link>https://pprakash.me/tech/2016/05/27/sync-s3-bucket-to-multiple-different-s3-buckets/</link>
      <pubDate>Fri, 27 May 2016 11:55:41 +0000</pubDate>
      <guid>https://pprakash.me/tech/2016/05/27/sync-s3-bucket-to-multiple-different-s3-buckets/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://aws.amazon.com/blogs/aws/new-cross-region-replication-for-amazon-s3/&#34;&gt;Cross-Region Replication for Amazon S3&lt;/a&gt; was introduced last year which enables replicating objects from a S3 bucket to a different S3 bucket located in different region (it can be same/different AWS account). It’s one of the most sought after feature for long time but it doesn’t solve some of the scenarios as defined below.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Synchronizing to a bucket in same region.&lt;/li&gt;&#xA;&lt;li&gt;Synchronizing to multiple destination buckets.&lt;/li&gt;&#xA;&lt;li&gt;Object ACLs needs to be set at the source bucket hence multiple different ACLs needs to be set when copying across different accounts.&lt;/li&gt;&#xA;&lt;li&gt;Replication doesn’t change the ownership of the objects hence bucket policy applied at the destination bucket won’t be honored.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Refer the feedback from AWS support team regarding the last point mentioned above.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automated Blue/Green deployment using Lambda and CloudFormation</title>
      <link>https://pprakash.me/tech/2016/05/05/automated-bluegreen-deployment-using-lambda-and-cloudformation/</link>
      <pubDate>Thu, 05 May 2016 07:42:54 +0000</pubDate>
      <guid>https://pprakash.me/tech/2016/05/05/automated-bluegreen-deployment-using-lambda-and-cloudformation/</guid>
      <description>&lt;p&gt;Blue/Green deployment is a well-known method to deploy an application without any downtime. Performing DNS switch is one of the very common techniques to achieve this. Using DNS switch has a minor issue with DNS caching which might take some time for DNS change to be propagated.&lt;/p&gt;&#xA;&lt;p&gt;Apart from DNS switch, AWS gives us two different options to switch the stacks. One is to have single ELB and swap it across auto-scaling group and another is switching the launch configuration of the auto-scaling group. Check the following presentation on various methods to achieve blue/green deployment in AWS.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sending response back to CFN custom resource from python Lambda function</title>
      <link>https://pprakash.me/tech/2015/12/20/sending-response-back-to-cfn-custom-resource-from-python-lambda-function/</link>
      <pubDate>Sun, 20 Dec 2015 06:00:56 +0000</pubDate>
      <guid>https://pprakash.me/tech/2015/12/20/sending-response-back-to-cfn-custom-resource-from-python-lambda-function/</guid>
      <description>&lt;p&gt;CloudFormation uses a pre-signed S3 URL to receive the response back from the custom resources managed by it. There are few blue prints available for Node.js Lambda custom resources but nothing available for python yet. Hence I created this simple function which shall be used to send the response back to CFN custom resource by performing PUT request to the pre-signed S3 URL.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; requests&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;lambda_handler&lt;/span&gt;(event, context):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    responseStatus &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SUCCESS&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    responseData &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; event[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;RequestType&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Delete&amp;#39;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        sendResponse(event, context, responseStatus, responseData)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    responseData &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Success&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Test Passed.&amp;#39;&lt;/span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sendResponse(event, context, responseStatus, responseData)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sendResponse&lt;/span&gt;(event, context, responseStatus, responseData):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    responseBody &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Status&amp;#39;&lt;/span&gt;: responseStatus,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Reason&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;See the details in CloudWatch Log Stream: &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log_stream_name,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;PhysicalResourceId&amp;#39;&lt;/span&gt;: context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;log_stream_name,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;StackId&amp;#39;&lt;/span&gt;: event[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;StackId&amp;#39;&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;RequestId&amp;#39;&lt;/span&gt;: event[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;RequestId&amp;#39;&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;LogicalResourceId&amp;#39;&lt;/span&gt;: event[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;LogicalResourceId&amp;#39;&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Data&amp;#39;&lt;/span&gt;: responseData}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;RESPONSE BODY:n&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(responseBody)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        req &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;put(event[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;ResponseURL&amp;#39;&lt;/span&gt;], data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(responseBody))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; req&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;status_code &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print req&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Exception&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Recieved non 200 response while sending response to CFN.&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exceptions&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;RequestException &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; e:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print e&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; __name__ &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lambda_handler(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;event&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;handler&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m using json module to form the response body, json module is available by default in the Lambda container. Whereas the requests module which I use to perform the http PUT request needs to be packaged along with the python script.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Continuous Integration - Manage shared resources across accounts automatically</title>
      <link>https://pprakash.me/2015/12/07/continuous-integration-manage-shared-resources-across-accounts-automatically/</link>
      <pubDate>Mon, 07 Dec 2015 18:28:16 +0000</pubDate>
      <guid>https://pprakash.me/2015/12/07/continuous-integration-manage-shared-resources-across-accounts-automatically/</guid>
      <description>&lt;p&gt;I prefer creating the base &lt;a href=&#34;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sharing-amis.html&#34;&gt;AMI&lt;/a&gt; using &lt;a href=&#34;https://www.packer.io/&#34;&gt;packer&lt;/a&gt;; &lt;a href=&#34;http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ShareSnapshot.html&#34;&gt;RDS snapshot&lt;/a&gt; using a Jenkins job which get triggered whenever there is a change in the database schema in the SCM. In case of installers, binaries, etc. it would be best to store them in a single &lt;a href=&#34;http://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html&#34;&gt;S3 bucket&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In all the above mentioned scenarios I prefer to share those resources to a 3rd party AWS account and remove the share when not needed. Automating this would be easy to handle add/remove permissions, hence I decided to hold the sharing details in a JSON file in the SCM. Changes to that file will trigger a Jenkins job which will invoke a Lambda function which in turn will share the resources based on the values in the JSON file.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Executing Ruby code in AWS Lambda</title>
      <link>https://pprakash.me/tech/2015/11/29/executing-ruby-code-in-aws-lambda/</link>
      <pubDate>Sun, 29 Nov 2015 18:41:59 +0000</pubDate>
      <guid>https://pprakash.me/tech/2015/11/29/executing-ruby-code-in-aws-lambda/</guid>
      <description>&lt;p&gt;AWS Lambda supports only Java, JavaScript &amp;amp; Python at the time of writing this post. I was wondering whether I can exploit the Lambda to execute chef’s &lt;a href=&#34;https://docs.chef.io/knife.html&#34;&gt;knife&lt;/a&gt; commands on it since Lambda runs on a Linux container. Using simple python function I have identified that the code of the Lambda function gets copied to &lt;code&gt;/var/task&lt;/code&gt; and executed from there.&lt;/p&gt;&#xA;&lt;p&gt;I decided to custom build ruby as embedded platform similar to how &lt;a href=&#34;https://downloads.chef.io/chef-client/&#34;&gt;chef-client&lt;/a&gt; or &lt;a href=&#34;https://downloads.chef.io/chef-dk/&#34;&gt;chefdk&lt;/a&gt; are distributed. My requirement is to execute knife commands and its uses embedded ruby version 2.1.0, hence I downloaded the source archive that specific version.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Save AWS costs by scheduled start and stop of EC2 instances</title>
      <link>https://pprakash.me/tech/2015/11/15/save-aws-costs-by-scheduled-start-and-stop-of-ec2-instances/</link>
      <pubDate>Sun, 15 Nov 2015 14:56:57 +0000</pubDate>
      <guid>https://pprakash.me/tech/2015/11/15/save-aws-costs-by-scheduled-start-and-stop-of-ec2-instances/</guid>
      <description>&lt;p&gt;Most of the AWS resources are billed on per-hour basis which provides us an opportunity to save cost based on the usage pattern. Especially in case of Dev/Test environment, we need them only during the working days and working hours.&lt;/p&gt;&#xA;&lt;p&gt;By using &lt;a href=&#34;https://aws.amazon.com/lambda/&#34;&gt;AWS Lambda&lt;/a&gt; function (&lt;a href=&#34;https://aws.amazon.com/blogs/aws/aws-lambda-update-python-vpc-increased-function-duration-scheduling-and-more/&#34;&gt;python&lt;/a&gt;) in combination with EC2 instance tags, scheduled start or stop can be achieved with few lines of code.&lt;/p&gt;&#xA;&lt;p&gt;Advantages of using AWS Lambda:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;For 128MB memory we get 3,200,000 seconds &lt;a href=&#34;https://aws.amazon.com/lambda/pricing/&#34;&gt;free tier usage per month in AWS Lambda&lt;/a&gt; which will be more than enough for this function.&lt;/li&gt;&#xA;&lt;li&gt;IAM role will be associated with the Lambda function which will be used to perform the required task and no separate keys need to be configured.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I used a tag with name as &lt;em&gt;schedule&lt;/em&gt; &amp;amp; JSON string for tag value using which I could define the day and time when it needs to be started or stopped.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
