<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: RedRobot.dev</title>
    <description>The latest articles on Forem by RedRobot.dev (@redrobotdev).</description>
    <link>https://forem.com/redrobotdev</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%2F1600825%2F231d77b1-c596-41fe-bc41-ecb8309bf37a.png</url>
      <title>Forem: RedRobot.dev</title>
      <link>https://forem.com/redrobotdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/redrobotdev"/>
    <language>en</language>
    <item>
      <title>Deploy Next.js using Amplify &amp; AWS CDK</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 25 Nov 2024 19:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/deploy-nextjs-using-amplify-aws-cdk-48g0</link>
      <guid>https://forem.com/redrobotdev/deploy-nextjs-using-amplify-aws-cdk-48g0</guid>
      <description>&lt;p&gt;In this guide, we'll dive into the process of deploying a Next.js application using AWS CDK (Cloud Development Kit) and Amplify Gen 2. We'll explore how these powerful tools can be combined to create a seamless, serverless deployment pipeline for your Next.js projects. You'll learn how to leverage AWS CDK's infrastructure-as-code capabilities to define your cloud resources, while harnessing Amplify's built-in support for Next.js to simplify hosting and continuous deployment. By the end of this journey, you'll have a robust understanding of how to create scalable, easily maintainable Next.js deployments on AWS.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Original Post&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/nextjs-aws-amplify" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;In this comprehensive guide, we'll explore the process of deploying a Next.js application using AWS CDK (Cloud Development Kit) and Amplify Gen 2. We'll demonstrate how these tools can be combined to create a seamless, serverless deployment pipeline for your Next.js projects. You'll learn to harness AWS CDK's infrastructure-as-code capabilities to define and manage your cloud resources efficiently, while leveraging Amplify's specialized support for Next.js to streamline hosting and enable continuous deployment. By the end of this tutorial, you'll have gained a robust understanding of how to deploy your Next.js app to AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44greozti67x18gvaql0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44greozti67x18gvaql0.gif" alt="Final Output" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/ababakanian/nextjs-aws-amplify" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Amplify
&lt;/h2&gt;

&lt;p&gt;AWS Amplify is a comprehensive service designed to simplify full-stack application development and deployment on AWS. It provides a unified, streamlined developer experience by abstracting away the complexity of managing multiple AWS services. Amplify leverages a suite of powerful AWS tools including S3, API Gateway, CodeBuild, Cognito, and Lambda, enabling developers to create robust infrastructure supporting their required features without needing deep expertise in cloud architecture.&lt;/p&gt;

&lt;p&gt;One of Amplify's key strengths is its dedicated UI libraries for popular frameworks such as React, Next.js, Angular, and Vue, facilitating faster integration and development. The core concept behind Amplify is elegantly simple: using only TypeScript code, developers can express their app's data model, business logic, authentication, and authorization rules. Amplify then automatically configures the appropriate cloud resources, eliminating the need to manually stitch together underlying AWS services. This approach positions Amplify as a comprehensive, end-to-end full-stack development framework.&lt;/p&gt;

&lt;p&gt;Amplify Gen 2 represents AWS's latest effort to further streamline the development process for full-stack applications. It builds upon the foundations of the original Amplify, offering enhanced features and improved performance. This new generation aims to make it even easier for developers to harness the power of AWS services, reducing the learning curve and allowing teams to focus more on building innovative applications rather than managing infrastructure. With Amplify Gen 2, AWS continues to bridge the gap between development and operations, empowering developers to create sophisticated, scalable applications with greater efficiency and less complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics Covered in this guide
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we'll walk through the process of deploying and updating a Next.js application using AWS CDK and Amplify. We'll cover the entire workflow from initial development to automated deployment. Here's what we'll accomplish:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Next.js application: We'll start by building a starter Next.js app that utilizes both Server-Side Rendering (SSR) and Static Site Generation (SSG) capabilities.&lt;/li&gt;
&lt;li&gt;Version control with GitHub: We'll push our frontend code to a GitHub repository, setting the stage for continuous integration and deployment.&lt;/li&gt;
&lt;li&gt;AWS CDK and Amplify setup: Using AWS CDK and Amplify libraries, we'll create an Amplify project that specifies the build steps and connects to our GitHub repository. This step will demonstrate how to define your cloud infrastructure as code.&lt;/li&gt;
&lt;li&gt;Initial deployment: We'll trigger an initial deployment to test our setup and ensure everything is working correctly.&lt;/li&gt;
&lt;li&gt;Implement and deploy changes: Finally, we'll make updates to our frontend, push these changes to GitHub, and observe how Amplify automatically detects and deploys these updates, showcasing the power of continuous deployment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Node.js and npm installed&lt;/li&gt;
&lt;li&gt;AWS cli and cdk setup and configured&lt;/li&gt;
&lt;li&gt;Basic knowledge in Javascript and Typescript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Github Project
&lt;/h2&gt;

&lt;p&gt;Open up Github, create a new repo and name it &lt;code&gt;nextjs-aws-amplify&lt;/code&gt;. See this repo as an example:&lt;br&gt;
&lt;a href="https://github.com/ababakanian/nextjs-aws-amplify" rel="noopener noreferrer"&gt;https://github.com/ababakanian/nextjs-aws-amplify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pull the code locally (replace the username with yours)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:&amp;lt;your-user-name&amp;gt;/nextjs-aws-amplify.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get an access token
&lt;/h3&gt;

&lt;p&gt;In addition, lets create an access token in github. Go to the &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;Github Personal access token page&lt;/a&gt; page and click on &lt;strong&gt;Generate new token (classic)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixaekomj9kevaawcaqui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixaekomj9kevaawcaqui.png" alt="github access token" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;select a name for the access token and from teh &lt;strong&gt;select scopes&lt;/strong&gt; list select the &lt;strong&gt;repo&lt;/strong&gt; option. Scroll down and click on &lt;strong&gt;Generate token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Copy the generate token and lets add it to an env file.&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;nextjs-aws-amplify
&lt;span class="nb"&gt;touch&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;open the .env file and add a variable for the github token in the env file.&lt;br&gt;
So your .env file should look this this.&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="nv"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Do no copy this value, this is not going to work for you as it belongs to our repo and also it's been deleted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Add the .env file to your .gitignore list, touch &lt;code&gt;.env&lt;/code&gt; and then open the file and add .env.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Next.js Project
&lt;/h2&gt;

&lt;p&gt;Make sure you are in the &lt;code&gt;nextjs-aws-amplify&lt;/code&gt; folder, then create a NextJS project. Open a terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;enter &lt;code&gt;frontend&lt;/code&gt; for the app name. Then you will be presented with several options, choose the options as you&lt;br&gt;
see here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Need to &lt;span class="nb"&gt;install &lt;/span&gt;the following packages:
create-next-app@14.2.5
Ok to proceed? &lt;span class="o"&gt;(&lt;/span&gt;y&lt;span class="o"&gt;)&lt;/span&gt; y

✔ What is your project named? … test-frontend
✔ Would you like to use TypeScript? … No / &lt;span class="k"&gt;**&lt;/span&gt;Yes&lt;span class="k"&gt;**&lt;/span&gt;
✔ Would you like to use ESLint? … No / &lt;span class="k"&gt;**&lt;/span&gt;Yes&lt;span class="k"&gt;**&lt;/span&gt;
✔ Would you like to use Tailwind CSS? … No / &lt;span class="k"&gt;**&lt;/span&gt;Yes&lt;span class="k"&gt;**&lt;/span&gt;
✔ Would you like to use &lt;span class="sb"&gt;`&lt;/span&gt;src/&lt;span class="sb"&gt;`&lt;/span&gt; directory? … No / &lt;span class="k"&gt;**&lt;/span&gt;Yes&lt;span class="k"&gt;**&lt;/span&gt;
✔ Would you like to use App Router? &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt; … No / &lt;span class="k"&gt;**&lt;/span&gt;Yes&lt;span class="k"&gt;**&lt;/span&gt;
✔ Would you like to customize the default import &lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;@/&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;? … &lt;span class="k"&gt;**&lt;/span&gt;No&lt;span class="k"&gt;**&lt;/span&gt; / Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will come back and modify the frontend code later. However, lets push this code to github and get the github config info.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial commit, added frontend nextjs"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a &lt;code&gt;.nvmrc&lt;/code&gt; file and add the value nodejs.&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"v20.11.1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .nvmrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create AWS CDK
&lt;/h2&gt;

&lt;p&gt;By leveraging an IaC system like AWS cdk, you can automate and replicate all the setup and configuration work typically done through the console. This approach significantly speeds up your website deployment process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a new CDK project, make sure you are in the top level &lt;code&gt;nextjs-aws-amplify&lt;/code&gt; folder created earlier. Then create an &lt;strong&gt;infrastructure&lt;/strong&gt; folder and initialize it with cdk code.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;infrastructure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;infrastructure
cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you haven't setup cdk yet, visit [AWS CDK Getting started (&lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Install the amplify library
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @aws-cdk/aws-amplify-alpha@2.39.1-alpha.0 &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: At the time of writing this post the library is in alpha stage. Check the &lt;a href="https://www.npmjs.com/package/@aws-cdk/aws-amplify-alpha/v/2.39.1-alpha.0" rel="noopener noreferrer"&gt;npm page&lt;/a&gt; here to see if the version has left the alpha stage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Install supporting libraries:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i dotenv &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a file named in lib named &lt;code&gt;lib/amplify-gen-stack.ts&lt;/code&gt; with the following content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;amplify&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-amplify-alpha&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;CfnOutput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SecretValue&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="nx"&gt;StackProps&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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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;BuildSpec&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="s2"&gt;aws-cdk-lib/aws-codebuild&lt;/span&gt;&lt;span class="dl"&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;ManagedPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ServicePrincipal&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="s2"&gt;aws-cdk-lib/aws-iam&lt;/span&gt;&lt;span class="dl"&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;CfnApp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CfnBranch&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="s2"&gt;aws-cdk-lib/aws-amplify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AmplifyStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;githubOauthToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SecretValue&lt;/span&gt;
  &lt;span class="nx"&gt;repoOwner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;repoName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;domain&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AmplifyStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&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;AmplifyStackProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amplifyApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;App&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="s2"&gt;AmplifyAppResource&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;appName&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;repoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nextjs frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Role&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="s2"&gt;AmplifyRoleWebApp&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;assumedBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ServicePrincipal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amplify.amazonaws.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;managedPolicies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nx"&gt;ManagedPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAwsManagedPolicyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AdministratorAccess-Amplify&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="na"&gt;sourceCodeProvider&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;amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GitHubSourceCodeProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;oauthToken&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;githubOauthToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;owner&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;repoOwner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;repository&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;repoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;buildSpec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BuildSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromObjectToYaml&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;applications&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="na"&gt;appRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;preBuild&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nvm install&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="s2"&gt;nvm use&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="s2"&gt;export NODE_OPTIONS=--max-old-space-size=8192&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="s2"&gt;npm install&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="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm run build&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="na"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;baseDirectory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cfnApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;amplifyApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultChild&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CfnApp&lt;/span&gt;
    &lt;span class="nx"&gt;cfnApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WEB_COMPUTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainBranch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;amplifyApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addBranch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main&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;autoBuild&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PRODUCTION&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;amplifyApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addDomain&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;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enableAutoSubdomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainBranch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapSubDomain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainBranch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;www&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="nx"&gt;cfnBranch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mainBranch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultChild&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CfnBranch&lt;/span&gt;
    &lt;span class="nx"&gt;cfnBranch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;framework&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Next.js - SSR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CfnOutput&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="s2"&gt;AmplifyAppURL&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://main.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amplifyApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultDomain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Amplify App URL&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;The &lt;code&gt;amplify.App&lt;/code&gt; construct has two main parts, the source code repo configuration and the build instructions.&lt;br&gt;
We define the code repo location using&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="nx"&gt;sourceCodeProvider&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;amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GitHubSourceCodeProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;oauthToken&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;githubOauthToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;owner&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;repoOwner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;repository&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;repoName&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;and we define the build and artifacts information:&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="nx"&gt;buildSpec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BuildSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromObjectToYaml&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;applications&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="na"&gt;appRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;preBuild&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nvm install&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="s2"&gt;nvm use&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="s2"&gt;export NODE_OPTIONS=--max-old-space-size=8192&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="s2"&gt;npm install&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="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm run build&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="na"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;baseDirectory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;essentially we are installing node, and installing all the node packages in the prebuild step. Then we run &lt;code&gt;npm run build&lt;/code&gt; to build the nextjs app.&lt;br&gt;
The artifacts section specifies where our external files will be located.&lt;/p&gt;

&lt;p&gt;To learn more check the &lt;a href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-amplify-alpha-readme.html" rel="noopener noreferrer"&gt;AWS cdk Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets use the stack in our &lt;code&gt;bin/infrastructure.ts&lt;/code&gt; file:&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="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source-map-support/register&lt;/span&gt;&lt;span class="dl"&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;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&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;AmplifyStack&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="s2"&gt;../lib/amplify-gen-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../.env&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;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;AWS_REGION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DOMAIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GITHUB_REPO_OWNER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GITHUB_REPO_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;AWS_ACCOUNT_ID&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_REPO_OWNER&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_REPO_NAME&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;DOMAIN&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;check .env file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;check .env file&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&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="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AmplifyStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AmplifyStack&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;githubOauthToken&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;SecretValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsafePlainText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;repoOwner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GITHUB_REPO_OWNER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;repoName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GITHUB_REPO_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DOMAIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AWS_REGION&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;add the remaining variable to the &lt;code&gt;.env&lt;/code&gt; file we created earlier:&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="nv"&gt;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AWS account number
&lt;span class="nv"&gt;AWS_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your deployment region
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your domain name
&lt;span class="nv"&gt;GITHUB_REPO_OWNER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;the github repo owner
&lt;span class="nv"&gt;GITHUB_REPO_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;the repo name
&lt;span class="nv"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;the github access token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so your data should look something like this;&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="nv"&gt;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"975421487117"&lt;/span&gt;
&lt;span class="nv"&gt;AWS_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redrobotexample.com
&lt;span class="nv"&gt;GITHUB_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ghp_KGu0GbvmdOiFNUzK6mGGFRBxBMM3rc1sTq0C
&lt;span class="nv"&gt;GITHUB_REPO_OWNER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redrobotdev
&lt;span class="nv"&gt;GITHUB_REPO_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nextjs-aws-amplify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now deploy the stack, make sure you are in the &lt;code&gt;infrastructure&lt;/code&gt; folder then call deploy.&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;infrastructure
cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once deployment, you will see the following message in the console&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;AmplifyStack: creating CloudFormation changeset...

 ✅  AmplifyStack

✨  Deployment &lt;span class="nb"&gt;time&lt;/span&gt;: 51.82s

Outputs:
AmplifyStack.AmplifyAppURL &lt;span class="o"&gt;=&lt;/span&gt; https://main.dqsf8v3g3qb5.amplifyapp.com
Stack ARN:
arn:aws:cloudformation:us-east-1:975050147627:stack/AmplifyStack/3e7e4c70-58c9-11ef-bff5-121072f7c15f

✨  Total &lt;span class="nb"&gt;time&lt;/span&gt;: 56.97s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy the Application
&lt;/h2&gt;

&lt;p&gt;So we have successfully created an Amplify project, we need to go to teh AWS console and start a deployment.&lt;br&gt;
Go to the AWS Console page, and open the &lt;code&gt;AWS Amplify&lt;/code&gt; service page. You should see the &lt;strong&gt;nextjs-aws-amplify&lt;/strong&gt;, project listed.&lt;/p&gt;

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

&lt;p&gt;Click on the project and if you see a Migrate to Github app message, ignore it by clicking Remind me later.&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;main&lt;/strong&gt; branch&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tt5bn5kvuf1jgpo434a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tt5bn5kvuf1jgpo434a.png" alt="nextjs-aws-amplify-overview" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on the &lt;strong&gt;Run job&lt;/strong&gt; button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudupixk1g5ut91mjp2b8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudupixk1g5ut91mjp2b8.png" alt="next-aws-amplify-run-job" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait until the Deployments is done&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4jijlylv29la6dib2sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4jijlylv29la6dib2sn.png" alt="nextjs-aws-amplify-deployments" width="800" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once deployed, the box should go green, and the status should say deployed&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5abodt4vl36yi7xvk7c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5abodt4vl36yi7xvk7c0.png" alt="deployed-status" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;visit the domain name and you should see the Nextjs page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokvkzs8wdh4x2vr148pf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokvkzs8wdh4x2vr148pf.png" alt="website" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Update the frontend
&lt;/h2&gt;

&lt;p&gt;Amplify has CI/CD integrated into it's system, so we can make changes to our frontend and push our changed directly to github. Amplify will get notified of a recent push, and it will automatically pull the code, build and redeploy it.&lt;/p&gt;

&lt;p&gt;Lets first install shadcn in our frontend. make sure you have traversed into the frontend folder &lt;code&gt;cd frontend&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn-ui@latest init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then install the card and button components&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn-ui@latest add card button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the file from the same frontend folder &lt;code&gt;/src/app/page.tsx&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex min-h-screen flex-col space-y-4 items-center p-24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;
        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/next.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Next.js Logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;priority&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/invoice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;underline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Invoice&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Lets create a new folder named &lt;code&gt;invoice&lt;/code&gt; and &lt;code&gt;page.tsx&lt;/code&gt; so you have the path &lt;code&gt;nextjs-aws-amplify/src/app/invoice/page.tsx&lt;/code&gt;. Paste the following content in there:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;force-dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&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;Card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CardContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CardHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CardTitle&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="s2"&gt;@/components/ui/card&lt;/span&gt;&lt;span class="dl"&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;Button&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="s2"&gt;@/components/ui/button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;FinancePage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt; &lt;span class="c1"&gt;// Random income between 50,000 and 150,000&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;income&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Random profit up to 30% of income&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container mx-auto p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold mb-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Financial&lt;/span&gt; &lt;span class="nx"&gt;Dashboard&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid grid-cols-1 md:grid-cols-2 gap-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardHeader&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardTitle&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Income&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardTitle&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardHeader&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;income&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardContent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Card&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardHeader&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardTitle&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Profit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardTitle&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardHeader&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CardContent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Card&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;commit and push the changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"added the invoice page"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the AWS console/Amplify Service page you will see a new deployment has started. Make sure the deployment goes through fine and refresh the website to see the affected changes.&lt;br&gt;
Verify the changes has taken affect and you can see the invoice page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The home page is a Static page so it's not showcasing the power of amplify serverless nextjs deployment. Go to the &lt;code&gt;invoice&lt;/code&gt; page and refresh the page and you will notice on each refresh the values changes. This page is Server Side Rendered and demonstrates the server side rendering capability of Next.js.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;In this short guide, we've walked through the process of deploying a simple Next.js page using AWS CDK and Amplify Gen 2. We've covered everything from setting up a Next.js project and managing it with GitHub, to creating an AWS CDK stack for Amplify deployment, and finally implementing and automatically deploying updates. By leveraging the power of AWS CDK's infrastructure-as-code capabilities and Amplify's streamlined deployment pipeline, we've demonstrated how to create a scalable, easily maintainable Next.js application on AWS. This approach not only simplifies the deployment process but also enables continuous integration and deployment, allowing developers to focus more on building innovative features rather than managing infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in learning more?
&lt;/h2&gt;

&lt;p&gt;If you are interested in creating a project from scratch using AWS CDK and serverless technologies, you can check out the course linked below. In this course, we go over each service in detail, explaining what they do, and actually create a dynamic application with user login and authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A&amp;amp;couponCode=LEARNNOWPLANS" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>amplify</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Next.js Deployment using ECS with Fargate</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 18 Nov 2024 19:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/nextjs-deployment-using-ecs-with-fargate-2cno</link>
      <guid>https://forem.com/redrobotdev/nextjs-deployment-using-ecs-with-fargate-2cno</guid>
      <description>&lt;p&gt;In this post, we'll explore how to deploy a Next.js application to AWS using Elastic Container Service (ECS). We'll cover two approaches: first, using the AWS Management Console, and then using AWS CDK (Cloud Development Kit). Throughout this process, you'll gain a comprehensive understanding of ECS and its key concepts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Original Post&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/nextjs-ecs-deployment" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Elastic Container Services
&lt;/h2&gt;

&lt;p&gt;Amazon Elastic Container Service (ECS) is a powerful container orchestration service that simplifies the process of deploying, managing, and scaling containerized applications. With ECS, you can upload your Docker image and run it in a highly scalable, high-performance, and resilient environment that automatically handles load balancing and auto-scaling for you.&lt;br&gt;
ECS integrates seamlessly with other AWS services such as Application Load Balancer (ALB) and Virtual Private Cloud (VPC) to provide the scalability and load balancing capabilities your application requires. As a comprehensive container orchestration solution, ECS offers the following key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auto-scaling: Automatically adjusts the number of containers based on demand&lt;/li&gt;
&lt;li&gt;Load balancing: Distributes incoming traffic across multiple containers&lt;/li&gt;
&lt;li&gt;IAM integration: Manages access control and permissions&lt;/li&gt;
&lt;li&gt;Networking: Provides flexible networking options through VPC integration&lt;/li&gt;
&lt;li&gt;Logging: Offers built-in logging capabilities for easy troubleshooting&lt;/li&gt;
&lt;li&gt;Monitoring: Enables real-time monitoring of your containerized applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This robust set of features makes ECS an excellent choice for running and scaling Docker containers on AWS, providing you with a reliable and efficient platform for your containerized applications.&lt;/p&gt;

&lt;p&gt;Before diving into ECS, it's important to understand two key concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Virtual Private Cloud (VPC): If you're not familiar with VPC, we recommend reading our &lt;a href="https://dev.to/learn/articles/aws-vpc"&gt;"AWS Virtual Private Network Explained"&lt;/a&gt; post. This will provide you with the necessary background information to effectively use ECS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Containerization: To use ECS, we need to containerize our Next.js application using Docker. If you're new to Docker and containers, our &lt;a href="https://dev.to/learn/articles/nextjs-containerization"&gt;"Next.js Containerization"&lt;/a&gt; post explains what containers are and how to containerize and run a Next.js app.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally, it's worth noting that an Application Load Balancer (ALB) is typically used when you have more than one task and need to route packets for high-availability deployments. The ALB distributes incoming application traffic across multiple targets, such as EC2 instances, in multiple Availability Zones.&lt;/p&gt;
&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;This is the typical ECS deployment, and in this post we will be creating the following architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwxcxmxjbf3crrzxl4qt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwxcxmxjbf3crrzxl4qt.png" alt="ECS Architecture" width="800" height="816"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't worry if this architecture seems complex at first glance—we'll guide you through creating it without delving into low-level details. Here's a simplified overview of how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clients send HTML page requests through the Internet Gateway.&lt;/li&gt;
&lt;li&gt;These requests are received by an Application Load Balancer (ALB).&lt;/li&gt;
&lt;li&gt;The ALB forwards the requests to one of the Next.js tasks.&lt;/li&gt;
&lt;li&gt;These tasks are managed by AWS Fargate and Elastic Container Service (ECS).&lt;/li&gt;
&lt;li&gt;During deployment, the Next.js image is loaded from Elastic Container Registry (ECR).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This setup ensures efficient distribution of incoming traffic and seamless management of your containerized Next.js application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using Console
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Upload image to AWS
&lt;/h3&gt;

&lt;p&gt;First step is to build and upload our container image to AWS ECR or the Elastic Container Registry.&lt;/p&gt;

&lt;p&gt;Follow the steps described &lt;a href="https://dev.to/learn/articles/nextjs-containerization#containerizing-a-nextjs-application"&gt;here&lt;/a&gt; to build and run a docker container of a Next.js application.&lt;/p&gt;

&lt;p&gt;To verify you have correctly built the image, run the following command and verify you see a similar output&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="nv"&gt;$ &lt;/span&gt;docker image &lt;span class="nb"&gt;ls
&lt;/span&gt;REPOSITORY                  TAG       IMAGE ID       CREATED      SIZE
nextjs-frontend             latest    f42f21949703   4 days ago   738MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a Register in the ECR console. Open the AWS Console and go to the ECS service page. From the left panel, click &lt;strong&gt;Repositories&lt;/strong&gt;, then create &lt;strong&gt;Create repository&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7or8jfg4dhtxg4zbbgm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7or8jfg4dhtxg4zbbgm.png" alt="ECR Service Page" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;private&lt;/strong&gt; for the visibility settings, and type in &lt;strong&gt;nextjs-frontend&lt;/strong&gt; for the repository name.&lt;/p&gt;

&lt;p&gt;Now lets upload the image to ECR, first you need to get an authentication token for each registry. run this to do that:&lt;/p&gt;

&lt;p&gt;replace the two "&amp;lt;region&amp;gt;" and the one "&amp;lt;aws_account_id&amp;gt;" values with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region&amp;gt; | docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; &amp;lt;aws_account_id&amp;gt;.dkr.ecr.&amp;lt;region&amp;gt;.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; 975050147627.dkr.ecr.us-east-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then tag your local image, with the name of the remote repository name, replace the command with the correct region and account id:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker tag nextjs-frontend &amp;lt;aws_account_id&amp;gt;.dkr.ecr.&amp;lt;region&amp;gt;.amazonaws.com/nextjs-frontend:lastest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker tag nextjs-frontend 975050147627.dkr.ecr.us-east-1.amazonaws.com/nextjs-frontend:lastest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to verify run &lt;code&gt;docker image ls&lt;/code&gt; and you should see a secondary image with the name you entered above.&lt;/p&gt;

&lt;p&gt;to finally push your image run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker push &amp;lt;aws_account_id&amp;gt;.dkr.ecr.&amp;lt;region&amp;gt;.amazonaws.com/nextjs-frontend:lastest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker push 975050147627.dkr.ecr.us-east-1.amazonaws.com/nextjs-frontend:lastest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;once pushed, you should see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;The push refers to repository &lt;span class="o"&gt;[&lt;/span&gt;975050147627.dkr.ecr.us-east-1.amazonaws.com/nextjs-frontend]
947f16d41eae: Pushed
df7925d45941: Pushed
f0d00ab152e9: Pushed
5e60551565b3: Pushed
f7561880256e: Pushed
60fb86bbe6c7: Pushed
dc01ec349cf7: Pushed
f87675c73d4d: Pushed
28576ee1ff32: Pushed
daa732f7b271: Pushed
7cc8f366b357: Pushed
78561cef0761: Pushed
latest: digest: sha256:4143d5b35602520f3f22b84cd3e15b90c6bbe1d315a44ad7b19a93791eb41266 size: 2821
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read the &lt;a href="https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html" rel="noopener noreferrer"&gt;"Pushing a Docker image to an Amazon ECR private repository"&lt;/a&gt; article from AWS for more detailed explanation or if you are having trouble with the steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining a VPC
&lt;/h3&gt;

&lt;p&gt;Follow the instructions in &lt;a href="https://dev.to/learn/articles/aws-vpc"&gt;AWS Virtual Private Network Explained&lt;/a&gt; to create a default VPC using the &lt;strong&gt;VPC and more&lt;/strong&gt; option. Name your vpc something like &lt;strong&gt;nextjs-vpc&lt;/strong&gt;. By the end you should have a VPC with two AZ's, with one public and one private subnet per AZ, with 3 routing tables, one connected to a IG and two isolating the private subnets, and we don't need a VPC endpoint for this.&lt;/p&gt;

&lt;p&gt;If you are new to Virtual Private Cloud (VPC) read &lt;a href="https://dev.to/learn/articles/aws-vpc"&gt;AWS Virtual Private Network Explained&lt;/a&gt; and follow the instructions. IF you are familair with VPC, create a VPC and use the "VPC and more" option to create a default VPC. Name your VPC something descriptive, such as "nextjs-vpc".&lt;/p&gt;

&lt;p&gt;After completing these steps, your VPC should have the following configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two Availability Zones (AZs)&lt;/li&gt;
&lt;li&gt;One public subnet and one private subnet per AZ&lt;/li&gt;
&lt;li&gt;Three routing tables, One connected to an Internet Gateway (IG), Two isolating the private subnets&lt;/li&gt;
&lt;li&gt;No VPC endpoint (not needed for this setup)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This configuration provides a secure and scalable network foundation for your ECS deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining a Task Definition
&lt;/h3&gt;

&lt;p&gt;To prepare your application to run on Amazon ECS, you need to create a task definition.&lt;br&gt;
Task definitions specify various parameters for your application such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Containers to use (up to a maximum of 10 that form your application)&lt;/li&gt;
&lt;li&gt;Launch type to use (such as Fargate or EC2)&lt;/li&gt;
&lt;li&gt;Inbound ports that need to be opened for your application&lt;/li&gt;
&lt;li&gt;Data volumes to be used with the containers in the task&lt;/li&gt;
&lt;li&gt;Additional launch type-specific parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Task definitions act as a blueprint for your application, defining how it should run within ECS. They allow you to specify resource requirements, network configurations, and other crucial settings that determine how your containerized application will operate.&lt;/p&gt;

&lt;p&gt;Here is an example of a task definition containing a single container that runs an NGINX web server using the&lt;br&gt;
the Fargate launch type.&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;"family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"containerDefinitions"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nginx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"cpu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"99"&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;"requiresCompatibilities"&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;"FARGATE"&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;"networkMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awsvpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"512"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cpu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"256"&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;Lets define a task definition. Go the ECS Service page, from the left panel select &lt;strong&gt;Task definition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyk26q003ahzr77uz3ko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyk26q003ahzr77uz3ko.png" alt="ecs-task-definition-list" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Create new task definition&lt;/strong&gt;, then select the &lt;strong&gt;Create new task definition&lt;/strong&gt; so we can explore some of the properties.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: One of the reason why it's important to know how to use the AWS console is to explore properties and options surrounding services and also learning how to debug the configuration settings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the &lt;strong&gt;Task definition family&lt;/strong&gt; enter a name such as &lt;strong&gt;nextjs-frontend-task&lt;/strong&gt;.&lt;br&gt;
The next section is the &lt;strong&gt;Infrastructure requirements&lt;/strong&gt; section. For this section select &lt;strong&gt;AWS Fargate&lt;/strong&gt; for the Launch type.&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Linux/x86_64&lt;/strong&gt; for the operating system/architecture.&lt;br&gt;
For the &lt;strong&gt;Task size&lt;/strong&gt; select, a CPU size of &lt;strong&gt;0.5vCPU&lt;/strong&gt; and &lt;strong&gt;1GB&lt;/strong&gt; for the Memory size.&lt;br&gt;
Set the Task role to &lt;strong&gt;None&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i8w66z6uvdolh127b5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i8w66z6uvdolh127b5f.png" alt="task-definition-infrastructure" width="800" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AWS Fargate is a serverless compute engine for containers that works with Amazon ECS. It offers several key advantages:&lt;/p&gt;

&lt;p&gt;Serverless Operation: Fargate allows you to run containers without managing servers or clusters.&lt;br&gt;
Simplified Management: You no longer need to provision, configure, or scale clusters of virtual machines to run your containers.&lt;br&gt;
Reduced Complexity: Fargate eliminates the need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose server types&lt;/li&gt;
&lt;li&gt;Decide when to scale your clusters&lt;/li&gt;
&lt;li&gt;Optimize cluster packing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Focus on Applications: With infrastructure management handled by Fargate, you can concentrate on designing and building your applications.&lt;/p&gt;

&lt;p&gt;In essence, Fargate abstracts away much of the underlying infrastructure complexity, allowing you to deploy and run containerized applications more easily and efficiently on Amazon ECS.&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;Container - 1&lt;/strong&gt; section, specify something like &lt;strong&gt;nextjs-frontend&lt;/strong&gt; for the name, and the Image URI is the ECR docker image URI that we used earlier. So it should be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;aws_account_id&amp;gt;.dkr.ecr.&amp;lt;region&amp;gt;.amazonaws.com/nextjs-frontend:lastest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can find this URL from the ECR Service page, by clicking on the Repository, and the &lt;strong&gt;nextjs-frontend&lt;/strong&gt; image name. The following page will be displayed with the &lt;strong&gt;URI&lt;/strong&gt; value in the Details section. Copy the value by clicking on the double square icon:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjf1scd7k0r3su7pforkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjf1scd7k0r3su7pforkl.png" alt="ecr-repository-details" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then add the value to the &lt;strong&gt;Image URI&lt;/strong&gt; value of the ECS page.&lt;br&gt;
For the &lt;strong&gt;Port mappings&lt;/strong&gt; specify port &lt;strong&gt;3000&lt;/strong&gt; as that is our default Next.js port number.&lt;/p&gt;

&lt;p&gt;Don't specify anything for the &lt;strong&gt;Resource allocation limits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6i635pki281akyu8wt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6i635pki281akyu8wt6.png" alt="Task Definition Container" width="800" height="704"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Explore the remaining optional configurations, but don't change any settings.&lt;br&gt;
Click &lt;strong&gt;Create&lt;/strong&gt; to finish.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create Cluster
&lt;/h3&gt;

&lt;p&gt;A Logical grouping of tasks or services.&lt;br&gt;
The services can include, EC2 launch types, containers, capacity providers, fargate launch types.&lt;br&gt;
What is it for?&lt;/p&gt;

&lt;p&gt;A regional grouping of one or more container instances where you can run task requests.&lt;br&gt;
Each account receives a default cluster the first time you use the Amazon ECS service,&lt;br&gt;
but you may also create other clusters. Clusters may contain more than one instance&lt;br&gt;
type simultaneously.&lt;/p&gt;

&lt;p&gt;Now lets create a cluster, from the left panel click &lt;strong&gt;Clusters&lt;/strong&gt;, then click on &lt;strong&gt;Create cluster&lt;/strong&gt;.&lt;br&gt;
In the cluster create view, specify the cluster name &lt;strong&gt;nextjs-frontend-cluster&lt;/strong&gt; and select &lt;strong&gt;AWS Fargate (serverless)&lt;/strong&gt; for the infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wielcakqn4heno7d5x4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wielcakqn4heno7d5x4.png" alt="cluster-configuration" width="800" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; to finish.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create Task
&lt;/h3&gt;

&lt;p&gt;So we have our Task Definition, our cluster now we need to create a task. First, lets create a single task and run it, then check to verify the container is working. Then we&lt;/p&gt;

&lt;p&gt;Click on the cluster created in the last step &lt;strong&gt;nextjs-frontend-cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgajp66wzdsx6g062jxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgajp66wzdsx6g062jxg.png" alt="cluster-frontend-details" width="800" height="851"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the &lt;strong&gt;Tasks&lt;/strong&gt; tab on the bottom, and click on &lt;strong&gt;Run new task&lt;/strong&gt;.&lt;br&gt;
In the &lt;strong&gt;Create&lt;/strong&gt; view go to the &lt;strong&gt;Deployment configuration&lt;/strong&gt; section&lt;/p&gt;

&lt;p&gt;for the &lt;strong&gt;Family&lt;/strong&gt; value, specify the task definition we specified earlier and set the number of desired tasks to 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaa7qj7hdu62adj5mqu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaa7qj7hdu62adj5mqu9.png" alt="task-deployment-configuration" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Networking&lt;/strong&gt; section, select the VPC &lt;strong&gt;nextjs-vpc&lt;/strong&gt; created in the first part.&lt;br&gt;
Clear the current subnet select, and from the new list, select to add the two public subnets.&lt;/p&gt;

&lt;p&gt;For the security group, create a new group and set port 3000 to be opened. You can name the security group &lt;strong&gt;port-3000&lt;/strong&gt; for easy reading.&lt;/p&gt;

&lt;p&gt;Leave the &lt;strong&gt;Public IP&lt;/strong&gt; enabled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8bkx7ky43x8gu06g4c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8bkx7ky43x8gu06g4c3.png" alt="ecs-networking" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; and in the next screen, wait until the &lt;strong&gt;Last status&lt;/strong&gt; value changes to Running. Once Ready, click on the Task to view the details&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsu4edsouv6wkv07s5m6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsu4edsouv6wkv07s5m6i.png" alt="task-running-state" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the task details view, in the &lt;strong&gt;Networking&lt;/strong&gt; tab, copy the public IP&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyrnxom10w03czy1ti6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyrnxom10w03czy1ti6m.png" alt="task-networking-details" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open a new tab, and paste the IP, appending the port number &lt;code&gt;:3000&lt;/code&gt; at the end.&lt;br&gt;
You should see the Next.js landing page&lt;/p&gt;

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

&lt;p&gt;We verified that our Task definition works and that if we deploy a task, the page loads and works fine.&lt;br&gt;
Now select the task from the cluster details view, and click &lt;strong&gt;Stop&lt;/strong&gt; to destroy the task. In the next step we are going to create a service that will automatically create multiple tasks.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create Service with a Load Balancer
&lt;/h3&gt;

&lt;p&gt;Now that we verified that the task is working, we can move on and create a service. A Service defines or encapsulates multiple tasks and it's typically created with a load balancer to route requests to different tasks. In addition to encapsulating tasks, the Service has a scheduler which maintains a desired count of tasks, so if a task fails and exits, or the health check is not responding, it will launch a new task and route traffic to the new task.&lt;/p&gt;

&lt;p&gt;To create a Service, go to the &lt;strong&gt;Cluster&lt;/strong&gt; details view and select the &lt;strong&gt;Services&lt;/strong&gt; tab this time instead of the &lt;strong&gt;Tasks&lt;/strong&gt; tab.&lt;br&gt;
Click &lt;strong&gt;Create&lt;/strong&gt; and you will see a similar view to the Task creation page.&lt;/p&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Deployment configuration&lt;/strong&gt; section and make sure the &lt;strong&gt;Application type&lt;/strong&gt; is Service. For the Family select the same task as before &lt;strong&gt;nextjs-frontend-task&lt;/strong&gt;, and set the service name to &lt;strong&gt;nextjs-frontend-service&lt;/strong&gt;. The set the &lt;strong&gt;Desired tasks&lt;/strong&gt; count to 2.&lt;/p&gt;

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

&lt;p&gt;In the &lt;strong&gt;Networking&lt;/strong&gt; section, select the VPC &lt;strong&gt;nextjs-vpc&lt;/strong&gt; created in the first part. Clear the current subnet select, and from the new list, select the two &lt;strong&gt;public&lt;/strong&gt; subnets. Also make sure to add the &lt;strong&gt;port-3000&lt;/strong&gt; and &lt;strong&gt;port-80&lt;/strong&gt; to the security group. Also turn on the Public IP option if not already enabled.&lt;/p&gt;

&lt;p&gt;We can stop here and click Create, but there is no point for a Service without a load balancer, especially for tasks that are not accessible.&lt;br&gt;
Scroll down to the &lt;strong&gt;Load balancing&lt;/strong&gt; optional section.&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;Load balancer type&lt;/strong&gt; select &lt;strong&gt;Application load balancer&lt;/strong&gt;. The container, should get automatically populated with &lt;strong&gt;nextjs-frontend 3000:3000&lt;/strong&gt;. Under the application load balancer. Select the &lt;strong&gt;Create a new load balancer&lt;/strong&gt; and for the load balancer name Type in &lt;strong&gt;nextjsalb&lt;/strong&gt;. On the bottom, where it says listener make sure that &lt;strong&gt;create new listener&lt;/strong&gt; options is selected and the port is set to 80 with the protocol as HTTP. And for the &lt;strong&gt;target group&lt;/strong&gt;, make sure the create new target group is selected and leave all values as is. The protocol should say HTTP And the health check protocol should say also HTTP with the health check path set to by default to "/".&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;create&lt;/strong&gt;. This will take a bit longer since it's creating several resources.&lt;br&gt;
Once done, open the clusters &lt;strong&gt;services&lt;/strong&gt; tab select the service we just created, it should have the name &lt;strong&gt;nextjs-frontend-service&lt;/strong&gt;. Then on the top, select the &lt;strong&gt;configure and networking&lt;/strong&gt; tab And scroll down to the &lt;strong&gt;network configurations&lt;/strong&gt; section. On the right side of that section you will see a DNS value. You can click on open address or copy the address and paste it in a new tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwf5piqiy3ad1zg8alnb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwf5piqiy3ad1zg8alnb.png" alt="alb-dns-name" width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you follow the instructions correctly, you will see the Nextjs default page load. The difference between this method and the method of deploying one task is that now we have a load balancer that is listening on port 80 and it is routing traffic to two separate tasks or containers that are running our nextjs app, and it will use A routing strategy to forward traffic to either task.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using AWS CDK
&lt;/h2&gt;

&lt;p&gt;By leveraging IaC, you can automate and replicate all the setup and configuration work typically done through the console. This approach significantly speeds up your website deployment process.&lt;/p&gt;

&lt;p&gt;Lets automate all of the steps we took using AWS CDK, which is an IaC or Infrastructure as code framework. All the steps we performed manually it can be automated and also we can add logic as well so based on some condition, ie if it's a production deployment we can add a few other steps vs if it's a test deployment we can skip a few other steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Node.js and npm installed&lt;/li&gt;
&lt;li&gt;AWS cli and cdk setup and configured&lt;/li&gt;
&lt;li&gt;Basic knowledge in Javascript and Typescript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setup, Code and Deploy
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a new CDK project:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;temp-project &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;temp-project
&lt;span class="nb"&gt;mkdir &lt;/span&gt;infrastructure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;infrastructure
cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Replace the content of the file &lt;code&gt;lib/infrastructure-stack.ts&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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;ecs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-ecs&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;IpAddresses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Vpc&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="s2"&gt;aws-cdk-lib/aws-ec2&lt;/span&gt;&lt;span class="dl"&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;ApplicationLoadBalancedFargateService&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="s2"&gt;aws-cdk-lib/aws-ecs-patterns&lt;/span&gt;&lt;span class="dl"&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;ApplicationProtocol&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="s2"&gt;aws-cdk-lib/aws-elasticloadbalancingv2&lt;/span&gt;&lt;span class="dl"&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="nc"&gt;InfrastructureStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vpc&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="s2"&gt;`&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="s2"&gt;-vpc`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;vpcName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-vpc`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;ipAddresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IpAddresses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10.0.0.0/16&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;maxAzs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Cluster&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="s2"&gt;`&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="s2"&gt;-cluster`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-cluster`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fargateService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApplicationLoadBalancedFargateService&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="s2"&gt;`&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="s2"&gt;-fargate`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-fargate-service`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;loadBalancerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-fargate-lba`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;memoryLimitMiB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationProtocol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;desiredCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;publicLoadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;taskImageOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ContainerImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAsset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../nextjs-frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="na"&gt;containerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-container`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Output the load balancer URL&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="nc"&gt;CfnOutput&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="s2"&gt;`&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="s2"&gt;-url`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fargateService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadBalancerDnsName&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;now deploy the stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once deployment, you will see a message in the console that has the load balancers DNS name. Copy paste the value and paste it in a browser and you should see the same Next.js landing page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And to destroy all the resources just run&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;And enter &lt;strong&gt;y&lt;/strong&gt; to confirm you want to delete. And that is it! all resource will been destroyed according to the dependency tree CDK keeps track of.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;This guide has walked through the process of deploying a Next.js application to AWS using Elastic Container Service (ECS), demonstrating both manual deployment via the AWS Console and automated deployment using AWS CDK. By containerizing the Next.js app and leveraging ECS, developers can create a scalable, high-performance infrastructure that takes advantage of features like auto-scaling and load balancing. The manual process provides a deep understanding of the components involved - from ECR for image storage to task definitions, clusters, and services - while the CDK approach showcases how Infrastructure as Code can streamline and automate the entire deployment process. Whether you choose the hands-on console method or the efficient CDK route, this guide equips you with the knowledge to deploy and manage containerized Next.js applications on AWS, setting the foundation for robust, cloud-native web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in learning more?
&lt;/h2&gt;

&lt;p&gt;If you are interested in creating a project from scratch using AWS CDK and serverless technologies, you can check out the course linked below. In this course, we go over each service in detail, explaining what they do, and actually create a dynamic application with user login and authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A&amp;amp;couponCode=LEARNNOWPLANS" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;AWS official ECS workshop has a great walkthrough&lt;br&gt;
&lt;a href="https://ecsworkshop.com/introduction/ecs_basics/" rel="noopener noreferrer"&gt;https://ecsworkshop.com/introduction/ecs_basics/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>nextjs</category>
      <category>amplify</category>
    </item>
    <item>
      <title>A Beginners Guide to AWS (VPS) Virtual Private Cloud</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 11 Nov 2024 19:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/a-beginners-guide-to-aws-vps-virtual-private-cloud-292m</link>
      <guid>https://forem.com/redrobotdev/a-beginners-guide-to-aws-vps-virtual-private-cloud-292m</guid>
      <description>&lt;p&gt;In this tutorial based guide we will go over what VPC is, why it exists, and when and why should you consider using it in your cloud architecture.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Original Post&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/aws-vpc" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Virtual Private cloud
&lt;/h1&gt;

&lt;p&gt;AWS VPC (Amazon Virtual Private Cloud) is one of the key networking service provided by AWS. VPC allows you to create an isolated section of the AWS cloud where you can launch resources in a defined virtual network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5b46t4ye7w6vov70ltmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5b46t4ye7w6vov70ltmi.png" alt="VPC Concept" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;VPC creates a separation between your resources and other Amazon resources. You can control if outside traffic should flow into your VPC using an Internet Gateway.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;VPC mainly provide security for your infrastructure. They provide a layer of network isolation, allowing you to control access to your resources and protect them from unauthorized access.&lt;/p&gt;

&lt;p&gt;Also you can customize your network using VPC, by controlling the network traffic paths, optimize data transfers to reduce cost and organize resources for better management.&lt;/p&gt;

&lt;p&gt;In this post we will create a VPC using AWS console, go over routing tables, internet gateway and finally recreate the network structure using AWS CDK.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use Case 1: A 3-tier Architecture
&lt;/h1&gt;

&lt;p&gt;Let's take the following example: We are tasked to create a Saas (Software as a Service) application that has a web interface giving users the capability to select a list of countries, cities, days of week and a button to generate weather video sequence similar to what you see in news broadcasts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqojlqirpns40vat4p8qn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqojlqirpns40vat4p8qn.png" alt="A Weather graphics source DW News" width="600" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At minimum, such a system would require to have the following components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;REST API to handle video render requests&lt;/li&gt;
&lt;li&gt;storage to hold videos&lt;/li&gt;
&lt;li&gt;video rendering engine&lt;/li&gt;
&lt;li&gt;frontend application that users can input the country, city and days and request for a video&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The block diagram would look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdox7ia0azi11llq3z9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdox7ia0azi11llq3z9n.png" alt="A Weather video rendering service" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using VPC, we can organize and secure our component by placing them into different areas of the network. So for our example, the user facing services (REST API, frontend), would need to go into the public subnet where users would need to access it, and the rest inside private networks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST API (public subnet)&lt;/li&gt;
&lt;li&gt;frontend application (public subnet)&lt;/li&gt;
&lt;li&gt;render engine, storage, database (private subnet)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a typical VPC structure,with a public and a private subnet and other components which we can ignore for now. The public subnet has access to the internet via an internet gateway and the private subnet doesn't. However, the devices or IP's located in both the private and public can access each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi9z13m0xupqzkr2yafu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi9z13m0xupqzkr2yafu.png" alt="A typical VPC diagram" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;organizing our components into network segments would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv0cai55n6fuayu1npvy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv0cai55n6fuayu1npvy.png" alt="A typical VPC diagram" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important&lt;br&gt;
This example is not entirely accurate, it's meant to convey the idea.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Use Case 2: Remote Company
&lt;/h1&gt;

&lt;p&gt;The second example we'll explore is a scenario where a company hosts its infrastructure on AWS. In this case, remote workers need to access company resources such as Jira, Jenkins, Confluence, Database and other internal tools. To achieve this securely, they would need to VPN into a VPC. Once connected, they gain access to all the company resources within that VPC.&lt;br&gt;
Implementing VPN Access&lt;br&gt;
To enable this setup, you would need to create an AWS Client VPN endpoint and configure VPN access to your VPC. This allows remote workers to securely connect to the company's network.&lt;/p&gt;

&lt;p&gt;This VPN method can also be used to access internal resources like databases when you need to perform specific queries or maintenance requiring direct access. However, it's important to note that this approach should be used cautiously, as it can pose security risks if not properly managed. For small teams and applications, though, it can be a convenient and practical solution.&lt;/p&gt;

&lt;p&gt;There are several ways to establish connectivity with your VPC:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Direct Connect: Ideal for connecting an on-premises data center or large database to an AWS VPC. This provides a dedicated, private connection.&lt;/li&gt;
&lt;li&gt;Site-to-Site VPN: Useful when you need a constant connection between your company's network and a VPC. This creates an encrypted tunnel between your on-premises network and AWS.&lt;/li&gt;
&lt;li&gt;AWS Client VPN: This is the solution for remote workers who need to VPN into the VPC and access company resources from various locations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We won't delve deeper into this use case, as it's primarily an IT infrastructure solution for companies rather than a typical setup for software hosting or Software as a Service (SaaS) applications. However, understanding these options is valuable for comprehensive cloud architecture knowledge.&lt;/p&gt;
&lt;h1&gt;
  
  
  Creating a VPC
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Using console
&lt;/h2&gt;

&lt;p&gt;Open the AWS Console and go to the VPC page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnpvzred4cd0bxmfx3pv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnpvzred4cd0bxmfx3pv.png" alt="VPC Console" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;VPCs&lt;/strong&gt; or the &lt;strong&gt;Your VPCs&lt;/strong&gt; button from the left side, to view the VPC. The other buttons are all related to VPC, it's broken down into categories for organization sake. So when you create a VPC, you can also create subnets which will list those in the Subnet section as well.&lt;/p&gt;

&lt;p&gt;Click on the first VPC line from the list if you have many.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbhueh9iaafb7peaox9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbhueh9iaafb7peaox9e.png" alt="VPC Console" width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you are just starting off, you should only see one VPC which is the default VPC created along when you first create your AWS account.&lt;/p&gt;

&lt;p&gt;Warning: Switch your region, and you should see separate VPC's exist for each of your regions. If you don't want to mess up any existing stack or resources, select another region from the top, typically a region that you won't normally be using.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Click on &lt;strong&gt;Create VPC&lt;/strong&gt; from the top. You should see the Create VPC page showing up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2sgbckysp0vu5xsqfn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2sgbckysp0vu5xsqfn.png" alt="VPC Settings" width="800" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;VPC and more&lt;/strong&gt;, and you should see the following diagram on the right side:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7nb7rnd4glgbvz3zls0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7nb7rnd4glgbvz3zls0.png" alt="VPC and more" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this option a typical VPC will be created, so lets describe what is being created for us.&lt;/p&gt;
&lt;h3&gt;
  
  
  Subnets
&lt;/h3&gt;

&lt;p&gt;In the subnets section, it shows there are two Availability Zone (AZ) &lt;strong&gt;us-east-1a&lt;/strong&gt; and &lt;strong&gt;us-east-1b&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlom6r62kqlegoiuoh7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlom6r62kqlegoiuoh7y.png" alt="VPC Subnets" width="418" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If your region is different, it would say something like &lt;strong&gt;your-region-1a&lt;/strong&gt;, &lt;strong&gt;your-region-1b&lt;/strong&gt;, &lt;strong&gt;your-region-1c&lt;/strong&gt; or something similar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AZ is one or more discrete data centers with redundant power networking, and connectivity in an AWS Region. So it's better to deploy your instance in such a way it gets replicated in multiple AZs, in case if something goes wrong in one data center - that way your application is highly available and more robust.&lt;/p&gt;

&lt;p&gt;You can reduce or increase the number of zones used in this setup from the left panel &lt;strong&gt;Number of Availability Zones (AZs)&lt;/strong&gt; section. You can pick how many zones you want to add, or click &lt;strong&gt;customize AZs&lt;/strong&gt; to specify which zones you want to create subnets in.&lt;/p&gt;

&lt;p&gt;There are two subnets per each AZ, a private and public subnet.&lt;br&gt;
The Blue icon means private and the Green one means public.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mxey7rf7vn3o0ild7ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mxey7rf7vn3o0ild7ij.png" alt="VPC Subnets" width="321" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also control the number of public and private subnets you want per zone by changing the values for &lt;strong&gt;Number of public subnets&lt;/strong&gt; and &lt;strong&gt;Number of private subnets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnex9nq547lgbgug3gnm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnex9nq547lgbgug3gnm.png" alt="VPC Subnets Configuration" width="532" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If your change the number of AZ's the value or options for the public and private subnet count changes as well. Meaning if you select 1 AZ, then the options for the public subnets will change to 0 and 1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Route tables
&lt;/h3&gt;

&lt;p&gt;The next box shows the Route tables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyshsowc34xe7huj3p3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyshsowc34xe7huj3p3w.png" alt="VPC Subnets Configuration" width="395" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Route tables conceptually are the very similar to the routing tables that are common networking routers. A routing table is set of rules, that determines how packets get redirected when traveling over an Internet Protocol (IP) stack.&lt;/p&gt;

&lt;p&gt;So if you mouse over the first entry you will see this connection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgj7w0xdb8luyo7rnj9ir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgj7w0xdb8luyo7rnj9ir.png" alt="VPC public route table" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see that our two public subnets use the first routing table, and the other two private subnets each have their own route table. The blue line shows that the public route table is also connected to a &lt;strong&gt;igw&lt;/strong&gt; or an internet gateway.&lt;/p&gt;

&lt;p&gt;We will go over the details of these route table in the next section but just understand that when packets travel between subnets, they first lookup the routing table to see which interface they have to go to. If a packet is targeting an outside IP like Google DNS (8.8.8.8), the routing table would direct the packet to an internet gateway. If the packet is targeting a database that is located in the private subnet (192.168.0.100), it will redirect the packet internally to the server that is running the database.&lt;/p&gt;
&lt;h3&gt;
  
  
  Network Connections
&lt;/h3&gt;

&lt;p&gt;The last section is the Network connections that right now there are two options:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy5vjx33pb4xoeq3at98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy5vjx33pb4xoeq3at98.png" alt="VPC network connections" width="380" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first item is an &lt;strong&gt;internet gateway&lt;/strong&gt; which allows traffic from and to the internet to be reachable to hosts belonging to this subnet.&lt;/p&gt;

&lt;p&gt;The second item is an &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html" rel="noopener noreferrer"&gt;&lt;strong&gt;VPC endpoint&lt;/strong&gt;&lt;/a&gt; which allows your internal services to communicate with other AWS services like S3, DynamoDB, SQS, SNS, RDS, SageMaker and etc without the traffic leaving the Amazon network. This option is favorable to have since it reduces latency and cost.&lt;/p&gt;

&lt;p&gt;On the bottom of the page click &lt;strong&gt;Create VPC&lt;/strong&gt; to create the VPC.&lt;br&gt;
After the VPC is created, rename the newly created vpc to something you would remember like &lt;strong&gt;test-vpc&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing our VPC with EC2 Instances
&lt;/h3&gt;

&lt;p&gt;To test our VPC, lets launch two EC2 instance and place one in the public subnet, and the other in the private subnet on our newly created VPC. We are going to verify to make sure we cannot connect to the EC2 machine in the private subnet, but can connect to the one in the public subnet. We also want to make sure we can connect to the EC2 machine in the private subnet from the public EC2 machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fke1h3dn8p6ektnh9iaf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fke1h3dn8p6ektnh9iaf9.png" alt="SSH to Public" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets start creating our EC2 instances. Open a new tab to AWS Console, and bring up the Amazon EC2 dashboard. Create a new instance by clicking the “Launch Instance” button.&lt;/p&gt;

&lt;p&gt;Create an instance named &lt;strong&gt;Public Linux Machine&lt;/strong&gt; and select the default Amazon Linux based systems so we can SSH into each machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyoj3u74sxk0rhruj5nmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyoj3u74sxk0rhruj5nmd.png" alt="EC2 Instance launch" width="800" height="1063"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important: Make sure to select a key pair or create a new one, and use the same for both machines.&lt;/p&gt;

&lt;p&gt;Note: If you are not familiar with EC2 instance creation and would like to learn more, visit the official docs &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html#ec2-launch-instance" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more info.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Under the Network Settings, click &lt;strong&gt;Edit&lt;/strong&gt; and then choose &lt;code&gt;test-vpc&lt;/code&gt; for the VPC value. Then from the subnets select a public one and enable the Auto-assign public IP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakm8w5b2nmgh68ga8w5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakm8w5b2nmgh68ga8w5g.png" alt="EC2 Network Settings" width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the Security group name, set &lt;strong&gt;test-vpc-linux-machine-sg&lt;/strong&gt; and open SSH and HTTP ports. See the screenshot for a better idea:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8dt2oh8y63wrwqgzt0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8dt2oh8y63wrwqgzt0e.png" alt="EC2 Security Groups" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create another one using similar configuration, except name the instance &lt;strong&gt;Private Linux Machine&lt;/strong&gt;, select the same key pair for this instance.&lt;br&gt;
Under the Network Settings, select the same VPC &lt;strong&gt;test-vpc&lt;/strong&gt;, but instead of the public subnet, select the private subnet.&lt;br&gt;
For the security groups, select &lt;strong&gt;Select existing security group&lt;/strong&gt; then from the list select &lt;strong&gt;text-vpc-linux-machine-sg&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;launch instance&lt;/strong&gt; to create the instance, then click &lt;strong&gt;View Instances&lt;/strong&gt;. You should see two instance like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56tjf0z4s8lmt15itd68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56tjf0z4s8lmt15itd68.png" alt="EC2 Instances" width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets try to connect to both EC2 machine using the terminal.&lt;br&gt;
To be certain that you are connecting to the right machine, right click on the machine, select connect and go to the ssh tab. In the end of the view, copy the ssh command, it should look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5m7nmdtvqoh7dl1ah73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5m7nmdtvqoh7dl1ah73.png" alt="EC2 Instances" width="800" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Public Linux Machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"test-ec2-key.pem"&lt;/span&gt; ec2-user@ec2-44-192-99-181.compute-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Private Linux Machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"test-ec2-key.pem"&lt;/span&gt; ec2-user@ec2-34-239-251-67.compute-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice that you will not (and shouldn't) be able to connect to the second machine since it's in a private network.&lt;/p&gt;

&lt;p&gt;Before doing that we need to copy the PEM file to the public EC2 instance.&lt;br&gt;
This will copy the pem file so we can use it to SSH into the private ec2 machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"test-ec2-key.pem"&lt;/span&gt; test-ec2-key.pem ec2-user@ec2-3-230-118-6.compute-1.amazonaws.com:.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to find the private address of the other EC2. We can do that by selecting the EC2 from the EC2 dashboard and reading the private IP address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3siq0rg5douiud1buokq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3siq0rg5douiud1buokq.png" alt="Private EC2 Instances" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now ssh back to the public machine,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"test-ec2-key.pem"&lt;/span&gt; ec2-user@ec2-44-192-99-181.compute-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and from within the EC2 instance, ssh into the private EC2 instance using the private IP address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"test-ec2-key.pem"&lt;/span&gt; 10.0.135.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should be able to connect to the machine - verify you have SSH'ed into a new device by running ifconfig and viewing the IP address.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important: Make sure to delete all resources once you are done testing out. First delete all the EC2 instances, then delete the VPC.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using AWS CDK
&lt;/h2&gt;

&lt;p&gt;By leveraging IaC, you can automate and replicate all the setup and configuration work typically done through the console. This approach significantly speeds up your website deployment process.&lt;/p&gt;

&lt;p&gt;Lets automate all of the steps we took using AWS CDK, which is an IaC or Infrastructure as code framework. All the steps we performed manually it can be automated and also we can add logic as well so based on some condition, ie if it's a production deployment we can add a few other steps&lt;br&gt;
vs if it's a test deployment we can skip a few other steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Node.js and npm installed&lt;/li&gt;
&lt;li&gt;AWS cli and cdk setup and configured&lt;/li&gt;
&lt;li&gt;Basic knowledge in Javascript and Typescript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setup, Code and Deploy
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a new CDK project:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;temp-project &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;temp-project
&lt;span class="nb"&gt;mkdir &lt;/span&gt;infrastructure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;infrastructure
cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Replace the content of the file &lt;code&gt;lib/infrastructure-stack.ts&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;SubnetType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IpAddresses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Vpc&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="s2"&gt;aws-cdk-lib/aws-ec2&lt;/span&gt;&lt;span class="dl"&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="nc"&gt;InfrastructureStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vpc&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="s2"&gt;`&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="s2"&gt;-vpc`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;vpcName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&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="s2"&gt;-vpc`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;ipAddresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IpAddresses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10.0.0.0/16&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;maxAzs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createInternetGateway&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;subnetConfiguration&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="na"&gt;cidrMask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;subnetType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SubnetType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PUBLIC&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="na"&gt;cidrMask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Private&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;subnetType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SubnetType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_ISOLATED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="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;now deploy the stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once deployment open AWS console, and go to the VPC page. You will see we have our VPC created with one small difference. The two public subnet will each have their own route table, where the one we created using console created one route table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And to destroy all the resources just run&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;And enter &lt;strong&gt;y&lt;/strong&gt; to confirm you want to delete. And that is it! all resource will been destroyed according to the dependency tree CDK keeps track of.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Interested in learning more?
&lt;/h2&gt;

&lt;p&gt;If you are interested in creating a project from scratch using AWS CDK, and serverless, you can checkout the class linked below, where we go over in details explain what each service does, and actually create a dynamic&lt;br&gt;
application with user login and authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;We've explored what VPC is, its key components like subnets and route tables, and walked through practical examples of creating a VPC both manually via the AWS Console and programmatically using AWS CDK.&lt;/p&gt;

&lt;p&gt;By leveraging VPCs, you can effectively isolate your resources, control network traffic, and organize your architecture for optimal performance and security. Whether you're building a multi-tier application or setting up a remote work environment, understanding and utilizing VPCs is crucial for creating robust and secure cloud solutions.&lt;/p&gt;

&lt;p&gt;In the future posts, we will be utilizing VPC and ECS, to create a container based deployment.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>vpc</category>
    </item>
    <item>
      <title>Next.js containerization using Docker</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 04 Nov 2024 19:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/nextjs-containerization-using-docker-dl3</link>
      <guid>https://forem.com/redrobotdev/nextjs-containerization-using-docker-dl3</guid>
      <description>&lt;p&gt;In this post, we'll explore how to containerize a Next.js application using Docker. We'll start with a real-world scenario to illustrate why containerization is valuable for modern web applications. Then, we'll explain what containers are, why this technology exists, and its benefits compared to traditional deployment methods. Finally, we'll walk through the process of containerizing a Next.js app step-by-step, giving you practical experience with this essential technology. By the end, you'll understand both the how and why of using containers for Next.js applications.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;*&lt;em&gt;Original Post&lt;br&gt;
*&lt;/em&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/nextjs-containerization" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Example Scenario
&lt;/h2&gt;

&lt;p&gt;Let's take the following example: We are tasked to create a Saas (Software as a Service) application that has a web interface giving users the capability to select a list of countries, cities, days of week and generate a weather video sequence similar to what you see in news broadcasts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27m5hhffi5ieq9p8kuhm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27m5hhffi5ieq9p8kuhm.png" alt="A Weather graphics source DW News" width="600" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At minimum, such a system would require to have the following components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;REST API to handle video render requests&lt;/li&gt;
&lt;li&gt;storage to hold videos&lt;/li&gt;
&lt;li&gt;video rendering engine&lt;/li&gt;
&lt;li&gt;frontend application that users can input the country, city and days and request for a video&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The block diagram would look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wv7cssutujrt5h0l9ms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wv7cssutujrt5h0l9ms.png" alt="A Weather video rendering service" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could develop the whole application using a single language like TS, JS, C++, C#, Rust or Go, ending up with a single executable that handles everything for us, but this is not a good solution for a SaaS application.&lt;/p&gt;

&lt;p&gt;This is referred to as a monolith architecture where in certain cases like a desktop application it is desirable. However, in our case since it's a server-based SaaS application it is better to break down our application into smaller self contained components. This has several benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Much easier to break down tasks and assign to different engineers&lt;/li&gt;
&lt;li&gt;Easier to test component in isolation, using mock input and output&lt;/li&gt;
&lt;li&gt;Easier to scale horizontally, so lets say in the future our user base grows and we need to handle larger traffic - we can easy duplicate an instance of the Rendering engine, add a load balancer in front so we can handle larger client requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This solution is referred to as microservice architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;So how would we go about and making this self contained components? Let's make it simple and only look at the frontend which is the topic of this post.&lt;/p&gt;

&lt;p&gt;We can make an executable of the Next.js process using something like [Nexe (&lt;a href="https://github.com/nexe/nexe" rel="noopener noreferrer"&gt;https://github.com/nexe/nexe&lt;/a&gt;) and run that on the destination server along with the other executables. But this solution has problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;the executable might not have bundled all the necessary 3rd libraries, say the libc lib that a package requires, and this could lead to missing dependencies when running hte executable on a destination server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the executable created or developed on one operating system, might not work on other operating system out of the box and will require extra work to make it intra operative&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the libraries included in the executable bundle might conflict with other software installed on the server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;there are other issues such as maintenance complexity, security issues and difficulty auditing, hard to patch issues, loss of flexibility and so forth&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can tell, this would be a nightmare to manage. Writing good and clean code is great, but if your solution is not future-proof and easy to fix, then it doesn't matter if your code is good or high quality. Imagine creating a factory with machines where it takes months to fix a machine; the whole factory is shut down with no products being produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;One approach would be to create a virtual machine (VM) and install Next.js along with Node and all of the required libraries - and then load that onto the server. This would be a good solution as the VM is isolated from the server, and in fact, we can do the same for the rest of the components like the database, rendering engine, and other elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4mdbr4xnhoxke411j9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4mdbr4xnhoxke411j9b.png" alt="Virtual Machine" width="662" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, there is one major downside to VMs - they consume a lot of resources. Virtual machines run a full operating system with their own kernel and drivers, requiring dedicated CPU and memory allocations.&lt;/p&gt;

&lt;p&gt;This is where containers come in. Containers are similar to VMs; however, they do not run a full operating system. Instead, they share the host operating system's kernel and resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containers
&lt;/h2&gt;

&lt;p&gt;Similar to virtual machines, containers are isolated environments that allow you to group applications and configurations into a single unit and run your application. Containers are more lightweight and efficient compared to VMs, making them an attractive option for deploying and scaling applications.&lt;/p&gt;

&lt;p&gt;We are going to containerize a basic Next.js application to demonstrate the process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Containerization refers to the process of packaging an application into a container or more accurately a container image, so we can run it using docker.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;Docker is one of the most popular containerization technologies and in this post we will be using Docker to create a container that hosts a Next.js application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonokwaq8ufh29wkbgmaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonokwaq8ufh29wkbgmaz.png" alt="Docker logo" width="659" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Containerizing a Next.js Application
&lt;/h2&gt;

&lt;p&gt;Lets containerize a Next.js application using Docker. If you don't have docker installed, install it from here &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;https://www.docker.com/&lt;/a&gt;. Following the instructions provided on the website for your operating system.&lt;/p&gt;

&lt;p&gt;Open up a terminal and create the Next.js frontend app by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter &lt;code&gt;frontend&lt;/code&gt; for the app name, and then press enter for all prompts until it finishes creating the Next.js app.&lt;/p&gt;

&lt;p&gt;update the &lt;code&gt;next.config.mjs&lt;/code&gt; file and add the following line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nextConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;output:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'standalone'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will automatically create a standalone folder that copies only the necessary files for a production deployment. This change in the Next.js config is required in order to get the outputs we need for a production build.&lt;/p&gt;

&lt;p&gt;Next, in the newly created &lt;code&gt;frontend&lt;/code&gt; folder we will create a file named &lt;code&gt;Dockerfile&lt;/code&gt; with the content of this link there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile" rel="noopener noreferrer"&gt;Dockerfile example from Vercel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the commands to create the file:&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;frontend
curl https://raw.githubusercontent.com/vercel/next.js/canary/examples/with-docker/Dockerfile &lt;span class="nt"&gt;-o&lt;/span&gt; Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what is this file for?&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile
&lt;/h2&gt;

&lt;p&gt;The file we just downloaded contains instructions that tell Docker how to build a container image. An image is essentially a blueprint that holds all your code, third-party libraries, OS-related data, and other necessary components in a single package.&lt;/p&gt;

&lt;p&gt;When you execute that image using Docker, you create a running instance of that image, which is referred to as a container. You can create multiple containers from a single image.&lt;/p&gt;

&lt;p&gt;Lets take a look into the file we just downloaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:18-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies only when needed&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;deps&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; libc6-compat
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies based on the preferred package manager&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./&lt;/span&gt;
&lt;span class="k"&gt;RUN  &lt;/span&gt;npm ci
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each line in the Dockerfile is a command, similar to how you would run a basic Linux command. If you would run &lt;code&gt;mkdir /app&lt;/code&gt; in a Unix terminal, in the Dockerfile you would write &lt;code&gt;RUN mkdir /app&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The top line &lt;code&gt;FROM node:18-alpine AS base&lt;/code&gt; tells Docker which base image to use for building your container. In this case, it's using Node.js version 18 on an Alpine Linux distribution. Docker will fetch this image if it's not in your local cache. This is analogous to choosing an operating system for a VM, but it's more lightweight.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The line &lt;code&gt;RUN apk add --no-cache libc6-compat&lt;/code&gt; is installing a specific compatibility package for libc inside the image. This is indeed better suited for the production output of Next.js. If we do this in an environment that has other applications depending on libc, it might cause problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The line &lt;code&gt;RUN npm ci&lt;/code&gt; installs all the Next.js project dependencies, as you would normally do for a freshly cloned Next.js app. The &lt;code&gt;ci&lt;/code&gt; command is used instead of install for more reproducible builds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The following lines, are building and copying the Next.js outputs to a working path.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; /app/.next/standalone ./&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; /app/.next/static ./.next/static&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And finally the last few lines expose port 3000 and starts the Next.js process:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; HOSTNAME="0.0.0.0" node server.js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are skipping most of the details here. The idea is to give you an overview of what is occurring in this Dockerfile. If you like to learn more about &lt;code&gt;Dockerfile&lt;/code&gt; and how to create your own, checkout this official guide from Docker:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/guides/docker-concepts/building-images/writing-a-dockerfile/" rel="noopener noreferrer"&gt;Guide to creating Dockerfile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the reference docs for all Dockerfile commands:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/reference/dockerfile/" rel="noopener noreferrer"&gt;Dockerfile Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now build our image, from inside the &lt;code&gt;frontend&lt;/code&gt; folder run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; nextjs-frontend &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is going to build a docker image named &lt;code&gt;nextjs-frontend&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure you are running the docker service, otherwise the command will fail&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you can check to see if the image is in your local registry by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;lets run our our newly created image. By running the image, we are creating a container effectively. Execute 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 run &lt;span class="nt"&gt;-p&lt;/span&gt; 4000:3000 nextjs-frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this command starts the docker image, and maps the internal port 3000 to 4000. So now if you open your browser and go to &lt;code&gt;http://localhost:4000/&lt;/code&gt; you will see the next.js page.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;CTRL + C&lt;/code&gt; to stop the container. Alternatively you can run the container in the background or detached mode by passing the &lt;code&gt;-d&lt;/code&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 4000:3000 nextjs-frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then to view any detached running container run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and the output should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CONTAINER ID   IMAGE                       COMMAND                  CREATED         STATUS         PORTS                    NAMES
955c54690c9d   nextjs--frontend            &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   4 seconds ago   Up 4 seconds   0.0.0.0:4000-&amp;gt;3000/tcp   great_hamilton
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To stop the container from running, take a note of the name and then run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alternatives to Docker
&lt;/h2&gt;

&lt;p&gt;White Docker is the most popular tool for containerization, other containerization technologies exist. Here are some of the popular ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;LXC (Linux Containers): A lightweight virtualization which is OS-level and allows you to create and run multiple isolated Linux virtual environments (VE) on a single control host. LXC is better suited for experienced users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LXD (Linux Daemon): it's a extension of LXC that aims to provide a better user experience. LXD is more user-friendly and it is similar to hypervisors like VMWare or KVM, but it's lighter on resources and doesn't require virtualization overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;containerd: A container runtime that's used by Docker but can also be used independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kubernetes (k8s): While primarily an orchestration platform, it includes its own container runtime interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenVZ: Primarily used for server virtualization on Linux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Windows Containers: Microsoft's native containerization technology for Windows.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Containerization, particularly using Docker, offers a powerful solution for deploying and managing complex applications like our Next.js frontend. Throughout this post, we've explored the challenges of deploying microservices and the advantages that containerization brings to the table.&lt;br&gt;
We've learned that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Containerization provides a middle ground between monolithic applications and resource-heavy virtual machines.&lt;/li&gt;
&lt;li&gt;Docker allows us to package our Next.js application along with all its dependencies into a portable, consistent environment.&lt;/li&gt;
&lt;li&gt;The process involves creating a Dockerfile, which serves as a blueprint for building our container image.&lt;/li&gt;
&lt;li&gt;With a few simple commands, we can build, run, and manage our containerized Next.js application.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By containerizing our Next.js frontend, we've created a scalable, portable, and easily manageable component of our larger microservices architecture. This approach not only simplifies deployment but also enhances our ability to develop, test, and scale our application efficiently.&lt;/p&gt;

&lt;p&gt;As we move forward in the world of modern web development, understanding and utilizing containerization technologies like Docker becomes increasingly crucial. Whether you're working on a small project or a large-scale SaaS application, the principles and practices we've discussed here will serve as a solid foundation for your containerization journey.&lt;br&gt;
Remember, while Docker is the most popular containerization tool, alternatives exist, and the field is constantly evolving. Stay curious, keep learning, and happy containerizing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Serverless Option
&lt;/h2&gt;

&lt;p&gt;I‘ve developed a comprehensive Udemy course &lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt; that guides you through building a Serverless Single Page Application (SPA) from the ground up using AWS, AWS CDK, AWS SDK, Next.js and all written in TypeScript.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>docker</category>
    </item>
    <item>
      <title>Next.js on AWS: Deployment Strategies</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 28 Oct 2024 18:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/nextjs-on-aws-deployment-strategies-explained-53d1</link>
      <guid>https://forem.com/redrobotdev/nextjs-on-aws-deployment-strategies-explained-53d1</guid>
      <description>&lt;p&gt;In this post we will explore the primary methods for deploying a Next.js app to AWS, discussing the pros and cons of each method.&lt;br&gt;
Before proceeding, it's beneficial to know some of the core Next.js concepts such as SSR, SSG, Hybrid, Hydration and difference between SPA and MPA. If you're unsure what these are, you can learn more by reading the &lt;a href="https://nextjs.org/docs/app/building-your-application/rendering" rel="noopener noreferrer"&gt;Next.js docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Original Post&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/nextjs-deployment-strategies" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Strategies
&lt;/h2&gt;

&lt;p&gt;In this section, we'll discuss all major deployment strategies for Next.js and the key points to consider when selecting a deployment method in the context of AWS. We'll also highlight potential pitfalls and important points that may seem trivial but become significant in practice. Here are the list of strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;(SSG + SPA) Static File Hosting&lt;/li&gt;
&lt;li&gt;(SSG + SSR + SPA) Containerization

&lt;ol&gt;
&lt;li&gt;on EC2&lt;/li&gt;
&lt;li&gt;on ECS&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;(SSG + SSR + SPA) Serverless

&lt;ol&gt;
&lt;li&gt;Amplify Gen 1&lt;/li&gt;
&lt;li&gt;Amplify Gen 2&lt;/li&gt;
&lt;li&gt;SST&lt;/li&gt;
&lt;li&gt;OpenNext&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  Pure static generated website
&lt;/h3&gt;

&lt;p&gt;SSG stands for Static Site Generation, which essentially means the content of the website is generated at build time.&lt;br&gt;
This strategy focuses on generating static pages during the build or deployment stage of your Next.js application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b7bsdawg7zyhbe97xvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b7bsdawg7zyhbe97xvd.png" alt="SSG Process Build" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method is contingent on knowing all the necessary data for constructing the pages at build or deployment time. This approach, pre-renders pages to static HTML, which can then be efficiently served to users. It's ideal for content that doesn't change frequently and when you can predict all possible page routes at build time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxz1ahra0xxeck85sl4pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxz1ahra0xxeck85sl4pm.png" alt="SSG Process Start" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the end, you will have a folder with all the files generated, including the css, javascript and all other assets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyfs9imkk4kzi5bl0bz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyfs9imkk4kzi5bl0bz6.png" alt="SSG Process End" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With the content generated, you can host the files in any regular HTML server for example nginx, apache http server, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  When you should deploy your website using SSG?
&lt;/h4&gt;

&lt;p&gt;There are two scenarios where this approach is suitable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you are developing a SPA (Single Page Application), with all the rendering and data fetching done on the client side (browser).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the website content is available at build time, even if it's in a database, and the content is under your control and not added, updated, or deleted by third-party users.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  When not to use SSG?
&lt;/h4&gt;

&lt;p&gt;If your website requires multi-user support such as user registration and login functionality, or the ability for users to add or modify content like blog posts or shopping carts and etc — you're dealing with dynamic content. These are scenarios where data is created and modified externally, and the rate and timing of such content changes are not under your direct control.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is referred to &lt;strong&gt;Dynamic&lt;/strong&gt; content, which essentially means the content can change after the website is built and deployed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  How to deploy
&lt;/h4&gt;

&lt;p&gt;For a detail step-by-step guide on how to deploy your Next.js app using this strategy checkout the blog post &lt;a href="https://redrobot.dev/learn/articles/static-website-deployment" rel="noopener noreferrer"&gt;static website deployment&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  SSR or Server Side rendering
&lt;/h3&gt;

&lt;p&gt;Server-side rendering (SSR) generates content on each request, and this strategy is primarily used for cases where the content is dynamic. And with this usually there is a form of content source (usually a database) available to the server to access and generate pages. In this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data is fetched and collected on the server for each incoming request&lt;/li&gt;
&lt;li&gt;The server then generates the complete HTML page using this data&lt;/li&gt;
&lt;li&gt;The fully rendered page is sent to the client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F168mauda28phtjzeacg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F168mauda28phtjzeacg0.png" alt="SSR Process" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For deploying server-side rendered Next.js applications, there are several approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containerization:&lt;/strong&gt; which means creating a Docker image of the Next.js app and running it on EC2 (Elastic Compute Cloud) or ECS (Elastic Container Service). The ECS approach offers greater flexibility and scalability, but it also requires more configuration as it has more "moving parts".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Segmented Deployment:&lt;/strong&gt; This method requires breaking down the Next.js app output into static and dynamic segments and deploying each type of content to appropriate resources such as S3 and Lambda. While this approach optimizes resource usage, it is more complex to set up manually as it requires a deeper understanding of Next.js internals.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  When you should deploy your website using SSR?
&lt;/h4&gt;

&lt;p&gt;This method of deployment is particularly useful when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Content needs to be up-to-date with each page load as data is dynamic or user-specific.&lt;/li&gt;
&lt;li&gt;SEO optimization is essential - This method works much better for SEO as search engines can easily index the fully rendered content, unlike with SPA applications.&lt;/li&gt;
&lt;li&gt;Page load time need to be fast - This approach can actually decrease page load time, especially in cases where the client browser is not very powerful. By leveraging the server to render pages, you offload processing from the client.&lt;/li&gt;
&lt;li&gt;In certain cases, this method would load the page faster, particularly if the database hosting the dynamic data is close to the server generating the pages.&lt;/li&gt;
&lt;li&gt;For security-critical cases where you have important content that you don't want to send over the wire or share with the world, server-side rendering offers a more secure environment instead of exposing data and IDs.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  When not to use SSR?
&lt;/h4&gt;

&lt;p&gt;While Server-Side Rendering (SSR) in Next.js offers a balance between dynamic content and performance, leveraging caching strategies and optimized rendering processes, it's important to note that it can be more resource-intensive than static generation. The server must process each request individually, potentially leading to higher server loads, increased costs, and slightly longer response times compared to serving pre-generated static pages.&lt;/p&gt;

&lt;p&gt;Server-Side Rendering (SSR) requires running a process to render pages dynamically, which incurs additional costs. Therefore, it's best avoided if your content is static. SSR also introduces complexity with components like reverse proxies, databases, and various frontends' (admin and client-side). This complexity not only expands the potential attack surface but also increases development and maintenance costs. While SSR offers significant flexibility, these factors should be carefully weighed when considering its implementation. The decision to use SSR should be based on a thorough evaluation of your specific needs and resources.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important&lt;br&gt;
Choose your deployment strategy carefully based on your specific use case. For instance, if you have a blog website where you plan to update content yourself infrequently, there's no need for Server-Side Rendering (SSR). Instead, you can create a Static Site Generated (SSG) application with your content hosted locally. This approach is more efficient and cost-effective for websites with primarily static content that doesn't require frequent real-time updates.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Hybrid SSG + SSR + SPA
&lt;/h3&gt;

&lt;p&gt;In the majority of cases, your website or app will likely contain a mix of dynamic and statically generated content, and may even include Single Page Application (SPA) elements. A good example is an e-commerce website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The landing page might be static&lt;/li&gt;
&lt;li&gt;The products page could be dynamic&lt;/li&gt;
&lt;li&gt;The admin interface might be an SPA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For such mixed-content scenarios, you'll typically run Next.js in production mode. In this mode, Next.js:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serves static files directly from directories&lt;/li&gt;
&lt;li&gt;Renders dynamic pages on-demand&lt;/li&gt;
&lt;li&gt;Caches data to optimize file serving&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process can be broken down into two main stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment Stage: Where pages are built and prepared&lt;/li&gt;
&lt;li&gt;Live Mode: Where the Next.js process is running, serving content, and managing caching and dynamic generation as needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach allows for optimal performance and flexibility, catering to the varied content types within a single application. It leverages the strengths of static content for speed and dynamic rendering for up-to-date information, all within the Next.js framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5itmkkdmvjhc808ebz5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5itmkkdmvjhc808ebz5j.png" alt="Hybrid Process" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next.js provides mechanism to optimize serving static and dynamic by separating static and dynamic content into different parts however you will still be running the Next.js process to host the static content which increasing CPU time and cost. It might be better to leverage Segmented Deployment options for these types of websites.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  AWS Deployment Options
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Static File Hosting
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Cloudfront + S3
&lt;/h4&gt;

&lt;p&gt;This method is suitable for SSG website that host static content or SPA apps. Deploying a Next.js app using CloudFront and S3 offers a robust and scalable solution for static site hosting.&lt;/p&gt;

&lt;p&gt;The benefits of this method are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;excellent performance due to CloudFront's edge locations,&lt;/li&gt;
&lt;li&gt;high scalability&lt;/li&gt;
&lt;li&gt;cost-effectiveness for serving static content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As mentioned This method has limitations - It's primarily suitable for static exports, which may not support all Next.js features, particularly those requiring server-side rendering.&lt;/p&gt;

&lt;p&gt;For deployment, mainly we need to utilize CloudFront as a Content Delivery Network (CDN), Route 53 for Domain Name System (DNS) management, AWS Certificate Manager for SSL certificate generation and management, and S3 buckets for storing and hosting the static content of your website. This approach creates a robust, scalable architecture where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CloudFront distributes your content globally, reducing latency for users&lt;/li&gt;
&lt;li&gt;Route 53 manages your domain and directs traffic to CloudFront&lt;/li&gt;
&lt;li&gt;Certificate Manager ensures secure HTTPS connections&lt;/li&gt;
&lt;li&gt;S3 acts as the origin server, storing your static files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2v57nyomsh2295788dkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2v57nyomsh2295788dkv.png" alt="AWS Cloudfront S3 Architecture" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For step-by-step guide on how to deploy such an app see &lt;a href="https://redrobot.dev/learn/articles/static-website-deployment" rel="noopener noreferrer"&gt;static website deployment&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Containerization
&lt;/h3&gt;
&lt;h4&gt;
  
  
  EC2
&lt;/h4&gt;

&lt;p&gt;This method comprises of creating an EC2 instance, it's simple and familiar as it's a VM so you will have full control over the server environment, customizable resources (CPU, RAM, storage), you can scale vertically by adding a more powerful instance and switching over the route forwarding, and flexibility to install and configure additional software, and it's low cost specially for high-traffic applications.&lt;/p&gt;

&lt;p&gt;However, it requires higher complexity in setup and maintenance, you have to manually handle scaling and load balancing setup, and updating security patches and as far as cost it's might be more expensive to run for low traffic websites.&lt;/p&gt;

&lt;p&gt;This would typically involve installing a reverse proxy (Nginx), a node process manager like (PM2) and then finally the node application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4tad4465yw8yvgw1ghs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4tad4465yw8yvgw1ghs.png" alt="AWS EC2 Architecture" width="800" height="704"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  ECS
&lt;/h4&gt;

&lt;p&gt;Deploying a Next.js app using Amazon ECS offers several advantages, including simplified container orchestration, easier scaling and load balancing, improved resource utilization, consistent deployments across environments, and seamless integration with other AWS services.&lt;br&gt;
However, it also comes with some drawbacks. These include a learning curve for container concepts and ECS specifics, potentially higher costs compared to EC2 for small-scale applications, less direct control over the underlying infrastructure, complexity in managing stateful applications, and possible performance overhead due to containerization. Despite these challenges, ECS can be an excellent choice for teams looking to leverage the benefits of containerization and streamlined deployment processes, especially as applications grow in scale and complexity.&lt;/p&gt;

&lt;p&gt;As illustrated in the diagram, this method involves more services and careful configuration. It's important to note that the associated costs can be higher, particularly if the setup is not optimized. Therefore, careful planning and monitoring are essential to ensure cost-effectiveness while leveraging the advantages of containerization.&lt;/p&gt;

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

&lt;p&gt;If you are interested in learning more checkout the following post &lt;a href="https://dev.to/learn/articles/nextjs-ecs-deployment"&gt;"Next.js Deployment using ECS with Fargate"&lt;/a&gt; where we guide you through step-by-step describing how to achieve this.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Serverless
&lt;/h3&gt;

&lt;p&gt;The serverless architecture for all of the mentioned solutions here will be similar to what this diagram shows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmbsx4li1kbi7ryoki8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmbsx4li1kbi7ryoki8f.png" alt="AWS Serverless Architecture" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However each have their own additional components, some are proprietary and some open source. The diagram represent in high level what the Serverless option would look like.&lt;/p&gt;
&lt;h4&gt;
  
  
  AWS Amplify Gen 1
&lt;/h4&gt;

&lt;p&gt;Deploying Next.js using AWS Amplify offers a mix of advantages and potential drawbacks.&lt;/p&gt;

&lt;p&gt;On the positive side, Amplify provides easy setup, integrated AWS services, automatic CI/CD pipelines, serverless architecture, and built-in hosting with CDN capabilities. With Amplify, you can point to your Next.js app from the console and it's up and running.&lt;/p&gt;

&lt;p&gt;However, there is no direct CDK integration - you are sort of tied into the Amplify eco system and for teams requiring maximum control over their AWS architecture might find this abstraction layer constraining. The choice to use Amplify ultimately depends on the specific needs and circumstances of the project.&lt;/p&gt;
&lt;h4&gt;
  
  
  AWS Amplify Gen 2
&lt;/h4&gt;

&lt;p&gt;Amplify Gen 2 represents a significant evolution from its predecessor, offering several key improvements tailored to modern web development needs. Unlike Gen 1, which primarily used Amazon S3 and CloudFront for hosting static sites, Gen 2 leverages AWS Lambda@Edge and CloudFront to provide a more flexible serverless architecture. This shift enables full server-side rendering (SSR) support, a feature that was limited in Gen 1. Gen 2 delivers enhanced performance and scalability, particularly for dynamic content, thanks to its serverless foundation. It also offers faster deployments, especially for incremental updates, and improved support for advanced frameworks like Next.js, including features such as API routes.&lt;/p&gt;

&lt;p&gt;A notable advantage of Gen 2 is its direct CDK support, allowing developers to seamlessly extend or connect their Next.js deployments with existing architecture. While Gen 1 was more straightforward for simple static sites, Gen 2 provides an improved developer experience for full-stack applications, offering greater customization options and tighter integration with other AWS services. Although Gen 2 may have different cost implications compared to Gen 1's potentially lower costs for simple static sites, it can be more cost-effective for dynamic applications due to its serverless nature. Overall, Amplify Gen 2 is designed to better support the complexities of modern web applications, offering developers more power and flexibility in building and deploying sophisticated, scalable web solutions.&lt;/p&gt;

&lt;p&gt;If you are interested in learning more checkout the following post &lt;a href="https://dev.to/learn/articles/nextjs-aws-amplify"&gt;"Next.js Deploying using AWS CDK &amp;amp; Amplify"&lt;/a&gt; where we guide you through a step-by-step process describing how deploy a SSR-enabled Next.js app using Amplify Gen 2.&lt;/p&gt;
&lt;h4&gt;
  
  
  SST
&lt;/h4&gt;

&lt;p&gt;Similar to Amplify, SST (Serverless Stack Toolkit) is another interesting option for deploying Next.js applications, particularly if you're looking to leverage AWS services more directly. In addition to supporting Next.js app deployment, SST offers other abstractions that makes it easy to create a full app faster compared to writing CDK from scratch yourself.&lt;/p&gt;

&lt;p&gt;SST uses AWS CDK under the hood, giving you the ability to define your infrastructure as code.&lt;/p&gt;

&lt;p&gt;To deploy a Next.js app using SST, you create an SST project using &lt;code&gt;npx create-sst@latest&lt;/code&gt; and then configure the NextJs app using using regular CDK syntax:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextjsSite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SSTConfig&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="s2"&gt;sst/constructs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_input&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-next-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&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="nf"&gt;stacks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Site&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="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NextjsSite&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;site&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;addOutputs&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;SiteUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;SSTConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Critical&lt;br&gt;
Merging this into your own CDK code is not easy and it's error prone. While SST is much closer to what we want, since it used AWS CDK however - it has it's own eco system build on top of AWS CDK which forces you to use it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  OpenNext
&lt;/h4&gt;

&lt;p&gt;OpenNext is a CDK (Cloud Development Kit) library that facilitates easy integration directly into your CDK project. This approach is particularly desirable in scenarios where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your company's entire infrastructure is managed using CDK&lt;/li&gt;
&lt;li&gt;You aim to maintain uniformity across your infrastructure code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using OpenNext, you can keep all of your infrastructure code, including your Next.js deployment configuration, within the same project. This consistency can lead to several benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simplified management: All infrastructure code is in one place&lt;/li&gt;
&lt;li&gt;Easier version control: Changes to both application and infrastructure can be tracked together&lt;/li&gt;
&lt;li&gt;Streamlined deployment processes: You can use the same deployment pipeline for both your application and infrastructure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This method is especially advantageous for organizations that prioritize a cohesive and standardized approach to infrastructure management across all their projects and services.&lt;/p&gt;

&lt;p&gt;We will be using &lt;a href="https://www.npmjs.com/package/cdk-nextjs-standalone" rel="noopener noreferrer"&gt;cdk-nextjs-standalone&lt;/a&gt; which is a package that is built on top of &lt;a href="https://open-next.js.org/config/simple_example" rel="noopener noreferrer"&gt;OpenNext&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments. Natively OpenNext has support for AWS Lambda and classic Node Server. It also offer partial support for the edge runtime in Cloudflare Workers.&lt;/p&gt;

&lt;p&gt;Here is a wrapper construct that encapsulated cdk-nextjs-standalone (it's good practice to always create wrappers around 3rd party 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CfnOutput&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;acm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-certificatemanager&lt;/span&gt;&lt;span class="dl"&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;route53&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-route53&lt;/span&gt;&lt;span class="dl"&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;Nextjs&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="s2"&gt;cdk-nextjs-standalone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NextJsServerlessDeploymentProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;nextJsRootPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;hostedZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IHostedZone&lt;/span&gt;
  &lt;span class="nx"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Certificate&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="nc"&gt;NextJsServerlessDeployment&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;nextJsRootPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;hostedZone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;NextJsServerlessDeploymentProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextjs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Nextjs&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="s2"&gt;Nextjs&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;nextjsPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextJsRootPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// relative path from your project root to NextJS&lt;/span&gt;
      &lt;span class="na"&gt;domainProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;domainName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;hostedZone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CfnOutput&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="s2"&gt;CloudFrontDistributionDomain&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextjs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distribution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distributionDomain&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;And this is how you would use it&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="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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;CertificateWrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextJsServerlessDeployment&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="s2"&gt;../constructs&lt;/span&gt;&lt;span class="dl"&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;getConfig&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="s2"&gt;../helpers&lt;/span&gt;&lt;span class="dl"&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="nc"&gt;MainServiceStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webSubdomain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CertificateWrapper&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="s2"&gt;certificateWrapper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NextJsServerlessDeployment&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="s2"&gt;dynamicWebsiteDeploy&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;nextJsRootPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hostedZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;certificate&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;h2&gt;
  
  
  None AWS options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vercel
&lt;/h3&gt;

&lt;p&gt;Using Vercel to deploy a Next.js app is much easier and streamlined, and reportedly runs faster than compared to the alternatives listed here. Vercel is the company behind Next.js and their platform is optimized for it. To upload you NextJs app to Vercel, it's as easy as creating a new project, pointing to your git repo where it holds the NextJs code&lt;br&gt;
and Vercel will deploy everything for you.&lt;/p&gt;

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

&lt;p&gt;In conclusion, deploying a Next.js application to AWS offers a variety of strategies, each with its own strengths and considerations. From static file hosting using CloudFront and S3 for simple static sites, to containerization on EC2 or ECS for more complex applications, to serverless options like AWS Amplify Gen 2, SST, and OpenNext for scalable and flexible deployments, developers have a wide range of choices.&lt;/p&gt;

&lt;p&gt;The selection of the most appropriate deployment method depends on factors such as the application's complexity, scalability requirements, budget constraints, and the development team's expertise. While AWS provides robust solutions, it's worth noting that alternatives like Vercel offer streamlined deployment processes optimized specifically for Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you choose the method?
&lt;/h3&gt;

&lt;p&gt;When choosing a deployment method for your Next.js application, consider your specific needs and constraints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For static content: If your pages are not dynamic, opt for a static deployment method. It's fast, cost-effective, and easily scalable using services like AWS S3 and CloudFront.&lt;/li&gt;
&lt;li&gt;For dynamic content outside AWS: If your content is dynamic and you're not committed to AWS, Vercel offers an optimized, streamlined deployment experience specifically designed for Next.js.&lt;/li&gt;
&lt;li&gt;For dynamic content within AWS: If you're already invested in AWS infrastructure and have dynamic content, your main choices are between container-based (EC2/ECS) or serverless solutions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;a. For maximum control: Choose EC2 or ECS. EC2 provides full control over the server environment, while ECS offers container orchestration with improved scalability. ECS, in particular, provides high availability but may come at a higher cost.&lt;/p&gt;

&lt;p&gt;b. For simplified management: Opt for serverless solutions like Amplify Gen 2. It's AWS's officially supported method for Next.js deployments, offering a balance between ease of use and performance. It's particularly suitable for projects that don't require extensive customization of the underlying infrastructure. Also you can extend it with your existing CDK infrastructure so it's a good choice for startups.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Consider scalability: Serverless options like Amplify Gen 2 offer automatic scaling, while EC2/ECS solutions require more manual configuration but can be optimized for high-traffic scenarios.&lt;/li&gt;
&lt;li&gt;Factor in team expertise: EC2/ECS deployments require more in-depth AWS knowledge, while Amplify Gen 2 has a gentler learning curve. Amplify Gen 2 also has developer sandboxes which allows multiple developer experiment with and working on the code simultaneously.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Interested in learning more?
&lt;/h2&gt;

&lt;p&gt;If you are new AWS and would like to get started using and learning it the right way (using AWS CDK as IaC) - check out our Udemy class&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>nextjs</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Deploy a static (Next.js) website to AWS using AWS CDK &amp; AWS console</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Mon, 21 Oct 2024 18:00:00 +0000</pubDate>
      <link>https://forem.com/redrobotdev/learn-how-to-deploy-a-static-nextjs-website-to-aws-using-aws-cdk-aws-console-62n</link>
      <guid>https://forem.com/redrobotdev/learn-how-to-deploy-a-static-nextjs-website-to-aws-using-aws-cdk-aws-console-62n</guid>
      <description>&lt;p&gt;Deploying a static website to AWS can be achieved by AWS S3 (Storage Service), AWS CloudFront (CDN Service), Route 53 (DNS Server) and Certificate Manager.&lt;/p&gt;

&lt;p&gt;In this post we will guide you through deploying a static website on AWS using two methods. First, we'll cover the step-by-step process using the AWS Console which requires no coding skills. Then, we'll explore a more efficient approach using AWS's Infrastructure as Code (IaC) framework, the Cloud Development Kit (CDK).&lt;/p&gt;

&lt;p&gt;We will simply uploading the HTML/JS/CSS content of our website to an S3 bucket and add a AWS CloudFront to host the bucket data, and finally create a certificate and configure DNS to route the domain requests to the CloudFront record.&lt;/p&gt;

&lt;p&gt;Original Post&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://redrobot.dev/learn/articles/static-website-deployment" rel="noopener noreferrer"&gt;
      redrobot.dev
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;This approach offers several advantages in specific scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Website loads very fast since it's all pre-build HTML files&lt;/li&gt;
&lt;li&gt;No need for a server side process to run to generate pages&lt;/li&gt;
&lt;li&gt;Static websites are much less prone to hacks, wordpress is notorious for this issue. This is ideal for business who need a simple website with few functions.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The static website can be a traditional multi-page site or a Single Page Application (SPA). SPAs load a single HTML page and dynamically update content as users interact with the app. To determine if an SPA suits your needs, consider factors like user experience, performance requirements, and development complexity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Topics Covered in This Guide
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a NextJS static website&lt;/li&gt;
&lt;li&gt;Deploy the website using AWS console, then destroy it&lt;/li&gt;
&lt;li&gt;Redeploy the website using AWS CDK and then destroy it&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a NextJs Webpage
&lt;/h2&gt;

&lt;p&gt;First, lets create a NextJS project. Open a terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;frontend &amp;amp; &lt;span class="nb"&gt;cd &lt;/span&gt;frontend
npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then you will be presented with several options, choose the options as you see in the page here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Need to &lt;span class="nb"&gt;install &lt;/span&gt;the following packages:
create-next-app@14.2.5
Ok to proceed? &lt;span class="o"&gt;(&lt;/span&gt;y&lt;span class="o"&gt;)&lt;/span&gt; y

✔ What is your project named? … test-frontend
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use &lt;span class="sb"&gt;`&lt;/span&gt;src/&lt;span class="sb"&gt;`&lt;/span&gt; directory? … No / Yes
✔ Would you like to use App Router? &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt; … No / Yes
✔ Would you like to customize the default import &lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;@/&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;? … No / Yes
Creating a new Next.js app &lt;span class="k"&gt;in&lt;/span&gt; /Users/~/tmp_frontend/test-frontend.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;open the project in and editor or directly open the &lt;code&gt;next.config.mjs&lt;/code&gt; file and set the output value to export, and set the distDir to dist:&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;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;export&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;distDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then open the terminal and go into the directory where NextJs code resides. Then run&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 build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should see the following text after building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ▲ Next.js 14.2.5

   Creating an optimized production build ...
 ✓ Compiled successfully
 ✓ Linting and checking validity of types
 ✓ Collecting page data
 ✓ Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;5/5&lt;span class="o"&gt;)&lt;/span&gt;
 ✓ Collecting build traces
 ✓ Finalizing page optimization

Route &lt;span class="o"&gt;(&lt;/span&gt;app&lt;span class="o"&gt;)&lt;/span&gt;                              Size     First Load JS
┌ ○ /                                    5.25 kB        92.4 kB
└ ○ /_not-found                          871 B            88 kB
+ First Load JS shared by all            87.1 kB
  ├ chunks/23-bc0704c1190bca24.js        31.6 kB
  ├ chunks/fd9d1056-2821b0f0cabcd8bd.js  53.6 kB
  └ other shared chunks &lt;span class="o"&gt;(&lt;/span&gt;total&lt;span class="o"&gt;)&lt;/span&gt;          1.86 kB


○  &lt;span class="o"&gt;(&lt;/span&gt;Static&lt;span class="o"&gt;)&lt;/span&gt;  pre-rendered as static content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will generate a static version of the pages, you can actually do a quick text and run a webserver locally and server these files using &lt;strong&gt;live-server&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't have live-server install the package globally via &lt;strong&gt;&lt;code&gt;npm i live-server -g&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Traverse inside the dist folder and run &lt;code&gt;live-server&lt;/code&gt;.&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;dist
live-server &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if browser doesn't open up automatically, open a browser and go to &lt;code&gt;http://127.0.0.1:8080/&lt;/code&gt;, then test the website make sure it runs. You should see this page in your browser:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Important: &lt;br&gt;
Although a basic HTML, CSS, and JavaScript website would have worked, we chose NextJs for their efficiency. Despite seeming more complex for this example, this approach actually simplified development, reduced setup time, and offered advantages like automated builds, type checking and etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Deploying Website using AWS Console
&lt;/h2&gt;

&lt;p&gt;This section covers deploying the website using the AWS Console. While not the recommended method, it's might be useful for understanding core concepts. Also&lt;br&gt;
this method doesn't require you to know any coding knowledge.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Configure the S3 bucket
&lt;/h3&gt;

&lt;p&gt;Open a browser and go to the AWS console, and login.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the Amazon S3 Service.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click on the &lt;strong&gt;Create New Bucket&lt;/strong&gt; option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Create Bucket page, under General configuration, select &lt;strong&gt;General purpose&lt;/strong&gt; from the bucket options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name your bucket something that you will remember, I have named it &lt;em&gt;"temp-console-website"&lt;/em&gt;, you could name it the same things to make following steps easier.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Note:&lt;br&gt;
The name is crucial to remember, as we'll use it again when specifying the bucket Resource value in the next section. This ensures correct resource linking in later steps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Object Ownership&lt;/strong&gt; section, select ACLs disabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Block Public Access settings for this bucket&lt;/strong&gt; section, uncheck the &lt;strong&gt;Block all pubic access&lt;/strong&gt;, and make sure all the other four checkboxes have been unchecked as well. You will notice a yellow alert box popping up with the following message:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Turning off block all public access might result in this bucket and the objects within becoming public&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Select or check the &lt;strong&gt;I acknowledge that the current settings might result in this bucket and the objects within becoming public&lt;/strong&gt; box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Bucket Versioning&lt;/strong&gt; select Disable versioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;everything else should be set to default, select &lt;strong&gt;Create bucket&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is an optional step, but to make things simple for us at the end where we need to destroy all resource, add a tag. Scroll down to the &lt;strong&gt;Tags&lt;/strong&gt; section and add a tag by click on edit, and adding a new tag with the key value of &lt;em&gt;temp-project&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Upload the files to S3
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Select the newly created bucket from the bucket list page. If you set the name to be &lt;em&gt;"temp-console-website"&lt;/em&gt; then that will show up in the list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the &lt;strong&gt;Upload&lt;/strong&gt; button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;add files&lt;/strong&gt;, then select all the files in the &lt;em&gt;dist&lt;/em&gt; folder from the NextJs folder, and then click the &lt;strong&gt;Upload&lt;/strong&gt; button to upload all the files. a progress bar will be displayed showing the upload progression. Once upload to the next step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Properties&lt;/strong&gt; tab, then scroll down to the &lt;strong&gt;Static website hosting&lt;/strong&gt; section and click Edit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under the &lt;strong&gt;Static website hosting&lt;/strong&gt; section select &lt;em&gt;Enable&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the &lt;strong&gt;Hosting type&lt;/strong&gt; select &lt;em&gt;Host a static website&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is an input field under &lt;strong&gt;Index document&lt;/strong&gt;, enter &lt;code&gt;index.html&lt;/code&gt; in that field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;enter &lt;code&gt;error.html&lt;/code&gt; for the &lt;strong&gt;Error document&lt;/strong&gt; but this is optional.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Save changes&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go into the &lt;strong&gt;Permissions&lt;/strong&gt; tab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll down until you see the &lt;strong&gt;Bucket Policy&lt;/strong&gt; section. Click on the &lt;strong&gt;Edit&lt;/strong&gt; button, then paste the following policy in there&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="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;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="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="s2"&gt;"s3:GetObject"&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;"arn:aws:s3:::temp-console-website/*"&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;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Save changes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The "temp-console-website" is the name I chose, if you have chosen a different name, then replace this value in the JSON object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've completed the S3 configuration. To view the website directly from S3, go to the &lt;strong&gt;Properties&lt;/strong&gt; tab and scroll to &lt;strong&gt;Static website hosting&lt;/strong&gt;. At the bottom, you'll find a URL under "Bucket website endpoint". The URL should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://temp-console-website.s3-website-us-east-1.amazonaws.com" rel="noopener noreferrer"&gt;http://temp-console-website.s3-website-us-east-1.amazonaws.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you should see the same NextJs page we saw when we ran locally.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuring DNS
&lt;/h3&gt;

&lt;p&gt;In this section we will configure to point a domain name to this CloudFront distribution or our website.&lt;br&gt;
If you already have a domain you purchased from a third party domain provider like GoDaddy, Namecheap,&lt;br&gt;
Google domain etc you have to login and change some of the settings.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will be moving back and forth between DNS, CloudFront and Certificate Manager in order to get this configured&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First lets add the domain to AWS Route 53. Route 53 is a DNS service provided by Amazon. Lets add our domain. For this example I have a test domain named &lt;code&gt;redrobotexample.com&lt;/code&gt;. This is a domain I use to try and test different applications.&lt;/p&gt;

&lt;p&gt;Go to the Route 53 page:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3iu3q4gqe28m0o8f8nlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3iu3q4gqe28m0o8f8nlf.png" alt="Route 53 Dashboard" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;strong&gt;Get started&lt;/strong&gt; button, and you will be presented with the following view:&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;Create hosted zones&lt;/strong&gt; option and click &lt;strong&gt;Get started&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Domain name field enter your domain name, ie &lt;code&gt;redrobotexample.com&lt;/code&gt;, and then click &lt;strong&gt;Create hosted zone&lt;/strong&gt;. Once done you will be presented with this page:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7e9djkh2z5qbmbsd252.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7e9djkh2z5qbmbsd252.png" alt="Route 53 Hosted Zone View" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expand the &lt;strong&gt;Hosted zone details&lt;/strong&gt; area by clicking on the triangle next to it. you will be presented with a few details. From that list, you need to copy the &lt;strong&gt;Name servers&lt;/strong&gt; value and paste them in your 3rd party domain provider DNS provider. In your 3rd party domain provider, find where you can define custom dns servers and paste the values, which should look like this:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ns-2042.awsdns-63.co.uk
ns-1452.awsdns-53.org
ns-543.awsdns-03.net
ns-92.awsdns-11.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For example, in namecheap this is the section where you define custom DNS values:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt; Scroll down to the &lt;strong&gt;Tags&lt;/strong&gt; section and add a tag and select the &lt;em&gt;temp-project&lt;/em&gt; value.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Creating a Certificates
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a new tab or browser windows, and go to the AWS Certificate Manager or (ACM)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;Request certificate&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the next page select &lt;strong&gt;Request a public certificate&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the next page, for the &lt;strong&gt;Fully qualified domain name&lt;/strong&gt; enter your domain name, ie &lt;code&gt;redrobotexample.com&lt;/code&gt; in our example&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the same section click on &lt;strong&gt;add another name&lt;/strong&gt; for the certificate and enter the same domain but add the the &lt;code&gt;www&lt;/code&gt; subdomain to it. So for our example it would be &lt;code&gt;www.redrobotexample.com&lt;/code&gt; then click &lt;strong&gt;Request&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the next page, scroll down to where it says &lt;strong&gt;Domains&lt;/strong&gt;, you will notice two CNAME values are presented - these need to be added ro your DNS entry so AWS certificate Manager can verify that the domain belongs to us. S we need to add those to the Route 53 entries and we can do that by clicking on the &lt;strong&gt;Create records in Route 53&lt;/strong&gt; in that same view (you can do this manually but AWS made things simple for us)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the next page, since we have been using the same domain name for our DNS values, AWS will filter the right DNS entries for us to select.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Click the &lt;strong&gt;Create Records in Route53&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the other tab, that has the Route 53 page open, verify the two new Route53 entries have been added to the record list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After this, we need to wait for the status of this certificate to change from "pending validation" to validated. In the Certificate Manager page, check the value of &lt;strong&gt;Status&lt;/strong&gt;. Once the status changes to "Issued" move to the next step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll down to the &lt;strong&gt;Tags&lt;/strong&gt; section and add a tag by click on edit, and adding a new tag with the key value of &lt;em&gt;temp-project&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Configuring CloudFront
&lt;/h3&gt;

&lt;p&gt;We have defined our DNS records and created our certificates, we would like to update the page so it points to a domain instead of the S3 generated URL. For that we need to setup a AWS CloudFront entry. CloudFront is a CDN service provided by AWS.&lt;/p&gt;

&lt;p&gt;Go to the AWS CloudFront page&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Then click on the &lt;strong&gt;Create a CloudFront Distribution&lt;/strong&gt;, the &lt;strong&gt;Create distribution&lt;/strong&gt; page will show up&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;Origin domain&lt;/strong&gt; field or dropdown, click on the field and the dropdown list will appear. From that list select the S3 entry we created in the last part. If you picked the same name from this guide, it should look something like this:&lt;/p&gt;

&lt;p&gt;temp-console-website.s3.us-east-1.amazonaws.com&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A pop should be displayed that says "This S3 bucket has static web hosting enabled. If you plan to use this distribution as a website, we recommend using the S3 website endpoint rather than the bucket endpoint." Click on the &lt;strong&gt;Use website endpoint&lt;/strong&gt; button to do this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Web Application Firewall (WAF) section, select &lt;em&gt;Do not enable security protections&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do not change any of the other configurations, we will come back here to update the config once we define our domain and certificates but for now, go ahead and click &lt;strong&gt;Create distribution&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once distribution is done, you can copy the URL value under &lt;strong&gt;Distribution domain name&lt;/strong&gt; and paste it in the browser. the value should look like something like this &lt;code&gt;d1wzzsoxu6i44i.cloudfront.net&lt;/code&gt; You should see the same page now as before&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Custom SSL certificate - optional&lt;/strong&gt; field, select the certificate we just created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the Alternative Domain names, add your domain name with and without the www subdomain, so essentially we are adding two values. In this example it would be:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redrobotexample.com
www.redrobotexample.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fcloudfront-deploying.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fcloudfront-deploying.png" alt="CloudFront Deploying" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;br&gt;
  It might be easier to open a secondary tab, and go to the CloudFront page and&lt;br&gt;
  check the name to make sure the value is the correct one.&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Scroll down to the &lt;strong&gt;Tags&lt;/strong&gt; section and add a tag&lt;br&gt;
by click on edit, and adding a new tag with the key value of &lt;em&gt;temp-project&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;click on &lt;strong&gt;Create records&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Updating DNS
&lt;/h3&gt;

&lt;p&gt;The last step is to update our DNS to point to the CloudFront CDN. With the certificates and CDN in place, we can add a record in our Route53 to our CloudFront dist.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the same Route 53 page, under the Records section click on &lt;strong&gt;Create record&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;Record Type&lt;/strong&gt; select &lt;em&gt;A - Route TRaffic to an IPv4 address&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Enable the &lt;em&gt;Alias&lt;/em&gt; toggle&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;Route traffic to&lt;/strong&gt; select the &lt;em&gt;Alias to CloudFront Distribution&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;and then on the bottom selector, select the CloudFront distribution we created in the last step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;you can do the same once more but add the www subdomain as well.&lt;/p&gt;

&lt;p&gt;We are done with out configuration, If you followed the steps exactly as described you should be able to go to your domain, (in our case redrobotexample.com) and view your website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Destroying all resources
&lt;/h3&gt;

&lt;p&gt;As you can see, the steps involved to get this up and running are tedious, and error prone and most importantly not repeatable. You will also notice that destroying these resources suffer from the same problem as we have to manually go to each service and destroy individual services.&lt;/p&gt;

&lt;p&gt;Before doing thing using IaC, lets delete/destroy all the created resources.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;Resource groups&lt;/strong&gt; page&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create resource group&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Tag based&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Under the &lt;strong&gt;Grouping criteria&lt;/strong&gt; enter &lt;em&gt;temp project&lt;/em&gt; in the tag field&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create group&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Then after creation, select the group&lt;/li&gt;
&lt;li&gt;On the group's detail you will see each resource listed.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The order of the resource might be different for you, so lets go over each resource by type and describe how to completely destroy them - the order which you need to destroy resource is important since we have created dependencies between resources.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Route 53 resource on a new tab or window.&lt;/li&gt;
&lt;li&gt;Check the 3 Record that have the record Type A and the two CNAME's. &lt;strong&gt;DO NOT DELETE&lt;/strong&gt; the NS and SOA records.&lt;/li&gt;
&lt;li&gt;close the tab, now open the CloudFront resource in a new tab&lt;/li&gt;
&lt;li&gt;Remember the distribution name, and go into the Distribution list view and select that item and click &lt;strong&gt;Disable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Once Disabled, then click &lt;strong&gt;Delete&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;If the Delete option isn't available, it means that CloudFront is still propagating your change to the edge locations. Wait until the new timestamp appears under the Last modified column&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Close the tab, now open the S3 resource&lt;/li&gt;
&lt;li&gt;Select all files from the list and click &lt;strong&gt;Delete&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A new page is presented, which will ask for your confirmation, enter the text &lt;em&gt;permanently delete&lt;/em&gt; in the bottom text box then click &lt;strong&gt;Delete objects&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Once deleted, click on the &lt;strong&gt;Buckets&lt;/strong&gt; item to view the list of Buckets&lt;/li&gt;
&lt;li&gt;Select the bucket (should be named temp-console-website) and click &lt;strong&gt;Delete&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A similar confirmation page is shown, enter the bucket name in the text field to confirm bucket deletion and click &lt;strong&gt;Delete bucket&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Close the tab, now open the certificate manager view&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Delete&lt;/strong&gt;. In the confirmation pop-up enter delete and then Delete again.&lt;/li&gt;
&lt;li&gt;close the tab, verify that all resource have been deleted from the resource group view&lt;/li&gt;
&lt;li&gt;If no other resource is left continue to the next section.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the end of the next section you will see that destroying resources is a single command.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Architecture
&lt;/h3&gt;

&lt;p&gt;The AWS architecture of the network we just created looks like this.&lt;/p&gt;

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

&lt;p&gt;we can show the traffic flow using the following UML diagram&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Using AWS CDK
&lt;/h2&gt;

&lt;p&gt;By leveraging IaC, you can automate and replicate all the setup and configuration work typically done through the console. This approach significantly speeds up your website deployment process. It allows you to maintain both your website structure and content in code, enabling quick redeployment when you need to add a blog post or change content.&lt;/p&gt;

&lt;p&gt;A key advantage of this method is its elimination of the need for a database to store and retrieve website content, or a server to render it. Instead, your entire site can be managed and updated directly through code. This approach simplifies maintenance, reduces costs, and improves scalability and performance and you can use a code subversion system like git to track all changes including the content.&lt;/p&gt;

&lt;p&gt;Lets automate all of the steps we took using AWS CDK, which is an IaC or Infrastructure as code framework.&lt;br&gt;
All the steps we performed manually it can be automated and also we can add logic as well so based on some condition, ie if it's a production deployment we can add a few other steps vs if it's a test deployment we can skip a few other steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Node.js and npm installed&lt;/li&gt;
&lt;li&gt;AWS cli and cdk setup and configured&lt;/li&gt;
&lt;li&gt;Basic knowledge in Javascript and Typescript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setup, Code and Deploy
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a new CDK project:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;temp-project &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;temp-project
&lt;span class="nb"&gt;mkdir &lt;/span&gt;infrastructure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;infrastructure
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;in addition, move the frontend folder we created from the first section of the guide into &lt;code&gt;temp-project&lt;/code&gt; folder.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replace the content of the file &lt;code&gt;lib/infrastructure-stack.ts&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;route53&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-route53&lt;/span&gt;&lt;span class="dl"&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;acm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-certificatemanager&lt;/span&gt;&lt;span class="dl"&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;s3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-s3&lt;/span&gt;&lt;span class="dl"&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;s3deploy&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-s3-deployment&lt;/span&gt;&lt;span class="dl"&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;cloudfront&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-cloudfront&lt;/span&gt;&lt;span class="dl"&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;route53Targets&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-route53-targets&lt;/span&gt;&lt;span class="dl"&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="nc"&gt;InfrastrucureStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redrobotexample.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subdomain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`www.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

    &lt;span class="c1"&gt;// fetch route53 zone&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;zone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HostedZone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromLookup&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="s2"&gt;zone&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;domainName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;// this will create a certificate&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;certificate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;acm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Certificate&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="s2"&gt;certificate&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;domainName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;subjectAlternativeNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subdomain&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CertificateValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromDns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;// viewer certificate&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;viewerCertificate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cloudfront&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ViewerCertificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAcmCertificate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;aliases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subdomain&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="c1"&gt;// bucket where website dist will reside&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="s2"&gt;WebsiteBucket&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;websiteIndexDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;websiteErrorDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;404.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;publicReadAccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;blockPublicAccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;blockPublicAcls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;blockPublicPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ignorePublicAcls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;restrictPublicBuckets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;removalPolicy&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;RemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DESTROY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;autoDeleteObjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;distro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cloudfront&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CloudFrontWebDistribution&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="s2"&gt;WebsiteCloudfrontDist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;viewerCertificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;originConfigs&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="na"&gt;s3OriginSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;s3BucketSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;behaviors&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="na"&gt;isDefaultBehavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// s3 construct to deploy the website dist content&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3deploy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BucketDeployment&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="s2"&gt;WebsiteDeploy&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;destinationBucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;s3deploy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../frontend/dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
      &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;distro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;distributionPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;memoryLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&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;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ARecord&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="s2"&gt;route53Domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;recordName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RecordTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAlias&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;route53Targets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CloudFrontTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;distro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ARecord&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="s2"&gt;route53FullUrl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;recordName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;www&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;route53&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RecordTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAlias&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;route53Targets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CloudFrontTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;distro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;now deploy the stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will get a list of resource that AWS CDK will create based on our code&lt;br&gt;
which is listed as such:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once deployment open the browser and go to the domain and view the page. That is it!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And to destroy all the resources just run&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;And enter &lt;strong&gt;y&lt;/strong&gt; to confirm you want to delete. And that is it! all resource will been destroyed according to the dependency tree CDK keeps track of.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, this method requires more knowledge but triumphs the manual method for all cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in learning more?
&lt;/h2&gt;

&lt;p&gt;If you are interested in taking this to the next level, checkout our Serverless fundamentals class at where we go over in details explain what each service does, and actually create a dynamic application with user login and authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Using CDK to deploy a static website to S3 provides a streamlined, code-based approach to infrastructure management. This method allows for version control, easy updates, and integration into CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;This is by no means a production configuration, This is the bare minimum config you need to upload your site - but for most small or medium sized business or personal websites, this solution is ideal.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>nextjs</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What is Serverless? An example based explanation</title>
      <dc:creator>RedRobot.dev</dc:creator>
      <pubDate>Fri, 05 Jul 2024 19:59:25 +0000</pubDate>
      <link>https://forem.com/redrobotdev/what-is-serverless-an-example-based-explanation-5d80</link>
      <guid>https://forem.com/redrobotdev/what-is-serverless-an-example-based-explanation-5d80</guid>
      <description>&lt;h2&gt;
  
  
  tl;dr (short version)
&lt;/h2&gt;

&lt;p&gt;Serverless is a cloud technology that allows you to focus more on your software application logic, rather than on the deployment or maintenance of servers hosting your application. This leaves more time to improve your application, test it thoroughly, and add new functions.&lt;/p&gt;

&lt;p&gt;The alternative to serverless is server-oriented deployment, which has its pros and cons. In general, if you have an application that needs to be accessed by the public via the internet, serverless is a good option, especially if you are in the beginning phase of application development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive
&lt;/h2&gt;

&lt;p&gt;Take the following Typescript/Javascript code as an example:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fetchInvoice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;generateInvoicePDF&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;../api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateCustomerInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerId&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeProject&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfGenResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateInvoicePDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filepath&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing fancy here, the function accepts a customer’s ID and then generates a PDF of the invoice. We are not interested in the low-level details; assume the function works correctly.&lt;/p&gt;

&lt;p&gt;So we want to call this function from our web, mobile, or desktop application — i.e., by clicking on a download PDF button and triggering this call. Take this UI as an example — user click on the download file icon next to the invoice and the function would be called (or triggered).&lt;/p&gt;

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

&lt;h2&gt;
  
  
  How can we achieve this?
&lt;/h2&gt;

&lt;p&gt;The usual way or the “non-serverless way” to do this is by running something like an Express Node.js app (maybe proxied via an Nginx server), that has a route like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/generateInvoice?customerId=75612312
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And the code would be something like this:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&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="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&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;generateCustomerInvoice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware to parse JSON bodies&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;// Route to generate invoice&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/generateInvoice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;customerId&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Customer ID is required&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateCustomerInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Start the server&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running at http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;And to run this in a production environment, you would have to manually provision a computer or a virtual machine (it can be Docker as well) and host this there.&lt;/p&gt;

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

&lt;p&gt;So the steps involved in deploying this would be the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a virtual machine (specify RAM, Storage, CPU Cores and Speed)&lt;/li&gt;
&lt;li&gt;Install Node.js&lt;/li&gt;
&lt;li&gt;Install Express&lt;/li&gt;
&lt;li&gt;transfer the code inside that machine&lt;/li&gt;
&lt;li&gt;run it&lt;/li&gt;
&lt;li&gt;monitor it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;in theory sounds easy enough, but in real world —not so much.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the issue with this solution?
&lt;/h2&gt;

&lt;p&gt;Here it comes — once you do all that (after deploying your code), you have the following responsibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Manage updating the operating system to make sure no vulnerabilities exist. This meaning keeping up to date with issues, patching your kernel etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you set up the firewall correctly so it’s secure and no one can access the machine. For this case, the firewall configuration is going to be easy but for larger and more complex application — managing IPTables requires a lot of reading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case of traffic spikes, increase the machine resources or create a secondary one and use a load balancer. But after the spikes, you have to undo that and go back to a single server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave the machine running at all times, even if the invoice creation function would only be called once in a while — so you’re wasting CPU resources, electricity, and money.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case something goes wrong — e.g., PC runs out of memory and crashes — you have to monitor the machine, restart it, and recover it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of this for just this simple function — imagine adding a database to this system or a caching system etc, now you have to monitor more stuff. This is precious time you have to spend supporting your function — where instead you could be updating your app or improve it.&lt;/p&gt;

&lt;p&gt;This is where serverless comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serverless
&lt;/h2&gt;

&lt;p&gt;Serverless solves all of the mentioned problems by giving you the tools to simply upload your function to the serverless provider of your choice, specify the API route that would call this function, and that’s it.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Technically speaking, “Serverless” is a misnomer, because you are very much still using a server, BUT you are not manually provisioning and managing the server. If you really want to name it properly, it should’ve been called something like “3rd Party Managed Servers” instead, but I think “Serverless” is a more marketable term.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Serverless will manage updating any underlying OS it’s running on, firewall, scale up when traffic spikes and scale down when there is no traffic, and handle all server related issues.&lt;/p&gt;

&lt;p&gt;...&lt;br&gt;
it’s a perfect solution for startups and proof of concept projects, as it reduces the time needed to fix and manage the supporting servers — so you have more time to work on application logic&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;So to define Serverless formally, it is a cloud-native computing model, (meaning it is feature that is only available on 3rd party cloud services like AWS, Cloudflare, fly.io, etc), which allows you to build and run applications and services without having to manage infrastructure.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why not use Serverless?
&lt;/h2&gt;

&lt;p&gt;As mentioned in the last sentence, serverless is a cloud-native solution, so if you plan on hosting your application on a private intranet — let’s say, a company that has local servers like a military-based company, or somewhere with slow or no internet connection — then serverless is not the right solution for you.&lt;/p&gt;

&lt;p&gt;Second, the pricing model is not deterministic — if you are not careful with your lambda configuration, and let’s say a DDoS attack happens, it will incur a &lt;a href="https://cybernews.com/news/ddos-attack-104k-bill-from-hosting-provider/" rel="noopener noreferrer"&gt;large amount of charges&lt;/a&gt;. Or if you get unexpected high traffic without any monetization strategy, the same issue will occur.&lt;/p&gt;

&lt;p&gt;Thirdly, my experience with serverless has been slow — the development process is very slow since you have to push your changes to the provider to test out the functions, whereas if you develop locally, like in a Docker environment, it would be much faster. In order to speed up your dev process, you actually have to become a better defensive coder to move faster developing code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sample Psudo Code
&lt;/h2&gt;

&lt;p&gt;This example demonstrates using AWS, AWS CDK, and TypeScript to create a sample codebase that automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Provisions serverless resources on AWS&lt;/li&gt;
&lt;li&gt;Uploads the Lambda function code&lt;/li&gt;
&lt;li&gt;Creates an API route to invoke the function&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the main entry point of the 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// cdk starting point&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SampleAppStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RedRobot&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;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;awsAccountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;awsRegion&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;this is the SampleAppStack call which create the lambda and REST resources (API Gateway)&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="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="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;constructs&lt;/span&gt;&lt;span class="dl"&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;lambdaNodeJs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-lambda-nodejs&lt;/span&gt;&lt;span class="dl"&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;lambda&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-lambda&lt;/span&gt;&lt;span class="dl"&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;apigateway&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/aws-apigateway&lt;/span&gt;&lt;span class="dl"&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="nc"&gt;SampleAppStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="nf"&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="c1"&gt;// create lambda&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lambdaPdfGen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;lambdaNodeJs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodejsFunction&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pdfGenerator&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;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../lambda/pdfGenerator&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="s2"&gt;index&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;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_20_X&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="c1"&gt;// top level api gateway construct&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;apigateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RestApi&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="s2"&gt;restApi&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;restApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/generatePDF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// attach the lamba PDF generator call to the rest api get call&lt;/span&gt;
    &lt;span class="nx"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&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;apigateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LambdaIntegration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lambdaPdfGen&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;and this is the lambda function&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="c1"&gt;// lambda/pdfGenerator&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;lambda&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;fetchInvoice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;generateInvoicePDF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;parseCustomerId&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;../api&lt;/span&gt;&lt;span class="dl"&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;generateCustomerInvoiceLambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APIGatewayProxyHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&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;lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APIGatewayProxyEvent&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="nx"&gt;lambda&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;try&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;customerId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseCustomerId&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;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchCustomerActiveProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeProject&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfGenResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateInvoicePDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pdfGenResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filepath&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is all you need to get started, eliminating the need for manual resource creation mentioned in the server section.&lt;/p&gt;

&lt;p&gt;An important point to note: We used AWS's Infrastructure as Code (IaC) framework, CDK, to write the infrastructure code. We could have done the same for the server-oriented code mentioned earlier, but it would have been more complex, involving writing a Dockerfile, using a service like Fargate to upload and host the Docker image, and etc.&lt;br&gt;
The IaC code shown here isn't strictly a component of serverless architecture. However, since serverless involves heavily utilizing AWS services, not using an IaC framework would make working with serverless very difficult. If you're interested in learning more about IaC, refer to the end of the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should I care about this as a Business owner?
&lt;/h2&gt;

&lt;p&gt;This version of the passage is well-written and clear. The improvements you've made have addressed the issues in the original text. Here's the passage with minor refinements:&lt;br&gt;
As a business owner, it's crucial to understand these technologies, particularly if your web application is central to your operations.&lt;br&gt;
It's equally important to recognize when serverless isn't the best choice. Depending on your specific requirements, serverless might be costlier compared to alternatives like a Kubernetes deployment solution.&lt;br&gt;
Consider a scenario where your business develops software for parsing and managing legal documents. In this case, you might opt for a container-based infrastructure instead of serverless due to the critical nature of the data being parsed and stored. This approach preserves the flexibility to deploy your code on-premises, which is especially valuable when dealing with sensitive data that cannot be hosted on public cloud infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you want to learn Serverless?
&lt;/h2&gt;

&lt;p&gt;I‘ve developed a comprehensive Udemy course that guides you through building a Serverless Single Page Application (SPA) from the ground up using AWS, AWS CDK, AWS SDK, Next.js and TypeScript, explaining key concepts as you progress through the class. Prerequisites are limited to basic JavaScript and React knowledge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/serverless-fullstack-fundamentals-with-aws-cdk-nextjs-typescript/?referralCode=C8DAB06460466F29B74A" rel="noopener noreferrer"&gt;Serverless Fullstack with AWS/CDK/NextJS &amp;amp; Typescript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://redrobot.dev/" rel="noopener noreferrer"&gt;https://redrobot.dev/&lt;/a&gt; if you need help with a project, consultation or training.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>serverless</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
