<?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: Sandro Volpic</title>
    <description>The latest articles on DEV Community by Sandro Volpic (@sandro_vol).</description>
    <link>https://dev.to/sandro_vol</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%2F653206%2F579f67df-2fec-4423-ae79-8b84dde56a1f.jpg</url>
      <title>DEV Community: Sandro Volpic</title>
      <link>https://dev.to/sandro_vol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sandro_vol"/>
    <language>en</language>
    <item>
      <title>How to add custom resources to AWS Amplify. Add an SQS queue that triggers lambda.</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Thu, 04 Nov 2021 15:33:41 +0000</pubDate>
      <link>https://dev.to/sandro_vol/how-to-add-custom-resources-to-aws-amplify-add-an-sqs-queue-that-triggers-lambda-546d</link>
      <guid>https://dev.to/sandro_vol/how-to-add-custom-resources-to-aws-amplify-add-an-sqs-queue-that-triggers-lambda-546d</guid>
      <description>&lt;p&gt;AWS Amplify is allowing you to build cloud-connected apps very easily. It has a broad range of categories it supports natively which you can use to build (see my  &lt;a href="https://sandro.volpee.de/what-can-you-build-with-aws-amplify-lets-see-all-categories-and-services" rel="noopener noreferrer"&gt;post&lt;/a&gt;  here). But there are still some major components missing, such as SQS and RDS. In this post, I want to show you how to add AWS services that are not currently supported in Amplify. We start with the general steps you need to take for adding these resources. In the second part, I show you how to add an SQS queue that triggers a lambda. &lt;/p&gt;

&lt;p&gt;There are many ways of doing this but I think the easiest is to use CloudFormation. It is also possible to use frameworks like CDK or Terraform but CloudFormation is best integrated into Amplify. All deployments and updates will still happen from the Amplify CLI and no other tool is needed. All code is in this &lt;a href="https://github.com/AlessandroVol23/amplify-custom-sqs" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add custom resources in general
&lt;/h2&gt;

&lt;p&gt;Amplify has a docs page &lt;a href="https://docs.amplify.aws/cli/usage/customcf/" rel="noopener noreferrer"&gt;here&lt;/a&gt; on how to add custom AWS resources. We need to do basically two steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Add custom resource in backend config&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the first step, you need to add a custom category name and custom resource name within your backend config &lt;code&gt;amplify/backend/backend-config.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"&amp;lt;custom-category-name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"&amp;lt;custom-resource-name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;custom-aws-service-name&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"providerPlugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awscloudformation"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could look like that. Remember that Amplify always uses the category name as a prefix. Think about that when using the names to not have the same category all over the resource names.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Add custom folders &amp;amp; CloudFormation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After that, you need to add the folders you referenced your category and resource names to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;amplify&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;\backend&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;\&amp;lt;custom-category-name&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;\&amp;lt;custom-resource-name&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;parameters_&amp;lt;custom-resource-name&amp;gt;.json&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;template_&amp;lt;custom-resource-name&amp;gt;.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;template_&amp;lt;custom-resource-name&amp;gt;.json&lt;/code&gt;: CloudFormation Templat&lt;br&gt;
&lt;code&gt;parameters_&amp;lt;custom-resource-name&amp;gt;.json&lt;/code&gt;: Additional parameters for CloudFormation&lt;/p&gt;

&lt;p&gt;You need both the parameters and the template files. Create them directly with the suffix &lt;code&gt;custom-resource-name&lt;/code&gt; to avoid any name clashes in the future. &lt;br&gt;
Now you would need to add your CloudFormation code in the template file. We'll see that in a second.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Reference existing parameters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The good thing here now is that you can reference output parameters of other CloudFormation categories. For example if you need the lambda ARN which was added by Amplify you can reference it in a &lt;code&gt;dependsOn&lt;/code&gt; block in the &lt;code&gt;backend-config.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"&amp;lt;custom-category-name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"&amp;lt;custom-resource-name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;custom-aws-service-name&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"providerPlugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awscloudformation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dependsOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"resourceName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lambda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`amplify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;status`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;resource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="s2"&gt;"arn"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;resource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specific&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cloudformation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;available&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Input parameters need to be defined in the created &lt;code&gt;template_&amp;lt;custom-resource-name&amp;gt;.json&lt;/code&gt; file. The format is &lt;code&gt;&amp;lt;category&amp;gt;&amp;lt;resource-name&amp;gt;&amp;lt;attribute-name&lt;/code&gt; .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"Parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"functionlambdaarn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step for referencing is to get the value into CloudFormation as well. For that you need to add an &lt;code&gt;Fn:GetAtt&lt;/code&gt; to your attribute name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"functionlambdaarn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Fn::GetAtt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"functionlambda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="s2"&gt;"Outputs.ARN"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you need to check out your environment again and push it to the cloud with &lt;code&gt;amplify env checkout &amp;lt;ENV&amp;gt;&lt;/code&gt; and &lt;code&gt;amplify push&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;So that is the theory and seems a lot first. Let's add an SQS queue and see how it works in reality. &lt;/p&gt;

&lt;h2&gt;
  
  
  Add a custom SQS queue
&lt;/h2&gt;

&lt;p&gt;We want an SQS queue that has access to a lambda function. At this point we don't care about what triggers the queue and which messages it will send, we simply want to create it.&lt;/p&gt;

&lt;p&gt;In this setup we have an active Amplify application and have created one lambda function named &lt;code&gt;service&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend Config
&lt;/h3&gt;

&lt;p&gt;First of all, we add a custom SQS resource. I am in root of my project and show you the following steps you need to do to create the queue. We start by editing the &lt;code&gt;amplify/backend/backend-config.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"providerPlugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awscloudformation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lambda"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"queue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SQS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"providerPlugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awscloudformation"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added the &lt;code&gt;queue&lt;/code&gt; parameter. Several things are defined here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;queue&lt;/code&gt;: That is the new category name. In lambda, it is &lt;code&gt;function&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;standardQueue&lt;/code&gt;: That is the resource name. That is how you name your queue. In lambda, this is &lt;code&gt;service&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;service&lt;/code&gt;: This is the custom AWS service we want to use. In this case, it is &lt;code&gt;SQS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;providerPlugin&lt;/code&gt;: That is the provider we use for provisioning the resources. In our case and mostly with Amplify this is CloudFormation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CloudFormation
&lt;/h3&gt;

&lt;p&gt;Now we need to add the folders we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; amplify/backend/queue/users
&lt;span class="nb"&gt;touch &lt;/span&gt;amplify/backend/queue/users/parameters_users.json
&lt;span class="nb"&gt;touch &lt;/span&gt;amplify/backend/queue/users/template_users.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's first fill the &lt;code&gt;template_users.json&lt;/code&gt;. We need to add the CloudFormation code here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AWSTemplateFormatVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2010-09-09"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Queue resource stack creation using Amplify CLI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Conditions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ShouldNotCreateEnvResources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Equals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"env"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"NONE"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SQS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::SQS::Queue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"QueueName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Fn::If"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"ShouldNotCreateEnvResources"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                                        &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"env"&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Outputs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SQS"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Arn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Fn::GetAtt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"SQS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"Arn"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::Region"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, we can push the SQS queue to the cloud and create it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;amplify &lt;span class="nb"&gt;env &lt;/span&gt;checkout &amp;lt;ENV&amp;gt; &lt;span class="c"&gt;# e.g. dev&lt;/span&gt;
amplify push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of &lt;code&gt;amplify push&lt;/code&gt; should now be:&lt;br&gt;
&lt;/p&gt;

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

    Current Environment: dev

┌──────────┬───────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin   │
├──────────┼───────────────┼───────────┼───────────────────┤
│ Queue    │ &lt;span class="nb"&gt;users&lt;/span&gt;         │ Create    │ awscloudformation │
├──────────┼───────────────┼───────────┼───────────────────┤
│ Function │ service       │ No Change │ awscloudformation │
└──────────┴───────────────┴───────────┴───────────────────┘
? Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;? &lt;span class="o"&gt;(&lt;/span&gt;Y/n&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's hit &lt;code&gt;Y&lt;/code&gt; and deploy our SQS queue. &lt;/p&gt;

&lt;p&gt;Let's check the CloudFormation template. Go to your Amplify console → find your environment and click on &lt;strong&gt;View in CloudFormation&lt;/strong&gt;. &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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403093511%2FNPA2qZQNQU.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403093511%2FNPA2qZQNQU.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at one of the nested stacks you will see that your SQS queue was created:&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403111866%2Fy5vyQLR3I.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403111866%2Fy5vyQLR3I.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now open  &lt;a href="https://eu-central-1.console.aws.amazon.com/sqs/v2/" rel="noopener noreferrer"&gt;SQS&lt;/a&gt;  and you see your queue being ready to process some messages. &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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403119996%2Fual2Nd06d.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403119996%2Fual2Nd06d.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Consumer
&lt;/h3&gt;

&lt;p&gt;Now we want to connect our SQS queue with our lambda function. To accomplish that we need to connect the lambda with our SQS queue and then define that queue as the trigger for the lambda. We already added the URL and ARN of our SQS queue in the &lt;code&gt;outputs&lt;/code&gt; section of the CloudFormation template. That means that the CloudFormation template will output these two parameters after it is finished and other resources have access to these parameters. Let's now use this as an input for lambda. For that, we need to edit the &lt;code&gt;amplify/backend/backend-config.json&lt;/code&gt; file again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"providerPlugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awscloudformation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lambda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dependsOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"resourceName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Arn"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We change the function part of the file so, that we are depending on the category &lt;code&gt;queue&lt;/code&gt; with our exact name &lt;code&gt;users&lt;/code&gt; and the attributes we want to pass. &lt;/p&gt;

&lt;p&gt;Now we just need to update the CloudFormation template of lambda to receive and handle these params. &lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;amplify/backend/function/service/service-cloudformation-template.json&lt;/code&gt; and edit the following things: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You need to add your queue name and queue ARN as an input parameter in  the section &lt;code&gt;Parameters&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You define the name of the SQS queue as an environment variable in the section &lt;code&gt;Resources/LambdaFunction/Environment/Variables&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWSTemplateFormatVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2010-09-09"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lambda Function resource stack creation using Amplify CLI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;THIS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ADDED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;CATEGORY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;RESOURCE&amp;gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(without&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;space)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"queueusersName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersName"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;THIS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ADDED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;CATEGORY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;RESOURCE&amp;gt;Arn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(without&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;space)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"queueusersArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersArn"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"LambdaFunction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::Lambda::Function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"aws:asset:path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"aws:asset:property"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Code"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nl"&gt;"Environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Variables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;THIS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ADDED:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Same&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;above&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"SQS_QUEUE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersName"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"ENV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"env"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"REGION"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::Region"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Fn::GetAtt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"LambdaExecutionRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"Arn"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Runtime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodejs14.x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Layers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After checking out the environment and pushing again with &lt;code&gt;amplify env checkout dev &amp;amp;&amp;amp; amplify push -y&lt;/code&gt; you see that the URL was added as an environment variable in lambda.&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403173736%2FNmjH4hxGF.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403173736%2FNmjH4hxGF.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SQS as input trigger
&lt;/h3&gt;

&lt;p&gt;Finally, let's call the lambda from the SQS queue. The connection of the environment variable should show how to pass arguments. Don't send a message from the SQS queue &lt;strong&gt;and&lt;/strong&gt; call the lambda from the SQS queue because this ends up in a loop. &lt;/p&gt;

&lt;p&gt;To add the queue as an input trigger we need to edit the CloudFormation template again. We will add the following things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;LambdaFunctionEventSourceMapping&lt;/code&gt; and add the SQS URL here&lt;/li&gt;
&lt;li&gt;Add an IAM policy statement to give it access to the resource&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See the full file  &lt;a href="https://github.com/AlessandroVol23/amplify-custom-sqs/blob/main/amplify/backend/function/service/service-cloudformation-template.json" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"LambdaFunctionEventSourceMapping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"DependsOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"lambdaexecutionpolicy"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::Lambda::EventSourceMapping"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"EventSourceArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersArn"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"FunctionName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LambdaFunction"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;THIS&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lambdaexecutionpolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"DependsOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"LambdaExecutionRole"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::IAM::Policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"PolicyName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lambda-execution-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LambdaExecutionRole"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"PolicyDocument"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;THIS&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:ReceiveMessage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:DeleteMessage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:GetQueueAttributes"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersArn"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;Let's push again &lt;code&gt;amplify env checkout dev &amp;amp;&amp;amp; amplify push -y&lt;/code&gt; and see that our lambda function now has SQS as a trigger&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403249049%2FFo-sjwVIJ.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403249049%2FFo-sjwVIJ.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally just change the resource in the IAM policy of the CloudFormation template to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:ReceiveMessage"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:DeleteMessage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sqs:GetQueueAttributes"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"queueusersArn"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, we follow the least privileged principle and don't give lambda access to all resources. This wasn't possible before because Amplify wouldn't recognize it. &lt;/p&gt;

&lt;p&gt;Now we see that the IAM policy is restricted on this one resource.&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403262365%2Fkht9wuNpU.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635403262365%2Fkht9wuNpU.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can go to SQS, send a message and see that the lambda was executed successfully. &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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635427139700%2FUxam9vkUO.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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1635427139700%2FUxam9vkUO.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The video shows it as well but can't be embedded right now 🤷🏽‍♂️&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/pRs3M7m0JX8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;That's it. It seems a bit much at the beginning but with CloudFormation and Amplify you are very flexible in how to add and connect different resources. &lt;/p&gt;

&lt;p&gt;Here is a short summary of the steps needed to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom resource in backend config&lt;/li&gt;
&lt;li&gt;Folders &amp;amp; CloudFormation for custom resource&lt;/li&gt;
&lt;li&gt;Pass parameter from SQS to lambda from backend config&lt;/li&gt;
&lt;li&gt;Adjust CloudFormation template in lambda to use the parameter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to know more about serverless, AWS, and building SaaS products on the cloud follow my &lt;a href="https://twitter.com/sandro_vol" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; 🙂&lt;/p&gt;

&lt;p&gt;References: &lt;a href="https://medium.com/@navvabian/how-to-add-an-sqs-queue-to-your-amplify-cli-bootstrapped-project-cb7781c636ed" rel="noopener noreferrer"&gt;https://medium.com/@navvabian/how-to-add-an-sqs-queue-to-your-amplify-cli-bootstrapped-project-cb7781c636ed&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>What can you build with AWS Amplify? Let's see all categories and services.</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Fri, 22 Oct 2021 05:44:00 +0000</pubDate>
      <link>https://dev.to/sandro_vol/what-can-you-build-with-aws-amplify-lets-see-all-categories-and-services-2f8h</link>
      <guid>https://dev.to/sandro_vol/what-can-you-build-with-aws-amplify-lets-see-all-categories-and-services-2f8h</guid>
      <description>&lt;h1&gt;
  
  
  What can you build with AWS Amplify? Let's see all categories and services.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Build serverless Apps with Amplify!
&lt;/h2&gt;

&lt;p&gt;AWS Amplify is a lot. In my &lt;a href="https://sandro.volpee.de/what-is-aws-amplify-it-is-a-lot"&gt;last post&lt;/a&gt; I already explained the different products Amplify refers to. In this blog post, I want to show which &lt;strong&gt;categories&lt;/strong&gt; and &lt;strong&gt;services&lt;/strong&gt; can be used by the &lt;strong&gt;Amplify CLI&lt;/strong&gt; and &lt;strong&gt;Amplify Libraries&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;As a short reminder, the CLI is here to bootstrap infrastructure based on a data schema and a CLI wizard. The libraries give us access to AWS components in different languages, mainly JavaScript. &lt;/p&gt;

&lt;p&gt;I will go through all available categories, show a short example use-case and the involved AWS services. &lt;/p&gt;

&lt;p&gt;You can see all available categories on the main page of the &lt;a href="https://docs.amplify.aws"&gt;Amplify Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c4yOZ4dS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634643323514/UNbgTybLL.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c4yOZ4dS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634643323514/UNbgTybLL.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS Services:&lt;/strong&gt; Cognito &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Authentication refers to all functionality regarding user registration, Sign-In, Social Sign-In, and restricting access to certain users or user groups. Example use cases here are all basic authentication procedures in your app. Social Sign-In via Facebook, Apple, Google, &amp;amp; Amazon is supported natively. All typical workflows like password forget, multi-factor authentication, and much more are supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; User Sign-In, Sign-Up with social providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; Lambda&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The category function is missing in the overview but I think it is one of the most important ones. Function handles everything regarding creating lambda functions. Especially, the handling of requirements, providing access to other AWS resources, and using lambda layers are really great within Amplify. Runtimes available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;.NET&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the latest news is that you also can use environment variables and secret parameters within Amplify and everything will be provisioned automatically. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Periodically update your database with new data, for example run a lambda daily at 12pm. &lt;/p&gt;

&lt;h2&gt;
  
  
  Storage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; DynamoDB, S3&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Storage refers to all functions regarding persisting data. This could either be object storage such as S3 or a NoSQL database like DynamoDB. A relational database is not supported (yet) in Amplify. The storage component makes it really easy to persist and access your data. Especially, when using DynamoDB, Amplify CLI, and GraphQL it is fairly easy to connect several tables and build a complex and high-performing data model. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Uploading and downloading images from your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; AppSync&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The category GraphQL API refers to the AWS service AppSync. AppSync is a fully-managed GraphQL API and it has some real benefits. First of all, it is fully managed. That means you don't have to handle any scalability or infrastructure issues. Secondly, you get a lot of things built in. For example, real-time subscriptions are automatically included in AppSync. You can build several authorization methods for your API like API keys, IAM users, or even a lambda authorizer. AppSync also allows an offline mode in combination with Amplify's DataStore to enable offline capabilities. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt;All API-related backends can be built with AppSync. Live updates on a news feed or stock price. &lt;/p&gt;

&lt;h2&gt;
  
  
  DataStore
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; AppSync, DynamoDB&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The DataStore category gives you the ability to persist data online and offline on your device. Under the hood, the services AppSync and DynamoDB are used for synchronizing the content. It is also possible to use it completely offline without any AWS account. As a query language also GraphQL is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Mobile social media app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Geo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; Amazon Location Service&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Geo is one of the newer services of AWS. It provides interfaces to the newly introduced Amazon Location Service. With this service, it is easily possible to build map and location web applications. UI components from maplibre can be used to combine AWS location service with the maplibre UI. You can do several things with the Geo service such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displaying maps&lt;/li&gt;
&lt;li&gt;Put markers on the map&lt;/li&gt;
&lt;li&gt;Draw points on the map&lt;/li&gt;
&lt;li&gt;Search for certain locations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Map enabled web applications. &lt;/p&gt;

&lt;h2&gt;
  
  
  REST API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; API Gateway&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; In the same way you can use a managed GraphQL API (AppSync) you can also use a fully managed REST API → API Gateway. With API gateway you can create several endpoints with the same authorization methods and use input and output templates for your data flow. Often times you will use lambdas as a resolver for resolving the given endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Any application which needs an API 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Analytics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; PinPoint, Kinesis&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Analytics gives us the opportunity to get insights into our user behavior. AWS PinPoint and Kinesis are used for this purpose. With Analytics you can track sessions of your user and also create custom events that should be tracked. Analytics data can also be streamed directly to kinesis for further analysis. PinPoint in general even allows more functions, for example sending out newsletters and creating different campaigns is also possible. Within Amplify the main functionality is analyzing user behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Analyse how users are using your app. &lt;/p&gt;

&lt;h2&gt;
  
  
  Push Notifications
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; PinPoint&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Push notifications handles everything related to notifying your users. Some things have to be configured to get it running on iOS and Android. Push notifications are currently just supported for React-Native projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Notify your mobile users when receiving new messages on a social media app.&lt;/p&gt;

&lt;h2&gt;
  
  
  XR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; Amazon Sumerian&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; XR allows you to build Augmented Reality and Virtual Reality applications. It supports one of the lesser-known AWS Services → Amazon Sumerian. With Sumerian, you are able to build 3D scenes and display them via your Amplify App.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; AR application for supporting car mechanics&lt;/p&gt;

&lt;h2&gt;
  
  
  PubSub
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; AWS IoT&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; With the PubSub category you are able to build messaging-oriented applications which can publish and subscribe data for a certain middleware. AWS IoT is the preferred and supported middleware in this category. Other middlewares such as MQTT or WebSockets are also possible. Basically, you can subscribe and publish data to a message broker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Weather station with many sensors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; Amazon Lex,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Interactions gives you the possibility to build interactive chatbots with the Amazon Lex service. I already made a &lt;a href="https://sandro.volpee.de/how-to-develop-a-serverless-chatbot-with-aws-amplify-amazon-lex-and-react"&gt;post&lt;/a&gt; about that. Lex is the service that is also used by Amazon Alexa, so it is battle-proven. The great thing is that Amplify is also offering a UI component for the Chatbot interface which makes it really easy to set up a complex chatbot within minutes for yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Customer service chatbot.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI / ML Predictions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS-Services:&lt;/strong&gt; Polly, Translate, Transcribe, Rekognition, Comprehend&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The AI and ML Prediction category offers several things. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text to speech: Polly&lt;/li&gt;
&lt;li&gt;Transcribe audio or text: Transcribe&lt;/li&gt;
&lt;li&gt;Translate languages: Translate&lt;/li&gt;
&lt;li&gt;Identify Text: Rekognition&lt;/li&gt;
&lt;li&gt;Identify entities: Rekognition&lt;/li&gt;
&lt;li&gt;Label objects: Rekognition&lt;/li&gt;
&lt;li&gt;Interpret sentiment: Comprehend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The great thing about this category and the different services is that you do not need any data science knowledge for building applications that use a lot of machine learning models. You can just use these services to give in proper input and get the results immediately. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use-Case:&lt;/strong&gt; Scan documents, identify the texts, and transcribe them to text. &lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;These were all categories AWS Amplify supports. You can build &lt;strong&gt;so much stuff&lt;/strong&gt; with these categories. If some categories are not supported (e.g. SQS → Please Amplify 🙏🏼) you can simply add them by adding CloudFormation templates or looking for community-made plugins. &lt;/p&gt;

&lt;p&gt;I've used Amplify already for a couple of projects and have two running SaaS applications on Amplify. If you want to know more about Amplify and building SaaS products on Amplify, follow my &lt;a href="https://twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt; 🙂&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is AWS Amplify? → It is a lot!</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Fri, 22 Oct 2021 05:39:43 +0000</pubDate>
      <link>https://dev.to/sandro_vol/what-is-aws-amplify-it-is-a-lot-pbd</link>
      <guid>https://dev.to/sandro_vol/what-is-aws-amplify-it-is-a-lot-pbd</guid>
      <description>&lt;h1&gt;
  
  
  What is AWS Amplify? → It is a lot!
&lt;/h1&gt;

&lt;h2&gt;
  
  
  AWS Amplify refers to 5 different products. Let's see them!
&lt;/h2&gt;

&lt;p&gt;AWS is &lt;strong&gt;not&lt;/strong&gt; really great with naming things. Nothing new here. Amplify is one of the products where A LOT of confusion exists on which product you are actually referring to. With this post, I will try to give some clarity. I will go through each product Amplify has, what the main purpose is, and how they are connected. Let's go! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fM3htbFB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017062262/tKNfKApJh.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fM3htbFB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017062262/tKNfKApJh.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TLDR; Basically there are 5 things which are Amplify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Amplify Hosting: Hosting service with DNS options&lt;/li&gt;
&lt;li&gt;Amplify Console: CI/CD for full-stack apps&lt;/li&gt;
&lt;li&gt;Amplify CLI: Bootstrap your infrastructure&lt;/li&gt;
&lt;li&gt;Amplify Libraries: Connect your app with AWS&lt;/li&gt;
&lt;li&gt;Amplify Admin UI: Use AWS without AWS account 🤯&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's get into some details. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://aws.amazon.com/amplify/hosting/"&gt;Amplify Hosting&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Amplify hosting offers the ability to quickly and easily host your static web page. If you have a react web app and want to host it, Amplify hosting is the way to go. Some really great features are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Workflows:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Amplify Hosting is deeply connected with Amplify Console (CI/CD) which we cover in the next part. After the website is built it can be automatically published and hosted. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR Preview:&lt;/strong&gt;Amplify Hosting allows you to preview new PRs in a completely own environment to test out new features&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom and not custom domains:&lt;/strong&gt;Amplify Hosting published your web page normally on some Amplify domain such as &lt;code&gt;develop.d23z478fg.amplifyapp.com&lt;/code&gt;. This is done automatically. If you want to map custom domains you can easily do this. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSL Certificate included&lt;/strong&gt;SSL is automatically included in both custom and not custom domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;You can monitor the metrics of the application and get SNS notifications in case you reach certain thresholds. Under the hood Amplify Hosting uses S3 and CloudFront to deliver your webpage over the globe. It abstracts the hassle of setting everything up manually and gives you a lot of options to customize the experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.amplify.aws/console/"&gt;Amplify Console&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Amplify Console is the CI/CD component of Amplify. It allows you to build full-stack apps by building your backend, frontend and deploying all of it with &lt;strong&gt;Amplify Hosting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The console follows a git-based workflow. That means it will automatically be triggered by pushes or PRs on your git branches. The console build is based on a docker image which you can adjust to anything you want. After setting the image you can define your build in the &lt;code&gt;build.yml&lt;/code&gt; file and follow several phases. The phases are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Provision: All AWS resources for the build will be provisioned&lt;/li&gt;
&lt;li&gt;Build: Backend and frontend deployment&lt;/li&gt;
&lt;li&gt;Deploy: Everything will be deployed.&lt;/li&gt;
&lt;li&gt;Verify: Tests will be executed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iGtJOVSF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017204520/URbTfZyWh.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iGtJOVSF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017204520/URbTfZyWh.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After deploying the website a preview is available to check how it looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.amplify.aws/cli/"&gt;Amplify CLI&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The Amplify CLI is one of these products which are normally meant if people talk about Amplify. A CLI is a command-line-interface, so a program you can execute just in the terminal without a GUI. The main idea of the CLI is to make the experience of programming fullstack apps on AWS a lot easier. The CLI handles a lot of things, but mainly it is doing the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provisioning resources by creating CloudFormation templates for pre-defined categories&lt;/li&gt;
&lt;li&gt;Deploying resources and updates (e.g. for lambdas)&lt;/li&gt;
&lt;li&gt;Generating boilerplate templates (e.g. VTL for GraphQL)&lt;/li&gt;
&lt;li&gt;Lokal mocking of some resources such as API, Lambda, DynamoDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Amplify you can easily add several services by following a wizard-like approach and Amplify will create the CloudFormation stacks you need for getting the resources. &lt;/p&gt;

&lt;p&gt;The CLI is doing quite a bit of magic to give you your desired services. I think it is an awesome product to use but be quite aware that you can run into some bugs where you maybe need some support. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pP9xLYMj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://docs.amplify.aws/assets/cli-b-roll.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pP9xLYMj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://docs.amplify.aws/assets/cli-b-roll.gif" alt="CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.amplify.aws/lib/q/platform/js/"&gt;Amplify Libraries&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Amplify also offers libraries for connecting your app with AWS services. Currently, the libraries are available for the following platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;li&gt;Android&lt;/li&gt;
&lt;li&gt;Flutter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be aware that for all other platforms you can also use the main SKD of AWS. Amplify is trying to make things easier for you but if it is not available use the SDK.&lt;/p&gt;

&lt;p&gt;The libraries let you connect the backend and frontend with the categories which are available in Amplify such as Authentication, DataStore, API, etc. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.amplify.aws/console/adminui/intro/"&gt;Amplify Admin-UI&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The Admin-UI is one of the latest products. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PpgeGVwS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017362058/vRItavYlU.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PpgeGVwS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634017362058/vRItavYlU.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is to create an app backend with a much nicer and cleaner interface compared to the typical AWS console. It also allows you to access AWS resources without using an AWS account. That means no handling of IAM policies and users. Just the first deployment of the backend needs an AWS account but after that, you can invite team members to the Admin-UI without an AWS account.&lt;/p&gt;

&lt;p&gt;It also allows you a visual data modeling approach. That means you can see how your data model interacts with each other and how the relationships look like. The really neat thing is that all configured resources you provisioned with the Admin-UI are also available in the CLI. So it is a great way of working together. &lt;/p&gt;

&lt;p&gt;Anna is the main PM of the Admin-UI and loves to improve the product, so if you want to help her, reach out to her 🙂&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ND3eyBGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1400519348717039622/NTUrbEg7_normal.jpg" alt="Anna M. Pfoertsch 🍌🥨 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Anna M. Pfoertsch 🍌🥨
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @_pananapread
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Learning from documentation is cool, but I want to hear from some users! 🤩 If you use &lt;a href="https://twitter.com/AWSAmplify"&gt;@AWSAmplify&lt;/a&gt; and have some thoughts to share, I would love to chat ✌️
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      18:17 PM - 17 Jun 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1405590477785624578" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1405590477785624578" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1405590477785624578" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;That's it! These are all Amplify services. I hope it will be easier for you now to know what services are doing and how they interact. If you want to know more about Amplify follow my &lt;a href="https://twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt; you can also see it as a Thread 😉&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B3waZEBo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FAW4caXWYAEaFxq.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--SbILg9la--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1377902800403902466/0vsBAGnc_normal.jpg" alt="Sandro Volpic profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Sandro Volpic
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/sandro_vol"&gt;@sandro_vol&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      AWS Amplify refers to different products.&lt;br&gt;&lt;br&gt;You are confused what Amplify exactly is? &lt;br&gt;&lt;br&gt;We know that AWS isn't the best with naming its products so let's see what Amplify products are exactly out there.&lt;br&gt;&lt;br&gt;1/6 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      08:04 AM - 28 Sep 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1442762063416283139" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1442762063416283139" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1442762063416283139" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
    </item>
    <item>
      <title>The Mom Test - How to talk to customers. A Summary</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Fri, 22 Oct 2021 05:37:22 +0000</pubDate>
      <link>https://dev.to/sandro_vol/the-mom-test-how-to-talk-to-customers-a-summary-17o2</link>
      <guid>https://dev.to/sandro_vol/the-mom-test-how-to-talk-to-customers-a-summary-17o2</guid>
      <description>&lt;h1&gt;
  
  
  The Mom Test - How to talk to customers. A Summary
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Have good customer conversations and validate your ideas.
&lt;/h2&gt;

&lt;p&gt;"&lt;strong&gt;The Mom Test, How to Talk to Customers &amp;amp; learn if your business is a good idea when everybody is lying to you"&lt;/strong&gt; by Rob Fitzpatrick is a book with the aim of improving your customer conversations and getting real learnings out of them! The idea behind the title is that you shouldn't ask your mum if your idea is a good idea because she will lie to you. Like you will learn in this book most people will lie to you, not even with evil intent. Unfortunately, this will not help you with validating your idea. &lt;/p&gt;

&lt;p&gt;The book tries to teach you how to get out of these lies and start a conversation where you actually learn something. The main takeaway is to validate the problem and not the idea. Start conversations that focus purely on the customer's life and the problem.&lt;/p&gt;

&lt;p&gt;This is a summary of the book with some quotes and the most important learnings I could gain from it. I list the table of contents and go through each chapter. If you want to learn more about it give the book a deep dive.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don't talk about your idea&lt;/li&gt;
&lt;li&gt;Let the customer talk&lt;/li&gt;
&lt;li&gt;Talk about the problem&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Mom Test
&lt;/h2&gt;

&lt;p&gt;In the chapter &lt;strong&gt;The Mom Test&lt;/strong&gt; the interesting part begins. Rob shows you a really common scenario on how a bad validation conversation looks like. It starts with the so-called Mom Test. A son wants to test his idea on his mum and asks her a couple of questions. Since the mum doesn't want to hurt the feelings of the son she "validates" the idea for him and tells him that it is really awesome. It follows a second conversation that focuses purely on the problem the idea wants to solve (digital recipes). With that approach, the son has some success, by focusing on the mum, her iPad, and cooking skills instead of pitching his idea.&lt;/p&gt;

&lt;p&gt;There are three main points to follow the mom test's approach:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Talk about their life instead of your idea&lt;/li&gt;
&lt;li&gt;Ask about specifics in the past instead of generics or opinions about the future&lt;/li&gt;
&lt;li&gt;Talk less and listen more&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are some examples of good and bad questions. Take them with a grain of salt, but the overall idea of the questions is the same. &lt;strong&gt;Focus on the customer's problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why do you bother?&lt;/li&gt;
&lt;li&gt;Talk me through your workflow&lt;/li&gt;
&lt;li&gt;What else have you tried?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bad questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you think it's a good idea?&lt;/li&gt;
&lt;li&gt;How much would you pay for X?&lt;/li&gt;
&lt;li&gt;Would you buy a product which did X?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You see a common rule here. The good questions focus on the customer's life and problem and how he will deal with it. The bad questions focus purely on your idea. &lt;/p&gt;

&lt;p&gt;One important question for me is always to ask &lt;strong&gt;What else have you tried&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;If somebody is complaining about a huge problem that he is so annoyed by but never looked for a solution, the workaround is maybe not worth it to pay for another product. If you see this pattern in several customer conversations it will be hard to sell your product if nobody even is looking for a solution. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If they haven't looked for ways of solving it already, they're not going to look for (or buy) yours.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Avoiding Bad Data
&lt;/h2&gt;

&lt;p&gt;The second chapter is &lt;strong&gt;Avoiding Bad Data.&lt;/strong&gt; Bad data refers to everything where you think you are learning something but you don't. They are also called false positives.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are three types of bad data:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compliments&lt;/li&gt;
&lt;li&gt;Fluff&lt;/li&gt;
&lt;li&gt;Ideas&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Compliments
&lt;/h3&gt;

&lt;p&gt;A typical conversation with bad data looks like that:&lt;/p&gt;

&lt;p&gt;You: (end of the pitch) .. and that is why you need my product. &lt;/p&gt;

&lt;p&gt;Them: Sounds awesome!&lt;/p&gt;

&lt;p&gt;You: Yes it is it will save your business.&lt;/p&gt;

&lt;p&gt;Them: Really, really cool.&lt;/p&gt;

&lt;p&gt;You go back to your team and say the meeting was awesome, they love it and it is definitely a proper validation. But really is it? They said they like it but it is nowhere a real validation if it will save any problem. Of course, compliments are good, everybody likes them. They prosper your motivation and it can be true of course that people like your idea. However, it is still not a validation. If you get compliments, Rob suggests doing the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;... try to get specific. Why did that person like the idea? How much money would it save him? How would it fit into his life? What else has he tried.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This again goes back to the problem, his life, and his approach to solving it. &lt;/p&gt;

&lt;p&gt;Even if you like compliments, they are just bad data and you have to avoid them. Often there is another way around, so that founders are fishing for compliments. Compliments are no learning. It is just unnecessary time wasted with a potential customer where you really could learn about solving his problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fluff
&lt;/h3&gt;

&lt;p&gt;Fluff is a special one. It basically refers to useless information. Customers will tell you a lot if you ask the wrong questions. One example from the book is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You: "Do you ever X"? &lt;/p&gt;

&lt;p&gt;Them: "Oh yeah all the time."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is not validation that the problem really exists. From here it is important to zoom in and get details. How does it happen? What is the workflow behind it? What else have you tried? I think you see the pattern... &lt;/p&gt;

&lt;h3&gt;
  
  
  Ideas
&lt;/h3&gt;

&lt;p&gt;The last type of bad data is ideas. And that is really interesting to see. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entrepreneurs are always drowning in ideas. We have too many ideas, not too few. Still, folks adore giving us more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main issue here is that everybody has ideas and most of the people are so convinced that their idea is just the best one. So, it often happens that customers start pitching their ideas. In terms of a software business, these ideas are often feature requests for your own product. Now, that is an essential part. You have a customer who likes your product and wants to improve it for his workflow of working with it. You have to go into this feature request and analyze it. But you don't have to go to your computer and start implementing it! Validate the idea or feature as well by talking about it. Maybe you find an underlying issue. Maybe your product is already able to do it in a much nicer way but you failed in explaining. Understand the &lt;strong&gt;why&lt;/strong&gt;. Understand why your customers want this feature and the root cause behind it. &lt;/p&gt;

&lt;p&gt;Rob again gives us some awesome and really basic questions for that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do you want that?&lt;/p&gt;

&lt;p&gt;What would that let you do?&lt;/p&gt;

&lt;p&gt;How are you coping without it?&lt;/p&gt;

&lt;p&gt;How would that fit into your day?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Tips
&lt;/h4&gt;

&lt;p&gt;At the end of the chapter, Rob gives you some general tips. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let the customer talk more than you do&lt;/li&gt;
&lt;li&gt;Don't mention your idea because then they start to protect your idea&lt;/li&gt;
&lt;li&gt;Don't fall into pitch mode&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Asking important questions
&lt;/h2&gt;

&lt;p&gt;You need to focus on asking important questions and not just random ones. Important questions vary from one idea and problem to another. But basically, you have to focus on two things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Find the bad news&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ask all questions which can be bad news and showstopper and ask them. Not starting something because you know it won't work is great learning. If you build a stock analyzer app but nobody will enter his financials because of security reasons, this is a show stopper! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't focus on details too much&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't focus on unimportant details of your problem. Focus first on the general problem and if it exists. If it does start digging deeper and zooming more into it. Start general and zoom in.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prepare your list of 3
&lt;/h4&gt;

&lt;p&gt;Rob also suggests creating a list of the 3 most important learning you need. They can (and often need to be) different for the different stakeholders. Keep them always ready that you can ask your potential customer at every given time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping it casual
&lt;/h2&gt;

&lt;p&gt;Keep it casual and don't make it overly professional just because you're talking about business. The main thing you want is a casual talk with another person about some problem. The best case is if the person doesn't even know that this is a discussion about some business and especially a business you want to build something for. &lt;br&gt;
You don't have to set up official meetings, send out several reminders and show up in a suit. Try to be a normal human being and have a normal, but interesting conversation. These meetings often occur not even in a planned fashion. If you meet an industry expert at a party and you have your list of 3 questions ready you can just start right in and talk to him. &lt;/p&gt;

&lt;h2&gt;
  
  
  Commitment and advancement
&lt;/h2&gt;

&lt;p&gt;Of course, at some point, you have to start talking about your solution and idea. This now brings us in danger that oftentimes the learning is over because we receive compliments, fluff, and just bad data in general. The great thing is if we know about that we can cut right through it and find the real meaning behind it. What you want to accomplish now are commitments and advancements of your customer. So after your pitch try to get a commitment or some advancement. Rob defines them as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Commitment&lt;/strong&gt;: They are showing they're serious by giving up something they value such as time, reputation, or money&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advancement&lt;/strong&gt; - They are moving to the next step of your real-world funnel and getting closer purchasing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you sell a SaaS product to a company and had the learnings and your pitch you now want to sell it. If you have meetings without any action points or commitments at the end you are often in the trap of an endless meeting circle. Try to get action points for the next meeting. If they don't want to settle on anything, use this as a learning and cancel this customer because he is often a dead end. But you also need to give them a concrete chance to buy or reject you. Don't hesitate to ask and give them different options for buying. If they won't commit to anything you can also get advancements such as introduction to other companies, teams, or industry experts. But if everything ends with fluff or compliments, really think about it if you should continue or not. Your time is not endless.&lt;/p&gt;

&lt;p&gt;Rob gives some good examples for good or bad meetings:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"There are a couple people I can introduce you to ..."&lt;/p&gt;

&lt;p&gt;"What are the next steps?"&lt;/p&gt;

&lt;p&gt;"Can I buy the prototype?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Bad&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"That's so cool. I love it"&lt;/p&gt;

&lt;p&gt;"Looks great. Let me know when it launches."&lt;/p&gt;

&lt;p&gt;"I would definitely buy that."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Good endings are with immediate actions, bad ones are just compliments and fluff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding conversations
&lt;/h2&gt;

&lt;p&gt;Now you know everything about talking to your customers. But how do you find them? There are several options to find them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cold calls:&lt;/strong&gt; Cold e-mail or call random people and ask if you can talk to them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use random situations:&lt;/strong&gt; You are at a party and hear that somebody is complaining about your problem? Talk to him and ask some questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use an excuse:&lt;/strong&gt; Be a bit sneaky and don't talk about your goal instead find an excuse to talk about another issue and slight slowly into your conversation. Do you want to talk to an investor about your stock analyzer? Maybe ask about some stock tips.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go where your customers are.&lt;/strong&gt; You want to build something for a specific group like crypto traders? Go to crypto meetups!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Landing Pages:&lt;/strong&gt; Launch a landing page and try to get as many conversations started as possible. If somebody is singing up talk to them!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can do it also the other way around. Bring the customers to you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organise meetups:&lt;/strong&gt; Meetups are an easy way for finding customers &amp;amp; gaining instant credibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speak &amp;amp; Teach:&lt;/strong&gt; If you're a good speaker you can find many customers as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industry blogging:&lt;/strong&gt; If you blog in that certain industry you can find a relevant audience and talk to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these customers will be cold-called above. They often don't know you (except for your online presence). Normally, you get way better results if you get a &lt;strong&gt;warm intro&lt;/strong&gt;. Try to get introduced to many people by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ask your friends&lt;/strong&gt;. You need a certain contact, just ask if anybody knows anybody in this area.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industry advisors.&lt;/strong&gt; If you have any former advisors or mentors ask them to help you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Universities&lt;/strong&gt;. If you're still a student ask your professors. Professors have endless contacts to the industry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investors&lt;/strong&gt;. You can ask VCs or smaller investors for some contacts in this area.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Framing the meeting
&lt;/h3&gt;

&lt;p&gt;Now you have the skills to talk to the customer and found the customer. How do you want to frame the meeting now? We already saw that we should keep it casual. But we also want to have an efficient meeting and don't waste the time of the customer. The format Rob suggests looks like that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vision / Framing / Weakness / Pedestal / Ask&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;You want to solve problem X with your vision Y&lt;/li&gt;
&lt;li&gt;You are currently in stage XYZ (prototype on an app)&lt;/li&gt;
&lt;li&gt;Show your weakness and why you need help&lt;/li&gt;
&lt;li&gt;Show why they can help (research them before)&lt;/li&gt;
&lt;li&gt;Ask for explicit help&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If possible do your meeting in person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing your customers
&lt;/h2&gt;

&lt;p&gt;You often find yourself having too many different options, ideas, and customers to focus on. You need to focus on specific ones. This is possible with different mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Customer segmentation:&lt;/strong&gt; Segment your customers by finding consistent and common problems and goals they have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer slicing:&lt;/strong&gt; Slice your segment into smaller groups. Look at the subsets and the commonalities and differences. If you find them put them into another sub-group.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running the process
&lt;/h2&gt;

&lt;p&gt;Now we have everything. We know how to talk to customers, we know how to find and group customers. Now we just have to execute it. The one really important part here is that just because you are the business guy or just because you read the book it is not a good idea to do the whole process by yourself. You should communicate with your team, ask them what learnings they need and focus on three main learnings for each group. If one person is just talking to the customer he has the ultimate product decisions because he can always vouch for the customer's perspective. That is why the whole learning should be shared in the most transparent way. The best one would be recordings but often that is not really suitable. The most suitable way is to take detailed notes and talk them through right after your talk. &lt;/p&gt;

&lt;p&gt;So you need some pre-, and post-processing of your work. You need to start with your list of the big 3 learnings and end with the analysis of your notes. But if you don't know what you want to learn from the beginning, you should not have the conversation in general.&lt;/p&gt;

&lt;p&gt;Rob also gives some suggestions on how to take notes, use smileys to make the process faster, and focus on also looking at the notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's it! That is the whole Mom Test. It covers on the one-side really the basics of customer conversations and on the other side surprises with a lot of obvious things which tend to happen a lot (e.g. looking for compliments). The book contains several great examples which I did not cover here. If you want to dig deeper I really recommend reading the book. It is not super long (~140 pages) and is really worth it. Rob did an awesome job here! &lt;/p&gt;

&lt;p&gt;In the conclusion, Rob also focuses on telling you that not everything will be perfect. You still will ask dumb questions, look for compliments and just talk about yourself. And that is okay. If you learn from that and try to do it better. To finish with his final quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's going to be okay.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to see The Mom Test in action and see how I use this book to build my Saas product, follow me on &lt;a href="https://twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to develop a Serverless Chatbot with AWS Amplify, Amazon Lex &amp; React</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Wed, 01 Sep 2021 06:06:40 +0000</pubDate>
      <link>https://dev.to/sandro_vol/how-to-develop-a-serverless-chatbot-with-aws-amplify-amazon-lex-react-4743</link>
      <guid>https://dev.to/sandro_vol/how-to-develop-a-serverless-chatbot-with-aws-amplify-amazon-lex-react-4743</guid>
      <description>&lt;h1&gt;
  
  
  How to develop a Serverless Chatbot with AWS Amplify, Amazon Lex &amp;amp; React
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Create your chatbot, step-by-step. Code &amp;amp; Architecture inclusive.
&lt;/h2&gt;

&lt;p&gt;This blog post gives you an introduction and step-by-step guide on how to create a chatbot application with AWS Amplify &amp;amp; AWS Lex. The great part about using this tech-stack is, that no Data Science or NLP knowledge is required because it is purely created with managed services by AWS. The same technology is used within Alexa so it is a bulletproof stack.&lt;/p&gt;

&lt;p&gt;In this post, we will create a chatbot for booking a car. You can find the code &lt;a href="https://github.com/AlessandroVol23/chatbot-with-amplify" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's go! &lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;Let's start with the architecture. &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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629264953915%2FHpi7Gw51_.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" 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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629264953915%2FHpi7Gw51_.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The architecture contains four different components:&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Interface - Chatbot Component
&lt;/h3&gt;

&lt;p&gt;The web interface is a Single Page Application (SPA), built with React &amp;amp; TypeScript. This gives us the opportunity to host the application in a cheap way and serve it very fast to users all over the world. We can also use already existing libraries (such as the chatbot implementation from Amplify) and we don't have to reinvent the wheel.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Amplify
&lt;/h3&gt;

&lt;p&gt;In this application, Amplify is used for two different use cases.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Amplify-CLI&lt;/strong&gt; for bootstrapping the cloud environment and building the infrastructure as code&lt;/li&gt;
&lt;li&gt;Amplify JS libraries for accessing AWS components and building the chatbot interface.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The web application is hosted via Amplify which uses S3 and CloudFront in the background. The chatbot and lambda function is created with Amplify. &lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon Lex
&lt;/h3&gt;

&lt;p&gt;Amazon Lex is the chatbot interaction service by AWS. It is the same service that uses Amazon Alexa and is built to serve many customers.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Lamdba
&lt;/h3&gt;

&lt;p&gt;Lambda is the serverless function service by AWS. For this use case it is optional. But normally it will be used to extend the functionality of chatbots by adding more business logic to them. For example for really booking an Uber.&lt;/p&gt;

&lt;p&gt;You can see the architecture is really simple and just consist of 4 different parts. &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Code!
&lt;/h2&gt;

&lt;p&gt;Now let's create the actual chatbot application. If you don't have already, please install the Amplify CLI, see &lt;a href="https://docs.amplify.aws/cli/start/install/" rel="noopener noreferrer"&gt;this guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Prerequisites for this project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amplify-CLI&lt;/li&gt;
&lt;li&gt;yarn or npm&lt;/li&gt;
&lt;li&gt;npx&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project Setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  React App
&lt;/h4&gt;

&lt;p&gt;First of all, let's start with the initial project setup and folder structure. Go into the folder where your project should reside and type in the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app chatbot-with-amplify --template typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bootstraps the initial folder structure with TypeScript as the main language.&lt;/p&gt;

&lt;h4&gt;
  
  
  Amplify App
&lt;/h4&gt;

&lt;p&gt;Now, we will do the same thing for Amplify. Just run &lt;code&gt;amplify init&lt;/code&gt; within your newly created project folder and follow the CLI commands.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CLI Workflow&lt;/strong&gt;: &lt;br&gt;
You can use the default values almost everywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Enter a name for the project chatbotwithamplify
The following configuration will be applied:

Project information
| Name: chatbotwithamplify
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start? Initialize the projectwith the above configuration? (Y/n) YUsingdefault provider  awscloudformation
? Select the authentication method you want touse: (Use arrow keys)
❯ AWS profile
  AWS accesskeys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you must choose your authentication method (either profile or access keys) and hit enter. I always suggest using AWS Profiles for your different accounts. &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is a short explanation of how to create them. After choosing it your Amplify project was created within the directory &lt;code&gt;amplify&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Chatbot
&lt;/h3&gt;

&lt;p&gt;Now we will build the actual chatbot component. Amplify has its own category for chatbot called &lt;a href="https://docs.amplify.aws/lib/interactions/getting-started/q/platform/js/#create-new-chatbot" rel="noopener noreferrer"&gt;&lt;strong&gt;interactions&lt;/strong&gt;&lt;/a&gt;. We start by using a pre-defined chatbot template for booking different trips.&lt;/p&gt;

&lt;p&gt;First, we start by adding an &lt;code&gt;interaction&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We have to configure a bunch of different stuff, just follow along the output here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Provide a friendly resource name that will be used to label this category in the project: (lex282f4c21) lex282f4c21
? Would you like to start with a sample chatbot or start from scratch? (Use arrow keys)
❯ Start with a sample
  Start from scratch
? Choose a sample chatbot: (Use arrow keys)
❯ BookTrip
  OrderFlowers
  ScheduleAppointment
? Please indicate if your use of this bot is subject to the Children's Online Privacy Protection Act (COPPA). No
Successfully added resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will start with the sample chatbot &lt;em&gt;BookTrip&lt;/em&gt;. After adding this resource we will push it to AWS. The &lt;code&gt;push&lt;/code&gt; command shows us a quick overview of all components to add.&lt;br&gt;
&lt;/p&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;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

    Current Environment: dev

┌──────────────┬─────────────────┬───────────┬───────────────────┐
│ Category     │ Resource name   │ Operation │ Provider plugin   │
├──────────────┼─────────────────┼───────────┼───────────────────┤
│ Auth         │ cognito8550b67d │ Create    │ awscloudformation │
├──────────────┼─────────────────┼───────────┼───────────────────┤
│ Interactions │ lex282f4c21     │ Create    │ awscloudformation │
└──────────────┴─────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? (Y/n) Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the overview we see that Amplify added one new &lt;code&gt;Interaction&lt;/code&gt; component &lt;code&gt;lex282f4c21&lt;/code&gt; and one &lt;code&gt;Auth&lt;/code&gt; component which acts as the authentication method for the bot. After hitting enter the CloudFormation templates will be executed and deployed on your AWS account.&lt;/p&gt;

&lt;p&gt;You can now open the service &lt;a href="https://eu-central-1.console.aws.amazon.com/lex/" rel="noopener noreferrer"&gt;Lex&lt;/a&gt; and see your newly created chatbot named: &lt;code&gt;BookTrip_dev&lt;/code&gt;.&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629823798498%2FdRY0hWOTG.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" 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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629823798498%2FdRY0hWOTG.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how the chatbot overview looks like. We will go through the different parts you can see here:&lt;/p&gt;

&lt;h4&gt;
  
  
  Intents
&lt;/h4&gt;

&lt;p&gt;On the far left side you can see the different intends. We have two:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;BookCar_dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BookHotel_dev&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One chatbot can have different intents it can serve. We will just look at &lt;code&gt;BookCar_dev&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sample Utterances
&lt;/h4&gt;

&lt;p&gt;Utterances are sentences or words on how to trigger a specific intent. In the case of the &lt;code&gt;BookCar&lt;/code&gt; chatbot these utterances are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Book a car&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Reserver a car&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Make a car reservation&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Slots
&lt;/h4&gt;

&lt;p&gt;Slots are data points that have to be collected by the user. In the example of booking a car, we need different information like the time, date and type of the car. The slot has different attributes like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Priority&lt;/strong&gt;: The order of the slot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Required&lt;/strong&gt;: Do we need this slot or not?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slot type&lt;/strong&gt;: What type is the slot. There are pre-defined types like &lt;code&gt;AMAZON.DATE&lt;/code&gt; or &lt;code&gt;AMAZON.TIME&lt;/code&gt; which can parse text into date or time. And there are self-defined types like for example the type &lt;code&gt;CarTypeValues&lt;/code&gt;. These were defined in the template and can be seen on the left side under &lt;code&gt;SlotTypes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt&lt;/strong&gt;: What is the question to show the user for receiving the slot as an answer?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Confirmation Prompt
&lt;/h4&gt;

&lt;p&gt;This is the final confirmation of the chatbot conversation. In this example, it is a summary of the whole car reservation. &lt;/p&gt;

&lt;h4&gt;
  
  
  Testing the chatbot
&lt;/h4&gt;

&lt;p&gt;You can test your chatbot by clicking on &lt;em&gt;TestChatbot&lt;/em&gt; on the right side of the window. A chatbot window pops up.&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629823902072%2FghIq1SMVp.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" 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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629823902072%2FghIq1SMVp.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is really helpful because while you enter your messages and receive responses you see the filled Slots. The great thing about the pre-defined slot types is that AWS parses for example dates that are hidden in text into proper date formats. If I answer the question &lt;em&gt;What day do you want to start your rental?&lt;/em&gt;, with &lt;em&gt;Tomorrow&lt;/em&gt; it parses it to the correct date.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chatbot information in Amplify
&lt;/h4&gt;

&lt;p&gt;All this was created by the sample defined in Amplify. Since we are using Amplify as Infrastructure as Code (IaC), this can be defined as code. If you take a look at your project in the file &lt;code&gt;amplify/backend/interactions/lex282f4c21/lex-params.json&lt;/code&gt; you will see all parameters in one JSON file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"resourceName": "lex282f4c21","intents": [
        {"cancelMessage": "Okay, I have cancelled your reservation in progress.","confirmationQuestion": "Okay, I have you down for a {CarType} rental in {PickUpCity} from {PickUpDate} to {ReturnDate}. Should I book the reservation?","slots": [
                {"name": "PickUpCity","type": "AMAZON.US_CITY","prompt": "In what city do you need to rent a car?","required": true,"customType": false },
              ...
            ],"utterances": ["Make a car reservation","Reserve a car","Book a car" ],"intentName": "BookCar","newSlotTypes": [
                {"slotType": "CarTypeValues","slotTypeDescription": "Enumeration representing possible types of cars available for rental","slotValues": ["standard","full size",
                       ...
                    ]
                }
            ]
        }
    ],"outputVoice": "Matthew","botName": "BookTrip","coppa": false}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these parameters, your can adjust and customize your chatbot in any way you want  😉&lt;/p&gt;

&lt;h3&gt;
  
  
  Interaction Component
&lt;/h3&gt;

&lt;p&gt;The next step is to have a Chatbot component in our own web application. For that, we open the react project in our favorite IDE (probably VSCode) and add a new folder &lt;code&gt;components&lt;/code&gt; and &lt;code&gt;chatbot&lt;/code&gt; and install &lt;code&gt;@aws-amplify/ui-react&lt;/code&gt; for using the pre-defined UI libraries. After that, we just start the development server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd chatbot-with-amplify
code .
mkdir src/components
mkdir src/components/Chatbot
touch src/components/Chatbot/Chatbot.tsx
yarn add aws-amplify @aws-amplify/ui-react 
yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;Chatbot.tsx&lt;/code&gt; file we return the &lt;code&gt;AmplifyChatbot&lt;/code&gt; component and connect it to our chatbot. The whole file can be seen &lt;a href="https://github.com/AlessandroVol23/chatbot-with-amplify/blob/main/src/components/Chatbot/Chatbot.tsx" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;amp;lt;AmplifyChatbot
    botName="BookTrip_dev" botTitle="This is a chatbot made with Amplify" welcomeMessage="Hi! I was made with Amplify. How can I help you?"/&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This renders the whole component of the chatbot and we can already speak to it like in the Lex interface. Just go to your &lt;code&gt;src/App.tsx&lt;/code&gt; and add the Chatbot and you should be able to see it. See &lt;code&gt;App.tsx&lt;/code&gt;&lt;a href="https://github.com/AlessandroVol23/chatbot-with-amplify/blob/main/src/App.tsx" rel="noopener noreferrer"&gt;here&lt;/a&gt; :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;functionApp() {return &amp;amp;lt;Chatbot /&amp;amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you open your browser and head to &lt;code&gt;http://localhost:3000/&lt;/code&gt; you can see your chatbot app and interact with it.&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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629443761097%2FgQfEkwuoF.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" 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.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629443761097%2FgQfEkwuoF.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After finishing your conversation you can check the console in the browser and find the filled slots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"slots": {"CarType": "luxuery","DriverAge": "21","PickUpCity": "Munich","PickUpDate": "2021-09-01","ReturnDate": "2021-09-02" }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Finished  🥳
&lt;/h3&gt;

&lt;p&gt;That's it! That is the whole workflow for building a chatbot. In this use case, we've used the easy approach of building a sample chatbot. The workflow is almost the same for building one from scratch. In one of the next posts, I will show you how to do exactly that. &lt;/p&gt;

&lt;p&gt;If you want to know more about AWS, serverless, and bootstrapping your product on AWS follow my &lt;a href="https://twitter.com/sandro_vol" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to develop a serverless mobile app with Amplify, React Native &amp; GraphQL</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Tue, 10 Aug 2021 12:26:48 +0000</pubDate>
      <link>https://dev.to/sandro_vol/how-to-develop-a-serverless-mobile-app-with-amplify-react-native-graphql-57a2</link>
      <guid>https://dev.to/sandro_vol/how-to-develop-a-serverless-mobile-app-with-amplify-react-native-graphql-57a2</guid>
      <description>&lt;p&gt;This post will show you an introduction to the architecture of a cross-platform (Android &amp;amp; iOS) mobile application. The app was built with React Native, Amplify, and GraphQL. I'll take my own application &lt;a href="https://www.deposur.de"&gt;deopsur&lt;/a&gt; as an example and explain all services and components based on this application. Deposur is an app for tracking your portfolios and investments.&lt;/p&gt;

&lt;p&gt;Let's first talk about why serverless and cross-platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Serverless?
&lt;/h2&gt;

&lt;p&gt;First of all, let's talk about why to develop an application serverless. These are the main reasons:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--SbILg9la--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1377902800403902466/0vsBAGnc_normal.jpg" alt="Sandro Volpic profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Sandro Volpic
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/sandro_vol"&gt;@sandro_vol&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Why develop you SaaS product serverless?&lt;br&gt;&lt;br&gt;🧷 Less risk: If nobody uses it → You won't pay anything&lt;br&gt;⬆️ Scalable: If many people are using it your infrastructure scales&lt;br&gt;🔒 Secure: Let AWS secure your environment, sorry but they are probably better 😉
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      13:11 PM - 27 Jun 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1409137185811435523" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1409137185811435523" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1409137185811435523" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;I could go on with potential benefits such as development time, costs, etc. but I think many of you know these benefits already. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why cross-platform.
&lt;/h2&gt;

&lt;p&gt;Cross-Platform development means that you render two native apps from just one codebase. This brings the main benefit that you just have to maintain and test this codebase. Of course, sometimes there are situations where you have to distinguish between both, for example in terms of styling, but this can be easily done.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Architecture
&lt;/h1&gt;

&lt;p&gt;Let's go over the architecture. I will explain the technologies, services, and components I used and why I used them. I separate the architecture into frontend and backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6fVFU1Gu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628486282451/g3Nv2dDSZS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6fVFU1Gu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1628486282451/g3Nv2dDSZS.png" alt="deposur.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;The frontend tech-stack has the following components and technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;react-native-elements&lt;/li&gt;
&lt;li&gt;Apollo (GraphQL)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  React Native
&lt;/h3&gt;

&lt;p&gt;React Native is an open-source framework, originally developed by Facebook for creating cross-platform applications with JavaScript. The main difference to other cross-platform technologies such as Cordova or Ionic is that the apps will not just be rendered in a web browser, but instead will be a proper native application. To have the same experience as with native applications, some customization for both platforms has to happen. &lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;React Native and its libraries are almost all supported in TypeScript. TypeScript is an additional layer to JavaScript built by Microsoft to have type-safety in your JavaScript code. The number one reason for using TypeScript is developer experience. This reason is often overlooked but it is so important to know which types you're passing around in your code. Especially, in the combination with GraphQL, it is really awesome to know which kind of data you will receive with which requests. &lt;/p&gt;

&lt;h3&gt;
  
  
  react-native-elements
&lt;/h3&gt;

&lt;p&gt;react-native-elements is an UI component library. It offers you customizable assets which you can reuse throughout your app. It implements the &lt;a href="https://material.io/design"&gt;Material Design&lt;/a&gt; that is really popular in Google applications. &lt;br&gt;
There are many component libraries out there, we built the first version of Deposur with UI Kitten but quickly switched back to react-native-elements for the theming and component implementation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Apollo
&lt;/h3&gt;

&lt;p&gt;For managing the internal state of the app we use &lt;a href="https://www.apollographql.com/docs/react/integrations/react-native/"&gt;Apollo&lt;/a&gt; in combination with AppSync and GraphQL. Apollo caches all queries and normalizes them by a key schema we define at the initialization of our app. It reduces the boilerplate and the complexity of using state management libraries such as Redux. It has some awesome capabilities like defining how to cache the data (network, local, etc.), when and how to refetch queries, and updating local data for optimistic mutations. &lt;/p&gt;
&lt;h2&gt;
  
  
  Backend
&lt;/h2&gt;

&lt;p&gt;Since this article is talking about building a serverless app, let's dive into the backend part. The main idea you want to focus on when building serverless is to &lt;strong&gt;not&lt;/strong&gt; managing any infrastructure by yourself.  Use as many managed services as possible and just take care of your business logic.&lt;br&gt;
The following parts will be separated into the different AWS services I'll recommend for building this kind of application.&lt;/p&gt;
&lt;h3&gt;
  
  
  Amplify
&lt;/h3&gt;

&lt;p&gt;Amplify can be distinguished into three different services: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Amplify-CLI: Infrastructure as code and graphql-transform&lt;/li&gt;
&lt;li&gt;Amplify-Console: CI/CD pipeline&lt;/li&gt;
&lt;li&gt;Amplify libraries: Frontend libraries for accessing AWS services.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I recommend using all three but this section is focused on the CLI. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amplify-CLI&lt;/strong&gt; gives you the opportunity to bootstrap your cloud environment with a few CLI commands and it creates CloudFormation templates for you automatically. This is also called Infrastructure as Code (IaC).&lt;/p&gt;

&lt;p&gt;For example, if you type in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; amplify add storage
? Please &lt;span class="k"&gt;select &lt;/span&gt;from one of the below mentioned services:
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Content &lt;span class="o"&gt;(&lt;/span&gt;Images, audio, video, etc.&lt;span class="o"&gt;)&lt;/span&gt;
  NoSQL Database
? Please provide a friendly name &lt;span class="k"&gt;for &lt;/span&gt;your resource that will be used to label this category &lt;span class="k"&gt;in &lt;/span&gt;the project:
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dynamodb
? Please provide table name:
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tablename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amplify creates several CloudFormation templates for the database, IAM permissions, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GraphQL Transform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main benefit of using Amplify is the graphql-transform library. It gives you the opportunity to annotate your &lt;code&gt;graphql.schema&lt;/code&gt; with annotations such as &lt;code&gt;model&lt;/code&gt;,  &lt;code&gt;connection&lt;/code&gt;, &lt;code&gt;searchable&lt;/code&gt;, or &lt;code&gt;auth&lt;/code&gt; for adding certain functionality and components to your architecture.&lt;/p&gt;

&lt;p&gt;Take for example this schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;searchable&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;funtion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;priceResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;model&lt;/code&gt; directive adds a DynamoDB table of the type Holding to your backend. Also, it adds an ElasticSearch Service and streams all data to this instance. The field &lt;code&gt;currentPrice&lt;/code&gt; will be resolved by a lambda function called &lt;code&gt;priceResolver&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Amplify also takes care of the deployment of all CloudFormation templates. This can be sometimes a headache (hello nested stacks) but in general, it takes away a huge burden. It also manages the deployment to different stages such as development, staging, and production.&lt;/p&gt;

&lt;p&gt;If you start building your serverless app I highly recommend checking out &lt;a href="https://docs.amplify.aws/start/q/integration/js"&gt;Amplify&lt;/a&gt; because it is an awesome project, has a great community, and gives you some really cool tools at hand for building your full-stack application. Be aware that some magic is happening in the background.&lt;/p&gt;

&lt;h3&gt;
  
  
  AppSync
&lt;/h3&gt;

&lt;p&gt;AppSync is the managed GraphQL API by AWS. It is one of the most unique services AWS offers in the serverless area. AppSync allows you to use almost any data source you want and map it to certain types. First of all, you need to define your GraphQL schema. We take the same one we saw before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;searchable&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;funtion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;priceResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is not a valid AppSync schema but a valid Amplify GraphQL schema. &lt;/p&gt;

&lt;p&gt;Since we are using Amplify in combination with AppSync we can use these directives. We already mentioned that the field &lt;code&gt;currentPrice&lt;/code&gt; will be resolved by a lambda function. In general AppSync fields can be resolved by one of these two methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;VTL Templates&lt;/strong&gt;: Velocity Templating Language. This is a templating language developed by Apache which is not completely straight forwards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda Resolvers&lt;/strong&gt;: You can use lambda functions for returning your fields.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amplify automatically generates VTL templates for your DynamoDB fields, for lambda resolvers you have to add the lambda function to your project and return the attributes you defined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query, Mutations, and Subscriptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not a complete GraphQL introduction. But in general, you can either &lt;strong&gt;query&lt;/strong&gt;, &lt;strong&gt;mutate&lt;/strong&gt; or &lt;strong&gt;subscribe&lt;/strong&gt; your data. &lt;br&gt;
A &lt;strong&gt;query&lt;/strong&gt; looks like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyQuery&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;getHolding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it returns a JSON object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"getHolding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ISIN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"currentPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;90.94999694824219&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mutation looks similar, just that you often have an input object which you have to pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We only use AppSync and GraphQL in our API for all data. There are two main benefits involved:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Frontend gets the power&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The frontend gets the power of fetching exactly the data it needs. There is no over-, or underfetching in GraphQL. You just get the data you specify to get.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;State management&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With GraphQL &amp;amp; Apollo, it is fairly easy to manage your state and cache in your app. You begin by normalizing your keys for the types in your schema and have them in your in-memory-cache. &lt;/p&gt;

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

&lt;p&gt;Lambda is the most known serverless service of AWS. As already mentioned in AppSync, lambda is purely used for our business logic as AppSync resolvers. Lambda executes your code without ever thinking about hardware. The main configuration is the memory setting which should always be maximized a bit to ensure fast execution. &lt;/p&gt;

&lt;p&gt;We follow the approach of having &lt;strong&gt;one&lt;/strong&gt; lambda function as a resolver for all AppSync fields and Lambda layers for handling the dependencies. &lt;/p&gt;

&lt;p&gt;The Lambda resolver is responsible for the following things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting the live price from a third-party API&lt;/li&gt;
&lt;li&gt;Getting historical prices from a third-party API&lt;/li&gt;
&lt;li&gt;Doing aggregations of the data&lt;/li&gt;
&lt;li&gt;Calculate different indicators such as the average buy-in price, invested capital, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the main use case of using Lambda here. There are also some minor use cases such as payment webhooks, newsletter campaigns, and monitoring services but the resolver is our main business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  DynamoDB
&lt;/h3&gt;

&lt;p&gt;DynamoDB is an amazing service. It is a fully managed NoSQL database by AWS. In combination with GraphQL, Amplify, and AppSync it works really well. Basically, it is a key-value database with JSON-like objects. &lt;/p&gt;

&lt;p&gt;All our DynamoDB tables come directly from our GraphQL schema. Amplify creates them automatically. We mainly access DynamoDB via VTL resolver from AppSync or our Lambda resolver for aggregating and mutating data. &lt;/p&gt;

&lt;h3&gt;
  
  
  ElasticSearch
&lt;/h3&gt;

&lt;p&gt;The last data source we use is the full-text search engine elastic search. It integrates really smoothly with using Amplify and all data gets streamed into elastic search automatically. You can query your data and execute searches with GraphQL as well. AppSync maps them via VTL resolvers. You can use different search operators such as &lt;code&gt;eq&lt;/code&gt;, &lt;code&gt;ne&lt;/code&gt;, &lt;code&gt;matchPhrase&lt;/code&gt;, and many &lt;a href="https://docs.amplify.aws/cli/graphql-transformer/searchable"&gt;more&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;It is really powerful, but unfortunately also the most expensive piece in this architecture. Since elastic search is &lt;strong&gt;not&lt;/strong&gt; serverless it is an instance that runs 24/7. Take this into consideration and &lt;strong&gt;think&lt;/strong&gt; about it to use it or not! If you don't have a complex search use case try to use smart access patterns within your DynamoDB and use them as an initial search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cognito
&lt;/h3&gt;

&lt;p&gt;Cognito is the authentication service in AWS. I (and many others) would always recommend never building certain systems by yourself. One of them is an authentication system. Arvid Kahl proves my point here as well:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vN0WDgyX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1201525049766883328/QPimCC9z_normal.jpg" alt="Arvid Kahl profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Arvid Kahl
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/arvidkahl"&gt;@arvidkahl&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Don't build this yourself: Authentication Systems.&lt;br&gt;&lt;br&gt;Why? Because you won't make it reliably secure. It'll be complicated and not extensible. &lt;br&gt;&lt;br&gt;Most importantly: it's not a core feature of your unique solution to your customer's critical problem. &lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/yeFoKDqqhn"&gt;thebootstrappedfounder.com/not-in-house-o…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      12:04 PM - 30 Mar 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1244596265473753088" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1244596265473753088" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1244596265473753088" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Cognito takes this burden away. It offers a sign-in and sign-up functionality even with a pre-defined hosted UI for signing up which you can integrate with no effort.&lt;/p&gt;

&lt;p&gt;The main benefit is to use social-sign-in functionality within your app. By using these features you give your users the opportunity to log in seamlessly with just one click.&lt;/p&gt;

&lt;p&gt;Cognito supports the following social sign-in provider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facebook&lt;/li&gt;
&lt;li&gt;Google&lt;/li&gt;
&lt;li&gt;Apple&lt;/li&gt;
&lt;li&gt;Amazon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, all functionalities like changing your password, resetting your password, etc. are supported natively by Cognito and you don't have to build it yourself. &lt;/p&gt;

&lt;h3&gt;
  
  
  Firebase Analytics
&lt;/h3&gt;

&lt;p&gt;The last service I show you is not from AWS but from GCP. Indeed, I thought about this a lot, but Firebase Analytics is just working way better and nicer compared to AWS pinpoint. Not just the UI is nicer (that is almost always the case if you compare GCP to AWS) but also the functionality is way better to incorporate into your mobile app. &lt;br&gt;
I recommend using &lt;a href="https://rnfirebase.io/"&gt;react-native-firebase&lt;/a&gt; for integrating Firebase into your app. &lt;/p&gt;

&lt;h1&gt;
  
  
  Costs
&lt;/h1&gt;

&lt;p&gt;One word about costs. Using this architecture as your app backend with an initial low number of users will cost you about nothing if you do not use elastic search. &lt;/p&gt;

&lt;p&gt;If you use the smallest elastic search instance it will cost you about 20€/instance/month. &lt;/p&gt;

&lt;p&gt;All other components will be completely in the free tier and just be billed on demand. That means if you really just have a low number of users it won't cost you anything. This reduces the risk immensely. If it starts to cost you money, or if you need a full-text search you can &lt;a href="https://sandro.volpee.de/how-you-get-1000-dollar-aws-credits-with-aws-activate-for-your-saas-product"&gt;always apply for the activate program and get 1000$ in credits for free&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this article, I showed you how an example serverless architecture for a cross-platform mobile application looks like. By learning this architecture you can apply it for so many different use cases. You are of course not restricted to mobile apps only, instead you can use it for all full-stack applications. &lt;/p&gt;

&lt;p&gt;Of course, we somehow cheat by using Amplify here but this really helps with building up your infrastructure in a fast and secure way.&lt;/p&gt;

&lt;p&gt;If you want to see more on building &amp;amp; bootstrapping serverless applications, follow my &lt;a href="https://twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt; 🙂&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>graphql</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Top 5 Serverless AWS Services founders &amp; Indie Hackers should know</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Fri, 06 Aug 2021 07:28:27 +0000</pubDate>
      <link>https://dev.to/sandro_vol/top-5-serverless-aws-services-founders-indie-hackers-should-know-33m9</link>
      <guid>https://dev.to/sandro_vol/top-5-serverless-aws-services-founders-indie-hackers-should-know-33m9</guid>
      <description>&lt;p&gt;The goal of this article is to introduce you to the top 5 serverless AWS services which I think every tech-founder or Indie Hacker should know. This is not a deep dive on these services and I want to explain them in a high level fashion and tell you why they are worth using and learning. With these services you are able to build almost every web- and mobile application you can think of. Almost all high level programming languages such as Python, TypeScript, JavaScript and Java can be used with these services. So, let’s jump straight in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Amplify CLI
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Smj_oeZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833461576/2L6Vbarte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Smj_oeZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833461576/2L6Vbarte.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I start with the obvious one, Amplify. Important to note is, that there are two (almost three) “services” called Amplify within AWS. We have to distinguish between:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Amplify CLI: Bootstrap your backend&lt;/li&gt;
&lt;li&gt;Amplify Libraries (e.g. JS libraries): Frontend libraries for accessing AWS resources&lt;/li&gt;
&lt;li&gt;Amplify Console: CI/CD pipeline for frontend and backend&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We talk about Amplify CLI here. With the Amplify CLI you are able to bootstrap your backend with a few commands within the Command Line Interface. Amplify has several categories you can add, for example these are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API: AppSync GraphQL or REST API Gateway&lt;/li&gt;
&lt;li&gt;Authentication: Cognito&lt;/li&gt;
&lt;li&gt;Storage: DynamoDB, S3&lt;/li&gt;
&lt;li&gt;Functions: Lambda&lt;/li&gt;
&lt;li&gt;Hosting: S3 &amp;amp; CloudFront&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a few commands you are able to build fullstack applications with a guided CLI.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;main benefit&lt;/strong&gt; in my eyes is the  &lt;a href="https://docs.amplify.aws/cli/graphql-transformer/model"&gt;graphql-tranform&lt;/a&gt;  library. This library enables you to create your data schema with custom annotations like model or connection and the library transforms this schema to a valid GraphQL schema and at the same time creates CloudFormation templates for creating your backend resources such as DynamoDB tables, Cognito connections, etc.&lt;/p&gt;

&lt;p&gt;Take this schema as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;funtion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;priceResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It creates the type &lt;em&gt;Holding&lt;/em&gt;. The &lt;em&gt;model&lt;/em&gt; annotation creates a table in DynamoDB with id as the primary key. &lt;em&gt;currentPrice&lt;/em&gt; will be resolved by the lambda function &lt;em&gt;priceResolver&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The *&lt;em&gt;main drawback *&lt;/em&gt; in my eyes is that you are not as flexible as with building up your infrastructure with a typical IaC solution like CDK or Terraform. Since a lot of magic is happening with Amplify you will likely run into some issues, especially when you are working with several team environments and lambda layers.&lt;/p&gt;

&lt;p&gt;Nevertheless, it is a great tool, it has a great community and the team is still developing the services further. The backend of  &lt;a href="https://www.deposur.de"&gt;deposur&lt;/a&gt;  was completely bootstrapped with Amplify. If you want to learn one service, learn this one!&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSync
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YqeVgTkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833603919/Wr5Van_Kx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YqeVgTkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833603919/Wr5Van_Kx.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This brings us to the next service, AppSync. AppSync is a fully managed GraphQL API by AWS. GraphQL enables you as a developer to get exactly the data you need without worrying about fetching too much or too less data overfetching &amp;amp; underfetching). In general you have three main functions within AppSync. These are &lt;strong&gt;Queries&lt;/strong&gt;, &lt;strong&gt;Mutations&lt;/strong&gt; and &lt;strong&gt;Subscriptions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Queries&lt;/strong&gt; you can query data from different data sources. That means that you can have a type Holding for example which gets data from different sources. Lets take our example schema again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;funtion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;priceResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The attribute &lt;em&gt;ISIN&lt;/em&gt; is a string which comes from DynamoDB, the &lt;em&gt;currentPrice&lt;/em&gt; gets resolved by a Lambda function called &lt;em&gt;priceResolver&lt;/em&gt;. Lambda resolvers give you the main flexibility here. In the lambda function you can have as much customised code as you need (request two different APIs, clean &amp;amp; preprocess data, …) and respond with exactly this data you need in your application. It doesn’t matter where your data lives, AppSync gives you the opportunity of resolving it under one hood for the application. This is a great deal of flexibility.&lt;/p&gt;

&lt;p&gt;You can query your data then with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyQuery&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;getHolding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;ISIN&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;currentPrice&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it returns the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"getHolding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ISIN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"currentPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;90.94999694824219&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;strong&gt;Mutations&lt;/strong&gt; you can change your data and update it. &lt;strong&gt;Subscriptions&lt;/strong&gt; give you the ability to live update your data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why to learn AppSync as a founder?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why should you learn AppSync as a founder? First of all you get the main benefit of using GraphQL which is working with type safety and giving the frontend developer the power of requesting exactly the data it needs. Secondly, you have so much flexibility by connecting every data source you need. Third, you let AWS doing most of the work. You have one single endpoint and no hassle with parsing requests and connecting different AWS services together. It will reduce your development time immensely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lambda
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7xyaUjhD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833708226/a3L9ejd8b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7xyaUjhD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833708226/a3L9ejd8b.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s go back to the roots, Lambda. Lambda is the most common known serverless service. When people talk about serverless many people just refer to lambda. The basic idea behind the lambda service is to run your code without ever thinking about infrastructure. AWS’s promise is just that your code will be executed. Lambda supports several runtimes such as Python, JavaScript, Java, C#, Rust, Go and many more. One of the latest features is that custom docker containers can be used as a runtime and that pricing happens every millisecond instead of every 100 ms. The maximum runtime of lambda is 15 minutes, take that into consideration when building your application. The only infrastructure setting is the memory setting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;: Lambda is &lt;strong&gt;cheap&lt;/strong&gt;. The first million requests per month are free. From that point on it will be calculated based on the minutes the lambda runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommendations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always increase memory to about 4 GB, the faster it runs the cheaper it is. There is a great library to test this assumption&lt;/li&gt;
&lt;li&gt;Declare all your static variables such as DynamoDb from boto3 outside of your handler function -&amp;gt; Decreases cold starts&lt;/li&gt;
&lt;li&gt;Keep cold starts in mind when designing your application. If you need certain response times pre-heat your lambda or provision concurrency before.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why learn lambda as a founder?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lambda gives you the ability of executing code without ever worrying about infrastructure. The pricing is really awesome. Your whole application can be based on Lambda. It depends on the use case and the overall architecture (go event-driven!) but most of the applications I know can be easily adopted to several lambda functions. You just pay on-demand, you have small development cycles and the deployment is way easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cognito
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B4ID5Hq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833755145/k7NDOzQQn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B4ID5Hq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833755145/k7NDOzQQn.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at Authentication. Cognito is AWS’s service for authentication and authorisation. You can use it for Sign-Up and Sign-In purposes, fine granular user group control and even federated logins such as Facebook, Google &amp;amp; Apple Login. If you start your SaaS business you really want to give users a seamless authentication experience and offer social logins. This is easily possible with Cognito. Cognito differentiates &lt;strong&gt;User Pools &amp;amp; Identity Pools.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Pools&lt;/strong&gt;: Directory of users with Sign-Up, Sign-In and federated login capability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity Pools&lt;/strong&gt;: Identity pools are for creating unique identities for users and giving them access to other AWS services. This is needed for example for generating temporary credentials for anonymous users.&lt;/p&gt;

&lt;p&gt;For the typical authentication capabilities you will use &lt;strong&gt;User Pools&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;: You pay per monthly active users and the first 50k are free!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Give your users the seamless authentication experience they deserve. With Cognito you are able to do that at any scale. You can customise your Sign-Up and Sign-In pages however you want or you can even use pre-built ones by AWS. With federated logins you are able to offer on-click logins.&lt;/p&gt;

&lt;h2&gt;
  
  
  DynamoDB
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hDIA5M4A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833812470/qJ4JP4kly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hDIA5M4A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1627833812470/qJ4JP4kly.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last service I want to introduce is DynamoDB. DynamoDB is a fully-managed NoSQL database which is highly scalable and highly available. I build almost every use case and project now with DynamoDB and I am a huge fan of it.&lt;/p&gt;

&lt;p&gt;The structure of DynamoDB is pretty similar to every other database. You have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tables&lt;/strong&gt;: A table has one or more items&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Items&lt;/strong&gt;: That is a collection of different attributes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys&lt;/strong&gt;: You distinguish between primary and sort keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streams&lt;/strong&gt;: You can have streams for triggering something (e.g. a lambda function) on every update on a table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DynamoDB is basically a key, value database where you can store different datatypes as a value. A value can also be a nested list or nested list of objects (like JSON). A DynamoDB Item looks like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"ISIN"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"BAY.MOTOREN WERKE AG ST"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key is the column name (ISIN) and the value is the data type (S: String) with the actual value. The item can also be shown with a typical JSON syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"ISIN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE0005190003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BAY.MOTOREN WERKE AG ST"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most SDKs are able to parse them into the correct DynamoDB representation.&lt;/p&gt;

&lt;p&gt;DynamoDB has some great features for increasing the performance even more such as Global Tables, DynamoDB Accelerator, Point-In-Time recovery and many more. When designing DynamoDB tables it is always important to keep you access patterns in mind. Rick is doing a wonderful job explaining DynamoDB strategies in this  &lt;a href="https://www.youtube.com/watch?v=6yqfmXiZTlM"&gt;video&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;: Pricing is based on reading, writing and storing data. Again, if you just start out your SaaS product the price is so low that it won’t cost you a Dollar. If you have a predictable amount of read and write requests you can even use provisioned capacity which is even cheaper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;Thats it! These are the services you should consider when building your application. All of these services have the great benefit of developing your application in a cloud-native way. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Risk-Free&lt;/strong&gt;. If nobody uses your app you won’t be charged. That minimises your risk immensely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt;. If you acquire a lot of users AWS will scale with your users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt;. You won’t secure your servers and applications as good as AWS engineers do. Concentrate on your business logic and let the boring stuff AWS do.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This was a high level overview of course and was not intended as a deep dive for the single services or to be complete. There are many more great services AWS offers. If you want to know more about building your SaaS service on AWS follow my  &lt;a href="https://www.twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt; !&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>How you get 1000 $ AWS credits with AWS Activate for your SaaS product</title>
      <dc:creator>Sandro Volpic</dc:creator>
      <pubDate>Tue, 22 Jun 2021 06:18:50 +0000</pubDate>
      <link>https://dev.to/sandro_vol/how-you-get-1000-aws-credits-with-aws-activate-for-your-saas-product-4b7p</link>
      <guid>https://dev.to/sandro_vol/how-you-get-1000-aws-credits-with-aws-activate-for-your-saas-product-4b7p</guid>
      <description>&lt;p&gt;When we started to build &lt;a href="https://www.deposur.de"&gt;deposur&lt;/a&gt; it was really important for us to keep our costs down from the beginning on. For that you have basically two approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep your cost down (wow!)&lt;/li&gt;
&lt;li&gt;You don’t have to pay for the costs (aha…)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since our app is completely serverless (except fulltext search) the costs are already pretty low. But some still come up. For example our elastic search and some larger data ingestions. Since AWS bills are not completely straightforward it is also a good feeling to know that you have a small money cushion in case you accidently trigger some script which will cost a lot (happened almost once).&lt;/p&gt;

&lt;p&gt;In this post I’ll quickly show you how we got 1000 $ AWS credits with the AWS Activate founders program which is exactly for bootstrappers.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is AWS Activate?
&lt;/h1&gt;

&lt;p&gt;AWS Activate is AWS’s program for Startups and Founders to get started quickly in the cloud. There are two different programs you can apply for. One is for VC backed startups and one is for the typical bootstrapped SaaS founder. I am talking about the second one, for bootstrapped startups.&lt;/p&gt;

&lt;p&gt;The prerequisites are really low:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your startup has to be less then 10 years old&lt;/li&gt;
&lt;li&gt;You need a landing page&lt;/li&gt;
&lt;li&gt;You need to have an AWS account&lt;/li&gt;
&lt;li&gt;You need LinkedIn account(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think landing page is even optional but I would highly recommend it to show what you are planning to do.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to apply?
&lt;/h1&gt;

&lt;p&gt;1.Sign in to your AWS account and go to &lt;a href="https://console.aws.amazon.com/activate/home/#/apply"&gt;https://console.aws.amazon.com/activate/home/#/apply&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.Click on your desired package → Founders package → Get started&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--inUmE7vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmpd9gaqo4p9vedpm22o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--inUmE7vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmpd9gaqo4p9vedpm22o.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.Check “Apply my credits to this account” and check if you are in the right account 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hzVMzW2C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/084to1c12tdd6wiuh5i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hzVMzW2C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/084to1c12tdd6wiuh5i0.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.Now you will see a form where you have to enter some basic information about your company like &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Company name&lt;/li&gt;
&lt;li&gt;Company description&lt;/li&gt;
&lt;li&gt;Website&lt;/li&gt;
&lt;li&gt;Industries (up to 10!)&lt;/li&gt;
&lt;li&gt;And some information in which services or areas you are interested in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5.The last step is to complete your team profile. Here, just enter your basic information and I recommend to add the LinkedIn profiles of all founders and team members.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R1CnxEEo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrgxz8laxjqbb6b00is2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R1CnxEEo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrgxz8laxjqbb6b00is2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. Click on submit application and wait for a couple of days and get your 1000 $. For deposur it took about 3 days and everything was set. You will see your credits then either in the Activate menu in your AWS account or in your billing account when you click on credits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SaSCMVdX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8hhd9xazdjn3pu3sxjbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SaSCMVdX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8hhd9xazdjn3pu3sxjbm.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefits
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;I think the first one is easy. You get money for free. 1000 $ in credits for almost all AWS services. The most important exception is that buying domains is not included. &lt;/p&gt;

&lt;h2&gt;
  
  
  Support Credits
&lt;/h2&gt;

&lt;p&gt;You get 350 $ in AWS developer support as well. I already had contact with some of them and they are super competent with discussing your architecture, ideas and troubleshoot your problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activate Console
&lt;/h2&gt;

&lt;p&gt;The last part and maybe not the most interesting is that you have access to the AWS activate console with additional information, workshops and tutorials. You also get &lt;strong&gt;exclusive offers&lt;/strong&gt; by certain partners like AirTable, ZenDesk or Jira. TBH I did not use them so far but I am sure they have some great offers as well. 😉&lt;/p&gt;

&lt;p&gt;That’s it. Have fun building your project for free!&lt;/p&gt;

&lt;p&gt;If you want to know about my journey of building serverless SaaS products on AWS, consider following my &lt;a href="https://twitter.com/sandro_vol"&gt;Twitter&lt;/a&gt; 🙂&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>saas</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
