<?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: Miguel A. Calles</title>
    <description>The latest articles on DEV Community by Miguel A. Calles (@miguelacallesmba).</description>
    <link>https://dev.to/miguelacallesmba</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%2F426540%2Fc3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png</url>
      <title>DEV Community: Miguel A. Calles</title>
      <link>https://dev.to/miguelacallesmba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miguelacallesmba"/>
    <language>en</language>
    <item>
      <title>Six Costly Findings in AWS Serverless Computing</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Tue, 23 Jan 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/seven-costly-findings-in-aws-serverless-computing-46h7</link>
      <guid>https://dev.to/aws-builders/seven-costly-findings-in-aws-serverless-computing-46h7</guid>
      <description>&lt;p&gt;I've worked in serverless computing for over five years and wanted to share some lessons learned.&lt;/p&gt;

&lt;p&gt;By the term "costly," I don't mean necessarily dollars or how expensive it was. "Costly" could mean difficulties in troubleshooting, difficulties in architecture, and just pain points I've discovered over the years.&lt;/p&gt;

&lt;p&gt;There are many more, but this post focuses on the costly findings that have stood out.&lt;/p&gt;

&lt;h2&gt;
  
  
  An overview of serverless
&lt;/h2&gt;

&lt;p&gt;Read the following post for an overview of serverless.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/serverless-is-cool/a-super-quick-overview-of-serverless-52b1e5cf9e2f"&gt;https://medium.com/serverless-is-cool/a-super-quick-overview-of-serverless-52b1e5cf9e2f&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Input injection
&lt;/h2&gt;

&lt;p&gt;Until just recently, OWASP Top Ten had input injection as the top risk. It is still the top risk in the Serverless Top Ten.&lt;/p&gt;

&lt;p&gt;The OWASP Top Ten API Security Risks has broken object-level authorization as the highest risk. This means that if I ask an API for data,  it  will give it to me. Then, if I ask it for another user's data, it'll give me that, too, even if I'm still logged in with my account. Since I'm not meant to get someone else's data,  it seems appropriate that it would be a higher risk than input injection.&lt;/p&gt;

&lt;p&gt;Input injection is still high on the list, and it would be important to address that first.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxup8xbe916cm7fxdiyy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxup8xbe916cm7fxdiyy2.png" alt="Input injection lesson" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the scenario above, we designed a Lambda function to get an update from the database to get an event from a DynamoDB table whenever the table data changes.&lt;/p&gt;

&lt;p&gt;The Lambda function then sends a clear cache command to the API Gateway.&lt;/p&gt;

&lt;p&gt;This workflow allowed the API Gateway to cache data and its cache to be cleared when there was new data. The DynamoDB table data stayed the same most of the time, and caching would reduce the number of read transactions on the table.&lt;/p&gt;

&lt;p&gt;Unfortunately, this resulted in an accidental input injection attack. Somehow, the DynamoDB stream would resend old events. Some of these events were old. Furthermore, multiple old events were sent in a short period.&lt;/p&gt;

&lt;p&gt;The Lambda function was designed to clear the API Gateway cache when it received an event. The numerous events resulted in multiple commands to the API. Shortly after, the API reached its rate limit and stopped responding to requests.&lt;/p&gt;

&lt;p&gt;We experienced a self-induced denial of service attack!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frr9y2mizo14pvk2oio0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frr9y2mizo14pvk2oio0k.png" alt="Input injection remediation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We reworked our Lambda function when we realized our users could not get data because of this DoS event.&lt;/p&gt;

&lt;p&gt;The Lambda function would validate each input rather than assuming it was "safe" to process. It would check the timestamp and only process events created within a few minutes. Furthermore, it would keep track of the last time it cleared the API cache. It would only clear the cache no sooner than five minutes than the previous time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4oq9ajha1vt3xwywmnnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4oq9ajha1vt3xwywmnnz.png" alt="Review of input injection" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some input injection risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Over-privileged policies
&lt;/h2&gt;

&lt;p&gt;I joined an existing serverless project. I discovered all the Lambda functions within a Serverless Framework service used the default IAM role instead of having one least privileged role per function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjhkcpr8bsc1d78ve0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjhkcpr8bsc1d78ve0f.png" alt="Over-privileged policies lesson" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above shows the example of a role with an over-privileged IAM policy.&lt;/p&gt;

&lt;p&gt;I emulated an injection attack where I would send a malicious command to the AWS CLI. (The Lambda function code allowed me to send Linux commands to the operating system with the AWS CLI installed.) I was able to modify other parts of the AWS infrastructure.&lt;/p&gt;

&lt;p&gt;An attacker could have issued a malicious command to IAM and started an account takeover.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdwtfedfo55h7umymh3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdwtfedfo55h7umymh3a.png" alt="Over-privileged policies remediation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created an IAM role for each function and assigned a unique IAM policy that had the least privileges to allow the function to execute successfully.&lt;/p&gt;

&lt;p&gt;I attempted the same malicious exploit, and the function threw an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6yusfc9fmfyvya775ky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6yusfc9fmfyvya775ky.png" alt="Review of over-provisioning" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some over-provisioning risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Failures and service outages
&lt;/h2&gt;

&lt;p&gt;It is easy to assume that AWS services will never go down or experience degradation. Designing for the "happy path" is the most logical approach. But, it is essential to consider the "negative path" where things go wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0l0r6kehuxfv4gm29ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0l0r6kehuxfv4gm29ny.png" alt="Failures and service outages lesson" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One day, we experienced degradation in CloudWatch rules. (Since then, it was rebranded to EventBridge.) Some of our functions failed to work for hours.&lt;/p&gt;

&lt;p&gt;Some functions were designed for the scheduled events to get third-party data to store it in our DynamoDB tables. The third-party data source only provided new data every six minutes. If we failed to save the data within that time, we would never have access to it again.&lt;/p&gt;

&lt;p&gt;We lost data for hours. That affected our user experience and billing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojh8focplnm8b9y092b3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojh8focplnm8b9y092b3.png" alt="Failures and service outages remediation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To remediate this, we started monitoring the health of the AWS services. We would be notified when there was an outage.&lt;/p&gt;

&lt;p&gt;We made sure all functions exited gracefully by using try-catch blocks. We could log errors that could be monitored. If our monitoring noticed an increase in logged errors, that would be an indicator to investigate.&lt;/p&gt;

&lt;p&gt;We explored having multi-region scheduled events. For example, if the North Virginia region was down, we could still get scheduled events from the Ohio region.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y0y8kdgq12ms2czyx1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y0y8kdgq12ms2czyx1c.png" alt="Review of failures and service outages" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some failure and service outage risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cost engineering
&lt;/h2&gt;

&lt;p&gt;We found our AWS bill was costly. For almost a year, we accepted it as the "cost of moving" to the cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgxaifl0j7tavv9fr2p5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgxaifl0j7tavv9fr2p5.png" alt="Cost engineering lessons" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We decided to investigate whether we were making the best use of the AWS cloud and being as efficient as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famjs9bc1uake0gm1cb1k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famjs9bc1uake0gm1cb1k.png" alt="Cost engineering remediations" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We observed our DynamoDB traffic patterns and realized they were irregular. We realized we would save money by moving to on-demand capacity even though it was more expensive than the provisioned capacity.&lt;/p&gt;

&lt;p&gt;We realized we had old log and S3 files that were no longer needed. We took advantage of lifecycle rules to delete old, unnecessary data.&lt;/p&gt;

&lt;p&gt;An initial version of an app used Kinesis, but we found it was more cost-effective to use SQS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5ix9eoc8ljprljc6l5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5ix9eoc8ljprljc6l5c.png" alt="Review of cost engineering" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some cost risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;We wanted to be super secure and enabled customer-managed KMS keys for all our data. We found our AWS bill increased considerably.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuvfik85id9ij18w7oxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuvfik85id9ij18w7oxj.png" alt="Encryption lessons" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We discovered the AWS-managed keys were less expensive than the customer-managed keys (CMK). We did not have security requirements that required us to use CMKs. We moved all our encryption to AWS-managed keys where possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e13rtd1qcsjsk8yrulg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e13rtd1qcsjsk8yrulg.png" alt="Encryption remediations" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Better security did not provide business value in this case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49cb8evg6az77n9aiira.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49cb8evg6az77n9aiira.png" alt="Lessons on encryption" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some encryption risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spaghetti
&lt;/h2&gt;

&lt;p&gt;We sometimes created "serverless spaghetti" designs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbvuxjwi1k0v9x5vyibo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbvuxjwi1k0v9x5vyibo.png" alt="Serverless spaghetti lesson" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Much like "spaghetti code" that is difficult to trace and has complex dependencies, the same can happen in a serverless design.&lt;/p&gt;

&lt;p&gt;The image above shows an unnecessarily complex design in an attempt to implement a "pure" and "clean" microservice design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0oycss67y6wtoq6ix8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0oycss67y6wtoq6ix8h.png" alt="Serverless spaghetti remediations" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We reviewed our design and attempted to simplify it. The above shows how we simplified the previous design example. Getting the data directly from the table was cleaner than going through a microservice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pwhgr30y9nyiflrlmf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pwhgr30y9nyiflrlmf3.png" alt="Review of serverless spaghetti" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows some serverless spaghetti risks and mitigations to consider.&lt;/p&gt;
&lt;h2&gt;
  
  
  Watch the LayerOne presentation
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Here are other posts you might enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/aws-cdk-serverless-cookbook-ebook-1d4d4e0488c"&gt;AWS CDK Serverless Cookbook: A Step-by-step Guide to Build a Serverless App in the Cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://miguelacallesmba.medium.com/using-docker-for-aws-cdk-development-7054086deb3d"&gt;Using Docker for AWS CDK development: Have a consistent development environment for your team on any OS&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.plainenglish.io/speed-up-aws-cdk-deploys-up-to-80-c47afad1c18c"&gt;Speed up AWS CDK deploys up to 80%: The ts-node package needed the speed boost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/illumination/build-robust-cloud-architectures-d512fb9eae1a"&gt;Build Robust Cloud Architectures: Applying Military Design Principles to Cloud Applications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1"&gt;Introduction to Cloud Computing Security: An excerpt from the Serverless Security book&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>serverless</category>
      <category>architecture</category>
    </item>
    <item>
      <title>We migrated from Serverless Framework to AWS CDK, and this is what we learned: Lessons from the AWS CDK Day 2023 presentation</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Mon, 08 Jan 2024 17:39:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/we-migrated-from-serverless-framework-to-cdk-and-this-is-what-we-learned-lessons-from-the-aws-cdk-day-2023-presentation-5hi1</link>
      <guid>https://dev.to/aws-builders/we-migrated-from-serverless-framework-to-cdk-and-this-is-what-we-learned-lessons-from-the-aws-cdk-day-2023-presentation-5hi1</guid>
      <description>&lt;p&gt;I will be sharing what my team and I learned when we migrated one of our applications from the Serverless Framework to AWS CDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to serverless
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is serverless?
&lt;/h3&gt;

&lt;p&gt;Serverless is a different way of developing. Rather than having a dedicated server (e.g., an EC2 instance) where you have to install the packages, configure runtimes, and cyber harden it.&lt;/p&gt;

&lt;p&gt;With serverless, you can rely on services to do what you need (e.g., compute, database, and storage).&lt;/p&gt;

&lt;p&gt;It doesn't mean you don't have servers. It means you rely more on your provider's services or functionality (e.g., AWS) provides.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0lyvb2p4hg1pscndaia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0lyvb2p4hg1pscndaia.png" alt="What is serverless?" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of serverless services
&lt;/h3&gt;

&lt;p&gt;There are different types of serverless services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ryp5xv83ugmyx80gye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ryp5xv83ugmyx80gye.png" alt="Types of serverless services" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most commonly known are for functions or code execution. That would be Lambda.&lt;/p&gt;

&lt;p&gt;APIs (that would be API Gateway).&lt;/p&gt;

&lt;p&gt;Databases (like DynamoDB).&lt;/p&gt;

&lt;p&gt;Object storage (like S3).&lt;/p&gt;

&lt;p&gt;There are also other things you can do with orchestration. You can use CloudWatch events, CICD with CodePipeline, CodeBuild, AI, and ML with SageMaker.&lt;/p&gt;

&lt;p&gt;You can integrate all these services together depending on your architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why choose serverless?
&lt;/h3&gt;

&lt;p&gt;There are different reasons, but it comes down to allowing you to be more agile and focus more on building and developing rather than maintaining, securing, and configuring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bqzhisf9tc83ioyk89v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bqzhisf9tc83ioyk89v.png" alt="Why choose serverless?" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It comes in handy when you're building prototypes, have a small team, or want to provide the most value with the least amount of maintenance effort.&lt;/p&gt;

&lt;p&gt;Serverless computing, designs, and architectures are not silver bullets. Sometimes, dedicated servers are more beneficial in some designs. These are just some common reasons why you would want to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  An example of a serverless architecture on AWS
&lt;/h3&gt;

&lt;p&gt;This is an example of a serverless architecture built on AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ihthaxx19zlm6xw3fv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ihthaxx19zlm6xw3fv3.png" alt="An example of a serverless architecture on AWS" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a serverless website that runs a single-page application that a browser can use to run that web app. &lt;br&gt;
You can use the CloudFront service to deploy a content delivery network that provides caching at edge routers. That way, the web application loads much faster when a user visits it.&lt;/p&gt;

&lt;p&gt;You can use the S3 service for website hosting. You can connect the CloudFront and the bucket so any HTML, CSS, or JavaScript file and image file that is loaded from the bucket gets cached via the CloudFront service.&lt;/p&gt;

&lt;p&gt;You can also build up your DNS (domain name service) on Route 53 or use an external domain name service. If you use Route 53, then the automatic deployment of any DNS records is managed through the AWS processes.&lt;/p&gt;

&lt;p&gt;The backend can also be serverless by using  an API gateway to send HTTP events to Lambda functions. A lambda function will run its code. It can get data from a database (like a DynamoDB table) if needed.&lt;/p&gt;

&lt;p&gt;The web app will communicate with your backend, and then if you have a mobile app, that too can make API calls to the API gateway.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using the Serverless Framework
&lt;/h2&gt;
&lt;h3&gt;
  
  
  History
&lt;/h3&gt;

&lt;p&gt;To build our application, we previously used the Serverless Framework to build a serverless web app, an  API, and its backend. We also built a mobile app that used its own serverless API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eumwc56cs2v148e7njx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eumwc56cs2v148e7njx.png" alt="History of using the Serverless Framework" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We chose the framework because the team was highly experienced with serverless development and the Serverless Framework.&lt;/p&gt;
&lt;h3&gt;
  
  
  The architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hatq77ypjvdbrdnbe1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hatq77ypjvdbrdnbe1m.png" alt="The architecture" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This application  had a web app and a mobile app. The web app had its own dedicated API, and so did the mobile app. They shared common backends, databases, and Lambda functions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Serverless Framework services
&lt;/h3&gt;

&lt;p&gt;The serverless framework is designed for services. When you use the Serverless Framework CLI create command, it creates a new service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwh93ta9ao1rqsyzmhkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwh93ta9ao1rqsyzmhkv.png" alt="Serverless Framework services" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You run the create command in different folders if you want multiple services. This follows the microservices concept, which is very popular.&lt;/p&gt;

&lt;p&gt;There were four key services:  the platform, which is the core functionality of our application (i.e., the backend); the account service (i.e., the identity provider) that authenticates users; the APIs for the mobile app and the web app to get data from the backend; the web app since it could be standalone.&lt;/p&gt;
&lt;h3&gt;
  
  
  Platform service
&lt;/h3&gt;

&lt;p&gt;The platform service allowed us to set up the hosted zone, which is where the DNS is set up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f7s9s2t1giqy948tu6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f7s9s2t1giqy948tu6v.png" alt="Platform service" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created our SSL certificates using the certificate manager.&lt;/p&gt;

&lt;p&gt;Our Lambda functions provided the code to power our APIs and to do the initial setup when we did onboarding or set up the application in a new AWS account.&lt;/p&gt;

&lt;p&gt;We used IAM for the security policies.&lt;/p&gt;

&lt;p&gt;We used EventBridge for the background processes.&lt;/p&gt;

&lt;p&gt;We also had a core set of DynamoDB tables shared across the application's different parts.&lt;/p&gt;

&lt;p&gt;We used various plugins to do different things. You will notice that there was a common set of plugins that will show up in all services.&lt;/p&gt;

&lt;p&gt;We built a reusable Serverless Framework service for use in future services and projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  Accounts service
&lt;/h3&gt;

&lt;p&gt;In the accounts service, we used Cognito. We used one user pool specifically for the web app and another one for the mobile app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymrsusi8e73c68l0enhz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymrsusi8e73c68l0enhz.png" alt="Accounts service" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The web app had one type of user. The mobile app had another type of user. Each type of user had different roles and functionality. Therefore, we felt keeping them separate with different user pools was important.&lt;/p&gt;

&lt;p&gt;There was also some data that we wanted to keep specific to the account that we chose not to store in Cognito. As a result, we had account DynamoDB tables.&lt;/p&gt;
&lt;h3&gt;
  
  
  APIs service
&lt;/h3&gt;

&lt;p&gt;We used GraphQL for the API instead of using a RESTful API. We had dedicated APIs for the web app and mobile app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61ta0hxhrcvn881v19dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61ta0hxhrcvn881v19dj.png" alt="APIs service" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Web app service
&lt;/h3&gt;

&lt;p&gt;The web app is a serverless web app. It used an S3 bucket, CloudFront distribution, and any related certificates from the platform service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqml5ps686429ft5dogm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqml5ps686429ft5dogm.png" alt="Web app service" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Findings
&lt;/h3&gt;

&lt;p&gt;We had pretty good success. We were able to deploy a minimum viable product pretty quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb2rt2h4fs2dwcp9ckrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb2rt2h4fs2dwcp9ckrw.png" alt="Findings" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We built a common library. We were using a mono repo with a common library folder and any common code shared across the different services.&lt;/p&gt;

&lt;p&gt;We found that the deployment order could be tricky sometimes. Some plugins require you to run a pre-deploy command. Others required you to do a post-deploy command. Sometimes, it had dependencies on other plugins. Other times, one service relied on another service's resource that had not been created yet.&lt;/p&gt;

&lt;p&gt;YAML was great, but as the file got bigger, reading it was a little confusing sometimes.&lt;/p&gt;

&lt;p&gt;The most "annoying" part was creating the IAM policies. There were some plugins that were great. They worked well in Serverless Framework version 1, but there were breaking changes in version 2. Some plugins stopped working in version 3. Using the native CloudFormation way of creating IAM policies was the most reliable, but can be tricky for some.&lt;/p&gt;

&lt;p&gt;Regardless, the Serverless Framework was still awesome to build and deploy. We created and deployed our MVP within months.&lt;/p&gt;
&lt;h2&gt;
  
  
  Moving to AWS CDK
&lt;/h2&gt;

&lt;p&gt;As a team, in 2021, we decided to try out this AWS CDK. It was at version 1 at the time and at least over 100 in the minor version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz28rjj20iouwjrno2x2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz28rjj20iouwjrno2x2z.png" alt="Moving to AWS CDK" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We had heard successes with CDK. We decided to experiment with CDK for future projects. We were building MVPs and trying out different product ideas internally.&lt;/p&gt;

&lt;p&gt;We tried CDK on one and found that it was a different way of thinking than the Serverless Framework. We had to think about apps and not microservices. Each Serverless Framework service was a CloudFormation stack, but a CDK app could consist of multiple stacks. Both CDK and Serverless Framework use CloudFormation in the underlying deployment method, but their organization is different.&lt;/p&gt;

&lt;p&gt;We also found using SSM parameters was much easier to work with in CDK than in Serverless Framework.&lt;/p&gt;

&lt;p&gt;In Serverless Framework, we used variables inside of the YAML code. We had to use a plugin to help interpret those variables since native support was limited.&lt;/p&gt;

&lt;p&gt;Another nice finding was building reusable components. CDK has level one (L1) and level two (L2) constructs that are ready to be used to deploy certain resources on services. You can also combine level two and level one constructs to build a level three construct. L3 constructs provide a lot better reuse.&lt;/p&gt;
&lt;h3&gt;
  
  
  Custom level 3 constructs
&lt;/h3&gt;

&lt;p&gt;These are some of the L3 constructs we built.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5p3homdq2vvggxal3ypt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5p3homdq2vvggxal3ypt.png" alt="Custom level 3 constructs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created a construct for the hosted zone and certificate so we could create the DNS and any required certificates.&lt;/p&gt;

&lt;p&gt;We created a function and  log group construct. We found that log groups are automatically created the first time a function is invoked. By creating the log group, we can configure its retention settings and other settings. Doing this will help lower costs by deleting old logs.&lt;/p&gt;

&lt;p&gt;We created an L3 construct for the web app app. We also used an existing L3 construct for deploying the web app.&lt;/p&gt;

&lt;p&gt;We created a CICI pipeline to deploy our CDK apps. We would deploy applications in multiple AWS accounts, and they were the same app, so having a consistent pipeline was important.&lt;/p&gt;
&lt;h3&gt;
  
  
  Serverless Framework services to CDK apps
&lt;/h3&gt;

&lt;p&gt;We needed to think about how we wanted to reorganize our Serverless Framework apps to CDK apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi4yw3yylqiptx9gorif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi4yw3yylqiptx9gorif.png" alt="Serverless Framework services to CDK apps" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Web app CDK app
&lt;/h3&gt;

&lt;p&gt;The web app service was the one service that had the least dependencies. We could deploy it by itself without a custom domain and have no external dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86w57cyr449hf4sjdp1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86w57cyr449hf4sjdp1j.png" alt="Web app CDK app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Backend CDK app
&lt;/h3&gt;

&lt;p&gt;We found most of our services and their resources could be in a single backend CDK app since they are related to each other. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnbn4of71mq1nntosdu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnbn4of71mq1nntosdu2.png" alt="Backend CDK app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We started with databases since we had a Serverless Framework service with just database tables. We created a database stack.&lt;/p&gt;

&lt;p&gt;We moved all the account services to a mobile app authentication stack and a web app authentication stack.&lt;/p&gt;

&lt;p&gt;We also moved the API services to a web app API stack and a mobile API stack. We specified the database and authentication stacks as dependencies. Doing this allows CDK to determine the deployment order automatically.&lt;/p&gt;

&lt;p&gt;We took a new approach to the pre-deploy and post-deploy commands. In Serverless Framework, we used plugins used in the CLI. For CDK, we created a setup stack that we would run as part of the deployment order. It would run the setup for the first deployment. It would not run again after that since there were no changes to any of the CloudFormation resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2irf2aijgj8tici87som.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2irf2aijgj8tici87som.png" alt="Backend CDK app, continued" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What did we learn from migrating to AWS CDK from Serverless Framework?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  More stuff comes "out of the box"
&lt;/h3&gt;

&lt;p&gt;We were able to use a lot of constructs that just came out of the box with CDK. And we could use these constructs to create L3 constructs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyrn414hq9vihlkibrglu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyrn414hq9vihlkibrglu.png" alt='More stuff comes "out of the box" with CDK' width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We did not need any plugins. Plugins were essential in Serverless Framework but were not required in CDK.&lt;/p&gt;

&lt;p&gt;Serverless Framework provides plugins for creating hosted zones and certificates, but this came native to CDK.&lt;/p&gt;

&lt;p&gt;Building Lambda function packages also came native to CDK.&lt;/p&gt;
&lt;h3&gt;
  
  
  Better organization
&lt;/h3&gt;

&lt;p&gt;We were able to organize our CDK apps better instead of having four main services. And we eliminated the need for pre-deploy and post-deploy commands for each service. We tried to put all the dependencies in their respective stacks. For those we couldn't, we specified which stacks depended on other stacks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Formx1p11f1unpe5cmc1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Formx1p11f1unpe5cmc1b.png" alt="Better organization with CDK" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CDK also has a synthesis that is able to catch issues like circular dependencies before you try to deploy.&lt;/p&gt;

&lt;p&gt;Working with SSM was easier, and we did not need dotenv files or plugins to work with environment variables.&lt;/p&gt;
&lt;h3&gt;
  
  
  Simpler deployments and better security
&lt;/h3&gt;

&lt;p&gt;We also found it easier to work with deployments and security.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9zr21ymu6nwghja1uth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9zr21ymu6nwghja1uth.png" alt="Simpler deployments and better security with CDK" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We only needed one CDK deploy command for each CDK app versus having pre-deploy, deploy, and post-deploy commands for each Serverless Framework service.&lt;/p&gt;

&lt;p&gt;Creating IAM roles could be as simple as using a grant function.&lt;/p&gt;

&lt;p&gt;CICD deployment was simpler. We created a build spec for each CDK app and used our L3 construct to create the pipeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  Watch the CDK Day 2023 presentation
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Here are other posts you might enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/aws-cdk-serverless-cookbook-ebook-1d4d4e0488c"&gt;https://medium.com/chapter-by-chapter/aws-cdk-serverless-cookbook-ebook-1d4d4e0488c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://miguelacallesmba.medium.com/using-docker-for-aws-cdk-development-7054086deb3d"&gt;https://miguelacallesmba.medium.com/using-docker-for-aws-cdk-development-7054086deb3d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.plainenglish.io/speed-up-aws-cdk-deploys-up-to-80-c47afad1c18"&gt;https://aws.plainenglish.io/speed-up-aws-cdk-deploys-up-to-80-c47afad1c18&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/illumination/build-robust-cloud-architectures-d512fb9eae1a"&gt;https://medium.com/illumination/build-robust-cloud-architectures-d512fb9eae1a&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1"&gt;https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Setting Up our AWS Account and CDK Environment</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sat, 23 Sep 2023 16:14:01 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/setting-up-our-aws-account-and-cdk-environment-5c8b</link>
      <guid>https://dev.to/miguelacallesmba/setting-up-our-aws-account-and-cdk-environment-5c8b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is chapter 1 of the &lt;a href="https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad"&gt;AWS CDK Serverless Cookbook&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will focus on setting up our AWS account and development environment to create our first CDK environment. We assume you already have access to an AWS account or can create one. We will use Docker[1] Desktop to help eliminate differences in Windows, Linux, and MacOS computing environments. We will also use GitHub as a git hosting provider for source control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a New Directory
&lt;/h2&gt;

&lt;p&gt;We will create a new directory named &lt;code&gt;cookbook&lt;/code&gt; where we put all our code. Create the &lt;code&gt;cookbook&lt;/code&gt; directory in any location you prefer. We will reference files starting with the directory name. For example, we will reference a readme file inside that directory as the &lt;code&gt;cookbook/README.md&lt;/code&gt; path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using GitHub and GitHub Desktop
&lt;/h2&gt;

&lt;p&gt;Setting up an account with GitHub is not necessary. We will use GitHub to allow the reader to download the code used in this book.&lt;/p&gt;

&lt;p&gt;The GitHub repository that will host the code from this book may be found at &lt;a href="https://github.com/miguel-a-calles-mba/aws-cdk-serverless-cookbook"&gt;https://github.com/miguel-a-calles-mba/aws-cdk-serverless-cookbook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cookbook&lt;/code&gt; directory is the top-level directory in our repository. For example, &lt;code&gt;cookbook/README.md&lt;/code&gt; will be &lt;code&gt;README.md&lt;/code&gt; inside the repository. When you clone the repository onto your machine, the directory will likely be called &lt;code&gt;aws-cdk-serverless-cookbook&lt;/code&gt;. If it makes it easier, rename the directory to &lt;code&gt;cookbook&lt;/code&gt; so there is a one-to-one match.&lt;/p&gt;

&lt;p&gt;Feel free to install GitHub Desktop to help with cloning the git repository and managing your own git respository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Docker Desktop
&lt;/h2&gt;

&lt;p&gt;We will use Docker Desktop to create a Linux container. A container is like a mini-computer that runs on our computers. The container runs an operating system with minimal dependencies and no graphical user interface. Running the same container configuration on a Windows, Mac, and Linux computer should provide the same environment. I have noticed differences in containers running 32-bit, 64-bit, and ARM architectures for some containers, but I have yet to find issues for the containers I used for CDK development.&lt;/p&gt;

&lt;p&gt;To install Docker Desktop, visit &lt;a href="https://www.docker.com"&gt;https://www.docker.com/&lt;/a&gt;, download the version of Docker Desktop that will work on your computer, and follow the installation instructions. You will be able to run the &lt;code&gt;docker&lt;/code&gt; command in your terminal application after successfully installing Docker Desktop.&lt;/p&gt;

&lt;p&gt;We will use the &lt;code&gt;docker&lt;/code&gt; command to control our containers. Specifically, we will use the Docker Compose feature in Docker Desktop to make it easier to work with containers. We will use the &lt;code&gt;docker compose&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Our Container
&lt;/h3&gt;

&lt;p&gt;Let’s create a file named &lt;code&gt;cookbook/docker-compose.yml&lt;/code&gt; and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nodejs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cimg/node:18.15"&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;circleci"&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/home/circleci"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./:/home/circleci"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bash"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This configuration file lets us download a container image and run a Docker container.&lt;/p&gt;

&lt;p&gt;We will run the following command to enter our container in our terminal application.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; nodejs bash
&lt;span class="c"&gt;# or&lt;/span&gt;
docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We will see our terminal change to something like the prompt below.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;circleci@a1b2c3d4e5f6:/home/nodejs&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We now have a Linux terminal we will use for the rest of the book.&lt;/p&gt;

&lt;p&gt;(Note: The &lt;code&gt;--rm&lt;/code&gt; option in the &lt;code&gt;docker compose&lt;/code&gt; command will delete the container after exiting it. This will help keep our computer clean.) Learn more about this development approach from the post below.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13?source=post_page-----2033be302795--------------------------------" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--KT9A9J04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1200/0%2AqLKQI8XGiXvaQo-u" height="532" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13?source=post_page-----2033be302795--------------------------------" rel="noopener noreferrer" class="c-link"&gt;
          User Docker container to run Node.js and global npm packages | Better Programming
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Protect your system from vulnerabilities
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--41Zxt9kW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/1%2Am-R_BkNf1Qjr1YbyOIJY2w.png" width="32" height="32"&gt;
        betterprogramming.pub
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting Up the AWS Account
&lt;/h2&gt;

&lt;p&gt;AWS accounts are free, but it requires a credit card to register. AWS also offers &lt;a href="https://aws.amazon.com/free/"&gt;free tiers&lt;/a&gt; for many services. Most services we will use in this book are eligible for the free tier. Some services are only eligible for the free tier for the first 12 months after creating an AWS account. It is up to the reader to determine whether to use an existing or new AWS account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Identity and Access Management (IAM)
&lt;/h3&gt;

&lt;p&gt;We will need IAM permissions to deploy our CDK app. We can create a user using the AWS IAM service or AWS Identity Center. The AWS Identity Center provides a more secure way to manage users and their IAM permission. For simplicity, we will create an IAM user and IAM policy it will use.&lt;/p&gt;

&lt;p&gt;To go to the AWS IAM service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into the &lt;a href="https://console.aws.amazon.com/"&gt;AWS console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Search for the IAM service and select it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To create an IAM policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Access management &amp;gt; Policies&lt;/li&gt;
&lt;li&gt;Click the “Create policy” button&lt;/li&gt;
&lt;li&gt;Click the “JSON” tab&lt;/li&gt;
&lt;li&gt;Paste the JSON code below into the policy editor&lt;/li&gt;
&lt;li&gt;Click the “Next” button&lt;/li&gt;
&lt;li&gt;Click the “Create policy” button
&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;"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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cdk"&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;"acm:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"apigateway:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudformation:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudwatch:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ecr:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"events:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:*"&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="s2"&gt;"logs:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3-object-lambda:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ssm:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"route53:*"&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="s2"&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;The IAM policy above gives us full permission to create and update the services used in our serverless application. (Note: The CDK bootstrap command needs “ecr” permission.) We will update the IAM policy as needed in the following chapters.&lt;/p&gt;

&lt;p&gt;To create an IAM user:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Access management &amp;gt; Users&lt;/li&gt;
&lt;li&gt;Click the “Add users” button&lt;/li&gt;
&lt;li&gt;Set the username to “cookbook”&lt;/li&gt;
&lt;li&gt;Click the “Next” button&lt;/li&gt;
&lt;li&gt;Check “Attach policies directly”&lt;/li&gt;
&lt;li&gt;Check the “cookbook” policy name in the “Permissions policies” section&lt;/li&gt;
&lt;li&gt;Click the “Next” button&lt;/li&gt;
&lt;li&gt;Click the “Create user” button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To create the IAM access key:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the “cookbook” IAM user&lt;/li&gt;
&lt;li&gt;Click the “Security credentials” tab&lt;/li&gt;
&lt;li&gt;Click the “Create access key” button in the “Access keys” section&lt;/li&gt;
&lt;li&gt;Check “Command Line Interface (CLI)”&lt;/li&gt;
&lt;li&gt;Click the “Next” button&lt;/li&gt;
&lt;li&gt;Check the “I understand the above recommendation and want to proceed to create an access key.”&lt;/li&gt;
&lt;li&gt;Click the “Next” button&lt;/li&gt;
&lt;li&gt;Click the “Create access key” button&lt;/li&gt;
&lt;li&gt;Click the “Download .csv file” button&lt;/li&gt;
&lt;li&gt;Click the “Done” button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will paste the access key values into our container’s terminal similar to the example below.&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;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"A...Y"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"7...B"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The CDK app will use the access key to deploy the app with the permissions from the IAM policy.&lt;/p&gt;

&lt;p&gt;As a good security practice, deactivate the access key when not using it and activate it when you need to use it.&lt;/p&gt;

&lt;p&gt;To activate/deactivate the IAM access key:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the IAM user&lt;/li&gt;
&lt;li&gt;Click on the “Security credentials” tab&lt;/li&gt;
&lt;li&gt;Go to the “Access keys” section&lt;/li&gt;
&lt;li&gt;Click the “Actions” dropdown&lt;/li&gt;
&lt;li&gt;Select “Activate” or “Deactivate”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to learn about the AWS Identity Center and create a user with the IAM policy above. This would be far more secure than using an IAM access key. Try experimenting with the AWS Cloud Shell available in the AWS console.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Our CDK app
&lt;/h2&gt;

&lt;p&gt;CDK supports JavaScript, TypeScript, Python, Java, C#, and Go. TypeScript provides the ease of JavaScript coding with the power of data types like Java. Also, the CDK framework is written in TypeScript. We will use TypeScript to create our CDK app for these two reasons.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating the CDK app
&lt;/h3&gt;

&lt;p&gt;In the container’s terminal, run the following commands to create CDK app:&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="c"&gt;# paste the AWS access key information&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/cdk-app
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/cdk-app
npx cdk init &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;span class="c"&gt;# follow any on screen prompts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We now have our CDK app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Bootstrapping the AWS account
&lt;/h3&gt;

&lt;p&gt;We must bootstrap the AWS account to allow CDK to deploy the app. Bootstrapping creates a CloudFormation stack that CDK will use.&lt;/p&gt;

&lt;p&gt;In the container’s terminal, run the following command to run the CDK bootstrap command to prepare the AWS account:&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="c"&gt;# paste the AWS access key information&lt;/span&gt;
npm run cdk bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Our AWS account now has the “CDKToolkit” CloudFormation stack, and we can deploy our CDK app in the next chapter; see Figure 1–1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7yo9zt2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5r615oquxlbpl42hg95h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7yo9zt2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5r615oquxlbpl42hg95h.png" alt="Image description" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figure 1–1. The CDKToolkit stack exists in the CloudFormation service.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter Review
&lt;/h2&gt;

&lt;p&gt;We created the directory to store all our code and shared the location of this book's GitHub source code repository. We downloaded and set up Docker Desktop to use a container when deploying our CDK app. We set up our AWS account to have an IAM user and access key that our CDK app will use. We used the access key to set up our AWS account to deploy CDK apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/describing-the-cdk-application-914efa958770"&gt;Next&lt;/a&gt;, we will describe the CDK app and prepare it to start building our application. The next section is coming soon.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/chapter-by-chapter/describing-the-cdk-application-914efa958770" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utkcDasS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/2%2ACC1gohycVhBFro5l2Yv-6g.jpeg" alt="Miguel A. Calles"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/chapter-by-chapter/describing-the-cdk-application-914efa958770" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Describing the CDK Application | Chapter by Chapter&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ &lt;time&gt;Jun 24, 2023&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Subscribe to &lt;a href="https://miguelacallesmba.medium.com/subscribe"&gt;my mailing list&lt;/a&gt; to get new chapters delivered to your email.&lt;/p&gt;

&lt;p&gt;Go to the &lt;a href="https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad"&gt;“AWS CDK Serverless Cookbook” table of contents&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelacallesmba" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vPqR0N4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--ZAbfppvt--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/426540/c3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png" alt="miguelacallesmba"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;AWS CDK Serverless Cookbook: A Step-by-step Guide to Building a Serverless App in the Cloud&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ May 28&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#serverless&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cloud&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cdk&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Endnotes
&lt;/h2&gt;

&lt;p&gt;[1] Docker is a registered trademark of Docker, Inc.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>serverless</category>
      <category>books</category>
    </item>
    <item>
      <title>An Overview of AWS, Serverless Computing, and CDK</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sat, 23 Sep 2023 15:56:55 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/an-overview-of-aws-serverless-computing-and-cdk-2poc</link>
      <guid>https://dev.to/miguelacallesmba/an-overview-of-aws-serverless-computing-and-cdk-2poc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the "Introduction" chapter of the &lt;a href="https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad"&gt;AWS CDK Serverless Cookbook&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This book will provide a step-by-step guide to creating a serverless application using Amazon Web Services. We will create a serverless website with databases, application programming interfaces, and processes to analyze data.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Overview of Amazon Web Services
&lt;/h2&gt;

&lt;p&gt;Amazon Web Services&lt;a href="https://dev.toAWS"&gt;1&lt;/a&gt; is a cloud computing service by Amazon. Cloud computing is a model where computing and data services (e.g., servers and storage) are hosted by another company and accessed over the Internet. Traditional models used on-premise hosting, where all servers and data storage are hosted inside the buildings where organizations run their operations. Some organizations have a hybrid model using a mix of on-premise and cloud-based solutions. This book will focus on cloud computing even though creating a serverless solution on-premise is possible.&lt;/p&gt;

&lt;p&gt;AWS became popular because it offered low-cost cloud-based storage and virtual servers in various geographical locations worldwide. Developers could create and delete web servers, databases, and storage quickly and efficiently. As their applications grew, they could easily scale their resources. As demand increased, they could add more servers to meet the demand. As demand decreased, they could remove unused or underutilized servers. AWS simplified development compared to the limitations of physical space, utilities, support staff, and procurement in the on-premise model.&lt;/p&gt;

&lt;p&gt;In 2014, AWS introduced its AWS Lambda. Lambda allowed developers to run code without having to provision a server. The introduction of Lambda introduced “serverless computing.”&lt;/p&gt;

&lt;h2&gt;
  
  
  An Overview of Serverless Computing
&lt;/h2&gt;

&lt;p&gt;The term “serverless” has evolved over the years. The initial definition with the launch of AWS Lambda was focused on computing (i.e., running code) with less focus on servers. Whether or not Lambda uses servers to run the service is irrelevant. Developers did not need to worry about creating a server, installing the dependencies and packages, keeping it up to date, and hardening security settings. Their main focus was uploading code to the Lambda service to create a function and having it execute some business logic.&lt;/p&gt;

&lt;p&gt;Over the years, serverless has been associated with certain key benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster development&lt;/li&gt;
&lt;li&gt;On-demand services&lt;/li&gt;
&lt;li&gt;Improved elasticity&lt;/li&gt;
&lt;li&gt;Increased scalability&lt;/li&gt;
&lt;li&gt;Simplified maintenance&lt;/li&gt;
&lt;li&gt;Reduced attack surfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These benefits came from the event-driven architectures typically used for serverless applications. An event-driven architecture assumes that an event drives system activity. For example, a computer will send an HTTP request to an Application Programming Interface (API). The API will forward the HTTP event to a Lambda function. The function will execute the code and send a response to the API. The API will forward the response to the computer. In this example, the API and Lambda functions will have no activity until it gets an HTTP request.&lt;/p&gt;

&lt;p&gt;Microservices architectures can be used in serverless computing. This design paradigm allows us to divide resources into logical groups. For example, we can have an API and Lambda functions for creating, reading, updating, and deleting user data. The application will make API calls to the microservices to process relevant data.&lt;/p&gt;

&lt;p&gt;Serverless applications can suffer from overly complex architectures that are difficult to maintain. For example, an HTTP event is sent to an API. The API forwards the request to a Lambda function. The Lambda function sends an event to a queue and a response to the API. Another Lambda function polls the queue and uses its data to write data to a database. The database sends an event to another Lambda function that writes data to an S3 bucket. The S3 bucket sends an event to another Lambda function that updates a value in a parameter store. We can easily fall into these confusing design traps when we develop a serverless application ad-hoc.&lt;/p&gt;

&lt;p&gt;We will focus more on building on our application than architecture design in this book. This book is meant to be a book for practitioners who want to learn to make a serverless application step-by-step. We will keep the serverless application design as simple as possible. We will use the Keep It Super Simple (KISS) principle.&lt;/p&gt;

&lt;p&gt;Read a more detailed introduction to cloud computing and security from the Serverless Security book.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utkcDasS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/2%2ACC1gohycVhBFro5l2Yv-6g.jpeg" alt="Miguel A. Calles"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Introduction to Cloud Computing Security | Serverless is Cool&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ &lt;time&gt;Jun 6, 2023&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  An Overview of Infrastructure as Code
&lt;/h2&gt;

&lt;p&gt;Over time, cloud developers realized creating cloud resources and deploying the application systematically was essential. Programmatic deployments were already typical in software, but early cloud computing lacked this capability. AWS users had to configure cloud resources and applications using the web-based AWS console.&lt;/p&gt;

&lt;p&gt;In 2010, AWS launched AWS CloudFormation, allowing users to write their cloud configurations in JSON and YAML file formats. A user would use the AWS command line interface (CLI) or software development kit (SDK) to request CloudFormation to create resources using the CloudFormation template. Teams could now use “code” to deploy their cloud infrastructure and maintain their cloud configuration in source code repositories.&lt;/p&gt;

&lt;p&gt;In 2015, the Serverless Framework[2] was launched to simplify the creation of CloudFormation templates for serverless computing. The framework provided a simple custom YAML template, making creating and deploying serverless designs easy.&lt;/p&gt;

&lt;p&gt;In 2018, AWS created the AWS Cloud Development Kit (CDK). Rather than writing CloudFormation templates, developers can create their cloud resources using JavaScript, TypeScript, Python, Java, C#, and Go. Unlike the Serverless Framework, CDK allows writing code to deploy any AWS resource that can be deployed using CloudFormation. The Serverless Framework can deploy CloudFormation templates for non-serverless cloud resources. Both frameworks have their benefits and drawbacks. Please read the post below for more details. We will create our cloud infrastructure with code with the AWS CDK framework.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://javascript.plainenglish.io/should-you-ditch-serverless-for-aws-cdk-fc5ac904688a" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--O-KoolRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1200/0%2AUET778T-re-GTcTL" height="533" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://javascript.plainenglish.io/should-you-ditch-serverless-for-aws-cdk-fc5ac904688a" rel="noopener noreferrer" class="c-link"&gt;
          Serverless vs. AWS CDK: Five Major Differences | JavaScript in Plain English
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The Serverless Framework is the most popular framework for building serverless applications, but does how it compare to the new AWS CDK?
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--cJcbXSzN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:256:256/1%2AAPjYv_YDdw1J7WCT4uKh9Q.png" width="256" height="256"&gt;
        javascript.plainenglish.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  An Overview of the AWS Cloud Development Kit
&lt;/h2&gt;

&lt;p&gt;The AWS CDK framework allows us to create infrastructure as code with CDK apps. A CDK app is used to deploy a group of AWS cloud resources. A CDK app is structured into the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The executable bin file that runs the application&lt;/li&gt;
&lt;li&gt;Stacks that have a group of cloud resources&lt;/li&gt;
&lt;li&gt;Cloud resources defined by constructs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A CDK stack will create a CloudFormation stack. Thus a CDK app allows us to develop multiple CloudFormation stacks using the CDK app code.&lt;/p&gt;

&lt;p&gt;CDK provides constructs that configure cloud resources. There are three types of constructs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Level 1 constructs allow us to configure a CloudFormation resource directly. The L1 construct provides the same properties as the CloudFormation template.&lt;/li&gt;
&lt;li&gt;Level 2 constructs are an abstraction of L1 constructs to configure a group of CloudFormation resources to deploy a logical group. For example, the aws_lambda package provides the Function construct that will create a Lambda function and the CloudFormation resources it needs. AWS writes the L2 constructs.&lt;/li&gt;
&lt;li&gt;Level 3 constructs are the next level of abstraction, allowing us to group L2 constructs. For example, we can create an L3 construct to create a Lambda function, the related CloudWatch log group, and add custom tags. We create constructs or get them from &lt;a href="https://constructs.dev/"&gt;Construct Hub&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concepts will become more apparent as we build our serverless application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter Review
&lt;/h2&gt;

&lt;p&gt;We quickly reviewed AWS, serverless computing, the infrastructure as code methodology, and AWS CDK. As we build our application, the following chapters will expand on relevant cloud computing and serverless concepts. In the next chapter, we will set up our environment to create our first CDK application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/miguelacallesmba/setting-up-our-aws-account-and-cdk-environment-5c8b"&gt;Next&lt;/a&gt;, we will set up our AWS account and development environment to create our application.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelacallesmba" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vPqR0N4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--ZAbfppvt--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/426540/c3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png" alt="miguelacallesmba"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/miguelacallesmba/setting-up-our-aws-account-and-cdk-environment-5c8b" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Setting Up our AWS Account and CDK Environment&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ Sep 23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cdk&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#serverless&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#books&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Subscribe to &lt;a href="https://miguelacallesmba.medium.com/subscribe"&gt;my mailing list&lt;/a&gt; to get new chapters delivered to your email.&lt;/p&gt;

&lt;p&gt;Go to the &lt;a href="https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad"&gt;“AWS CDK Serverless Cookbook” table of contents&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelacallesmba" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vPqR0N4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--ZAbfppvt--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/426540/c3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png" alt="miguelacallesmba"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;AWS CDK Serverless Cookbook: A Step-by-step Guide to Building a Serverless App in the Cloud&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ May 28&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#serverless&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cloud&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cdk&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Endnotes
&lt;/h2&gt;

&lt;p&gt;[1] Amazon, Amazon Web Services and AWS are registered trademarks of Amazon Web Services, Inc.&lt;/p&gt;

&lt;p&gt;[2] Serverless Framework is a registered trademark of Serverless, Inc.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>serverless</category>
      <category>books</category>
    </item>
    <item>
      <title>Using Docker for AWS CDK development</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sun, 16 Jul 2023 16:14:18 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/using-docker-for-aws-cdk-development-31n0</link>
      <guid>https://dev.to/miguelacallesmba/using-docker-for-aws-cdk-development-31n0</guid>
      <description>&lt;p&gt;Have a consistent development environment for your team on any OS&lt;/p&gt;




&lt;p&gt;Support me by reading &lt;a href="https://medium.com/@miguelacallesmba/using-docker-for-aws-cdk-development-7054086deb3d"&gt;this post on Medium&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In early 2022, I was starting a new project on AWS. I was using AWS CDK for about one year at this time. In a previous project, the team members used a mix of macOS and Linux computers. It was only a matter of time before a Windows user joined the team. Having a consistent development environment was beneficial. Based on previous experiments with Docker, I decided to use a Docker container as that development environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13"&gt;https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About one year later, in early 2023, I worked on a different CDK project. I started the project using macOS. About one month later, the team leader gave me a Windows laptop for me to use going forward. It was super simple to move my development environment. I installed Docker and git, cloned the git repository, ran the Docker command, and I was able to start developing right away. Using Docker containers saved me a lot of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here is how I set up my Docker container
&lt;/h2&gt;

&lt;p&gt;In my git repository, I created a &lt;code&gt;docker-compose.yml&lt;/code&gt; file where I added the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nodejs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# used for local development&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cimg/node:18.15'&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;circleci'&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/home/cdk'&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./:/home/cdk'&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the terminal, I ran the following command to start the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I have a terminal running within the container.&lt;/p&gt;

&lt;p&gt;I go to my AWS CDK app folder.&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;cd &lt;/span&gt;my-cdk-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I paste my AWS credentials into the terminal. I can now run typical CDK commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run cdk synth
npm run cdk deploy
cdk synth
cdk deploy
&lt;span class="c"&gt;# or however you have your cdk command execution set up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The setup was pretty simple. Now we have a consistent development environment regardless of the operating system. Leave a comment and let me know your experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Here are other posts you might enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/aws-cdk-serverless-cookbook-ebook-1d4d4e0488c"&gt;AWS CDK Serverless Cookbook: A Step-by-step Guide to Build a Serverless App in the Cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.plainenglish.io/speed-up-aws-cdk-deploys-up-to-80-c47afad1c18c"&gt;Speed up AWS CDK deploys up to 80%: The ts-node package needed the speed boost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/illumination/build-robust-cloud-architectures-d512fb9eae1a"&gt;Build Robust Cloud Architectures: Applying Military Design Principles to Cloud Applications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/serverless-is-cool/introduction-to-cloud-computing-security-a37b6c4bc4f1"&gt;Introduction to Cloud Computing Security: An excerpt from the Serverless Security book&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>docker</category>
      <category>typescript</category>
      <category>node</category>
    </item>
    <item>
      <title>Speed up AWS CDK deploys up to 80%</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sun, 16 Jul 2023 14:21:24 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/speed-up-aws-cdk-deploys-up-to-80-3m0</link>
      <guid>https://dev.to/miguelacallesmba/speed-up-aws-cdk-deploys-up-to-80-3m0</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;The ts-node package needed the speed boost&lt;/p&gt;




&lt;p&gt;Support me by reading &lt;a href="https://aws.plainenglish.io/speed-up-aws-cdk-deploys-up-to-80-c47afad1c18c"&gt;this post on Medium&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The Amazon Web Services Cloud Development Kit is an infrastructure-as-code solution. CDK allows us to write code (in JavaScript, TypeScript, Python, for example) to programmatically deploy resources in our AWS account.&lt;/p&gt;

&lt;p&gt;CDK is written in TypeScript and uses the ts-node package to deploy. When we run the cdk command in the terminal, the npm package uses the ts-node package to transpile the CDK code before running it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The issue
&lt;/h2&gt;

&lt;p&gt;I was finding it was taking “forever” when running a &lt;code&gt;cdk deploy&lt;/code&gt; or &lt;code&gt;cdk synth&lt;/code&gt; command. When I was troubleshooting or developing code, I wanted faster deploys. I was using the &lt;code&gt;cdk watch&lt;/code&gt; command to hotswap changes during development. This was a “little” faster but still felt super slow. I wanted to find out why these CDK commands were taking so long.&lt;/p&gt;

&lt;h2&gt;
  
  
  This was the solution
&lt;/h2&gt;

&lt;p&gt;I will share the solution upfront. The rest of the post will share my findings.&lt;/p&gt;

&lt;p&gt;I installed a new ts-node transpiler using npm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @swc/core @swc/helpers regenerator-runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I updated my &lt;code&gt;tsconfig.json&lt;/code&gt; file to tell ts-node to use the new SWC transpiler. I added the &lt;code&gt;ts-node&lt;/code&gt; property and the &lt;code&gt;swc&lt;/code&gt; property under it.&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;"ts-node"&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;"swc"&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="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;I noticed a significant improvement when running &lt;code&gt;cdk&lt;/code&gt; and &lt;code&gt;npx ts-node&lt;/code&gt; commands in the terminal.&lt;/p&gt;

&lt;p&gt;Keep in mind this note from the &lt;a href="https://swc.rs/docs/migrating-from-tsc"&gt;SWC website&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SWC only transpiles the code and doesn’t perform type checking. Therefore, it’s recommended that you continue to use tsc for detecting any type errors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How I found the solution
&lt;/h2&gt;

&lt;p&gt;I realized that ts-node could be the issue. I write command line scripts with TypeScript. I use the &lt;code&gt;npx ts-node myfile.ts&lt;/code&gt; command to execute them. They took a while to execute but did not think much about it. When I was getting frustrated by the CDK command start times, I started to realize the TypeScript script execution time was slow too.&lt;/p&gt;

&lt;p&gt;I decided to investigate if they were speed issues with the ts-node package.&lt;/p&gt;

&lt;p&gt;I found a GitHub issue where others expressed their concerns with the slowness of ts-node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TypeStrong/ts-node/issues/1070"&gt;https://github.com/TypeStrong/ts-node/issues/1070&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The discussion taught me about the SWC transpiler that can speed up the time ts-node uses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typestrong.org/ts-node/docs/swc/"&gt;https://typestrong.org/ts-node/docs/swc/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I installed the SWC packages and updated my &lt;code&gt;tsconfig.json&lt;/code&gt; file. I noticed a significant improvement when using &lt;code&gt;cdk deploy&lt;/code&gt;, &lt;code&gt;cdk synth&lt;/code&gt;, &lt;code&gt;cdk watch&lt;/code&gt;, and &lt;code&gt;npx ts-node&lt;/code&gt; commands in the terminal. Development time was much faster now.&lt;/p&gt;

&lt;p&gt;I updated my CI/CD pipeline that deploys multiple CDK apps and runs various TypeScript command line scripts. My CI/CD pipeline execution time dropped from 345 seconds to 74 seconds when I added the ts-node SWC setting. Wow! That’s over 75%.&lt;/p&gt;

&lt;p&gt;I needed to share this finding with the CDK community. I submitted a GitHub pull request to add the SWC settings to the TypeScript app template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws/aws-cdk/pull/25089"&gt;https://github.com/aws/aws-cdk/pull/25089&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the pull request is approved and merged, new CDK apps created by the cdk init command will get this speed boost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Empirical testing
&lt;/h2&gt;

&lt;p&gt;Let’s do some testing to see the effects of the SWC transpiler.&lt;/p&gt;

&lt;p&gt;Let’s create a folder for our CDK apps. We will use the ~/cdkapps folder. Note: My setup &lt;a href="https://medium.com/better-programming/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13"&gt;uses Docker&lt;/a&gt; rather than installing Node.js directly onto my machine.&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;cd&lt;/span&gt; ~
&lt;span class="nb"&gt;mkdir &lt;/span&gt;cdkapps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The first test
&lt;/h2&gt;

&lt;p&gt;We will create a new CDK app.&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;cd&lt;/span&gt; ~/cdkapps
&lt;span class="nb"&gt;mkdir &lt;/span&gt;test1-cdk
&lt;span class="nb"&gt;cd &lt;/span&gt;test1-cdk
npx cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s test the time it takes to synthesize an empty app.&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;time &lt;/span&gt;npm run cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command sent this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;real 0m38.681s
user 0m46.195s
sys 0m1.769s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took 46 seconds to synthesize a CDK app.&lt;/p&gt;

&lt;p&gt;Now let’s test with the SWC transpiler. (The command assumes the steps to add the SWC transpiler were already done.)&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;time &lt;/span&gt;npm run cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command sent this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;real 0m9.562s
user 0m9.105s
sys 0m0.703s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took 9 seconds to synthesize a CDK app when using SWC. That’s an 80% improvement!&lt;/p&gt;

&lt;h2&gt;
  
  
  The second test
&lt;/h2&gt;

&lt;p&gt;Now let’s create a new CDK app with one TypeScript Lambda function.&lt;/p&gt;

&lt;p&gt;We will create a new CDK app.&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;cd&lt;/span&gt; ~/cdkapps
&lt;span class="nb"&gt;mkdir &lt;/span&gt;test2-cdk
&lt;span class="nb"&gt;cd &lt;/span&gt;test2-cdk
npx cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s add the packages to help with adding a Lambda function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @types/aws-lambda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create the Lambda function.&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;touch &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create the function code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* ~/cdkapps/test2-cdk/function.ts */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-lambda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create the function resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* ~/cdkapps/test2-cdk/lib/test2-cdk-stack.ts */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Test2CdkStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_lambda_nodejs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodejsFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;handler&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODEJS_18_X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;__dirname&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s test the time it takes to synthesize an app on a bare TypeScript Lambda function.&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;time &lt;/span&gt;npm run cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command sent this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;real 0m49.314s
user 0m58.874s
sys 0m3.818s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took 58 seconds to synthesize a CDK app.&lt;/p&gt;

&lt;p&gt;Now let’s test with the SWC transpiler. (The command assumes the steps to add the SWC transpiler were already done.)&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;time &lt;/span&gt;npm run cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command sent this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;real 0m18.985s
user 0m18.625s
sys 0m2.186s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took 18 seconds to synthesize a CDK app when using SWC. That’s a 67% improvement.&lt;/p&gt;

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

&lt;p&gt;Consider adding the SWC transpiler for ts-node to your AWS CDK apps. The time results will vary depending on your setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you go
&lt;/h2&gt;

&lt;p&gt;Here are other posts you might enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/aws-cdk-serverless-cookbook-ebook-1d4d4e0488c"&gt;AWS CDK Serverless Cookbook: A Step-by-step Guide to Build a Serverless App in the Cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13"&gt;Stop Installing Node.js and Global Npm Packages, Use Docker Instead: Protect your system from vulnerabilities&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.plainenglish.io/cloudflare-v-aws-a-comparison-of-their-serverless-offerings-a32e2a000735"&gt;Cloudflare v. AWS: A Comparison of Their Serverless Offerings: They both have their benefits and downsides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.plainenglish.io/how-i-caused-an-amazon-api-gateway-denial-of-service-cba93810e18f"&gt;How I Caused an Amazon API Gateway Denial of Service: The DoS attack was caused by a Lambda function&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Photo by PAUL SMITH on Unsplash&lt;/p&gt;

</description>
      <category>aws</category>
      <category>typescript</category>
      <category>node</category>
      <category>devops</category>
    </item>
    <item>
      <title>AWS CDK Serverless Cookbook: A Step-by-step Guide to Building a Serverless App in the Cloud</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sun, 28 May 2023 13:54:11 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad</link>
      <guid>https://dev.to/miguelacallesmba/aws-cdk-serverless-cookbook-a-step-by-step-guide-to-building-a-serverless-app-in-the-cloud-5cad</guid>
      <description>&lt;h1&gt;
  
  
  Foreward
&lt;/h1&gt;

&lt;p&gt;I started developing serverless applications on Amazon Web Services in 2018. The team used the Serverless Framework heavily. The framework made it simple to begin developing serverless applications on AWS. Over the years, I wanted greater control of provisioning and updating cloud resources. In 2020, my team and I experimented with the AWS CDK framework to deploy our applications. It was a different experience and required more lines of code than the same setup in the Serverless Framework. An AWS CDK developer needed to understand cloud provisioning better to use it effectively. I found the CDK refreshing and wrote a blog post sharing five significant differences between the two frameworks.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://javascript.plainenglish.io/should-you-ditch-serverless-for-aws-cdk-fc5ac904688a" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--O-KoolRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1200/0%2AUET778T-re-GTcTL" height="533" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://javascript.plainenglish.io/should-you-ditch-serverless-for-aws-cdk-fc5ac904688a" rel="noopener noreferrer" class="c-link"&gt;
          Serverless vs. AWS CDK: Five Major Differences | JavaScript in Plain English
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The Serverless Framework is the most popular framework for building serverless applications, but does how it compare to the new AWS CDK?
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--cJcbXSzN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:256:256/1%2AAPjYv_YDdw1J7WCT4uKh9Q.png" width="256" height="256"&gt;
        javascript.plainenglish.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Both frameworks were at version 1 at the time. We were not locked into any AWS deployment framework. As a team, we decided to continue using AWS CDK from then on. After using CDK in multiple projects, we found it allowed us to create patterns that we could reuse. We put standard deployment methods or cloud resources into reusable constructs. Spinning up new projects thus became faster and more efficient. Furthermore, we were able to make upgrades to configurations by simply updating the constructs. For example, when AWS announced deprecations to software runtimes, we would update the runtime in the construct, and all projects would benefit.&lt;/p&gt;

&lt;p&gt;I wrote this book to share my experience using AWS CDK to build cloud-native serverless applications. I hope you find my experience over the past few years beneficial in helping you start building a serverless app with CDK.&lt;/p&gt;

&lt;p&gt;You may be wondering why I am writing a book on Medium. These posts explain why.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/illumination/would-you-read-a-book-on-medium-if-it-were-posted-one-chapter-at-a-time-45173f4a7a53" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utkcDasS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/2%2ACC1gohycVhBFro5l2Yv-6g.jpeg" alt="Miguel A. Calles"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/illumination/would-you-read-a-book-on-medium-if-it-were-posted-one-chapter-at-a-time-45173f4a7a53" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Would you read a book on Medium if it were posted one chapter at a time? | by Miguel A. Calles | ILLUMINATION | Medium&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ &lt;time&gt;May 12, 2023&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/illumination/writing-a-tech-book-on-medium-part-2-523bf382437a" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utkcDasS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/2%2ACC1gohycVhBFro5l2Yv-6g.jpeg" alt="Miguel A. Calles"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/illumination/writing-a-tech-book-on-medium-part-2-523bf382437a" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Writing a tech book on Medium, part 2 | by Miguel A. Calles | ILLUMINATION | Medium&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ &lt;time&gt;May 7, 2023&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction: An Overview of AWS, Serverless Computing, and CDK
&lt;/h2&gt;

&lt;p&gt;A quick overview of Amazon Web Services, serverless computing, infrastructure-as-code, and AWS CDK.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelacallesmba" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vPqR0N4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--ZAbfppvt--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/426540/c3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png" alt="miguelacallesmba"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/miguelacallesmba/an-overview-of-aws-serverless-computing-and-cdk-2poc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;An Overview of AWS, Serverless Computing, and CDK&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ Sep 23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cdk&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#serverless&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#books&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Chapter 1: Setting Up our AWS Account and CDK Environment
&lt;/h2&gt;

&lt;p&gt;We will set up our AWS account and development environment to create our application.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelacallesmba" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vPqR0N4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--ZAbfppvt--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/426540/c3a6ac8a-b6cf-4c55-affb-9bacfdd111d0.png" alt="miguelacallesmba"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/miguelacallesmba/setting-up-our-aws-account-and-cdk-environment-5c8b" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Setting Up our AWS Account and CDK Environment&lt;/h2&gt;
      &lt;h3&gt;Miguel A. Calles ・ Sep 23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cdk&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#serverless&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#books&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Chapter 2: Describing the CDK Application and Serverless Architecture
&lt;/h2&gt;

&lt;p&gt;We will review and modify the CDK app structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/describing-the-cdk-application-914efa958770"&gt;https://medium.com/chapter-by-chapter/describing-the-cdk-application-914efa958770&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 3: Describing the Serverless Architecture
&lt;/h2&gt;

&lt;p&gt;We will describe the serverless website we will build using CDK and the cloud resources needed to make it functional and practical.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 4: Launching a Website
&lt;/h2&gt;

&lt;p&gt;We will create a website and make it accessible on the Internet.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 5: Creating an API
&lt;/h2&gt;

&lt;p&gt;We will build an application programming interface the website will call to get information.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 6: Adding a Database
&lt;/h2&gt;

&lt;p&gt;We will create a serverless database and have the API read its data.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 7: Adding Authentication
&lt;/h2&gt;

&lt;p&gt;We will update the website to allow users to sign up, log in, and access protected pages.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 8: Saving Data
&lt;/h2&gt;

&lt;p&gt;We will allow logged-in users to save data to the website.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 9: Analyzing Data
&lt;/h2&gt;

&lt;p&gt;We will create a repeatable process to analyze the data.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 10: Conclusion
&lt;/h2&gt;

&lt;p&gt;We will discuss next steps and other things to consider.&lt;/p&gt;

&lt;p&gt;Coming soon…&lt;/p&gt;

&lt;h1&gt;
  
  
  Before you go
&lt;/h1&gt;

&lt;p&gt;Subscribe to my mailing list to get new chapters delivered to your email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://miguelacallesmba.medium.com/subscribe"&gt;https://miguelacallesmba.medium.com/subscribe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is your dream to write a book but you are worried you do not have what it takes? You can start writing one chapter at a time. Submit your drafts to the Chapter by Chapter publication and start realizing your dream.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/chapter-by-chapter/how-to-start-writing-your-book-with-chapter-by-chapter-1ec05495dcf4"&gt;https://medium.com/chapter-by-chapter/how-to-start-writing-your-book-with-chapter-by-chapter-1ec05495dcf4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>cloud</category>
      <category>cdk</category>
    </item>
    <item>
      <title>Be careful when using .env files</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Mon, 26 Sep 2022 16:19:11 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/be-careful-when-using-env-files-7fl</link>
      <guid>https://dev.to/miguelacallesmba/be-careful-when-using-env-files-7fl</guid>
      <description>&lt;p&gt;Not even within 24 hours, a recently launched website was being sniffed for secrets. A bot was searching for a &lt;code&gt;.env&lt;/code&gt; file where some projects store secrets. Fortunately, this website was protected by Cloudflare.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we learn from this?
&lt;/h2&gt;

&lt;p&gt;The .env file should be treated as a potential source of a cyber breach. We should be cautious about what data we store there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should we put secrets in the &lt;code&gt;.env&lt;/code&gt; file?
&lt;/h2&gt;

&lt;p&gt;No, when possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where should we store and use secrets?
&lt;/h2&gt;

&lt;p&gt;Store secrets in a secrets manager or database. Limit the use of secrets to the backend code (i.e., the code not used in the frontend web application code).&lt;/p&gt;

&lt;h2&gt;
  
  
  How can we protect the &lt;code&gt;.env&lt;/code&gt; file?
&lt;/h2&gt;

&lt;p&gt;We should use a Web Application Firewall to stop external HTTP requests from reading this file. The file should only be read by the application code.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://miguelacallesmba.medium.com/be-careful-when-using-env-files-be2e67db0248"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>When to use ?? and || in JavaScript and TypeScript</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Sat, 17 Sep 2022 00:26:17 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/when-to-use-and-in-javascript-and-typescript-pfh</link>
      <guid>https://dev.to/miguelacallesmba/when-to-use-and-in-javascript-and-typescript-pfh</guid>
      <description>&lt;p&gt;In this short post, I want to share a simple way to remember when to use &lt;code&gt;??&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; when checking values in JavaScript and TypeScript code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: You can read this post on &lt;a href="https://javascript.plainenglish.io/when-to-use-and-in-javascript-and-typescript-74533943d5f9"&gt;Medium&lt;/a&gt; too&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use &lt;code&gt;??&lt;/code&gt; when checking a value?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;??&lt;/code&gt; is an or operator where the left side must be empty before returning the right side.&lt;/p&gt;

&lt;p&gt;The question mark &lt;code&gt;?&lt;/code&gt; is like asking yourself, “Does the value exist?”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;varMustBeEmptyToReturnThisVar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;p&gt;Suppose you get an object where some properties are optional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;optional&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no optional property exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// returns 'no optional property exists'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be careful when the property returns a &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Falsy"&gt;falsy&lt;/a&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no required property exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// returns ''&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to use &lt;code&gt;||&lt;/code&gt; when checking a value?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;||&lt;/code&gt; is an or operator where the left side must be &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Falsy"&gt;falsy&lt;/a&gt; before returning the right side.&lt;/p&gt;

&lt;p&gt;The vertical bar &lt;code&gt;|&lt;/code&gt; is like putting up a barrier where only &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy"&gt;truthy&lt;/a&gt; values can stay on the left side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;varMustBeFalsyToReturnThisVar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Suppose you get an object where some properties are falsy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required property is falsy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// returns 'required property is falsy'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I sometimes misuse the &lt;code&gt;??&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; and thought I should write this reminder to myself. Hopefully that helps you too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before you go
&lt;/h3&gt;

&lt;p&gt;These are other articles you might enjoy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13"&gt;Stop Installing Node.js and Global Npm Packages, Use Docker Instead&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/geekculture/five-scary-linux-commands-you-should-not-run-4222773188bb"&gt;Five scary Linux commands you should not run&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/how-to-remove-sensitive-data-and-plaintext-secrets-from-github-ca8ca0b7675a"&gt;How to Remove Sensitive Data and Plaintext Secrets From GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/postman-secrets-cookies-cryptojs-4051db70e8c2"&gt;How to use CryptoJS and Cookies to Work with Secrets in Postman&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@towfiqu999999"&gt;Towfiqu barbhuiya&lt;/a&gt; on &lt;a href="https://unsplash.com"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Present like a boss with transcription and analytics based on Deepgram</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Fri, 01 Apr 2022 00:14:46 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/present-like-a-boss-with-transcription-and-analytics-based-on-deepgram-35f7</link>
      <guid>https://dev.to/miguelacallesmba/present-like-a-boss-with-transcription-and-analytics-based-on-deepgram-35f7</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;I learned about Deepgram from the hackathon on DEV. I had not heard of them prior. After reviewing their docs, it seemed to make speech to text much easier to adopt than some other services. Other services seem complex to build upon and building simple uses would take a long time. Deepgram seems like it could shorten development of simple use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Deepgram Use-Case
&lt;/h3&gt;

&lt;p&gt;Have you ever heard of someone giving a talk or a presentation and been impressed with their ability to present? You may have noticed they did not use filler words like "umm", "so", "and", etc.&lt;/p&gt;

&lt;p&gt;Think about the last time you heard a presentation and the speaker used these filler words frequently. Did you find the presentation hard to follow? Did the filler words seem to get louder and louder?&lt;/p&gt;

&lt;p&gt;Organizations like Toastmasters count how many filler words people use in their presentations. What if you could practice a presentation with an app and it would give you stats on filler words?&lt;/p&gt;

&lt;p&gt;What if the app could give you a score on sentiment? What if it could tell you how well your presentation would be received?&lt;/p&gt;

&lt;h3&gt;
  
  
  Dive into Details
&lt;/h3&gt;

&lt;p&gt;The app would Deepgram's text to speech. Either the prerecorded or live streaming options would work.&lt;/p&gt;

&lt;p&gt;Initially, the app would count filler words. The app would give statistics per presentation and over time. Whenever the number of filler words drops by every 10%, the presenter would get a badge. Another badge would get a special badge when they present without any filler words.&lt;/p&gt;

&lt;p&gt;Based on this Deepgram &lt;a href="https://developers.deepgram.com/use-cases/talk-time-analytics/"&gt;tutorial&lt;/a&gt;, the app could provide statistics on total pause time per presentation and even pauses between words. The app could suggest optimal pause lengths and frequency for a good presentation.&lt;/p&gt;

&lt;p&gt;Another feature would be add give statistics similar to reading level. Once the presentation is text form, the text could be analyzed for reading level. The average reading level would be provided and specifics for each sentence. The assumption is that the reading level would indicate what type of audience would be able to understand the presentation. A high reading level would indicate that the presentation is meant for expects, while a lower reading level would indicate a general audience. A presentation with the lowest reading level might be best appropriate for children.&lt;/p&gt;

&lt;p&gt;The apps analytics will evolve based on presentation best practices and user feedback.&lt;/p&gt;

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

&lt;p&gt;Deepgram's text to speech API seems to make transcriptions and analyzing the speech much easier than other platforms. Their capability can be used to help individuals improve their presentation and speaking skills by providing meaningful statistics and recommendations.&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@xteemu?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Teemu Paananen&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/presentation?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hackwithdg</category>
    </item>
    <item>
      <title>If you build it, you should break it</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Wed, 02 Mar 2022 16:57:01 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/if-you-build-it-you-should-break-it-14hb</link>
      <guid>https://dev.to/miguelacallesmba/if-you-build-it-you-should-break-it-14hb</guid>
      <description>&lt;p&gt;You may have heard, “If you build it, they will come.”&lt;/p&gt;

&lt;p&gt;Have you heard, “If you build it, I will break it?”&lt;/p&gt;

&lt;p&gt;This is a skill I developed over my career to build better systems. It is a skill that took me a while to learn I had.&lt;/p&gt;

&lt;p&gt;Shortly before I graduated from college, I decided to leave the material science industry because I had a tendency to break stuff. When working with toxic substances, this can be hazardous. As a result, I changed to the systems engineering field.&lt;/p&gt;

&lt;p&gt;It turned out I had a knack for breaking stuff there too. For a long while, I avoided working on things I could break. Yet, I found I wasn’t growing as much as my peers. So I decided I needed to do some hands-on work.&lt;/p&gt;

&lt;p&gt;As it turns out, I was breaking stuff, and people were getting mad. They had to fix deficiencies and errors I discovered. A time came people started expecting me to fix what I broke. That was a pivotal moment in my career.&lt;/p&gt;

&lt;p&gt;I had to learn how to fix things, and I wasn’t trained as an engineer. My undergrad was in material science. I started learning how to fix things and became more knowledgeable about the technology. I eventually learned how to find defects, flaws, and deficiencies in designs.&lt;/p&gt;

&lt;p&gt;I turned what I thought was a flaw into a skill. I could help build more reliable systems by “breaking them.” Penetration testers do this type of work. They look for vulnerabilities and ways to break “in.” I had a knack for finding ways to break “down” systems. If I can learn why a system could falter, I can help prevent it.&lt;/p&gt;

&lt;p&gt;My recommendation for your systems: Plan to break your system before it breaks on you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want to Connect?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://miguelacallesmba.com/"&gt;Miguel&lt;/a&gt; is a Principal Engineer and the author of the “&lt;a href="https://serverlesssecuritybook.com/"&gt;Serverless Security&lt;/a&gt;” book. He has worked on multiple serverless projects as a developer and security engineer, contributed to &lt;a href="https://github.com/miguel-a-calles-mba?tab=repositories"&gt;open-source serverless projects&lt;/a&gt;, and worked on large military systems in various engineering roles.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://miguelacallesmba.medium.com/if-you-build-it-you-should-break-it-25e06f2d53b6"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@marcrafanell"&gt;Marc Rafanell López&lt;/a&gt; on &lt;a href="https://unsplash.com/@marcrafanell"&gt;https://unsplash.com/@marcrafanell&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>security</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Stop Installing Node.js and Global Npm Packages, Use Docker Instead and Protect Your System from Vulnerabilities</title>
      <dc:creator>Miguel A. Calles</dc:creator>
      <pubDate>Wed, 23 Feb 2022 03:04:10 +0000</pubDate>
      <link>https://dev.to/miguelacallesmba/stop-installing-nodejs-and-global-npm-packages-use-docker-instead-protect-your-system-from-vulnerabilities-4ne4</link>
      <guid>https://dev.to/miguelacallesmba/stop-installing-nodejs-and-global-npm-packages-use-docker-instead-protect-your-system-from-vulnerabilities-4ne4</guid>
      <description>&lt;p&gt;There is a way to keep our computers isolated from malicious npm packages and cybersecurity vulnerabilities. It’s almost like Node and npm will be on an island.&lt;/p&gt;

&lt;p&gt;We can use a Docker container to run Node.js and install npm packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Docker containers and why should we use them?
&lt;/h2&gt;

&lt;p&gt;Docker is a software technology that creates a container that runs on our computer. A container is like running a mini computer within ours and restricts access to our files.&lt;/p&gt;

&lt;p&gt;The problem with running Node.js on our computer is the growth of malicious npm packages. There are some malicious actors that purposely put malware in npm packages. They create packages with similar names (called typosquatting) hoping we will install the incorrect version so they can deliver the malware.&lt;/p&gt;

&lt;p&gt;These types of npm attacks have been &lt;a href="https://threatpost.com/5-top-threatpost-stories-2021/177278/"&gt;growing significantly&lt;/a&gt; and will continue &lt;a href="https://www.securityweek.com/cyber-insights-2022-supply-chain"&gt;being an issue in 2022&lt;/a&gt; and future years.&lt;/p&gt;

&lt;p&gt;What if we installed a malicious npm package and we can limit the extent of the damage? That is where containers can help.&lt;/p&gt;

&lt;p&gt;Suppose we installed an &lt;a href="https://blog.sonatype.com/fake-npm-roblox-api-package-installs-ransomware-spooky-surprise"&gt;npm package that deployed ransomware&lt;/a&gt;. All our files would become a victim to the ransomware attack if we were running Node.js on our computer.&lt;/p&gt;

&lt;p&gt;Suppose we installed it inside a container. A properly configured container will limit access to the files added to the container. In theory, only those specific files will be compromised and our personal files should be protected. We can stop the container, delete the container image, purge all files associated with the container, and run an antivirus scan just to be safe. Given we commit our code to a software repository, we probably only lost a little bit of our code.&lt;/p&gt;

&lt;p&gt;Using a Docker container to run Node.js is like putting our code in quarantine so that an infection does not put a strain on the whole computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I set up Node.js and npm on my machine?
&lt;/h2&gt;

&lt;p&gt;Start by installing &lt;a href="https://www.docker.com/products/docker-desktop"&gt;Docker Desktop&lt;/a&gt; on our development machine. We will want to create a Docker account also to take advantage Docker scan feature that we will discuss later.&lt;/p&gt;

&lt;p&gt;After we install it, go to the settings.&lt;/p&gt;

&lt;p&gt;Enable “Docker Compose V2” in the “General” section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GTpz4UEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol2f14nexxt831hwge30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GTpz4UEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol2f14nexxt831hwge30.png" alt="Docker General settings." width="700" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;General settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Set the desired resource load in the “Resources Advanced” section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eK7P_CMJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqks19dzyh77i8ptpna8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eK7P_CMJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqks19dzyh77i8ptpna8.png" alt="Docker Advanced Resources settings.&amp;lt;br&amp;gt;
" width="700" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Advanced Resources settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ensure software updates are enabled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_gglfIgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nscn578y7tknba4rt9qo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_gglfIgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nscn578y7tknba4rt9qo.png" alt="Docker Software Updates settings." width="700" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Software Updates settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Go to our code folder. Create a file called &lt;code&gt;docker-compose.yml&lt;/code&gt; in the top-level directory (or in every folder that we want a customized container).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node:14.18.1-buster-slim"&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node"&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/node/dev&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/home/node/dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker Compose file creates and runs a Docker container without to build it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;image:&lt;/code&gt; property defines the node container. The example uses an official Node.js container image. The version was selected based on the recommendation from the Docker scan.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;working_dir:&lt;/code&gt; property defines the home directory as &lt;code&gt;/home/node/dev&lt;/code&gt;. (When we start the container it will show dev as the current folder.)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;volumes:&lt;/code&gt; property allows running Docker within container and puts all the files where the &lt;code&gt;docker-compose.yml&lt;/code&gt; exists, and mounts them to the &lt;code&gt;/home/node/dev&lt;/code&gt; directory within the container. (We can delete the first line if we do not need Docker running within the container.)&lt;/p&gt;

&lt;p&gt;Using another image like one from Circle (e.g., &lt;code&gt;circleci/node:14-bullseye&lt;/code&gt;) provides git and other common Linux utilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;circleci/node:14-bullseye"&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/node/dev&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/home/node/dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our computer’s terminal, run the following command to start the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; dev bash
&lt;span class="c"&gt;# Or the following if Docker Compose v2 was not checked above&lt;/span&gt;
docker-compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; dev bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will now see a prompt like &lt;code&gt;node@502104098e72:~/code$&lt;/code&gt; in the terminal. This means our terminal is now inside the Docker container running node.&lt;/p&gt;

&lt;p&gt;Type the &lt;code&gt;ls&lt;/code&gt; command to see our files. We should see our the files within the directory.&lt;/p&gt;

&lt;p&gt;Open Docker Desktop and we will see our container running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s-1i1XZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o38a56sctqd0lg1yw6w1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s-1i1XZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o38a56sctqd0lg1yw6w1.png" alt="A Docker container is running." width="700" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A container is running.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We can now run &lt;code&gt;npm i -g some_package_name&lt;/code&gt; and &lt;code&gt;npm ci&lt;/code&gt; within the container.&lt;/p&gt;

&lt;p&gt;(If we have Node installed on our machine, we can try installing a different global npm package in our container. We open a new terminal window, try running the global npm package and we should get an error because it is only installed in our container.)&lt;/p&gt;

&lt;p&gt;In the container’s terminal, type the &lt;code&gt;exit&lt;/code&gt; command. Go to Docker Desktop and we should no longer see the container.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CqT5gItl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs7zlkdr31kcca12ylka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CqT5gItl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs7zlkdr31kcca12ylka.png" alt="No Docker container is running." width="700" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No container is running.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--rm&lt;/code&gt; flag in the &lt;code&gt;docker compose run&lt;/code&gt; commands tells Docker to delete the container after it terminates. This way we can keep our machine cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping Docker up to date and clean
&lt;/h2&gt;

&lt;p&gt;We should apply the Docker software updates when they become available.&lt;/p&gt;

&lt;p&gt;After we apply the updates, we should scan our container for vulnerabilities with a &lt;a href="https://docs.docker.com/engine/scan/"&gt;Docker scan&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We need to accept the license to get started with Docker scan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker scan &lt;span class="nt"&gt;--accept-license&lt;/span&gt; &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can scan our Node.js container with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker scan node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scan output will recommend which container image to use. We will update the &lt;code&gt;image:&lt;/code&gt; property within the &lt;code&gt;docker-compose.yml&lt;/code&gt; file to have the recommend image.&lt;/p&gt;

&lt;p&gt;Every so often we should clean up the images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tResplrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nx0bsmsgrx4j533sm9ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tResplrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nx0bsmsgrx4j533sm9ik.png" alt="Cleaning up Docker images." width="700" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cleaning up images.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And remove old volumes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q-tt2mG3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1771jsgzynbbo35ignd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q-tt2mG3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1771jsgzynbbo35ignd.png" alt="Removing Docker volumes." width="700" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Removing volumes.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Using Docker containers is one way to protect our computers from malicious npm packages and Node.js vulnerabilities because code execution and runtimes are isolated to the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want to Connect?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://miguelacallesmba.com/"&gt;Miguel&lt;/a&gt; is a Principal Engineer and the author of the “&lt;a href="https://serverlesssecuritybook.com/"&gt;Serverless Security&lt;/a&gt;” book. He has worked on multiple serverless projects as a developer and security engineer, contributed to &lt;a href="https://github.com/miguel-a-calles-mba?tab=repositories"&gt;open-source serverless projects&lt;/a&gt;, and worked on large military systems in various engineering roles.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://medium.com/better-programming/stop-installing-node-js-and-global-npm-packages-use-docker-instead-42597990db13"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@twinckels"&gt;Tom Winckels&lt;/a&gt; on &lt;a href="https://unsplash.com/"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>node</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
  </channel>
</rss>
