<?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>DEV Community: Chetan Pawar</title>
    <description>The latest articles on DEV Community by Chetan Pawar (@pawarrchetan).</description>
    <link>https://dev.to/pawarrchetan</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%2F434230%2Fb7ce2384-5757-434e-b9a7-0917c8af52d4.jpeg</url>
      <title>DEV Community: Chetan Pawar</title>
      <link>https://dev.to/pawarrchetan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pawarrchetan"/>
    <language>en</language>
    <item>
      <title>Securing APIs with AWS Amplify and Cognito</title>
      <dc:creator>Chetan Pawar</dc:creator>
      <pubDate>Wed, 06 Jan 2021 09:37:36 +0000</pubDate>
      <link>https://dev.to/pawarrchetan/securing-apis-with-aws-amplify-and-cognito-27g2</link>
      <guid>https://dev.to/pawarrchetan/securing-apis-with-aws-amplify-and-cognito-27g2</guid>
      <description>&lt;h1&gt;
  
  
  Securing APIs with AWS Amplify and Cognito
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://epilot.cloud/en/career-engineering/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffnbppwjezekl7t56nfxz.png" alt="We are hiring!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;AWS Amplify is one of the fastest ways to help front-end web and mobile developers build full stack applications, hosted in AWS.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://cloudychetan.medium.com/using-amplify-for-rest-apis-and-web-hosting-f27ad2867908" rel="noopener noreferrer"&gt;first part&lt;/a&gt; of this blog series, &lt;a href="https://cloudychetan.medium.com/using-amplify-for-rest-apis-and-web-hosting-f27ad2867908" rel="noopener noreferrer"&gt;Using Amplify for REST APIs and Web hosting&lt;/a&gt; we built an API using AWS Amplify to quickly setup and host an API with minimal coding.&lt;/p&gt;

&lt;p&gt;In this part we build an authentication system for the API using &lt;a href="https://aws.amazon.com/cognito/" rel="noopener noreferrer"&gt;Amazon Cognito&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Amazon Cognito lets us add user sign-up, sign-in, and access control to our web and mobile apps quickly and easily. It is highly scaleable and supports sign-in with social identity providers, such as Facebook, Google, and Amazon, and enterprise identity providers via SAML 2.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Secure and scalable user directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Standards-based authentication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security for your apps and users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy integration with our App&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to Build ?
&lt;/h2&gt;

&lt;p&gt;In this Blog we quickly build an authentication system for a simple REST API using AWS Amplify CLI.&lt;/p&gt;

&lt;p&gt;We will build&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An authenticated ExpressJS server that returns a random number&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Amplify CLI — Open terminal and run npm install -g @aws-amplify/clito update to the latest Amplify CLI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amplify CLI configured — If you have not configured the Amplify CLI yet, follow &lt;a href="https://docs.amplify.aws/cli/start/install#configure-the-amplify-cli" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; in the documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup a new Amplify project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command to create a new Amplify project called “amplify-rest-containerized” or if you already have an existing Amplify project skip to the next section.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir amplify-rest-containerized
cd amplify-rest-containerized
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize an Amplify project by running:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a quick implementation, we can just accept the default values in the amplify init workflow console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable container based deployments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Container-based deployments need to be explicitly enabled. Run &lt;strong&gt;amplify configure project&lt;/strong&gt; to review your project configuration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify configure project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Accept the defaults and answer &lt;strong&gt;Yes&lt;/strong&gt; when asked if you want to enable container-based deployments:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ...
    ? Do you want to enable container-based deployments? Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add an authenticated container-based ExpressJS API
&lt;/h2&gt;

&lt;p&gt;For the demo, let’s quickly create a REST API. More detailed explanation can be found &lt;a href="https://cloudychetan.medium.com/using-amplify-for-rest-apis-and-web-hosting-f27ad2867908" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create our authenticated container-based REST API, execute:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify add api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Choose the following options:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Please select from one of the below mentioned services: REST
    ? Which service would you like to use API Gateway + AWS Fargate (Container-based)
    ? Provide a friendly name for your resource to be used as a label for this category in the project: container622e561f
    ? What image would you like to use ExpressJS - REST template
    ? When do you want to build &amp;amp; deploy the Fargate task On every "amplify push" (Fully managed container source)
    ? Do you want to restrict API access Yes
    Successfully added auth resource locally.
    Successfully added resource container622e561f locally.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After a successful completion of the CLI workflow, we’ll see these new files added to the project folder structure.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify/backend/api/&amp;lt;your-api-name&amp;gt;
    ├── amplify.state
    ├── containerb5734e35-cloudformation-template.json
    ├── parameters.json
    └── src
        ├── Dockerfile
        ├── DynamoDBActions.js
        ├── buildspec.yml
        ├── index.js
        ├── package-lock.json
        └── package.json

    amplify/backend/auth/&amp;lt;your-api-name&amp;gt;
    ├── cognitod17bb34c-cloudformation-template.yml
    └── parameters.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;src/index.js&lt;/strong&gt; we will find a starter ExpressJS source code to interact with DynamoDB.&lt;br&gt;
Let’s edit that to return a random number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the &lt;strong&gt;index.js&lt;/strong&gt; file with the following code:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const express = require("express");
    const bodyParser = require('body-parser');
    const port = process.env.PORT || 3001;const app = express();
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));// Enable CORS for all methods
    app.use(function (req, res, next) {
        res.header("Access-Control-Allow-Origin", "*")
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        next()
    });app.get("/", async (req, res, next) =&amp;gt; {    try {
            res.contentType("application/json").send({ 
                "randomNumber": Math.floor(Math.random() * 101) 
            })
        } catch (err) {
            next(err);
        }
    });app.listen(port, () =&amp;gt; {
        console.log('Example app listening at [http://localhost:'](http://localhost:') + port);
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now let’s deploy our API:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify push
    ✔ Successfully pulled backend environment dev from the cloud.

    Current Environment: dev

    | Category | Resource name     | Operation | Provider plugin   |
    | -------- | ----------------- | --------- | ----------------- |
    | Auth     | cognitod17bb34c   | Create    | awscloudformation |
    | Api      | container622e561f | Create    | awscloudformation |
    ? Are you sure you want to continue? Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;As we see amplify also deploys authentication related resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s happening under the hood ?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We are deploying an API just like the &lt;a href="https://cloudychetan.medium.com/using-amplify-for-rest-apis-and-web-hosting-f27ad2867908" rel="noopener noreferrer"&gt;first blog&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding authentication related resources like AWS Cognito User Pool, Identity Pool, User Pool Client, Client Role, Authorizer Lambda function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amplify uses a &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html" rel="noopener noreferrer"&gt;Nested CloudFormation Stack&lt;/a&gt; to deploy each component from the App. In this example, it would deploy a network stack, a cognito resources stack and a containerized API stack.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test our containerized and authenticated ExpressJS API
&lt;/h2&gt;

&lt;p&gt;This is where we come to the tricky part.&lt;/p&gt;

&lt;p&gt;There are several ways in which we can interact with AWS Cognito APIs to get the necessary authentication token for getting access to the API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.amplify.aws/lib/auth/getting-started/q/platform/js#create-authentication-service" rel="noopener noreferrer"&gt;&lt;strong&gt;AWS SDK for JavaScript&lt;/strong&gt;&lt;/a&gt; to include components in your code to obtain token using pre-built UI components in React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS CLI&lt;/strong&gt; commands to perform sign-up for a user, confirm the user registration and request for generating a token for authentication.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For quick testing, we would use the &lt;strong&gt;AWS CLI&lt;/strong&gt; generated token for authenticating our request to the API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites to generate Token
&lt;/h3&gt;

&lt;p&gt;You would need the following information before you start the process&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;AppClient-ID&lt;/strong&gt; for the AWS Cognito User Pool — This can be obtained from AWS Console for AWS Cognito or from the CloudFormation Stack Resources Details Tab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;UserPool-ID&lt;/strong&gt; for the AWS Cognito User Pool — This can be obtained from AWS Console for AWS Cognito or from the CloudFormation Stack Resources Details Tab&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to generate the token ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a Sign-up request for the required User
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    aws cognito-idp sign-up --region &amp;lt;region&amp;gt; --client-id &amp;lt;client_id&amp;gt; --username xyz.abc --password xxxx --user-
    attributes Name="email",Value="xyz.abc@efg.com"

    Response :
    {
        "UserConfirmed": false,
        "CodeDeliveryDetails": {
            "Destination": "xxx@xxx.com",
            "DeliveryMedium": "EMAIL",
            "AttributeName": "email"
        },
        "UserSub": "0bf218e6-65ab-4160-8ae9-48bb4e9f22cd"
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Confirm the registration of the User
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    aws cognito-idp admin-confirm-sign-up --region &amp;lt;region&amp;gt; --user-pool-id &amp;lt;user_pool_id&amp;gt; --username xyz.abc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The password set for the new user in Step 1 is temporary and it needs to be changed before generating the authentication request
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    aws cognito-idp initiate-auth \
            --client-id &amp;lt;client_id&amp;gt; \
            --auth-flow USER_PASSWORD_AUTH \
            --auth-parameters "USERNAME=xyz.abc,PASSWORD=xxxxxxxx"

    Response:

    {
        "ChallengeName": 'NEW_PASSWORD_REQUIRED',
        'ClientId' =&amp;gt; '&amp;lt;client_id&amp;gt;',
        'Session' =&amp;gt; &amp;lt;session_token&amp;gt;,
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the &lt;strong&gt;session_token&lt;/strong&gt; from the above response to set the new password
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    aws cognito-idp respond-to-auth-challenge --client-id &amp;lt;client_id&amp;gt; --challenge-name NEW_PASSWORD_REQUIRED --challenge-responses USERNAME=xyz.abc,NEW_PASSWORD="xxxxxxxx" --session "&amp;lt;session_token&amp;gt;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The above request responds with the Tokens generated after successful authentication with AWS Cognito
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    {
        "ChallengeParameters": {},
        "AuthenticationResult": {
            "AccessToken": "xxxxxxxxxxxxxxxxxxx",
            "ExpiresIn": 3600,
            "TokenType": "Bearer",
            "RefreshToken": "xxxxxxxxxxxxxxxxxxx",
            "IdToken": "xxxxxxxxxxxxxxxxxxx"
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally we can use the &lt;strong&gt;AccessToken&lt;/strong&gt; to test our API&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing the API
&lt;/h3&gt;

&lt;p&gt;The best way to demonstrate the authenticated API is from the Postman App using Authentication.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup authentication parameters in Postman App — Enter the AccessToken in the Token section.&lt;/li&gt;
&lt;/ul&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%2Fcdn-images-1.medium.com%2Fmax%2F5128%2F1%2Arpl7-n0RCiZsSCEX27XS8g.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%2Fcdn-images-1.medium.com%2Fmax%2F5128%2F1%2Arpl7-n0RCiZsSCEX27XS8g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute the request to the API&lt;/li&gt;
&lt;/ul&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%2Fcdn-images-1.medium.com%2Fmax%2F5128%2F1%2AmnzHgZY_oD7UPvQsAaQmbA.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%2Fcdn-images-1.medium.com%2Fmax%2F5128%2F1%2AmnzHgZY_oD7UPvQsAaQmbA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API endpoint is printed at the end of the “&lt;strong&gt;amplify push&lt;/strong&gt;” command or when you execute “&lt;strong&gt;amplify status&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a simple use case just to showcase the workflow. &lt;br&gt;
We used the AWS CLI to quickly demonstrate the authentication flow. However, actual authentication for your app should be done seamlessly using the appropriate AWS SDK for your code.&lt;br&gt;
Review Amplify documentation if you’re interested in any other scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did we learn ?
&lt;/h2&gt;

&lt;p&gt;This blog post gives a quick way to deploy an authenticated API using Amplify CLI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Quickly setup and authenticated API using AWS Amplify&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to authenticate the requests to the authenticated API using AWS CLI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is so much more to explore.&lt;/p&gt;

&lt;p&gt;Keep building…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://epilot.cloud/en/career-engineering/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffnbppwjezekl7t56nfxz.png" alt="We are hiring!"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>restapi</category>
      <category>amplify</category>
      <category>cognito</category>
      <category>aws</category>
    </item>
    <item>
      <title>Using Amplify for REST APIs and Web hosting</title>
      <dc:creator>Chetan Pawar</dc:creator>
      <pubDate>Mon, 21 Dec 2020 13:55:20 +0000</pubDate>
      <link>https://dev.to/epilot/using-amplify-for-rest-apis-and-web-hosting-32fa</link>
      <guid>https://dev.to/epilot/using-amplify-for-rest-apis-and-web-hosting-32fa</guid>
      <description>&lt;p&gt;&lt;a href="https://epilot.cloud/en/career-engineering/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffnbppwjezekl7t56nfxz.png" alt="We are hiring!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;AWS Amplify is one of the fastest ways that can be used to help front-end web and mobile developers build full stack applications, hosted in AWS. &lt;br&gt;
With Amplify, we can configure app backends and connect our app in minutes, deploy static web apps in a few clicks, and easily manage app content outside the AWS console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Portability of backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Out of the box infrastructure setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum efforts for deployment pipeline&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to Build ?
&lt;/h2&gt;

&lt;p&gt;In this Blog we quickly build a REST API using AWS Amplify CLI.&lt;/p&gt;

&lt;p&gt;We will build&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An ExpressJS server that returns a random number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An ExpressJS server that runs a &lt;a href="https://en.wikipedia.org/wiki/Fizz_buzz" rel="noopener noreferrer"&gt;FizzBuzz&lt;/a&gt; algorithm on a Python/Flash random number generator server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Amplify CLI — Open terminal and run npm install -g @aws-amplify/cli to update to the latest Amplify CLI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amplify CLI configured — If you have not configured the Amplify CLI yet, follow &lt;a href="https://docs.amplify.aws/cli/start/install#configure-the-amplify-cli" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; in the documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup a new Amplify project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command to create a new Amplify project called &lt;code&gt;amplify-rest-containerized&lt;/code&gt; or if you already have an existing Amplify project skip to the next section.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir amplify-rest-containerized
cd amplify-rest-containerized
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize an Amplify project by running:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a quick implementation, we can just accept the default values in the amplify init workflow console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable container based deployments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Container-based deployments need to be explicitly enabled. Run amplify configure project to review your project configuration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify configure project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Accept the defaults and answer Yes when asked if you want to enable container-based deployments:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
? Do you want to enable container-based deployments? Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add a new container-based ExpressJS API
&lt;/h2&gt;

&lt;p&gt;Amplify CLI has the same distribution as any existing API workflow. &lt;br&gt;
Once container-based deployments are enabled, we have the ability to select “REST” → “API Gateway + AWS Fargate (Container-based)” with the amplify add api command.&lt;/p&gt;

&lt;p&gt;Amplify CLI supports both &lt;strong&gt;GraphQL&lt;/strong&gt; and &lt;strong&gt;REST API&lt;/strong&gt; options for container based deployments. &lt;br&gt;
We can use container-based deployments alongside existing &lt;strong&gt;AppSync and API Gateway + Lambda&lt;/strong&gt; options. &lt;br&gt;
For the demo, let’s create a REST API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create our first container-based REST API, execute:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;amplify add api&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose the following options:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ? Please select from one of the below mentioned services:
    &amp;gt; REST
    ? Which service would you like to use
    &amp;gt; API Gateway + AWS Fargate (Container-based)
    ? Provide a friendly name for your resource to be used as a label for this category in the project:
    &amp;gt; containerb5734e35
    ? What image would you like to use
    &amp;gt; ExpressJS - REST template
    ? When do you want to build &amp;amp; deploy the Fargate task
    &amp;gt; On every "amplify push" (Fully managed container source)
    ? Do you want to restrict API access
    &amp;gt; No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After a successful completion of the CLI workflow, we’ll see these new files added to the project folder structure.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify/backend/api/&amp;lt;your-api-name&amp;gt;
    ├── amplify.state
    ├── containerb5734e35-cloudformation-template.json
    ├── parameters.json
    └── src
        ├── Dockerfile
        ├── DynamoDBActions.js
        ├── buildspec.yml
        ├── index.js
        ├── package-lock.json
        └── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the &lt;code&gt;src/index.js&lt;/code&gt; we will find a starter ExpressJS source code to interact with DynamoDB. &lt;br&gt;
Let’s edit that to return a random number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the &lt;code&gt;index.js&lt;/code&gt; file with the following code:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const express = require("express");
    const bodyParser = require('body-parser');
    const port = process.env.PORT || 3001;

    const app = express();
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    // Enable CORS for all methods
    app.use(function (req, res, next) {
        res.header("Access-Control-Allow-Origin", "*")
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        next()
    });

    app.get("/", async (req, res, next) =&amp;gt; {

        try {
            res.contentType("application/json").send({ 
                "randomNumber": Math.floor(Math.random() * 101) 
            })
        } catch (err) {
            next(err);
        }
    });

    app.listen(port, () =&amp;gt; {
        console.log('Example app listening at http://localhost:' + port);
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now let’s deploy our API:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s happening under the hood ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Amplify creates APIs as an ECS Service to ensure that your application is monitored and tasks are in a healthy and active state, automatically recovering if an instance fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you make changes to your source code, the build and deployment pipeline will take your source code as inputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One or more containers will be built in AWS CodeBuild using your source code and pushed to ECR with a build hash as a tag, allowing you to roll back deployments if something unexpected happens in your application code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the build is complete, the pipeline will perform a rolling deployment to launch AWS Fargate Tasks automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only when all new versions of the image are in a healthy &amp;amp; running state will the old tasks be stopped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally the build artefacts in S3 (in the fully managed scenario) and ECR images are set with a lifecycle policy retention of 7 days for cost optimization.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test our new containerized ExpressJS API
&lt;/h2&gt;

&lt;p&gt;The best way to demonstrate the containerized API is just by calling it with Postman App.&lt;/p&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%2Fcdn-images-1.medium.com%2Fmax%2F5116%2F1%2Aiv2eTJei-sFMJ7-CFnlspA.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%2Fcdn-images-1.medium.com%2Fmax%2F5116%2F1%2Aiv2eTJei-sFMJ7-CFnlspA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API endpoint is printed at the end of the “amplify push” command or when you run “amplify status”.&lt;/p&gt;

&lt;p&gt;Deployments for Containers can take a bit longer to build and deploy, but after a few minutes, you can verify the availability by checking the CodePipeline URL printed at the beginning of your “amplify push” command or run “amplify console api”, select the API, and select “CodePipeline”&lt;/p&gt;

&lt;p&gt;Note: This is a simple use case just to showcase the workflow. The ExpressJS template also provides out-of-the-box support to create a CRUD interface for a DynamoDB table. &lt;br&gt;
Review Amplify documentation if you’re interested in any other scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-container deployments
&lt;/h2&gt;

&lt;p&gt;Amplify CLI fully relies on a Docker Compose configuration to enable multi-container deployments. &lt;br&gt;
Amplify automatically infers the Fargate and ECS settings based on our app’s &lt;code&gt;Dockerfile&lt;/code&gt; or Docker Compose. &lt;br&gt;
Amplify also allows us to have inter-container networking based on the configured ports in your Docker Compose configuration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To demonstrate that, let’s run amplify add api and &lt;br&gt;
select “REST” → “API Gateway + AWS Fargate (Container-based)” → “Docker Compose — ExpressJS + Flask template” value to add a new multi-container API. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This will create a following folder structure in your amplify/backend/api// folder.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    amplify/backend/api/&amp;lt;your-api-name&amp;gt;/
    ├── amplify.state
    ├── &amp;lt;your-api-name&amp;gt;-cloudformation-template.json
    ├── parameters.json
    └── src
        ├── buildspec.yml
        ├── docker-compose.yml
        ├── express
        │   ├── Dockerfile
        │   ├── DynamoDBActions.js
        │   ├── index.js
        │   └── package.json
        └── python
            ├── Dockerfile
            ├── requirements.txt
            └── src
                └── server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The top level &lt;code&gt;docker-compose.yml&lt;/code&gt; references the express server and the python server. &lt;br&gt;
Docker Compose provides a mechanism to deploy multiple containers at once. &lt;br&gt;
For more information on Docker Compose, please review the official Docker Compose guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This time we’ll have the Python server return a random number and the ExpressJS runs a &lt;a href="https://en.wikipedia.org/wiki/Fizz_buzz" rel="noopener noreferrer"&gt;FizzBuzz&lt;/a&gt; algorithm based on the Python server’s random number. Let’s replace our &lt;code&gt;server.py&lt;/code&gt; file with the following content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    from flask import Flask
    from random import randrange

    server = Flask(__name__)

    @server.route('/random')
    def hello():
        return str(randrange(150))

    if __name__ == "__main__":
       server.run(host='0.0.0.0')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We created a Flask server that has a /random route which returns a random number between 0 and 150.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we edit the express server to interface with the Python server and then run the FizzBuzz algorithm. &lt;br&gt;
Start by replacing the content of the &lt;code&gt;index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const express = require("express");
    const bodyParser = require('body-parser');
    const http = require('http');
    const port = process.env.PORT || 3000;

    const app = express();
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    // Enable CORS for all methods
    app.use(function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*")
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
      next()
    });

    app.get("/fizzbuzz", (req, res, next) =&amp;gt; {
        // add networking code to Python server code here
    });

    app.listen(port, () =&amp;gt; {
      console.log('Example app listening at http://localhost:' + port);
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Then add the networking logic to interface with the Python server. &lt;br&gt;
If we test locally with the Docker CLI, reference the Python server by the Docker Compose container name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple containers are deployed as a single unit in Fargate (e.g. same Task Definition). This opinionated deployment allows ease of networking between containers on the local loopback interface and avoids extra configuration, costs, operations, and debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following code right below the comment: “// add networking code to Python server code here”&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const options = {
        port: 5000,
        host: 'localhost', // replace with 'python' for local development
        method: 'GET',
        path: '/random'
      };

      http.get(options, data =&amp;gt; {
        var body = '';
        data.on('data', (chunk) =&amp;gt; {
          body += chunk;
        });
        data.on('end', () =&amp;gt;{
          console.log(body);
          const randomNumber = body
          let fizzOrBuzz = ''
          // Add FizzBuzz logic code here

          try {
            res.contentType("application/json").send({
             "newRandomNumber": body,
             "fizzOrBuzz": fizzOrBuzz
            });
          } catch (err){
            console.log(err);
            next(err);
          }
        }).on('error', (error) =&amp;gt; {
          console.log(error);
        });
      })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Last but not least, add the FizzBuzz algorithm and return the result to the API caller. Add this FizzBuzz algorithm below “//Add FizzBuzz logic here”
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    if (randomNumber % 15 === 0) {
            fizzOrBuzz = 'FizzBuzz'
          }
          else if (randomNumber % 3 === 0) {
            fizzOrBuzz = 'Fizz'
          }
          else if (randomNumber % 5 === 0) {
            fizzOrBuzz = 'Buzz'
          }
          else {
            fizzOrBuzz = randomNumber
          }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We’ve got our business logic completed! Let’s deploy our multi-container API by running the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test our new multi-container ExpressJS API
&lt;/h2&gt;

&lt;p&gt;The best way to demonstrate the multi-container API is just by calling it with Postman App.&lt;/p&gt;

&lt;p&gt;The API endpoint is printed at the end of the “amplify push” command or when you run amplify status&lt;br&gt;
You should now be able to see the random number and FizzBuzz result returned:&lt;/p&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%2Fcdn-images-1.medium.com%2Fmax%2F5116%2F1%2AaZWH2cXxTcaDazEI074vYA.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%2Fcdn-images-1.medium.com%2Fmax%2F5116%2F1%2AaZWH2cXxTcaDazEI074vYA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What did we learn ?
&lt;/h2&gt;

&lt;p&gt;This blog post gives a quick way to deploy single and multiple containers using Amplify CLI. &lt;br&gt;
There is much more to explore serverless containers which includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure an API using Amazon Cognito&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://epilot.cloud/en/career-engineering/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffnbppwjezekl7t56nfxz.png" alt="We are hiring!"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amplify</category>
      <category>api</category>
      <category>fargate</category>
    </item>
  </channel>
</rss>
