<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rajan Panchal</title>
    <description>The latest articles on Forem by Rajan Panchal (@rajanpanchal).</description>
    <link>https://forem.com/rajanpanchal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F434376%2F97abe946-dbea-4143-9b8f-1b13a1babe68.jpg</url>
      <title>Forem: Rajan Panchal</title>
      <link>https://forem.com/rajanpanchal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rajanpanchal"/>
    <language>en</language>
    <item>
      <title>What is Lambda Layers and how to use it with Java runtime?</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Thu, 19 Nov 2020 05:04:59 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/what-is-lambda-layers-and-how-to-use-it-with-java-runtime-21di</link>
      <guid>https://forem.com/rajanpanchal/what-is-lambda-layers-and-how-to-use-it-with-java-runtime-21di</guid>
      <description>&lt;p&gt;When developing serverless functions,  you often need additional dependencies or libraries for the function to work. For &lt;a href="https://rajanpanchal.net/write-your-first-aws-lambda-in-java/"&gt;Lambda functions in java&lt;/a&gt;,  you need amazon dependencies of the services used in the function. Then you zip the function and its dependencies into a fat jar and upload it to the Lambda function. If you are not familiar with creating lambda function in java then refer to &lt;a href="https://rajanpanchal.net/write-your-first-aws-lambda-in-java"&gt;this&lt;/a&gt; post for a quick start.&lt;/p&gt;

&lt;p&gt;The fat jar approach works fine but if you have multiple functions that use the same dependencies then creating a fat jar of each function is not a good approach and maintenance of such code is also difficult. A change in the version of a jar requires a change in each of the individual lambda functions.&lt;/p&gt;

&lt;p&gt;A more elegant solution is to use Lambda layers. &lt;/p&gt;

&lt;h3&gt;
  
  
  What is Lambda Layers?
&lt;/h3&gt;

&lt;p&gt;A layer is a ZIP archive that contains libraries, a custom runtime, or other dependencies. With layers, you can use libraries in your function without needing to include them in your deployment package. Layers let you keep your deployment package small, which makes development easier.&lt;/p&gt;

&lt;p&gt;Layers are extracted to the /opt directory in the function execution environment. Each runtime looks for libraries in a different location under /opt, depending on the language.&lt;/p&gt;

&lt;p&gt;You can specify up to 5 layers in your function's configuration, during or after function creation. You choose a specific version of a layer to use. If you want to use a different version later, update your function's configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's see it in action
&lt;/h3&gt;

&lt;p&gt;We will write a basic Lambda function that would just print lambda environment variables and event details. We will create 2 maven projects. In the first project, we include amazon and other essential dependencies. This project will serve as our Lambda Layer. In the second project, we include our first project as a dependency and will write the Lambda handler. &lt;/p&gt;

&lt;p&gt;Create the first maven project called Lambda-Layer-Base and update pom as below:&lt;br&gt;
This project contains all common dependencies required by the functions. In our case, we added &lt;code&gt;lamdba-core&lt;/code&gt; and &lt;code&gt;gson&lt;/code&gt; dependency. We also added &lt;code&gt;maven-shade-plugin&lt;/code&gt; to create fat jar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;net.rajanpanchal&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;lambda-layer-base&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;Lambda-Layer-Base&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;Lambda base&amp;lt;/description&amp;gt;
    &amp;lt;properties&amp;gt;
        &amp;lt;maven.compiler.source&amp;gt;1.8&amp;lt;/maven.compiler.source&amp;gt;
        &amp;lt;maven.compiler.target&amp;gt;1.8&amp;lt;/maven.compiler.target&amp;gt;
        &amp;lt;aws.java.sdk.version&amp;gt;2.14.11&amp;lt;/aws.java.sdk.version&amp;gt;
    &amp;lt;/properties&amp;gt;
    &amp;lt;dependencyManagement&amp;gt;
        &amp;lt;dependencies&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;software.amazon.awssdk&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;bom&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;${aws.java.sdk.version}&amp;lt;/version&amp;gt;
                &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
                &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
            &amp;lt;/dependency&amp;gt;
        &amp;lt;/dependencies&amp;gt;
    &amp;lt;/dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.amazonaws&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;aws-lambda-java-core&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.google.code.gson&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;gson&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.8.6&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;source&amp;gt;${maven.compiler.source}&amp;lt;/source&amp;gt;
                    &amp;lt;target&amp;gt;${maven.compiler.target}&amp;lt;/target&amp;gt;
                &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;3.2.4&amp;lt;/version&amp;gt;
                &amp;lt;executions&amp;gt;
                    &amp;lt;execution&amp;gt;
                        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;
                        &amp;lt;goals&amp;gt;
                            &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;
                        &amp;lt;/goals&amp;gt;
                    &amp;lt;/execution&amp;gt;
                &amp;lt;/executions&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This project will only contain dependencies. Now execute maven &lt;code&gt;clean install&lt;/code&gt; and it should generate a jar (&lt;code&gt;lambda-layer-base-1.jar&lt;/code&gt;) in the target folder.&lt;/p&gt;

&lt;p&gt;Create another maven project and update pom with the below contents. We included our first project as a dependency (&lt;code&gt;lambda-layer-base&lt;/code&gt;). Also note, we no longer use maven shade plugin since we don't want dependencies to be included in the jar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;net.rajanpanchal&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;lambda-java-demo&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;
    &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;
    &amp;lt;name&amp;gt;Lambda-Layers-Demo&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;HelloWorld Lambda Layers Demo&amp;lt;/description&amp;gt;
    &amp;lt;properties&amp;gt;
        &amp;lt;maven.compiler.source&amp;gt;1.8&amp;lt;/maven.compiler.source&amp;gt;
        &amp;lt;maven.compiler.target&amp;gt;1.8&amp;lt;/maven.compiler.target&amp;gt;
        &amp;lt;aws.java.sdk.version&amp;gt;2.14.11&amp;lt;/aws.java.sdk.version&amp;gt;
    &amp;lt;/properties&amp;gt;
    &amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;net.rajanpanchal&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;lambda-layer-base&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;source&amp;gt;${maven.compiler.source}&amp;lt;/source&amp;gt;
                    &amp;lt;target&amp;gt;${maven.compiler.target}&amp;lt;/target&amp;gt;
                &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a class file in src/main/java that will contain Lambda logic. Here we are just logging some stuff.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.rajanpanchal.handlers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.Context&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.LambdaLogger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.RequestHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.GsonBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloWorldHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;{&lt;/span&gt;

      &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;LambdaLogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"200 OK"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ENVIRONMENT:"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="c1"&gt;// log execution details&lt;/span&gt;
        &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GsonBuilder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setPrettyPrinting&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ENVIRONMENT VARIABLES: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONTEXT: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="c1"&gt;// process event&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EVENT: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EVENT TYPE: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute maven &lt;code&gt;package&lt;/code&gt; command to create the jar for the project. A jar (&lt;code&gt;lambda-java-demo-1.jar&lt;/code&gt;) should get created in target folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Lamdba Layer
&lt;/h3&gt;

&lt;p&gt;Before we head to the console to create the layer, let's complete one important step. Remember that layers gets extracted to a folder in /opt directory. You need to package the layer in folder structure as per your runtime. For java, you need to package jar in &lt;code&gt;java/lib&lt;/code&gt; folder. The final folder structure,  in the lambda runtime, would be &lt;code&gt;/opt/java/lib/&amp;lt;your jar&amp;gt;&lt;/code&gt;. So now create folders java/lib and copy jar from the first project and zip the folder. Now we are ready to upload the jar as lambda layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1HUrPoRU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/Layer_create.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1HUrPoRU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/Layer_create.PNG" alt="Lambda Layers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Lambda function
&lt;/h3&gt;

&lt;p&gt;Now create the lambda function and specify the layer that we just created. Also, upload the jar from the second project as our function code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--110e4mEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/lambda-function.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--110e4mEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/lambda-function.PNG" alt="Lambda Layers create function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add Layers to the function&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cKgAf5hj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/layer_add.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cKgAf5hj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/layer_add.PNG" alt="Lambda Layers add "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upload function code jar and update runtime settings&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aGnM05T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/lambda.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aGnM05T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/lambda.PNG" alt="Lambda Layers add "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a test event and execute the test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nk0HC2Mh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/test.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nk0HC2Mh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/layers/test.PNG" alt="Lambda Layers add "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Source Code:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/rajanpanchal/lambda-layers"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8OChJCRf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github-readme-stats.vercel.app/api/pin/%3Fusername%3Drajanpanchal%26repo%3Dlambda-layers" alt="AWS Lambda dynamic content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Lambda layer makes your development easy and error-free. It reduces the size of the function deployment package. You can use the same layer in multiple functions. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like the post, feel free to share and follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>java</category>
      <category>lambda</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to create dynamic content using AWS Lambda?</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Wed, 21 Oct 2020 03:44:19 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/how-to-create-dynamic-content-using-aws-lambda-din</link>
      <guid>https://forem.com/rajanpanchal/how-to-create-dynamic-content-using-aws-lambda-din</guid>
      <description>&lt;p&gt;Hello Everyone! Today we are going to see how you can generate dynamic content in  Lamdba. We are going to use Java 8, Apache Maven, AWS SDK for Java, Apache Velocity to achieve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uses Cases
&lt;/h2&gt;

&lt;p&gt;There are several scenarios where you want to create dynamic content. For example, to create an HTML page response for an API method instead of returning just data in JSON/ XML. The other scenario is to generate a file or message with dynamic content. For instance, create welcome letters for your customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Dive In
&lt;/h2&gt;

&lt;p&gt;We are going to create welcome letters for our credit card customers. The letter's template is :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Hello ${name},

Say hi to your new credit card!
Your credit card number is ${creditCardNumber}.

Regards,
Your Credit Company

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda would populate &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;credit card number&lt;/code&gt;. The generated file is uploaded to S3 for further processing like printing and mailing.&lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 1:
&lt;/h4&gt;

&lt;p&gt;Create an empty maven project and update pom to the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
    &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;net.rajanpanchal&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lambda-java&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Dynamic-content-Lambda&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Generate Dynamic content in Lambda&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;aws.java.sdk.version&amp;gt;&lt;/span&gt;2.14.11&lt;span class="nt"&gt;&amp;lt;/aws.java.sdk.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;software.amazon.awssdk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;bom&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${aws.java.sdk.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.amazonaws&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aws-java-sdk-s3&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.11.865&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.amazonaws&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aws-lambda-java-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.velocity&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;velocity-engine-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.velocity&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;velocity-tools&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;source&amp;gt;&lt;/span&gt;${maven.compiler.source}&lt;span class="nt"&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;${maven.compiler.target}&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-shade-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.2.4&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;package&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;shade&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are adding AWS dependencies and apache velocity dependencies. The &lt;code&gt;maven-shade-plugin&lt;/code&gt; to create a fat jar.&lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 2:
&lt;/h4&gt;

&lt;p&gt;We will have our template, discussed earlier, in the &lt;code&gt;resources&lt;/code&gt; folder (&lt;code&gt;src/main/resources&lt;/code&gt;) with the name &lt;code&gt;welcomeLetter.vm&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 3:
&lt;/h4&gt;

&lt;p&gt;Create a class file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.rajanpanchal.handlers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.File&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.FileWriter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Properties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.Template&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.VelocityContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.app.VelocityEngine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.exception.ParseErrorException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.exception.ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.velocity.runtime.RuntimeConstants&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.regions.Regions&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.Context&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.RequestHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.s3.AmazonS3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.s3.AmazonS3ClientBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.s3.model.ObjectMetadata&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.s3.model.PutObjectRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WelcomeLetterGeneratorHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Regions&lt;/span&gt; &lt;span class="n"&gt;clientRegion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Regions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;US_EAST_1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileObjKeyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"welcome_letter.txt"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;bucketName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"welcomelettersbucket"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;VelocityContext&lt;/span&gt; &lt;span class="n"&gt;vContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Template&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;AmazonS3&lt;/span&gt; &lt;span class="n"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AmazonS3ClientBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;standard&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;withRegion&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientRegion&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Create a new Velocity Engine&lt;/span&gt;
            &lt;span class="nc"&gt;VelocityEngine&lt;/span&gt; &lt;span class="n"&gt;velocityEngine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VelocityEngine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// Set properties that allow reading vm file from classpath.&lt;/span&gt;
            &lt;span class="nc"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;velocityEngine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RESOURCE_LOADER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"file,class"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;velocityEngine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"class.resource.loader.class"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="s"&gt;"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;velocityEngine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;velocityEngine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTemplate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcomeLetter.vm"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;vContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VelocityContext&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;LambdaLogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Add data to velocity context&lt;/span&gt;
            &lt;span class="n"&gt;vContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Rajan"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;vContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"creditCardNumber"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1234 5678 9012 3456"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp/"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;fileObjKeyName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;FileWriter&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileWriter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// merge template and Data&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vContext&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// Upload a file as a new object with ContentType and title specified.&lt;/span&gt;
            &lt;span class="nc"&gt;PutObjectRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PutObjectRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileObjKeyName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;ObjectMetadata&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMetadata&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"plain/text"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addUserMetadata&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Welcome Letter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMetadata&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Success"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error:"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;static&lt;/code&gt; block we are creating a velocity engine, setting resource loaders for the engine ('class' and 'file' resource loaders). Then we get the template and create a context to hold data to populate on the template.&lt;/p&gt;

&lt;p&gt;In Lambda handler &lt;code&gt;handleRequest&lt;/code&gt;, we add data like name and credit card number to the context, and using a FileWriter object we merge the template and the data. Note that we create the file in &lt;code&gt;/tmp/&lt;/code&gt; directory in the Lambda execution environment. Lambda provides some disk space to the function to use. Then we upload this file to the S3 bucket (&lt;code&gt;welcomelettersbucket&lt;/code&gt;) with the filename &lt;code&gt;welcome_letter.txt&lt;/code&gt;. My bucket exists in US-EAST-1 as indicated by the variable &lt;code&gt;clientRegion&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 4
&lt;/h4&gt;

&lt;p&gt;Now execute maven &lt;code&gt;package&lt;/code&gt; command to generate the fat jar with all dependencies. &lt;br&gt;
A jar would be generated in the &lt;strong&gt;target&lt;/strong&gt; folder.&lt;/p&gt;
&lt;h4&gt;
  
  
  STEP 5:
&lt;/h4&gt;

&lt;p&gt;Go to AWS Console, create a Lambda function with runtime Java 8, let it create a default execution role. Upload the jar under &lt;em&gt;Function Code&lt;/em&gt; section. Edit &lt;em&gt;Basic Settings&lt;/em&gt; and add our handler package and method name&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net.rajanpanchal.handlers.WelcomeLetterGeneratorHandler::handleRequest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  STEP 6:
&lt;/h4&gt;

&lt;p&gt;Add S3 access policy to the Lambda execution role.  Click on &lt;em&gt;Permissions&lt;/em&gt; tab - &amp;gt; &lt;em&gt;Execution Role&lt;/em&gt; hyperlink. It will take you to the IAM Role. For simplicity, I added   &lt;strong&gt;AmazonS3FullAccess&lt;/strong&gt; permission, but you can add fine-grain S3 access.&lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 7:
&lt;/h4&gt;

&lt;p&gt;Go back to lambda and create Test event. Lambda executed successfully.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5flX7Wk6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/success.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5flX7Wk6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/success.PNG" alt="AWS Lamdba Dynamic Content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check S3 bucket, the file is saved.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4X8LwF23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/file_generated.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4X8LwF23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/file_generated.PNG" alt="AWS Lambda Dynamic Content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agx5uIio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/file_content.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agx5uIio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/Lambda-dynamic-content/file_content.PNG" alt="AWS Lambda Dynamic Content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file is ready for further processing!&lt;/p&gt;

&lt;h4&gt;
  
  
  Source Code:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/rajanpanchal/Lambda-dynamic-content"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ryKKGpwB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github-readme-stats.vercel.app/api/pin/%3Fusername%3Drajanpanchal%26repo%3DLambda-dynamic-content" alt="AWS Lambda dynamic content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;It's super easy to create dynamic content in Lambda using Apache Velocity and Java SDK. In addition, using lambda you only pay for what you use.   Let me know your thoughts on the article in the comments and how you are going to use this?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like the post, feel free to share and follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>java</category>
      <category>lambda</category>
      <category>cloud</category>
    </item>
    <item>
      <title>What Is IKEA Effect And How To Benefit From It?</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Tue, 06 Oct 2020 20:27:04 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/what-is-ikea-effect-and-how-to-benefit-from-it-1jnj</link>
      <guid>https://forem.com/rajanpanchal/what-is-ikea-effect-and-how-to-benefit-from-it-1jnj</guid>
      <description>&lt;p&gt;For those who don't know,  IKEA is a Swedish multinational group designs and sells &lt;strong&gt;ready-to-assemble furniture&lt;/strong&gt;, kitchen appliances, home accessories, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is IKEA Effect
&lt;/h3&gt;

&lt;p&gt;The IKEA effect is a cognitive bias in which consumers place a disproportionately high value on products they partially created. A 2011 study found that subjects were willing to pay more for furniture they had assembled themselves, than for equivalent pre-assembled items. &lt;/p&gt;

&lt;p&gt;Now you might be wondering why we are discussing it on a tech blog? Read on and you would understand how it impacts you as an IT Professional.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Labor Leads to Love
&lt;/h3&gt;

&lt;p&gt;Normally, when you buy a product from IKEA it requires some level of assembly before the product can be used. The study found that when someone puts labor into something, they start liking it more, even if it is poorly constructed. Hence, the phenomenon,“IKEA effect”, is named in honor of the Swedish manufacturer whose products typically arrive with some&lt;br&gt;
assembly required.  The study also found that the "IKEA Effect" dissipates when the creations are destroyed.  The creation has to stay intact for IKEA effect to be effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  How you can use IKEA Effect to your advantage?
&lt;/h3&gt;

&lt;p&gt;You might have experienced the IKEA effect even if you didn't know the term before. To take advantage of this, you need to build things. No matter how small it is. If you are learning a new language, a library or a technology, think of a small business problem and try to solve it using the knowledge that you have.  For example, I am upskilling myself in AWS. So first I learn the concepts and then I think of a problem that can be solved using different AWS services.  Once you solve it you will value your solution more than anything else even if it's not of production grade or perfect. This will keep you motivate to learn more and create more. You can also contribute to open source projects. Open source projects are more popular because IKEA effect is in place. Your name gets connected to projects you make contribution to. This gives a sense of accomplishment and motivates you to contribute more.&lt;/p&gt;

&lt;p&gt;Also, don't throw away your solution, instead preserve it using your favorite version control like GitHub, GitLab,  etc. Or you can also write blog about it. &lt;/p&gt;

&lt;p&gt;Let me know your thoughts in comments !&lt;/p&gt;

&lt;p&gt;Now, this post will be incomplete without these memes!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zUsmRrAa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zUsmRrAa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/01.png" alt="IKEA Effect "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sd6I-RU1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/02.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sd6I-RU1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/02.jpg" alt="IKEA Effect "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QHa84DMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/03.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QHa84DMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/03.jpg" alt="IKEA Effect "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cnib-Xzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/04.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cnib-Xzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/ikea-effect/04.jpg" alt="IKEA Effect "&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>developer</category>
      <category>learning</category>
    </item>
    <item>
      <title>AWS Serverless Application Model : Guide to writing your first AWS SAM Application</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Tue, 29 Sep 2020 22:30:12 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/aws-serverless-application-model-guide-to-writing-your-first-aws-sam-application-2ol7</link>
      <guid>https://forem.com/rajanpanchal/aws-serverless-application-model-guide-to-writing-your-first-aws-sam-application-2ol7</guid>
      <description>&lt;p&gt;Today we are going to see how one can write a serverless application using Serverless Application Model (SAM).&lt;br&gt;
First, let's understand what Serverless Application Model is.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is Serverless Application Model?
&lt;/h3&gt;

&lt;p&gt;What do you do when you want to create a resource on AWS, for example, Lambda function? You log in to the AWS console and manually go to the Lambda service to create a function. Now say you want to create 10 such functions you have to do the same process 10 times. This can be error-prone and time-consuming. With SAM you can just write once and deploy as many times you want flawlessly. It is similar to Cloud Formation. You can say SAM is the superset of Cloudformation.&lt;/p&gt;

&lt;p&gt;The AWS Serverless Application Model (SAM) is an open-source framework for building serverless applications. It provides shorthand syntax to express functions, APIs, databases, and event source mappings. With just a few lines of code, you can define the application you want and model it using YAML. During deployment, SAM transforms and expands the SAM syntax into AWS CloudFormation syntax, enabling you to build serverless applications faster. &lt;/p&gt;

&lt;p&gt;With the use of Environment variables and parameters, you can dynamically name all your resources and create different environments like DEV, TEST, PROD with the same set of resources.&lt;/p&gt;
&lt;h3&gt;
  
  
  Getting started with SAM
&lt;/h3&gt;

&lt;p&gt;To use SAM you will need SAM-CLI installed. SAM CLI provides a Lambda-like execution environment that lets you locally build, test, and debug applications defined by SAM templates. You can also use the SAM CLI to deploy your applications to AWS.&lt;br&gt;
You can follow the guide &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html"&gt;here&lt;/a&gt; to install SAM CLI.&lt;br&gt;
Before we proceed make sure your user has all the permissions to create resources and configured on the machine. To configure AWS account, install AWS CLI and run &lt;code&gt;aws configure&lt;/code&gt; command to set up credentials. I am using the admin user that has all the permissions. &lt;/p&gt;

&lt;p&gt;Now we are ready to download sample application and examine its contents. Run the following command on terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sam init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It will ask you to make several choices. Note: you need to have your runtime already installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu@ubuntu-VirtualBox:~/MyWorkspace/BlogPosts/SAM$ sam init
Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1

Which runtime would you like to use?
    1 - nodejs12.x
    2 - python3.8
    3 - ruby2.7
    4 - go1.x
    5 - java11
    6 - dotnetcore3.1
    7 - nodejs10.x
    8 - python3.7
    9 - python3.6
    10 - python2.7
    11 - ruby2.5
    12 - java8.al2
    13 - java8
    14 - dotnetcore2.1
Runtime: 2

Project name [sam-app]: SAM application

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
    1 - Hello World Example
    2 - EventBridge Hello World
    3 - EventBridge App from scratch (100+ Event Schemas)
    4 - Step Functions Sample App (Stock Trader)
    5 - Elastic File System Sample App
Template selection: 1

-----------------------
Generating application:
-----------------------
Name: SAM application
Runtime: python3.8
Dependency Manager: pip
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./SAM application/README.md

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go to the file system and it would have created following file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SAM application/
   ├── README.md
   ├── events/
   │   └── event.json
   ├── hello_world/
   │   ├── __init__.py
   │   ├── app.py            #Contains your AWS Lambda handler logic.
   │   └── requirements.txt  #Contains any Python dependencies the application requires, used for sam build
   ├── template.yaml         #Contains the AWS SAM template defining your application's AWS resources.
   └── tests/
       └── unit/
           ├── __init__.py
           └── test_handler.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open template.yml and let's breakdown the contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless-2016-10-31&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;SAM application&lt;/span&gt;

  &lt;span class="s"&gt;Sample SAM Template for SAM application&lt;/span&gt;

&lt;span class="c1"&gt;# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst&lt;/span&gt;
&lt;span class="na"&gt;Globals&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt; &lt;span class="c1"&gt;# More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello_world/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.8&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;HelloWorld&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt; &lt;span class="c1"&gt;# More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hello&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function&lt;/span&gt;
  &lt;span class="c1"&gt;# Find out more about other implicit resources you can reference within SAM&lt;/span&gt;
  &lt;span class="c1"&gt;# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldApi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Gateway&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;endpoint&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;URL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Prod&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;stage&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;function"&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Lambda&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Function&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ARN"&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;HelloWorldFunction.Arn&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunctionIamRole&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Implicit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;IAM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Role&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;created&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;function"&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;HelloWorldFunctionRole.Arn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;AWSTemplateFormatVersion&lt;/code&gt; - The first line always stays the same for every template.yml. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Transform&lt;/code&gt; - It specifies one or more macros that AWS CloudFormation uses to process your template. This is a required section.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Description&lt;/code&gt; is self-explanatory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Globals&lt;/code&gt; - It is unique to the SAM and defines properties shared by the whole template. In this case, the &lt;code&gt;timeout&lt;/code&gt; will apply to all functions. Globals don't exist in cloud formation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Resources&lt;/code&gt; -  You define all AWS resources under this. This is also a mandatory section.&lt;br&gt;
Here we have defined a function with the logical name &lt;code&gt;HelloWorldFunction&lt;/code&gt;, it is of type &lt;code&gt;AWS::Serverless::Function&lt;/code&gt; with a runtime of python 3.8, &lt;code&gt;CodeUri&lt;/code&gt; points to the folder where our handler resides on the filesystem. &lt;code&gt;Handler&lt;/code&gt; is the filename and the method. &lt;code&gt;Events&lt;/code&gt; would create an API in the API Gateway with method type &lt;code&gt;GET&lt;/code&gt; and path &lt;code&gt;/hello&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Outputs&lt;/code&gt;- Describes the values that are returned and available for use after the stack is created. For example, in our template, &lt;code&gt;HelloWorldApi&lt;/code&gt; output gives the API Url generated by the function. We are also setting Lambda and IAM Role ARN as output.&lt;br&gt;
Also note &lt;code&gt;!Sub&lt;/code&gt; &amp;amp; &lt;code&gt;GetAtt&lt;/code&gt; functions in output,  &lt;code&gt;!Sub&lt;/code&gt; is used to substitute a variable with a value. Here it will substitute ${AWS::Region} and ${ServerlessRestApi}.  &lt;code&gt;GetAtt&lt;/code&gt; function returns the value of an attribute from a resource in the template. Here we are asking for ARN of the HelloWorldfunction.&lt;/p&gt;

&lt;p&gt;Now examine the app.py file. It is straightforward and returns "hello world" as a response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;

&lt;span class="c1"&gt;# import requests
&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Sample pure Lambda function

    Parameters
    ----------
    event: dict, required
        API Gateway Lambda Proxy Input Format

        Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format

    context: object, required
        Lambda Context runtime methods and attributes

        Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

    Returns
    ------
    API Gateway Lambda Proxy Output Format: dict

        Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
    """&lt;/span&gt;

    &lt;span class="c1"&gt;# try:
&lt;/span&gt;    &lt;span class="c1"&gt;#     ip = requests.get("http://checkip.amazonaws.com/")
&lt;/span&gt;    &lt;span class="c1"&gt;# except requests.RequestException as e:
&lt;/span&gt;    &lt;span class="c1"&gt;#     # Send some context about this error to Lambda Logs
&lt;/span&gt;    &lt;span class="c1"&gt;#     print(e)
&lt;/span&gt;
    &lt;span class="c1"&gt;#     raise e
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;# "location": ip.text.replace("\n", "")
&lt;/span&gt;        &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Get back to the terminal and &lt;code&gt;cd&lt;/code&gt; into the directory where the &lt;code&gt;template.yml&lt;/code&gt; resides,  run the command: &lt;code&gt;sam build&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu@ubuntu-VirtualBox:~/MyWorkspace/BlogPosts/SAM/SAM application$ sam build
Building function 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sam build&lt;/code&gt; command builds any dependencies that your application has, and copies your application source code to folders under .aws-sam/build to be zipped and uploaded to Lambda. Check the contents of &lt;code&gt;.aws-sam&lt;/code&gt; folder in project directory. It would be something similar to shown below. In HelloWorldFunction folder, there would be many other files along with app.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.aws_sam/
   └── build/
       ├── HelloWorldFunction/
       └── template.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now its time to run &lt;code&gt;sam deploy -g&lt;/code&gt;. It will ask you couple of configuration information like application name,  region name where you want to create the stack, etc, and will wait for your confirmation if you asked for confirmation before deploy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;buntu@ubuntu-VirtualBox:~/MyWorkspace/BlogPosts/SAM/SAM application$ sam deploy -g

Configuring SAM deploy
======================

    Looking for samconfig.toml :  Not found

    Setting default arguments for 'sam deploy'
    =========================================
    Stack Name [sam-app]: my-first-sam-app
    AWS Region [us-east-1]: us-east-1
    #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
    Confirm changes before deploy [y/N]: y
    #SAM needs permission to be able to create roles to connect to the resources in your template
    Allow SAM CLI IAM role creation [Y/n]: y
    HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
    Save arguments to samconfig.toml [Y/n]: y

    Looking for resources needed for deployment: Found!

        Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1xyg1t2j2ws5k
        A different default S3 bucket can be set in samconfig.toml

    Saved arguments to config file
    Running 'sam deploy' for future deployments will use the parameters saved above.
    The above parameters can be changed by modifying samconfig.toml
    Learn more about samconfig.toml syntax at 
    https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Uploading to my-first-sam-app/9601808ead19b558184dcec8285866a3  538937 / 538937.0  (100.00%)

    Deploying with following values
    ===============================
    Stack name                 : my-first-sam-app
    Region                     : us-east-1
    Confirm changeset          : True
    Deployment s3 bucket       : aws-sam-cli-managed-default-samclisourcebucket-1xyg1t2j2ws5k
    Capabilities               : ["CAPABILITY_IAM"]
    Parameter overrides        : {}

Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.
Uploading to my-first-sam-app/362accae02d25f5921348967d73b9d29.template  1115 / 1115.0  (100.00%)

Waiting for changeset to be created..
CloudFormation stack changeset
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                                          LogicalResourceId                                                  ResourceType                                                     
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                                              HelloWorldFunctionHelloWorldPermissionProd                         AWS::Lambda::Permission                                          
+ Add                                                              HelloWorldFunctionRole                                             AWS::IAM::Role                                                   
+ Add                                                              HelloWorldFunction                                                 AWS::Lambda::Function                                            
+ Add                                                              ServerlessRestApiDeployment47fc2d5f9d                              AWS::ApiGateway::Deployment                                      
+ Add                                                              ServerlessRestApiProdStage                                         AWS::ApiGateway::Stage                                           
+ Add                                                              ServerlessRestApi                                                  AWS::ApiGateway::RestApi                                         
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:us-east-1:&amp;lt;account #&amp;gt;:changeSet/samcli-deploy1599948737/03d65ab9-a943-494d-8db6-abf6aad17537


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: 

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you confirm, it will start creating stack. Below is the output after the stack creation completes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-09-12 17:13:45 - Waiting for stack create/update to complete

CloudFormation events from changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                                    ResourceType                                      LogicalResourceId                                 ResourceStatusReason                            
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                                AWS::IAM::Role                                    HelloWorldFunctionRole                            -                                               
CREATE_IN_PROGRESS                                AWS::IAM::Role                                    HelloWorldFunctionRole                            Resource creation Initiated                     
CREATE_COMPLETE                                   AWS::IAM::Role                                    HelloWorldFunctionRole                            -                                               
CREATE_IN_PROGRESS                                AWS::Lambda::Function                             HelloWorldFunction                                -                                               
CREATE_IN_PROGRESS                                AWS::Lambda::Function                             HelloWorldFunction                                Resource creation Initiated                     
CREATE_COMPLETE                                   AWS::Lambda::Function                             HelloWorldFunction                                -                                               
CREATE_IN_PROGRESS                                AWS::ApiGateway::RestApi                          ServerlessRestApi                                 -                                               
CREATE_IN_PROGRESS                                AWS::ApiGateway::RestApi                          ServerlessRestApi                                 Resource creation Initiated                     
CREATE_COMPLETE                                   AWS::ApiGateway::RestApi                          ServerlessRestApi                                 -                                               
CREATE_IN_PROGRESS                                AWS::Lambda::Permission                           HelloWorldFunctionHelloWorldPermissionProd        Resource creation Initiated                     
CREATE_IN_PROGRESS                                AWS::ApiGateway::Deployment                       ServerlessRestApiDeployment47fc2d5f9d             -                                               
CREATE_IN_PROGRESS                                AWS::Lambda::Permission                           HelloWorldFunctionHelloWorldPermissionProd        -                                               
CREATE_COMPLETE                                   AWS::ApiGateway::Deployment                       ServerlessRestApiDeployment47fc2d5f9d             -                                               
CREATE_IN_PROGRESS                                AWS::ApiGateway::Deployment                       ServerlessRestApiDeployment47fc2d5f9d             Resource creation Initiated                     
CREATE_IN_PROGRESS                                AWS::ApiGateway::Stage                            ServerlessRestApiProdStage                        -                                               
CREATE_IN_PROGRESS                                AWS::ApiGateway::Stage                            ServerlessRestApiProdStage                        Resource creation Initiated                     
CREATE_COMPLETE                                   AWS::ApiGateway::Stage                            ServerlessRestApiProdStage                        -                                               
CREATE_COMPLETE                                   AWS::Lambda::Permission                           HelloWorldFunctionHelloWorldPermissionProd        -                                               
CREATE_COMPLETE                                   AWS::CloudFormation::Stack                        my-first-sam-app                                  -                                               
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                                                                                
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                                                                                                                          
Description         Implicit IAM Role created for Hello World function                                                                                                                                 
Value               arn:aws:iam::&amp;lt;account #&amp;gt;:role/my-first-sam-app-HelloWorldFunctionRole-27OIM6WD99F0                                                                                                

Key                 HelloWorldApi                                                                                                                                                                      
Description         API Gateway endpoint URL for Prod stage for Hello World function                                                                                                                   
Value               https://3kuuurt63m.execute-api.us-east-1.amazonaws.com/Prod/hello/                                                                                                                 

Key                 HelloWorldFunction                                                                                                                                                                 
Description         Hello World Lambda Function ARN                                                                                                                                                    
Value               arn:aws:lambda:us-east-1:&amp;lt;account #&amp;gt;:function:my-first-sam-app-HelloWorldFunction-1U5YD9NICU5LP                                                                                   
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - my-first-sam-app in us-east-1

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see in the outputs, the &lt;code&gt;HelloWorldApi&lt;/code&gt; URL was generated which you can hit in the browser and verify your API is working fine. You can also see the same information in Cloud Formation's output section on AWS console.&lt;/p&gt;

&lt;p&gt;Great Job! You have successfully completed your First SAM App!&lt;/p&gt;

&lt;h3&gt;
  
  
  What else you can do in SAM?
&lt;/h3&gt;

&lt;p&gt;This is not the end, you can also test the function locally before deploy. The AWS SAM CLI provides the &lt;code&gt;sam local&lt;/code&gt; command to run your application using Docker containers that simulate the execution environment of Lambda.&lt;br&gt;
I am on linux machine, hence I am going to run command : &lt;code&gt;sudo /home/linuxbrew/.linuxbrew/bin/sam local start-api&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SAM CLI now collects telemetry to better understand customer needs.

    You can OPT OUT and disable telemetry collection by setting the
    environment variable SAM_CLI_TELEMETRY=0 in your shell.
    Thanks for your help!

    Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html

Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-09-12 22:31:06  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you hit the URL(&lt;a href="http://127.0.0.1:3000/hello"&gt;http://127.0.0.1:3000/hello&lt;/a&gt;) in the browser, you should see the same response as before "hello world" and on the terminal, it should show something similar to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoking app.lambda_handler (python3.8)
Failed to download a new amazon/aws-sam-cli-emulation-image-python3.8:rapid-1.1.0 image. Invoking with the already downloaded image.
Mounting /home/ubuntu/MyWorkspace/BlogPosts/SAM/SAM application/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: f4945824-0a1a-1742-2f46-4d0bc2bbe515 Version: $LATEST
END RequestId: f4945824-0a1a-1742-2f46-4d0bc2bbe515
REPORT RequestId: f4945824-0a1a-1742-2f46-4d0bc2bbe515  Init Duration: 216.83 ms    Duration: 2.88 ms   Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 24 MB  
No Content-Type given. Defaulting to 'application/json'.
2020-09-12 22:38:28 127.0.0.1 - - [12/Sep/2020 22:38:28] "GET /hello HTTP/1.1" 200 -

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Where to go from here?
&lt;/h3&gt;

&lt;p&gt;This was a very basic SAM application but I hope you got the gist of it. As an exercise, you can add more resources like CloudFront, Route53, DynamoDB, ACM etc, and see how to model it in YAML. Take a look &lt;a href="https://blog.rajanpanchal.net/aws-kms-use-case-with-serverless-application-model-sam-an-end-to-end-solution"&gt;here&lt;/a&gt; and &lt;a href="https://blog.rajanpanchal.net/my-experiments-with-aws-cloud-cloud-resume-challenge"&gt;here&lt;/a&gt; for more complex SAM Templates.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like my articles feel free to follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>cloud</category>
      <category>lambda</category>
    </item>
    <item>
      <title>REST API using AWS Java SDK</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Tue, 22 Sep 2020 18:29:48 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/rest-api-using-aws-java-sdk-154k</link>
      <guid>https://forem.com/rajanpanchal/rest-api-using-aws-java-sdk-154k</guid>
      <description>&lt;p&gt;In the &lt;a href="https://rajanpanchal.net/write-your-first-aws-lambda-in-java/"&gt;previous post&lt;/a&gt;, we looked at a simple Lambda handler using the AWS Java SDK. In this post, we're going to implement Rest API with Lambda (using Lambda Proxy Integration).  &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Lambda Proxy Integration
&lt;/h2&gt;

&lt;p&gt;When a client submits an API request, API Gateway passes the request to the integrated Lambda function as-is, except that the order of the request parameters is not preserved. This request data includes the request headers, query string parameters, URL path variables, payload, and API configuration data. &lt;/p&gt;

&lt;p&gt;The configuration data can include current deployment stage name, stage variables, user identity, or authorization context (if any). The backend Lambda function parses the incoming request data. The API gateway simply acts as a postman to pass requests and responses. One advantage is that you can change the implementation of the Lambda without impacting the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's implement using AWS Java SDK
&lt;/h2&gt;

&lt;p&gt;Create an empty maven project and update the pom.xml with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
    &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;net.rajanpanchal&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lambda-api-demo&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;LambdaApiDemo&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Demonstrates API Request &lt;span class="ni"&gt;&amp;amp;amp;&lt;/span&gt; Response Using Lambda and Java SDK for AWS&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;1.8&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;aws.java.sdk.version&amp;gt;&lt;/span&gt;2.14.11&lt;span class="nt"&gt;&amp;lt;/aws.java.sdk.version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;software.amazon.awssdk&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;bom&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${aws.java.sdk.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-events --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.amazonaws&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aws-lambda-java-events&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.amazonaws&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aws-lambda-java-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;source&amp;gt;&lt;/span&gt;${maven.compiler.source}&lt;span class="nt"&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;${maven.compiler.target}&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-shade-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.2.4&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;package&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;shade&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are adding 2 main dependencies here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; aws-lambda-java-core - This provides &lt;code&gt;RequestHandler&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;aws-lambda-java-events -  This provides &lt;code&gt;APIGatewayProxyRequestEvent&lt;/code&gt; and &lt;code&gt;APIGatewayProxyResponseEvent&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Added 2 plugins:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compiler plugin - determines java version for the compiler.&lt;/li&gt;
&lt;li&gt;maven-shade-plugin -  to generate fat jar aka Uber jar (with all dependencies)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a class &lt;code&gt;LambdaHandler&lt;/code&gt;, with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.rajanpanchal.handlers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.Context&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.LambdaLogger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.RequestHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LambdaHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt; &lt;span class="n"&gt;requestEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="n"&gt;responseEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;LambdaLogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"requestEventString:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;requestEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"query string param:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;requestEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getQueryStringParameters&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"headers:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;requestEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeaders&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="c1"&gt;// fetching the value send in the request body&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requestEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// Request request = gson.fromJson(message, Request.class);&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message body:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// setting up the response message&lt;/span&gt;
            &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from Lambda!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid Response"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;responseEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above code is simple. &lt;code&gt;requestEvent&lt;/code&gt; object is of type &lt;code&gt;APIGatewayProxyRequestEvent&lt;/code&gt;. You will get headers, body, query-string, etc. from this object.&lt;br&gt;
&lt;code&gt;responseEvent&lt;/code&gt; object is of type &lt;code&gt;APIGatewayProxyResponseEvent&lt;/code&gt;. You can set response headers, body, status, etc in this object.&lt;/p&gt;

&lt;p&gt;Now execute maven command &lt;code&gt;mvn package&lt;/code&gt; to generate a jar file in the target folder.&lt;br&gt;
Login to AWS console, create Lambda function with Java 8 runtime, let it create execution role, and upload the jar file under &lt;strong&gt;Function Code&lt;/strong&gt; section.&lt;br&gt;
In Basic Settings, set the handler name in format :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*net.rajanpanchal.handlers.LambdaHandler::handleRequest*

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now go to API Gateway, create a REST API&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRGk-kxq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/lambda%2Bapi.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRGk-kxq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/lambda%2Bapi.PNG" alt="AWS Java SDK Rest API using Lambda Proxy Integration"&gt;&lt;/a&gt;&lt;br&gt;
Go to actions and create a new method of type &lt;code&gt;GET&lt;/code&gt;. Select the following configuration:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--udafiCUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/rest%2Bmethod.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--udafiCUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/rest%2Bmethod.PNG" alt="AWS Java SDK Rest API using Lambda Proxy Integration"&gt;&lt;/a&gt;&lt;br&gt;
To enable proxy integration, make sure to check the checkbox. Save to create a method.&lt;/p&gt;

&lt;p&gt;Go to actions and click deploy API and give the following information and click deploy.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tUoXwdBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/deploy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tUoXwdBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/deploy.PNG" alt="Lambda proxy integration using java sdk"&gt;&lt;/a&gt;&lt;br&gt;
Use the URL generated to access the API&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RbYLdeda--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/url.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RbYLdeda--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/url.PNG" alt="AWS Java SDK Rest APIk"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Hit the URL in the browser and you should see the below response:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NnG-pgsa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/access-api.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NnG-pgsa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/access-api.PNG" alt="AWS Java SDK Rest API using Lambda Proxy Integration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Cloud Watch, access Log Groups from the left-hand navigation, and access the logs corresponding to your lambda function. You should see the log statements from the lambda handler.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9QpZ2iX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/log-group.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9QpZ2iX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-lambda-api/log-group.PNG" alt="AWS Java SDK Rest API using Lambda Proxy Integration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Source Code:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/rajanpanchal/lambda-api-aws-sdk"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ibI2AXin--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github-readme-stats.vercel.app/api/pin/%3Fusername%3Drajanpanchal%26repo%3Dlambda-api-aws-sdk" alt="AWS Java SDK Rest API using Lambda Proxy Integration"&gt;&lt;/a&gt;&lt;br&gt;
Here we complete our REST API with Lambda!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like the post, feel free to share and follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>java</category>
      <category>restapi</category>
    </item>
    <item>
      <title>Amazon S3 Quick Reference </title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Wed, 16 Sep 2020 04:37:04 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/amazon-s3-quick-reference-p2m</link>
      <guid>https://forem.com/rajanpanchal/amazon-s3-quick-reference-p2m</guid>
      <description>&lt;p&gt;Amazon S3 Quick Reference for Certification, interview and study!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jc9PJdxe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/s3-infographics/s3-infographics.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jc9PJdxe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/s3-infographics/s3-infographics.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like the post, feel free to share and follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>infographics</category>
    </item>
    <item>
      <title>AWS Lambda Performance Optimizations</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Thu, 10 Sep 2020 22:24:47 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/aws-lambda-performance-optimizations-4hn6</link>
      <guid>https://forem.com/rajanpanchal/aws-lambda-performance-optimizations-4hn6</guid>
      <description>&lt;p&gt;In this post we are going to see how you can optimize performance of AWS Lambda function. Although Lambda is a managed service by AWS and it automatically scales, based on shared responsibility model, the underlying service details will be managed by AWS but its client's responsibility to correctly use the service. By using these optimizations you can lower your Lambda bill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lets look at some of the Lambda Performance Optimizations
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Execution context Reuse
&lt;/h4&gt;

&lt;p&gt;When a Lambda function is invoked, AWS Lambda launches an execution context based on the configuration settings you provide like Memory, runtime, etc. The execution context is a temporary runtime environment that initializes any external dependencies of your Lambda function code, such as database connections or HTTP endpoints, etc. After the Lambda function completes the execution it maintains the execution context in hopes that another invocation of same function will happen. If it does happen, then it will reuse the context. &lt;br&gt;
So the objects declared outside of the lambda handler (Lambda global variables) can be reused. You can declare any objects there. Following code snippets defines S3 as client that will be reused in subsequent invocation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;boto3&lt;/span&gt;
&lt;span class="c1"&gt;#DynamoDB defined outside of handler
&lt;/span&gt;&lt;span class="n"&gt;dynamodb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'dynamodb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MyTable"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'userid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Item) 
      }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A word of caution: Its is not guaranteed that subsequent function invocation would go to the same execution context.  Lambda may decide to create a new invocation context runtime so don't maintain any state information. Always have logic in Lambda handler to instantiate or reconnect the connections objects if cannot be reused.&lt;/p&gt;

&lt;h4&gt;
  
  
  Minimize Deployment Package
&lt;/h4&gt;

&lt;p&gt;A deployment package is a ZIP archive that contains your compiled function code and dependencies. In case your Lambda handler is in Java,  you need to have a fat-jar aka Uber Jar to upload to Lambda. Uber jar will contain all the dependencies required to execute the handler. Its is important that you only import those packages that are required. For example, if you only need basic Lambda implementation, then import only &lt;em&gt;lambda-java-core&lt;/em&gt; dependency - It defines handler method interfaces and the context object that the runtime passes to the handler. If you define your own input types, this is the only library you need.   You don't need whole &lt;em&gt;aws-sdk&lt;/em&gt; dependency to write simple Lambda handlers. Use Bill of Materials POM (&lt;a href="https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bom"&gt;https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bom&lt;/a&gt;) in the maven project and provides individual dependencies from BOM POM to import. This will reduce the fat jar size. Keep in mind that in lambda, you are working off a limited disk size and memory as defined in the configuration.&lt;br&gt;
In Python and other languages you can only import modules that you need. For example, in TypeScript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import entire SDK&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// import AWS object without services&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk/global&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// import individual service&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk/clients/s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Use Simple Frameworks
&lt;/h4&gt;

&lt;p&gt;Instead of using full blown spring framework try to use lightweight frameworks that accomplish the same tasks. For example:  If you need Java dependency injection in your app then use lightweight frameworks like Guice (pronounced 'juice' is a lightweight dependency injection framework for Java 6 and above, brought to you by Google)&lt;/p&gt;

&lt;p&gt;Are there any other Lambda optimization techniques? Let us know in comments!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like my articles feel free to follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt;Twitter&lt;/a&gt; for updates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>performance</category>
      <category>java</category>
    </item>
    <item>
      <title>Write your first AWS Lambda in Java</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Thu, 10 Sep 2020 22:23:06 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/write-your-first-aws-lambda-in-java-1j2k</link>
      <guid>https://forem.com/rajanpanchal/write-your-first-aws-lambda-in-java-1j2k</guid>
      <description>&lt;p&gt;So far I have been writing Lambda function in Python for all my  AWS &lt;a href="https://github.com/rajanpanchal"&gt;projects&lt;/a&gt; . In Python its easy, just import boto3 module and starting coding. Things are bit different when you write Lambda handlers in Java. Lets explore and see how you can write a simple HelloWorld Lambda handler in java. I have planned couple of how-to projects that I am going to write in Java. Hence I thought to do HelloWorld post before we dive into complex handlers. Feel free to follow me on &lt;a href="https://twitter.com/PanchalRajan"&gt; twitter&lt;/a&gt;  for upcoming updates.&lt;/p&gt;

&lt;p&gt;To implement handler, we are going to use Maven, Eclipse and AWS SDK for Java. Below are the version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java:  1.8&lt;/li&gt;
&lt;li&gt;Eclipse:  Version: 2020-06 (4.16.0)&lt;/li&gt;
&lt;li&gt;AWS SDK: 2.14.11&lt;/li&gt;
&lt;li&gt;Maven: 3.6.3 (Included with eclipse)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get started, create a new empty maven project in eclipse. Go to File-&amp;gt; New-&amp;gt; Maven Project. In new project dialog box. select "create simple project" and hit next. On next screen. add appropriate information about the project and hit finish. For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nIk0ME7X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/new-maven-project.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nIk0ME7X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/new-maven-project.PNG" alt="aws sdk java new maven project"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now your project is created. Open pom.xml and add following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;net.rajanpanchal&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;lambda-java-demo&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;Lambda-Java-Demo&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;HelloWorld Lambda handler in java&amp;lt;/description&amp;gt;
    &amp;lt;properties&amp;gt;
        &amp;lt;maven.compiler.source&amp;gt;1.8&amp;lt;/maven.compiler.source&amp;gt;
        &amp;lt;maven.compiler.target&amp;gt;1.8&amp;lt;/maven.compiler.target&amp;gt;
        &amp;lt;aws.java.sdk.version&amp;gt;2.14.11&amp;lt;/aws.java.sdk.version&amp;gt;
    &amp;lt;/properties&amp;gt;
    &amp;lt;dependencyManagement&amp;gt;
        &amp;lt;dependencies&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;software.amazon.awssdk&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;bom&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;${aws.java.sdk.version}&amp;lt;/version&amp;gt;
                &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
                &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
            &amp;lt;/dependency&amp;gt;
        &amp;lt;/dependencies&amp;gt;
    &amp;lt;/dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.amazonaws&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;aws-lambda-java-core&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.google.code.gson&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;gson&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.8.6&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;source&amp;gt;${maven.compiler.source}&amp;lt;/source&amp;gt;
                    &amp;lt;target&amp;gt;${maven.compiler.target}&amp;lt;/target&amp;gt;
                &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;3.2.4&amp;lt;/version&amp;gt;
                &amp;lt;executions&amp;gt;
                    &amp;lt;execution&amp;gt;
                        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;
                        &amp;lt;goals&amp;gt;
                            &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;
                        &amp;lt;/goals&amp;gt;
                    &amp;lt;/execution&amp;gt;
                &amp;lt;/executions&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are setting some properties in &lt;code&gt;&amp;lt;properties&amp;gt;&lt;/code&gt; tag like AWS SDK version and Java Version. We are adding AWS SDK dependency and Lambda core dependency with desired version. Google JSON dependency is added to convert between JSON and Java object and vice versa.&lt;br&gt;
In plugins, we define maven compiler plugin to compile the code and another important plugin called &lt;code&gt;maven-shade-plugin&lt;/code&gt;. This plugin helps to create &lt;strong&gt;fat jar&lt;/strong&gt; a.k.a &lt;strong&gt;Uber jar&lt;/strong&gt;. This jar will contain all the dependencies that are required to successfully run the lambda function.&lt;/p&gt;

&lt;p&gt;Now lets create the handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.rajanpanchal.handlers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.Context&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.LambdaLogger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.RequestHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.GsonBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloWorldHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GsonBuilder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setPrettyPrinting&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="nd"&gt;@Override&lt;/span&gt;
      &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;LambdaLogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"200 OK"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// log execution details&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ENVIRONMENT VARIABLES: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONTEXT: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="c1"&gt;// process event&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EVENT: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EVENT TYPE: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here were are implementing &lt;code&gt;RequestHandler&lt;/code&gt; that will accept a &lt;code&gt;Map&lt;/code&gt; of &lt;code&gt;String&lt;/code&gt; and outputs a &lt;code&gt;String&lt;/code&gt; response. The handler is not doing much. Just logging some stuff from &lt;code&gt;context&lt;/code&gt; and &lt;code&gt;event&lt;/code&gt;  and in response it sends &lt;code&gt;200 OK&lt;/code&gt; string.&lt;br&gt;
After this right click on project, go to 'Run as' and click 'Maven build'. A configuration window will open. In 'Goals' type &lt;code&gt;package&lt;/code&gt; and hit 'Run' . Build should be successful and will create a fat jar in &lt;code&gt;target&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Now go to AWS console and create a new Lambda function with Java 8 as runtime and upload this jar from &lt;strong&gt;Function Code&lt;/strong&gt; section. In Basic Settings, you have to specify package.class::methodName in the handler textbox. To test this Lambda, create a test event and execute the test.&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zYANw1vq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/test-event.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zYANw1vq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/test-event.PNG" alt="Java SDK Lambda Test Event"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The ouput might look similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476 Version: $LATEST
ENVIRONMENT VARIABLES: {
  "PATH": "/usr/local/bin:/usr/bin/:/bin:/opt/bin",
  "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2",
  "LAMBDA_TASK_ROOT": "/var/task",
  "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "128",
  "TZ": ":UTC",
  "AWS_SECRET_ACCESS_KEY": "&amp;lt;keyid&amp;gt;",
  "AWS_EXECUTION_ENV": "AWS_Lambda_java8",
  "AWS_DEFAULT_REGION": "us-east-1",
  "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/helloworldjava",
  "_HANDLER": "net.rajanpanchal.handlers.HelloWorldHandler::handleRequest",
  "LANG": "en_US.UTF-8",
  "LAMBDA_RUNTIME_DIR": "/var/runtime",
  "AWS_SESSION_TOKEN": "&amp;lt;session token&amp;gt;",
  "LD_LIBRARY_PATH": "/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib",
  "_X_AMZN_TRACE_ID": "Root\u003d1-5f545c5d-22c8a803badd636859a0f387;Parent\u003d23df427f78bc46e4;Sampled\u003d0",
  "AWS_SECRET_KEY": "&amp;lt;secret key&amp;gt;",
  "AWS_REGION": "us-east-1",
  "AWS_LAMBDA_LOG_STREAM_NAME": "2020/09/06/[$LATEST]57c598b33b164acf8e8151660249e50e",
  "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2:2000",
  "_AWS_XRAY_DAEMON_PORT": "2000",
  "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR",
  "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
  "AWS_ACCESS_KEY": "&amp;lt;access key&amp;gt;",
  "AWS_LAMBDA_FUNCTION_NAME": "helloworldjava"
}CONTEXT: {
  "memoryLimit": 128,
  "awsRequestId": "c40b4095-27f5-4153-ac37-fd2c103f4476",
  "logGroupName": "/aws/lambda/helloworldjava",
  "logStreamName": "2020/09/06/[$LATEST]57c598b33b164acf8e8151660249e50e",
  "functionName": "helloworldjava",
  "functionVersion": "$LATEST",
  "invokedFunctionArn": "arn:aws:lambda:us-east-1:&amp;lt;AccountId&amp;gt;:function:helloworldjava",
  "cognitoIdentity": {
    "identityId": "",
    "poolId": ""
  },
  "logger": {}
}EVENT: {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}EVENT TYPE: class java.util.LinkedHashMapEND RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476
REPORT RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476  Duration: 516.04 ms Billed Duration: 600 ms Memory Size: 128 MB Max Memory Used: 79 MB  Init Duration: 393.54 ms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we complete our first Lambda handler in Java. In next post we will see how we can implement API using AWS SDK.&lt;/p&gt;

</description>
      <category>java</category>
      <category>aws</category>
      <category>lamdba</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Automate Application deployment using GitHub Actions</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Wed, 02 Sep 2020 23:26:03 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/automate-application-deployment-using-github-actions-1acp</link>
      <guid>https://forem.com/rajanpanchal/automate-application-deployment-using-github-actions-1acp</guid>
      <description>&lt;p&gt;GitHub Actions makes it easy to automate all your software workflows. You can Build, test, and deploy your code right from GitHub. In this post we will explore how you can use GitHub Actions to automate serverless application deployment on AWS. You can also use AWS's own CI/CD services to achieve the same. But here we are going to keep our discussion limited to GitHub Actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use GitHub Actions?
&lt;/h3&gt;

&lt;p&gt;Creating a GitHub action is simple. Go to your GitHub repository that you want to automate and click on "Actions"&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tDG-iV1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-action-create-new.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tDG-iV1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-action-create-new.PNG" alt="github actions new workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be taken to Actions page where you can create a new Blank workflow or select existing actions from the marketplace. The actions from marketplace are reusable actions that you can use in your workflow. We are going to create a blank action and we will also use some actions from marketplace.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YXN6hCbE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-actions-blank-workflow.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YXN6hCbE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-actions-blank-workflow.PNG" alt="github actions blank action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets rename the YAML file to workflow.yml. You can name anything you like. We are going to create a Lambda function with API gateway in Serverless Application Model (SAM) template and deploy it using GitHub Actions. &lt;br&gt;
Below is our SAM template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless-2016-10-31&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;GitHub Actions demonstration App&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ApiGatewayApi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Api&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;StageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prod&lt;/span&gt;
    &lt;span class="na"&gt;Auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;UsagePlan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CreateUsagePlan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PER_API&lt;/span&gt;
      &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Usage plan for this API&lt;/span&gt;
      &lt;span class="na"&gt;Quota&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;Limit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;
       &lt;span class="na"&gt;Period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MONTH&lt;/span&gt;
      &lt;span class="na"&gt;Throttle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;BurstLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
       &lt;span class="na"&gt;RateLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
  &lt;span class="na"&gt;LamdbaFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;    
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lambda.handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.8&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;getCounter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hello&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;
            &lt;span class="na"&gt;RestApiId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ApiGatewayApi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;lambda.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def handler(event, context):
            return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body':'Hello from Lambda!'
        ,
        "isBase64Encoded": False
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This contains one Lambda function and API with path hello. Lets first deploy manually using SAM CLI and then we will automate it. Create samconfig.toml with below details.&lt;br&gt;
create s3_bucket that will be used for SAM deploy and update in samconfig.toml.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-github-actions-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1xyg1t2j2ws5k"
s3_prefix = "sam-app"
region = "us-east-1"
confirm_changeset = false
capabilities = "CAPABILITY_IAM"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also create empty requirements.txt along with template.yml. Run &lt;strong&gt;SAM build&lt;/strong&gt; and &lt;strong&gt;SAM deploy -g&lt;/strong&gt; on CLI. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f2LHcBEg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/sam-deploy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f2LHcBEg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/sam-deploy.PNG" alt="SAM Deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to API gateway and hit the url in browser. You should get "hello from Lambda!" response.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ngweiLpb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/api.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ngweiLpb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/api.PNG" alt="github actions api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to our workflow file on GitHub. We will deploy as soon as we push updates to the repo.&lt;br&gt;
Below is our workflow.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a basic workflow to help you get started with Actions&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS Lambda &amp;amp; API gateway deployment demonstration&lt;/span&gt;
&lt;span class="c1"&gt;# Controls when the action will run. Triggers the workflow on push or pull request&lt;/span&gt;
&lt;span class="c1"&gt;# events but only for the master branch&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# A workflow run is made up of one or more jobs that can run sequentially or in parallel&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# This workflow contains a single job called "build"&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# The type of runner that the job will run on&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="c1"&gt;# Steps represent a sequence of tasks that will be executed as part of the job&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="c1"&gt;# Installs Python&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python &lt;/span&gt;&lt;span class="m"&gt;3.8&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.8&lt;/span&gt;
    &lt;span class="c1"&gt;# Installs PIP&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;python -m pip install --upgrade pip&lt;/span&gt;
    &lt;span class="c1"&gt;# Configures AWS credentials from github secrets&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS Credentials&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;aws-access-key-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
        &lt;span class="na"&gt;aws-secret-access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
    &lt;span class="c1"&gt;# Build using SAM &lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SAM Build&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;youyo/aws-sam-action/python3.8@master&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;sam_command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;us-east-1&lt;/span&gt;
    &lt;span class="c1"&gt;# Deploy on AWS&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sam deploy&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;youyo/aws-sam-action/python3.8@master&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;sam_command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--stack-name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;myApp&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--no-fail-on-empty-changeset'&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We first indicate that we want to run this action on push to the master. Then we select runner (Ubuntu) on which our steps will execute. In Steps, we first checkout code, then install python and its dependencies. Then we use other actions from marketplace to configure AWS credentials and then we use another action to do SAM build and SAM deploy.  Please note that we need ti supply AWS ACCESS KEY and SECRET ACCESS KEY to actions for commands to work. We setup here GitHub Secrets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oQx-9wg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/secrets.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oQx-9wg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/secrets.PNG" alt="Github secrets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as you check-in workflow.yml, the action would trigger.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0OcgQVnI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/workflow_build.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0OcgQVnI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/workflow_build.PNG" alt="Github actions workflow trigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploying stack&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YSMoStQe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/deploy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YSMoStQe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/deploy.PNG" alt="Github actions deploying AWS stack"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw7ncvOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/job_complete.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw7ncvOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/job_complete.PNG" alt="Github Actions job completes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can login to the AWS console and confirm the stack is created.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KPGC79iy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/stack_created.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KPGC79iy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/stack_created.PNG" alt="AWS cloud formation stack created"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Resources tab and access the API Gateway. Go to stages and access the Prod stage API.&lt;br&gt;
Open the URL in browser with the path /hello and you should see below output!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x8F5RYpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/testing.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x8F5RYpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/testing.PNG" alt="AWS Lambda function output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully automated AWS deployment using GitHub Actions!&lt;br&gt;
You can download the code from here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/rajanpanchal/aws-github-actions"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mVM-eN2g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github-readme-stats.vercel.app/api/pin/%3Fusername%3Drajanpanchal%26repo%3Daws-github-actions" alt="github actions repo card"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>automation</category>
      <category>aws</category>
      <category>serverless</category>
    </item>
    <item>
      <title>AWS Certified Developer - Associate Exam Tips (2020)</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Wed, 02 Sep 2020 23:23:48 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/aws-certified-developer-associate-exam-tips-2020-1049</link>
      <guid>https://forem.com/rajanpanchal/aws-certified-developer-associate-exam-tips-2020-1049</guid>
      <description>&lt;p&gt;In June 2020, I passed the AWS Certified Solution Architect Exam after almost preparing for 5 months ( an hour or so everyday) and I was so pumped that I decided to take another AWS exam. I started preparing for the Developer Associate exam at the end of June and cleared by July end.&lt;/p&gt;

&lt;p&gt;Here is my badage: &lt;a href="https://www.youracclaim.com/badges/2f8b7d13-cea5-421c-99eb-53c157c75558"&gt;AWS Badge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developer associate is Developer focused and its bit different than the solution architect exam. I found Developer associate exam harder than the Solution Architect, but YMMV.&lt;/p&gt;

&lt;p&gt;So here are my tips and preparation topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You success in exam depends upon recognizing keywords in the questions.  All answers may look similar but keywords will lead to right answer. Pay attention to words. For example: 'low cost', 'encryption at rest vs encryption in transit'.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Know how to do Read Capacity Units (RCU) and Write Capacity Units (WCU) calculations. You might get one or two questions on determining RCU/WCU. Don't forget to pay attention to strongly consistent/ Eventual consistent keyword in question.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sometimes you may find answer to questions in other questions. While reviewing see if any other question has answer to it. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use all the time available for the exam. If finished early, spend time in reviewing all questions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attempt as many mock exams you can. This will prepare you on time management and questions patterns. Questions will be verbose in real exam.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There could be command level questions like what this command do, when to use etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to understand the concepts very well and should have some hands on. It is easy to eliminate two answers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Know CI/CD services like CodeDeploy, CodeBuild, CodeCommit. Understand BuildSpec and AppSpec difference. Code Deploy lifecycle hooks. CodeDeploy Deployment Types for Lambda, ECS and EC2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloudformation, KMS, SQS, SNS, ECS, API gateway, IAM (Inline policies/ Managed Policies) and Lambda (Concurrent execution Limit, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DynamoDB. Local Secondary Index vs Global. DynamoDB Accelerator. DynamoDB Streams. SCAN vs Query. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amazon S3, EC2, Elastic Beanstalk and its deployment types. Knows CORS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CloudWatch, CloudTrail, App X-Ray&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You might also get architecture level questions but not much.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good Luck!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>certification</category>
      <category>developer</category>
    </item>
    <item>
      <title>How to serve premium/private content on your site?</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Sun, 23 Aug 2020 03:46:08 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/how-to-serve-premium-private-content-on-your-site-41kl</link>
      <guid>https://forem.com/rajanpanchal/how-to-serve-premium-private-content-on-your-site-41kl</guid>
      <description>&lt;p&gt;A lot of online companies (for example: Netflix, Udemy etc ) distribute contents over internet that is accessible only to the members of the site or who have subscribed or paid a premium. Today in this post we see how you can achieve this for your website using Amazon Web Services. We will see how you can securely serve private content to your users from AWS S3 bucket using S3 Presigned URLs&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Presigned URLs?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Presigned URL&lt;/strong&gt; is a &lt;strong&gt;URL&lt;/strong&gt; that provides limited permission and time to make a request. Anyone who receives the presigned URL can then access the object. For example, if you have a file in your bucket and both the bucket and the object are private, you can share the file with others by generating a presigned URL. &lt;/p&gt;

&lt;h4&gt;
  
  
  Some important points on Presigned URLs
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The creator of Presigned URL should have access to object for URL to work, otherwise URL wont work.&lt;/li&gt;
&lt;li&gt;You can create a presigned URL that's are not usable or doesn’t work. &lt;/li&gt;
&lt;li&gt;It doesn’t cost anything to create Presigned URLs.&lt;/li&gt;
&lt;li&gt;You can set expiration time on the URLs &lt;/li&gt;
&lt;li&gt;If you created a presigned URL using a temporary token, then the URL expires when the token expires, even if the URL was created with a later expiration time&lt;/li&gt;
&lt;li&gt;You can revoke the URL by removing the permissions to access the object from the user created the URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to create Presigned URL?
&lt;/h3&gt;

&lt;p&gt;When you create a presigned URL for your object, you must provide your security credentials, specify a bucket name, an object key, specify method and expiration time.&lt;/p&gt;

&lt;p&gt;In Python, using Boto3, you can use &lt;em&gt;generate_presigned_url&lt;/em&gt; method to generate the URL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;response = s3_client.generate_presigned_url('get_object',
            Params={'Bucket': bucket_name,
            'Key': object_name},
            ExpiresIn=expiration)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;response&lt;/em&gt; object will contain the URL which will look similar to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://somebucketname-rep.s3.amazonaws.com/someFileName.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=ASIAQS3IOUWUZF7YSXGA%2F20200821%2Fus-east-2%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20200821T051228Z&amp;amp;X-Amz-Expires=3600&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Security-Token=FwoGZXIvYXdzEH8aDCfJDxO0y6xQxYmdGCK2AXe71W%2FgZEg%2FSnSWC%2Fw%2FaJHeZ20M7OI7AqMEum5c98Chl6pSNPwE5Awsc3ySwokDF6L8a9wP0ceXWAmxT3WXLSoFeNHDbbEHfUKWnvGL8yFzAxdmf%2Fmi%2B5Tnl62td8Nad%2F0Ct1Sx11Mip1h2qdYxw80OX5bCTq7cAHHjpmupvaDt%2BZ3qVyIA9WZmeS63dCPOlieE9IiBZf%2FjxF4Mcs5w4ZIHtZL%2F3LvqMXAy3XfzCgnlYVZeCNczKLuv%2FfkFMi0mStwkzyO%2BfMIxWJ82GJmyNi7LZuY5r0Hx0mE%2BxLnre8jp9%2FACoV%2FM92GnsR0%3D&amp;amp;X-Amz-Signature=17046b630ad4dede85af1cd57204bba8adc462a1825a35d93e81b656c683ad75
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this URL in the browser and access the object! Simple.. isn't it?&lt;/p&gt;

&lt;h3&gt;
  
  
  Lets see it in Action
&lt;/h3&gt;

&lt;p&gt;We are going to implement this on top of previous two posts, &lt;a href="https://blog.rajanpanchal.net/aws-kms-use-case-with-serverless-application-model-sam-an-end-to-end-solution-ckdfenqag00lsqqs1csp05vhj" rel="noopener noreferrer"&gt;in the first post&lt;/a&gt;, we implemented custom identity broker(signup/login), using AWS KMS to encrypt decryt password. In &lt;a href="https://blog.rajanpanchal.net/how-to-give-access-to-aws-resources-without-creating-100s-of-iam-users-ckds91qj100pf97s1gc3v8vwb" rel="noopener noreferrer"&gt;second post&lt;/a&gt;, we used AWS STS to AssumeRole to read bucket files names and now we will extend that to use presigned url. Download code for second post from github.com/rajanpanchal/aws-kms-sts and modify it.&lt;br&gt;
Here is how overall process looks like&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2Fpresignedurl_diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2Fpresignedurl_diagram.png" alt="free cloud storage on s3, presigned URL diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open file showFiles.py from the Lamdba folder and lets add function to generate presigned URL. Call this function from &lt;em&gt;getFilesList&lt;/em&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getSignedUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;KeyUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_presigned_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_object&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;filesBucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="n"&gt;ExpiresIn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;KeyUrl&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;KeyUrl&lt;/span&gt;


&lt;span class="c1"&gt;# Returns list of files from bucket using STS    
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getFilesList&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;sts_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Call the assume_role method of the STSConnection object and pass the role
&lt;/span&gt;    &lt;span class="c1"&gt;# ARN and a role session name.
&lt;/span&gt;    &lt;span class="n"&gt;assumed_role_object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sts_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assume_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;RoleArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;RoleSessionName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AssumeRoleSession1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# From the response that contains the assumed role, get the temporary 
&lt;/span&gt;    &lt;span class="c1"&gt;# credentials that can be used to make subsequent API calls
&lt;/span&gt;    &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;assumed_role_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Credentials&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Use the temporary credentials that AssumeRole returns to make a 
&lt;/span&gt;    &lt;span class="c1"&gt;# connection to Amazon S3  
&lt;/span&gt;    &lt;span class="n"&gt;s3_resource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AccessKeyId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SecretAccessKey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;aws_session_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SessionToken&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s3_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AccessKeyId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SecretAccessKey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="n"&gt;aws_session_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SessionToken&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;filesBucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getSignedUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using the temporary credentials obtained from &lt;em&gt;AssumeRole&lt;/em&gt; to generate Presigned URL in &lt;em&gt;getSignedUrl&lt;/em&gt; function. The &lt;em&gt;getFilesList&lt;/em&gt; functions returns list of file names and presigned URL.&lt;/p&gt;

&lt;p&gt;Now, modify showFiles.html, to iterate over response and create links for files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha512-8bHTC73gkZ7rZ7vpqUQThUDhqcNFyYi2xgDgPDHc+GXVGHXq+xPjynxIopALmOPqzo9JZj0k6OqqewdGO3EsrQ=="&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script
  &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.jquery.com/jquery-3.1.1.min.js"&lt;/span&gt;
  &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="&lt;/span&gt;
  &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui raised very text container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;File Access System&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"folder open icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Files&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"files"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading..&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; https://g4m3zpzp95.execute-api.us-east-2.amazonaws.com/Prod/showFiles/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;i class='file alternate outline icon'&amp;gt;&amp;lt;a href='&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;' target='_blank'&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now do SAM build and Deploy.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2FpresignedUrlStack.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2FpresignedUrlStack.PNG" alt="Free cloud storage Presigned URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modify login.html, signup.html and showFiles.html to update the api urls from cloudformation outputs.&lt;br&gt;
Upload these files to the bucket &lt;em&gt;stsexamplebucket&lt;/em&gt; or the bucket you created. Keep these files Public&lt;/p&gt;

&lt;p&gt;You can find the code here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/rajanpanchal/aws-kms-sts-presigned-url" rel="noopener noreferrer"&gt;https://github.com/rajanpanchal/aws-kms-sts-presigned-url&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2FtestingVideo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fblog-images-rajanpanchal.net%2FpresignedUrl%2FtestingVideo.gif" alt="private content serve using Presigned URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know if you have any questions or comments!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>serverless</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to give access to AWS resources without creating 100s of IAM Users?</title>
      <dc:creator>Rajan Panchal</dc:creator>
      <pubDate>Thu, 13 Aug 2020 03:35:15 +0000</pubDate>
      <link>https://forem.com/rajanpanchal/how-to-give-access-to-aws-resources-without-creating-100s-of-iam-users-4b9m</link>
      <guid>https://forem.com/rajanpanchal/how-to-give-access-to-aws-resources-without-creating-100s-of-iam-users-4b9m</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published at &lt;a href="https://www.rajanpanchal.net/aws-sts-example/"&gt;https://www.rajanpanchal.net/aws-sts-example/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario:
&lt;/h3&gt;

&lt;p&gt;Imagine you are a solution architect in a company with 100s of Sales employees and you are migrating from on premise to AWS Cloud. You want to use existing employee authentication system and you want to store files on S3 that employee uses in their day to day work. You don't want to keep S3 bucket public, that will expose all files to everybody. &lt;br&gt;
You have 2 options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create single role with S3 bucket access and login credentials for all of the employees. With this user have to use 2 different logins. One to access their existing system and other to access S3 files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use AWS Security Token Service (STS) to assume role with S3 access and use that to give access to the files. User will still authenticate with their existing system. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post, we will explore and implement option # 2. Please note that we are building this example on top of &lt;a href="https://dev.to/rajanpanchal/aws-kms-use-case-with-serverless-application-model-sam-an-end-to-end-solution-1066"&gt;previous&lt;/a&gt; post.&lt;/p&gt;
&lt;h3&gt;
  
  
  About Security Token Service (STS)
&lt;/h3&gt;

&lt;p&gt;AWS Security Token Service (AWS STS) is a web service that enables you to request temporary, limited-privilege credentials for AWS Identity and Access Management (IAM) users or for users that you authenticate. You can use &lt;strong&gt;AssumeRole&lt;/strong&gt; action on STS that returns a set of temporary security credentials that you can use to access AWS resources that you might not normally have access to. These temporary credentials consist of an access key ID, a secret access key, and a security token. Typically, you use AssumeRole within your account or for cross-account access. In our case, we are using AssumeRole within same account. &lt;/p&gt;
&lt;h3&gt;
  
  
  How to setup users and roles?
&lt;/h3&gt;

&lt;p&gt;In our case, we are going to create a role called &lt;em&gt;S3ReadOnlyAccessAssumeRole&lt;/em&gt;. As name suggests it has only S3 read access policy. We will also create a Trust Policy and attached to this S3 role. Trust policy will allow this role to be assumed by our lambda execution role. Here is how our SAM will look like for this role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;IamS3Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::IAM::Role&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="na"&gt;AssumeRolePolicyDocument&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2012-10-17&lt;/span&gt;
       &lt;span class="na"&gt;Statement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Allow&lt;/span&gt;
            &lt;span class="na"&gt;Principal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;AWS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;ShowFilesFunctionRole.Arn&lt;/span&gt;
            &lt;span class="na"&gt;Action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sts:AssumeRole'&lt;/span&gt;
      &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Readonly&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;S3&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lamdba&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Assume&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;at&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;runtime'&lt;/span&gt;
      &lt;span class="na"&gt;ManagedPolicyArns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess&lt;/span&gt;
      &lt;span class="na"&gt;RoleName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;S3ReadOnlyAccessAssumeRole&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In above snippet, &lt;em&gt;AssumeRolePolicyDocument&lt;/em&gt; attribute specifies trust policy that allow Lamdba execution role identified by principle &lt;strong&gt;AWS: !GetAtt ShowFilesFunctionRole.Arn&lt;/strong&gt; to AssumeRole to which this policy is attached to i.e S3ReadOnlyAccessAssumeRole .  The &lt;em&gt;ManagedPolicyArns&lt;/em&gt; attribute species the policy for &lt;strong&gt;S3ReadOnlyAccessAssumeRole&lt;/strong&gt; that allows read only access to S3 buckets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Handler
&lt;/h3&gt;

&lt;p&gt;Now, lets write our Lamdba handler that will use this role. Here is the SAM confgiuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Origin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://stsexamplebucket.s3.us-east-2.amazonaws.com&lt;/span&gt;
  &lt;span class="na"&gt;FilesBucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;s3-sales-rep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ApiGatewayShowFilesApi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Api&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;StageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prod&lt;/span&gt;
    &lt;span class="na"&gt;Auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;UsagePlan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CreateUsagePlan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PER_API&lt;/span&gt;
      &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Usage plan for this API&lt;/span&gt;
      &lt;span class="na"&gt;Quota&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;Limit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;
       &lt;span class="na"&gt;Period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MONTH&lt;/span&gt;
      &lt;span class="na"&gt;Throttle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;BurstLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
       &lt;span class="na"&gt;RateLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="na"&gt;ShowFilesFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;userTable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;myDynamoDBTable&lt;/span&gt;
          &lt;span class="na"&gt;s3role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;IamS3Role.Arn&lt;/span&gt;
          &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s"&gt;${Origin}&lt;/span&gt;
          &lt;span class="na"&gt;filesBucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s"&gt;${FilesBucket}&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lambda/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;showfiles.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.8&lt;/span&gt;
      &lt;span class="na"&gt;Policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;DynamoDBCrudPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;myDynamoDBTable&lt;/span&gt;      
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;getCounter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/showFiles&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET&lt;/span&gt;
            &lt;span class="na"&gt;RestApiId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ApiGatewayShowFilesApi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are defining here couple of parameters that will be set as environment variables for Lambda. With &lt;strong&gt;Origin&lt;/strong&gt; we specifying the origin domain for &lt;a href="https://www.w3.org/wiki/CORS_Enabled"&gt;CORS&lt;/a&gt;. It is our S3 bucket's &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html"&gt;Virtual hosted style URL&lt;/a&gt;. &lt;strong&gt;FilesBucket&lt;/strong&gt; is the bucket where files are stored. In Serverless Function definition, it uses showfiles.py as lambda handler. Function has permissions to use DB. We also create API for this lamdba with path &lt;em&gt;/showFiles&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Lets see what we do in the Lambda handlers. We modified login.py lambda handler from previous post. We are setting a cookie once the user is authenticated. This is completely optional and really not required for STS to work but you might need some kind of system to identify that user is already authenticated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;decryptedPass&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; 
      &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token_hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'userid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;AttributeUpdates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;'Value'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'headers'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
             &lt;span class="s"&gt;'Set-Cookie'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;'tkn='&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'&amp;amp;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;';Secure;SameSite=None;HttpOnly;Domain=.amazonaws.com;Path=/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'text/html'&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;script&amp;gt;window.location.href = &lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'showFilesUrl'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s"&gt; &amp;lt;/script&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Login Failed'&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When user submits the username and password, Login lambda handler will authenticate the user, store the unique id in DB, set the cookie in response with location to showFiles url html page from S3 bucket. On page load, browser will change the location to showfiles url that will trigger the showFiles Lambda handler defined in showFiles.py&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;showFiles.html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha512-8bHTC73gkZ7rZ7vpqUQThUDhqcNFyYi2xgDgPDHc+GXVGHXq+xPjynxIopALmOPqzo9JZj0k6OqqewdGO3EsrQ=="&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script
  &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.jquery.com/jquery-3.1.1.min.js"&lt;/span&gt;
  &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="&lt;/span&gt;
  &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui raised very text container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;File Access System&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"folder open icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ui label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Files&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"files"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading..&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://9nimlkmz74.execute-api.us-east-2.amazonaws.com/Prod/showFiles/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;i class='file alternate outline icon'&amp;gt;&amp;lt;a href='#'&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We call the showFiles API, that gets the list of Files from S3 bucket and display on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;showFiles.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#retuns login cookie information userid and unique token
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getLoginCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;keyValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;keyValue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="s"&gt;'tkn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;cookieValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keyValue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;tknvalues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cookieValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'&amp;amp;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'uid'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tknvalues&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'tkn'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tknvalues&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;cookieValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="c1"&gt;#verifies unique token that is saved in database vs in request      
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verifyLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;dynamodb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'dynamodb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'userTable'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'userid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'uid'&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="n"&gt;json_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Item'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;resp_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'tkn'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Returns list of files from bucket using STS    
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getFilesList&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;sts_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'sts'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Call the assume_role method of the STSConnection object and pass the role
&lt;/span&gt;    &lt;span class="c1"&gt;# ARN and a role session name.
&lt;/span&gt;    &lt;span class="n"&gt;assumed_role_object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sts_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assume_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;RoleArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'s3role'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;RoleSessionName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"AssumeRoleSession1"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# From the response that contains the assumed role, get the temporary 
&lt;/span&gt;    &lt;span class="c1"&gt;# credentials that can be used to make subsequent API calls
&lt;/span&gt;    &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;assumed_role_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Credentials'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Use the temporary credentials that AssumeRole returns to make a 
&lt;/span&gt;    &lt;span class="c1"&gt;# connection to Amazon S3  
&lt;/span&gt;    &lt;span class="n"&gt;s3_resource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;'s3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'AccessKeyId'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'SecretAccessKey'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;aws_session_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'SessionToken'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'filesBucket'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Cookie'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;";"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getLoginCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;isVerified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;verifyLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isVerified&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getFilesList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'headers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'Access-Control-Allow-Origin'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'origin'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;'Access-Control-Allow-Credentials'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'true'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Focus on the lamdba_handler function here. We first get the cookie and verify the login.  If verified we call the &lt;strong&gt;getFilesList&lt;/strong&gt; function where the magic of STS happens. We get the arn of role to be assumed from Lambda environment variables. The &lt;em&gt;assume_role&lt;/em&gt; function returns the credentials that contains the access key id, secret access key and session token. You can use this credentials to get S3 resources and access the bucket. We create list of files as array and send it as response. &lt;/p&gt;

&lt;p&gt;You can find full SAM template.yml and other code for this here&lt;br&gt;
&lt;a href="https://github.com/rajanpanchal/aws-kms-sts"&gt;https://github.com/rajanpanchal/aws-kms-sts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before you run SAM deploy, create a S3 bucket that will store the html files. In our case, its &lt;strong&gt;stsexamplebucket&lt;/strong&gt;. We use urls from this bucket in our SAM Template. On SAM Deploy, It will generate output with 3 URLS for the APIs. Modify the html files to point to those url and upload to S3 bucket. Make sure you make those files public.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;You need to create a bucket with name specified in &lt;em&gt;FilesBucket&lt;/em&gt; parameter in SAM template. This bucket will store the files for display.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e665dM8G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/kms-sts/testing.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e665dM8G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://s3.amazonaws.com/blog-images-rajanpanchal.net/kms-sts/testing.gif" alt="Testing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In summary, we used a custom identity broker that authenticates the user and then AWS STS that allows access to AWS resources to those users. You might wonder we could have given access to S3 to Lambda Execution role instead of using STS. Of course you can and it will work. But the idea here is to use STS and you can use STS irrespective of Lambda i.e in your other applications like spring boot, java, python application, etc. &lt;br&gt;
In next post, we will further extend this to use S3 signed url to give access to files stored in S3.&lt;/p&gt;

&lt;p&gt;Feel free to point out any suggestions, errors and give your feedback in comments!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>awssts</category>
    </item>
  </channel>
</rss>
