<?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: Mariam Adedeji</title>
    <description>The latest articles on Forem by Mariam Adedeji (@mariehposa).</description>
    <link>https://forem.com/mariehposa</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%2F378643%2Ffaefd879-a74a-4d20-ab58-3975f2012938.jpg</url>
      <title>Forem: Mariam Adedeji</title>
      <link>https://forem.com/mariehposa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mariehposa"/>
    <language>en</language>
    <item>
      <title>Secrets Management for Platforms: AWS Secrets Manager vs Parameter Store</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Thu, 27 Nov 2025 23:43:47 +0000</pubDate>
      <link>https://forem.com/aws-builders/secrets-management-for-platforms-aws-secrets-manager-vs-parameter-store-5db5</link>
      <guid>https://forem.com/aws-builders/secrets-management-for-platforms-aws-secrets-manager-vs-parameter-store-5db5</guid>
      <description>&lt;p&gt;When building platforms on AWS, one of the most important decisions is how to store and manage secrets-things like database passwords, API tokens, and sensitive configuration. AWS offers two main tools for this: &lt;strong&gt;Secrets Manager&lt;/strong&gt; and &lt;strong&gt;Parameter Store&lt;/strong&gt;. They look similar at first, but they solve slightly different problems. Choosing the right one can simplify your platform, reduce cost, and improve security.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secrets Manager in Simple Terms
&lt;/h2&gt;

&lt;p&gt;Secrets Manager is built specifically for highly sensitive secrets. Its biggest advantage is that it can automatically rotate secrets for services like RDS, Redshift, DocumentDB, and any custom integration you build with Lambda. It also has strong auditing and supports cross-region and cross-account setups out of the box.&lt;/p&gt;

&lt;p&gt;The downside is cost. You pay for each secret, each API call, and each rotation. This adds up quickly, especially for large platform teams managing dozens or hundreds of credentials.&lt;/p&gt;

&lt;p&gt;Use Secrets Manager when your secrets change often, when rotation matters, or when the secret is critical to your production systems.&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%2F3ej0m51s6vvw4z77xle3.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%2F3ej0m51s6vvw4z77xle3.png" alt="aws-secrets-manager" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parameter Store in Simple Terms
&lt;/h2&gt;

&lt;p&gt;Parameter Store is more general-purpose. It is great for application configuration, environment variables, feature flags, and low-sensitivity secrets. It uses a simple folder-like path system, which makes organisation easy. It also integrates nicely with EC2, Lambda, ECS, CodeBuild, and CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;The biggest advantage is price. The standard tier is free, and many teams use it heavily without paying anything.&lt;/p&gt;

&lt;p&gt;The limitation is that Parameter Store doesn't rotate secrets on its own, and its throughput is lower unless you upgrade to Advanced parameters. If you need rotation, you must write your own automation.&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%2Fcpi1t0yem1jo2h5vlq6f.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%2Fcpi1t0yem1jo2h5vlq6f.png" alt="aws-parameter-store" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So Which One Should You Use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use Secrets Manager when the secret is highly sensitive or needs rotation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Parameter Store for configs and secrets that rarely change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most platform teams end up using both. Secrets Manager handles core secrets like database credentials or third-party API keys. Parameter Store handles things like service endpoints (&lt;code&gt;/prod/api/base_url&lt;/code&gt;) or operational settings (&lt;code&gt;/dev/user-service/timeout&lt;/code&gt;). This hybrid approach gives strong security where needed and a low-cost configuration everywhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices &amp;amp; Recommendations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep things encrypted, even for non-sensitive values. &lt;/li&gt;
&lt;li&gt;Add a clear naming structure for all your parameters and secrets, as this prevents confusion across environments. &lt;/li&gt;
&lt;li&gt;Cache values inside applications instead of calling AWS on every request.&lt;/li&gt;
&lt;li&gt;And give your app runtime roles read-only access while keeping write and update permissions restricted to only allowed users or platforms.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Secrets Manager&lt;/strong&gt; and &lt;strong&gt;Parameter Store&lt;/strong&gt; are not competitors, but they complement each other. Secrets Manager shines when security and rotation matter. Parameter Store shines when you want a simple and organised configuration without high cost. Together, they form a clean and effective secrets management strategy for AWS platforms.&lt;/p&gt;

&lt;p&gt;If you found this article helpful, please leave a like or comment and share it with others. If you have any questions, feel free to ask in the comments section.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>devops</category>
      <category>platform</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Mon, 01 Sep 2025 12:45:59 +0000</pubDate>
      <link>https://forem.com/mariehposa/-nk7</link>
      <guid>https://forem.com/mariehposa/-nk7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h" class="crayons-story__hidden-navigation-link"&gt;Top 10 AWS Services Every Developer Should Know in 2025&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mariehposa" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F378643%2Ffaefd879-a74a-4d20-ab58-3975f2012938.jpg" alt="mariehposa profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mariehposa" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mariam Adedeji
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mariam Adedeji
                
              
              &lt;div id="story-author-preview-content-2810137" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mariehposa" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F378643%2Ffaefd879-a74a-4d20-ab58-3975f2012938.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mariam Adedeji&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 30 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h" id="article-link-2810137"&gt;
          Top 10 AWS Services Every Developer Should Know in 2025
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloudcomputing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloudcomputing&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/developers"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;developers&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;11&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>developers</category>
      <category>devops</category>
    </item>
    <item>
      <title>Top 10 AWS Services Every Developer Should Know in 2025</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Sat, 30 Aug 2025 23:33:06 +0000</pubDate>
      <link>https://forem.com/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h</link>
      <guid>https://forem.com/mariehposa/top-10-aws-services-every-developer-should-know-in-2025-f1h</guid>
      <description>&lt;p&gt;In 2025, Amazon Web Services (AWS) remains the dominant provider in cloud computing. With hundreds of services available, it can feel overwhelming to decide which ones you should focus on as a developer. The truth is, you don’t need to know everything. Mastering a core set of AWS services gives you the foundation to build scalable, secure, and cost-effective applications.&lt;/p&gt;

&lt;p&gt;In this article, we’ll cover the 10 AWS services every developer should know, what they do, why they matter, and how you can start using them today.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Amazon EC2 (Elastic Compute Cloud)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Virtual servers in the cloud.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; EC2 remains the backbone of many applications that require full control over the operating system, custom runtimes, or complex workloads.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Hosting APIs, batch processing, or running monolith applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. AWS Lambda
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A serverless compute service that runs code without provisioning servers.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Ideal for event-driven apps, microservices, and pay-per-execution workloads.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Automatically process images uploaded to S3 or run lightweight APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Amazon S3 (Simple Storage Service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Highly scalable object storage for files, images, logs, backups, and more.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Nearly every AWS application touches S3 at some point.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Store user uploads, serve static websites, or maintain data lakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Amazon RDS (Relational Database Service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Managed relational databases (PostgreSQL, MySQL, SQL Server, etc).&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Saves developers from handling backups, patches, and scaling headaches.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Powering transactional apps like e-commerce or banking systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Amazon DynamoDB
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A fully managed NoSQL database with millisecond response times.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Perfect for apps that require scale, reliability, and near-zero latency.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Gaming leaderboards, IoT device data, or session stores.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Amazon API Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Fully managed service for creating, publishing, and managing APIs.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Provides a quick way to expose serverless functions or microservices securely.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Backend for mobile apps, IoT APIs, or REST/GraphQL endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Amazon CloudFront
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A Content Delivery Network (CDN) for fast and secure global content delivery.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Reduces latency by serving content from edge locations worldwide.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Accelerating website content, APIs, or video streaming.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. AWS IAM (Identity and Access Management)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Service for managing user access, roles, and permissions.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; Security in AWS starts with IAM. Without proper roles and policies, you risk major vulnerabilities.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Developers having least-privilege access to deploy only what they need.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Amazon CloudWatch
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Monitoring and observability service for logs, metrics, and alarms.&lt;br&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; You can’t fix what you can’t measure. CloudWatch helps you monitor app performance and costs.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Tracking API latency, logging Lambda errors, or setting alerts for high CPU usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Amazon ECS / EKS (Containers on AWS)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ECS (Elastic Container Service):&lt;/strong&gt; AWS-managed container orchestration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EKS (Elastic Kubernetes Service):&lt;/strong&gt; Fully managed Kubernetes on AWS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; Containers dominate modern application deployments. AWS provides managed services to scale them easily.&lt;br&gt;
&lt;strong&gt;Example use case:&lt;/strong&gt; Running microservices, CI/CD pipelines, or scalable backend APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you’re just starting, begin with EC2, S3, Lambda, and IAM. They’re simple to learn and power a surprising range of applications. As you grow, add RDS, DynamoDB, and API Gateway to your toolkit. For developers looking toward large-scale or production-ready systems, CloudFront, CloudWatch, and containers (ECS/EKS) are essential.&lt;/p&gt;

&lt;p&gt;If you found this article helpful, please leave a like or comment, and share it with others. If you have any questions, feel free to ask in the comments section.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>developers</category>
      <category>devops</category>
    </item>
    <item>
      <title>Managing AWS EKS with Terraform</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Thu, 07 Nov 2024 09:43:05 +0000</pubDate>
      <link>https://forem.com/mariehposa/managing-aws-eks-with-terraform-4ma8</link>
      <guid>https://forem.com/mariehposa/managing-aws-eks-with-terraform-4ma8</guid>
      <description>&lt;p&gt;In this tutorial, we'll learn how to use Terraform to manage an AWS Elastic Kubernetes Service (EKS) cluster.&lt;/p&gt;

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

&lt;p&gt;Terraform is an Infrastructure-as-Code (IaC) tool that enables you to define and provision infrastructure resources using a declarative configuration language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Terraform for AWS EKS?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure-as-Code:&lt;/strong&gt; Automate and version control your infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Easily scale your EKS cluster with Terraform configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Provision of multiple AWS services with a single tool.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Terraform - Installed on your local machine. You can set it up following this &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="noopener noreferrer"&gt;guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS Account – You’ll need an AWS account to access the AWS EKS and some other services. If you don’t have one, sign up &lt;a href="https://signin.aws.amazon.com/signup?request_type=register" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;AWS CLI: Installed and configured with your AWS credentials.&lt;/li&gt;
&lt;li&gt;kubectl: Installed to manage your EKS cluster from your machine.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Create Your Terraform Project Directory&lt;/li&gt;
&lt;li&gt;Define the AWS Provider&lt;/li&gt;
&lt;li&gt;Define the VPC and Networking Resources&lt;/li&gt;
&lt;li&gt;Define the EKS Cluster&lt;/li&gt;
&lt;li&gt;Create EKS Worker Nodes&lt;/li&gt;
&lt;li&gt;Apply the Terraform Configuration&lt;/li&gt;
&lt;li&gt;Configure kubectl to Access the EKS Cluster&lt;/li&gt;
&lt;li&gt;Deploy an Application Using Terraform&lt;/li&gt;
&lt;li&gt;Clean Up&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let’s get to it!&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1 — Create Your Terraform Project Directory &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We’ll need to create a project directory where all our Terraform configuration files will live.&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;terraform-eks
&lt;span class="nb"&gt;cd &lt;/span&gt;terraform-eks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Define the AWS Provider (main.tf) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Create &lt;strong&gt;main.tf&lt;/strong&gt; file and add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-west-2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we make Terraform use AWS as the provider and define the region in &lt;code&gt;eu-west-2&lt;/code&gt;, but you can choose a region closer to your desired location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Define the VPC and Networking Resources (network.tf) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;AWS EKS requires a Virtual Private Cloud (VPC) and subnets to run.&lt;/p&gt;

&lt;p&gt;Add the following configuration to the &lt;strong&gt;network.tf&lt;/strong&gt; file. This will create a VPC, subnets, an internet gateway and route tables for your EKS cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_availability_zones"&lt;/span&gt; &lt;span class="s2"&gt;"available"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc"&lt;/span&gt; &lt;span class="s2"&gt;"eks_vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;  &lt;span class="c1"&gt;# IP range for the VPC&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"eks_subnet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cidrsubnet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cidr_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;availability_zone&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_availability_zones&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;available&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;map_public_ip_on_launch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;# Enable auto-assign public IP&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_internet_gateway"&lt;/span&gt; &lt;span class="s2"&gt;"eks_igw"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_vpc&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;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route_table"&lt;/span&gt; &lt;span class="s2"&gt;"eks_route_table"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;
    &lt;span class="nx"&gt;gateway_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_internet_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_igw&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route_table_association"&lt;/span&gt; &lt;span class="s2"&gt;"eks_route_table_assoc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;# Associates the route table with each subnet&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_id&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_subnet&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;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;route_table_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_route_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_route_table&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Define the EKS Cluster (eks.tf) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, let's create the EKS cluster itself, along with the required IAM role to manage the cluster. Create an &lt;strong&gt;eks.tf&lt;/strong&gt; file and add the following configuration to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"eks_role"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks-role"&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&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;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"eks.amazonaws.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ec2.amazonaws.com"&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="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"eks_policy"&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;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"eks_node_policy"&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;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"eks_cni_policy"&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;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"eks_ec2_policy"&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;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_eks_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"eks_cluster"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks-cluster"&lt;/span&gt;
  &lt;span class="nx"&gt;role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;

  &lt;span class="nx"&gt;vpc_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_subnet&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The EKS cluster needs an IAM role that grants it permissions to manage AWS services. Therefore, we attach &lt;code&gt;eks_role&lt;/code&gt; with the necessary policies to EKS.&lt;/li&gt;
&lt;li&gt;We also create an EKS cluster using &lt;code&gt;aws_eks_cluster&lt;/code&gt; and specify the VPC subnets created earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5 — Create EKS Worker Nodes (eks-workers.tf) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Create &lt;strong&gt;eks-workers.tf&lt;/strong&gt; file and add the following configuration. This will create a node group that will scale between 1 to 3 nodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_eks_node_group"&lt;/span&gt; &lt;span class="s2"&gt;"node_group"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;node_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks-node-group"&lt;/span&gt;
  &lt;span class="nx"&gt;node_role_arn&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_subnet&lt;/span&gt;&lt;span class="p"&gt;[*].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;scaling_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;desired_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;# Initial number of nodes&lt;/span&gt;
    &lt;span class="nx"&gt;max_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="c1"&gt;# Maximum number of nodes&lt;/span&gt;
    &lt;span class="nx"&gt;min_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="c1"&gt;# Minimum number of nodes&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;instance_types&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"t3.medium"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Type of EC2 instances for worker nodes&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We define an EKS node group, which is a set of EC2 instances (worker nodes) that run the Kubernetes workloads.&lt;/li&gt;
&lt;li&gt;The node group can scale between 1 and 3 nodes, depending on your workload's demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6 — Apply the Terraform Configuration &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Initialize Terraform to download the necessary plugins for AWS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before applying, it’s best practice to see the changes Terraform plans to make in our infrastructure. You can achieve this with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the planning looks good, you can apply the configuration to create the EKS cluster and its resources with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm with &lt;code&gt;yes&lt;/code&gt; when prompted.&lt;/p&gt;

&lt;p&gt;Now, Terraform has created the EKS cluster, VPC, subnets, worker nodes and IAM roles based on the configurations we've written.&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%2Ft9a61e8t985zrbdt92zc.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%2Ft9a61e8t985zrbdt92zc.png" alt="create eks with terraform" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you check your AWS console, your EKS cluster should be up and running!&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%2Fgqddjhg9c9h1rjsfuxzu.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%2Fgqddjhg9c9h1rjsfuxzu.png" alt="aws console showing eks" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7 — Configure kubectl to Access the EKS Cluster &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To manage the EKS cluster, we need to configure &lt;code&gt;kubectl&lt;/code&gt;. This can be done using the &lt;strong&gt;AWS CLI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Run the following command to configure your local &lt;code&gt;kubectl&lt;/code&gt; to communicate with the EKS cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks &lt;span class="nt"&gt;--region&lt;/span&gt; eu-west-2 update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; eks-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the following command to confirm that you have access to the EKS cluster by listing Kubernetes services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 8 — Deploy an Application Using Terraform (deploy-nginx.tf) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, let’s deploy a simple Nginx application to the EKS cluster using the Kubernetes provider in Terraform.&lt;/p&gt;

&lt;p&gt;First, create a &lt;strong&gt;deploy-nginx.tf&lt;/strong&gt; file and define the Kubernetes provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"kubernetes"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;host&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_ca_certificate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;base64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;certificate_authority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;token&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_eks_cluster_auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_eks_cluster_auth"&lt;/span&gt; &lt;span class="s2"&gt;"eks_auth"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the following configuration to &lt;strong&gt;deploy-nginx.tf&lt;/strong&gt; to define the Nginx pod and expose it via a Kubernetes service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"kubernetes_pod"&lt;/span&gt; &lt;span class="s2"&gt;"nginx"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx"&lt;/span&gt;
    &lt;span class="nx"&gt;labels&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="s2"&gt;"nginx"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;spec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx"&lt;/span&gt;
      &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx:latest"&lt;/span&gt;

      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;limits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;cpu&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.5"&lt;/span&gt;
          &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"512Mi"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;requests&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;cpu&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.25"&lt;/span&gt;
          &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"256Mi"&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;resource&lt;/span&gt; &lt;span class="s2"&gt;"kubernetes_service"&lt;/span&gt; &lt;span class="s2"&gt;"nginx_service"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx-service"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;spec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;selector&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="s2"&gt;"nginx"&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="nx"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
      &lt;span class="nx"&gt;target_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"LoadBalancer"&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;ul&gt;
&lt;li&gt;The Kubernetes Pod defines an Nginx pod in the EKS cluster.&lt;/li&gt;
&lt;li&gt;The Kubernetes Service exposes the Nginx pod as a LoadBalancer service so that it can be accessed publicly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;strong&gt;deploy-nginx.tf&lt;/strong&gt; properly configured, you can now deploy it to your EKS cluster using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan

terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the deployment is complete, you can check that the Nginx pod and service are running in your cluster with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods

kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fk1gwoc4b7y9i93fi2m7r.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%2Fk1gwoc4b7y9i93fi2m7r.png" alt="nginx pod and services" width="800" height="81"&gt;&lt;/a&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%2Fajxk4cm012p6gj70tqc6.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%2Fajxk4cm012p6gj70tqc6.png" alt="nginx app" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 9 — Clean Up (Optional) &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you no longer need all these resources, you can destroy them all to avoid unnecessary charges. To do that, run 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;terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;In summary, we now have a working EKS cluster on AWS managed through Terraform. We set up the necessary VPC, created an EKS cluster with worker nodes, configured kubectl, and deployed an Nginx application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mariehposa/terraform-eks" rel="noopener noreferrer"&gt;Link to code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve found this article helpful, please leave a like or a comment. If you have any questions, please let me know in the comment section.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploying a Serverless Function with AWS Lambda</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Sun, 29 Sep 2024 21:35:43 +0000</pubDate>
      <link>https://forem.com/mariehposa/deploying-a-serverless-function-with-aws-lambda-161j</link>
      <guid>https://forem.com/mariehposa/deploying-a-serverless-function-with-aws-lambda-161j</guid>
      <description>&lt;p&gt;In this tutorial, you will learn how to create a simple AWS Lambda function using JavaScript to handle HTTP requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  First off, what is Serveless?
&lt;/h2&gt;

&lt;p&gt;Serverless computing allows you to run code without provisioning or managing servers. It basically allows you to focus on coding and forget about infrastructure. AWS Lambda is one of the most popular services for running serverless functions. &lt;/p&gt;

&lt;p&gt;Let’s start by highlighting all the steps needed and then explaining them in detail below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up AWS Lambda function&lt;/li&gt;
&lt;li&gt;Write a JavaScript function&lt;/li&gt;
&lt;li&gt;Set Up an API Gateway Trigger&lt;/li&gt;
&lt;li&gt;Test Serverless Function&lt;/li&gt;
&lt;li&gt;(Optional) Monitor and Scale&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;AWS Account – You’ll need an AWS account to access the AWS Lambda service. If you don’t have one, sign up &lt;a href="https://signin.aws.amazon.com/signup?request_type=register" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Basic Understanding of JavaScript – We'll be writing a simple JS function.&lt;/li&gt;
&lt;li&gt;Some Coffee ☕ – To keep things fun, of course!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1 — Set Up AWS Lambda
&lt;/h2&gt;

&lt;p&gt;1) &lt;strong&gt;Login to AWS Console:&lt;/strong&gt;&lt;br&gt;
   Go to the &lt;a href="https://aws.amazon.com/console/" rel="noopener noreferrer"&gt;AWS Management Console&lt;/a&gt; and sign in.&lt;/p&gt;

&lt;p&gt;2) &lt;strong&gt;Navigate to Lambda:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the search bar, type "Lambda" and select &lt;strong&gt;Lambda&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3) &lt;strong&gt;Create a New Lambda Function:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Author from scratch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;Function name&lt;/strong&gt;, enter &lt;code&gt;myServerlessFunction&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;Runtime&lt;/strong&gt;, choose &lt;code&gt;Node.js 20.x&lt;/code&gt; (for JavaScript support).&lt;/li&gt;
&lt;li&gt;Leave other options as default.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Function&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwfgx7tzhvq6tgrvr20g.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%2Fwwfgx7tzhvq6tgrvr20g.png" alt="Set up AWS Lambda"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now have a basic Lambda function ready to be customized!&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%2F6ic2173fn46epq7a5wtp.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%2F6ic2173fn46epq7a5wtp.png" alt="Set up AWS Lambda"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2 - Write Your JavaScript Function
&lt;/h2&gt;

&lt;p&gt;By default, AWS Lambda creates a template function. Let’s modify it to respond to HTTP requests.&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Edit the Code:&lt;/strong&gt;&lt;br&gt;
   In the &lt;strong&gt;Code&lt;/strong&gt; tab, you’ll see a file named &lt;code&gt;index.mjs&lt;/code&gt;. Replace the code with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="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;name&lt;/span&gt; &lt;span class="o"&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;queryStringParameters&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;! Welcome to Serverless.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event object:&lt;/strong&gt; This contains request data. Here, we are reading query parameters (e.g., ?name=John).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response:&lt;/strong&gt; It returns a 200 status with a JSON body containing a greeting message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2) &lt;strong&gt;Deploy the Function:&lt;/strong&gt; Click &lt;strong&gt;Deploy&lt;/strong&gt; to save and publish your function changes.&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%2F31iilmzzoe0br6uo5ut0.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%2F31iilmzzoe0br6uo5ut0.png" alt="Deploy the Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Set Up an API Gateway Trigger
&lt;/h2&gt;

&lt;p&gt;To make your Lambda function accessible over HTTP, we’ll use AWS API Gateway.&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Add API Gateway Trigger:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scroll to the &lt;strong&gt;Function 0verview&lt;/strong&gt; section and click &lt;strong&gt;Add trigger&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;From the dropdown, select &lt;strong&gt;API Gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Create a new API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;API Type&lt;/strong&gt;, select &lt;strong&gt;HTTP API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;Security&lt;/strong&gt;, choose &lt;strong&gt;Open&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Leave the defaults for &lt;strong&gt;Additional settings&lt;/strong&gt; and click &lt;strong&gt;Add&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2660r38a9dvnebvihy1q.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%2F2660r38a9dvnebvihy1q.png" alt="Add API Gateway Trigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;strong&gt;Get the API URL:&lt;/strong&gt; After adding the trigger, you will see the API Gateway URL. Copy this URL, you will use it to call your function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 - Test Your Serverless Function
&lt;/h2&gt;

&lt;p&gt;With everything set up, let’s test your function.&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Open a Web Browser or Postman:&lt;/strong&gt; Use the API Gateway URL you copied earlier. Test the function by appending the name query parameter to the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://your-api-url?name&lt;span class="o"&gt;=&lt;/span&gt;John
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) &lt;strong&gt;Result:&lt;/strong&gt; If everything is working, you should get a response like:&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%2Fb88v9c0xuo8u9up4ru8k.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%2Fb88v9c0xuo8u9up4ru8k.png" alt="Result with query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you omit the name query parameter, you should get the default:&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%2Frhuuln3svl0jmj8895p3.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%2Frhuuln3svl0jmj8895p3.png" alt="Result without query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - (Optional) Monitor and Scale
&lt;/h2&gt;

&lt;p&gt;AWS Lambda automatically scales based on the number of requests. You don’t need to worry about managing infrastructure, but you can monitor your function’s performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go to the Monitoring tab&lt;/strong&gt;: Inside your Lambda function dashboard, you’ll see metrics such as invocation count, duration, errors, etc.&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%2F5tntocefjmx4xtn68kl7.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%2F5tntocefjmx4xtn68kl7.png" alt="Monitoring tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yay! That’s it! You can extend this function to do practically anything, like querying databases, processing files, or integrating with other AWS services.&lt;/p&gt;

&lt;p&gt;If you’ve found this article helpful, please leave a like or a comment. If you have any questions or constructive feedback, please let me know in the comment section.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>serverless</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AWS Cost Management and Optimization: Tips and Tools for Monitoring and Reducing Your AWS Costs</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Thu, 23 May 2024 19:09:39 +0000</pubDate>
      <link>https://forem.com/mariehposa/aws-cost-management-and-optimization-tips-and-tools-for-monitoring-and-reducing-your-aws-costs-4kib</link>
      <guid>https://forem.com/mariehposa/aws-cost-management-and-optimization-tips-and-tools-for-monitoring-and-reducing-your-aws-costs-4kib</guid>
      <description>&lt;p&gt;Managing and optimizing AWS costs is an important aspect of using AWS services effectively. Given the extensive range of services and pricing models available, understanding how to monitor, control, and reduce costs can save your organization significant amounts of money. This article covers everything you need to know about AWS cost management and optimization, including practical tips, tools, and best practices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Understanding AWS Cost Structure
&lt;/h4&gt;

&lt;p&gt;Before I proceed with cost management, it's important to understand the fundamental components of AWS costs. AWS charges you based on the following primary categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compute Costs&lt;/strong&gt;: These include charges for EC2 instances, Lambda functions, and other compute services. Compute costs are typically billed based on the instance type, usage duration, and some other features like Elastic IP addresses and data transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage Costs&lt;/strong&gt;: Storage costs are associated with services like Amazon S3, EBS volumes, and other storage solutions. These costs vary based on the amount of data stored, the storage class used, and the frequency of data access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Transfer Costs&lt;/strong&gt;: Data transfer charges occur when data is transferred between AWS services, across regions, or out to the internet. Understanding data transfer pricing is vital for optimizing costs, especially for applications with significant data movement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other Service Costs&lt;/strong&gt;: AWS offers a lot of services like RDS, DynamoDB, CloudFront, and many more. Each service has its own pricing model, and the costs can add up depending on usage patterns and service configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS provides detailed cost breakdowns in the AWS Billing and Cost Management console, where you can see your usage and charges categorized by service, region, account and cost. This visibility is critical for effective cost management.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up AWS Budgets
&lt;/h4&gt;

&lt;p&gt;AWS Budgets allows you to set custom cost and usage budgets which helps you monitor and control your spending. Setting up budgets involves a few straightforward steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Budget&lt;/strong&gt;: Navigate to the AWS Budgets dashboard and click on "Create a budget". You can choose from cost budget, usage budget, savings plans or reservation budget. Define your budget parameters, such as the name, scope, budgeted amount and the period (e.g. monthly, quarterly, etc).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure Alerts&lt;/strong&gt;: To stay informed, set up alerts that notify you when your costs or usage exceed certain thresholds. These alerts can be sent via email, SNS or Chatbot to ensure you are always aware of your spending patterns and can take corrective actions promptly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Monitoring Costs with AWS Cost Explorer
&lt;/h4&gt;

&lt;p&gt;AWS Cost Explorer is a powerful tool for visualizing and analyzing your AWS costs. It offers several features to help you understand and manage your spending:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Explore Your Data&lt;/strong&gt;: Access AWS Cost Explorer from the Billing and Cost Management console. You can filter and group your data by various dimensions: service, usage type, region, and tags. This flexibility allows you to drill down into specific areas and identify cost drivers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Reports&lt;/strong&gt;: Create custom reports to track your costs and usage over time. These reports can be saved and scheduled for regular review, providing ongoing insights into your spending patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forecast Costs&lt;/strong&gt;: Cost Explorer's forecasting feature helps predict future costs based on historical data. This predictive capability enables better budget planning and resource allocation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Using AWS Trusted Advisor
&lt;/h4&gt;

&lt;p&gt;AWS Trusted Advisor provides real-time guidance to help you provision your resources according to AWS best practices. It covers several areas, including cost optimization, security, fault tolerance, and performance improvement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access Trusted Advisor&lt;/strong&gt;: Access the AWS Trusted Advisor console to review cost optimization recommendations. These recommendations often include actions like deleting unused resources, resizing instances and using cheaper pricing options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Recommendations&lt;/strong&gt;: Follow the suggestions provided by Trusted Advisor to reduce costs. This might involve stopping underused instances, optimizing storage, or adjusting configurations to align with usage patterns.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Using AWS Cost Anomaly Detection
&lt;/h4&gt;

&lt;p&gt;This helps to identify unexpected increases in your costs and provides an additional layer of financial oversight:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create an Anomaly Monitor&lt;/strong&gt;: In the AWS Cost Management console, select "Cost Anomaly Detection". Create an anomaly monitor and specify the scope (e.g. linked account, cost category, etc). This monitor continuously scans your cost data for anomalies and highlights any unexpected spending.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Up Notifications&lt;/strong&gt;: Configure alerts to notify you of anomalies via email, chatbot or SNS. These notifications ensure that any unexpected cost spikes are promptly addressed and prevent budget overruns.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Implementing Tagging Strategies
&lt;/h4&gt;

&lt;p&gt;Tagging resources is essential for cost allocation and management. A well-defined tagging strategy helps in organizing resources and tracking costs effectively:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define a Tagging Policy&lt;/strong&gt;: Establish a consistent tagging strategy for all resources. Common tags include &lt;code&gt;Environment&lt;/code&gt; (e.g. production, staging, development), &lt;code&gt;Project&lt;/code&gt;, and &lt;code&gt;Department&lt;/code&gt;. Clear tagging policies ensure that resources are easily identifiable and associated costs can be accurately allocated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply Tags&lt;/strong&gt;: Apply tags to all AWS resources. AWS Tag Editor allows for bulk tagging, making it easier to manage large numbers of resources. Consistent tagging practices facilitate detailed cost analysis and reporting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cost Allocation Tags&lt;/strong&gt;: Enable cost allocation tags in the Billing and Cost Management console. These tags allow you to break down costs by specific tags in your reports and provide deeper insights into how different projects or departments are consuming resources.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Optimizing EC2 Costs
&lt;/h4&gt;

&lt;p&gt;EC2 instances are often a major contributor to AWS costs. Several strategies can help optimize EC2 expenses:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Right-Sizing Instances&lt;/strong&gt;: Regularly review and adjust the size of your instances to match your workload requirements. Overprovisioning can lead to unnecessary costs, while underprovisioning can impact performance. Use AWS Compute Optimizer recommendations for right-sizing instances based on usage patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Spot Instances&lt;/strong&gt;: Take advantage of EC2 Spot Instances for non-critical workloads. Spot Instances can save up to 90% compared to On-Demand prices which makes them an excellent option for batch processing, big data analytics, and other flexible tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Purchase Reserved Instances (RIs)&lt;/strong&gt;: For long-term, stable workloads, purchasing Reserved Instances can provide significant discounts over On-Demand prices. Evaluate your usage patterns and consider a combination of Standard and Convertible RIs to balance savings and flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Auto Scaling&lt;/strong&gt;: Use Auto Scaling to automatically adjust the number of instances based on demand. This ensures that you only pay for the capacity you need and reduces costs during periods of low demand.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Managing S3 Storage Costs
&lt;/h4&gt;

&lt;p&gt;Amazon S3 provides several options for reducing storage costs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use the Right Storage Class&lt;/strong&gt;: Choose appropriate S3 storage classes based on your access patterns. Options include S3 Standard for frequently accessed data, S3 Intelligent-Tiering for automatically optimizing storage costs and S3 Glacier for long-term archival storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle Policies&lt;/strong&gt;: Implement lifecycle policies to automatically transition objects to cheaper storage classes or delete them after a certain period. Lifecycle policies help manage data retention and optimize storage costs over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor Storage Metrics&lt;/strong&gt;: Use the S3 Storage Lens group to gain insights into your storage usage and trends. Storage Lens provides detailed metrics and actionable recommendations to optimize your storage footprint.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Optimizing RDS Costs
&lt;/h4&gt;

&lt;p&gt;Amazon RDS offers several optimization strategies to reduce database costs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use RDS Reserved Instances&lt;/strong&gt;: Purchase RDS Reserved Instances for long-term database workloads. Reserved Instances provide significant discounts compared to On-Demand pricing, making them ideal for stable and predictable workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right-Sizing&lt;/strong&gt;: Regularly review and adjust the instance size and storage of your RDS instances. Right-sizing ensures that your database instances are appropriately scaled to meet performance requirements without incurring unnecessary costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Aurora Serverless&lt;/strong&gt;: Consider Aurora Serverless for variable workloads. Aurora Serverless automatically adjusts capacity based on demand thereby providing cost savings for workloads with fluctuating usage patterns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cost optimization is an ongoing process. Regularly reviewing your AWS usage and costs, and implementing best practices ensures that you remain efficient and cost-effective. By following these tips, you can effectively manage and optimize your AWS costs which guarantees you get the most value from your cloud investment. This approach to cost management will help you maintain control over your spending and continuously improve the efficiency of your AWS environment.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>optimization</category>
      <category>tips</category>
    </item>
    <item>
      <title>Looking Back On 2021 - A Year In Review</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Fri, 31 Dec 2021 16:15:36 +0000</pubDate>
      <link>https://forem.com/mariehposa/looking-back-on-2021-a-year-in-review-njh</link>
      <guid>https://forem.com/mariehposa/looking-back-on-2021-a-year-in-review-njh</guid>
      <description>&lt;p&gt;A life they say is full of sweet and bitter moments and I'm grateful my sweet moments outweigh the bitter ones even though the pandemic made things a lot more difficult.&lt;/p&gt;

&lt;p&gt;I started this year thinking of transitioning from web development into cloud engineering and although it has not been a bed of roses, I'm really  glad I took the leap. Thanks to my friends and the communities I joined  that make the journey worthwhile. Y'all are the best!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Got selected to participate in SheCodeAfrica (SCA) Cloud School.&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%2Fuser-images.githubusercontent.com%2F33374159%2F147829646-29e9849b-5b53-4f59-85ea-8bcd9981a845.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%2Fuser-images.githubusercontent.com%2F33374159%2F147829646-29e9849b-5b53-4f59-85ea-8bcd9981a845.png" alt="sca"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got featured in &lt;a href="https://www.businessinsider.com/open-source-booming-in-nigeria-fintech-startups-paystack-nigeria-2021-1?r=US&amp;amp;IR=T" rel="noopener noreferrer"&gt;Business Insider&lt;/a&gt; about the growth of open source in Nigeria.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got serious with writing technical articles. My articles have gotten more than 20,000 views on Dev🎉🎉. Thanks to all my readers!&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%2Fuser-images.githubusercontent.com%2F33374159%2F147829842-22eba9ec-1d1d-4f7d-8f5d-620750b6b34c.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%2Fuser-images.githubusercontent.com%2F33374159%2F147829842-22eba9ec-1d1d-4f7d-8f5d-620750b6b34c.png" alt="dashboard"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Awarded the &lt;strong&gt;top 7 author of the week&lt;/strong&gt; on Dev.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Awarded the &lt;strong&gt;top Node author of the week&lt;/strong&gt; on Dev.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got a full-time role as a Software Engineer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got three technical writing gigs from international companies. Oh my my!🤩&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volunteered and got selected for SCA cloud school Person of Contact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interviewed with a few FAANG(MANGA, now :)) companies. I'm going to write about this another time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volunteered and got selected for SCA summer Code Camp Person of Contact (POC).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got enrolled into the Udacity Cloud DevOps Nanodegree through an IA scholarship.&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%2Fuser-images.githubusercontent.com%2F33374159%2F147829934-dbfbd723-d414-45b1-aa32-e7f277b2a571.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%2Fuser-images.githubusercontent.com%2F33374159%2F147829934-dbfbd723-d414-45b1-aa32-e7f277b2a571.png" alt="Ire scholarship"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Received good reviews on my articles (one of the best wins)💃.&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%2Fuser-images.githubusercontent.com%2F33374159%2F147830062-7f40da3d-a78d-4f13-9d36-0807fd9a6903.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%2Fuser-images.githubusercontent.com%2F33374159%2F147830062-7f40da3d-a78d-4f13-9d36-0807fd9a6903.png" alt="review"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F147830393-e45445d3-79b9-4f22-bb8c-b05bfe008b70.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%2Fuser-images.githubusercontent.com%2F33374159%2F147830393-e45445d3-79b9-4f22-bb8c-b05bfe008b70.png" alt="review2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aced two out of three DevOps interviews. Got an offer from one of them🔥.&lt;/li&gt;
&lt;li&gt;Left a toxic workplace.&lt;/li&gt;
&lt;li&gt;Completed my &lt;a href="https://en.wikipedia.org/wiki/National_Youth_Service_Corps" rel="noopener noreferrer"&gt;National Youth Service Corps (NYSC)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Improved my mental health.&lt;/li&gt;
&lt;li&gt;Passed the AWS Cloud Practitioner exam🎉.&lt;/li&gt;
&lt;li&gt;Got a lot of swags from different companies (the sweetest).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got selected as a Runner-up for the 2021 GitHub actions hackathon on Dev🔥🔥.&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%2Fuser-images.githubusercontent.com%2F33374159%2F147829961-5b06d7a6-57f1-4fa5-885e-628c700733a1.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%2Fuser-images.githubusercontent.com%2F33374159%2F147829961-5b06d7a6-57f1-4fa5-885e-628c700733a1.png" alt="hackathon"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Successfully transitioned from web development to cloud engineering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Made new and amazing friends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bad
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Burnout. I was doing a lot of things together, a full time role with two writing gigs and a Udacity course were just too much for me to handle. I had to drop the writing gigs at some point.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Got a rejection from one of the  two DevOps interviews I thought I aced.&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%2Fuser-images.githubusercontent.com%2F33374159%2F147830015-fcee416b-6cef-453a-adac-7b20b6b7f706.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%2Fuser-images.githubusercontent.com%2F33374159%2F147830015-fcee416b-6cef-453a-adac-7b20b6b7f706.png" alt="zcash"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Turned down the opportunity to speak at two events  due to imposter syndrome and lack of preparation time. I hope to do more public speaking next year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My social life was a mess and I hope to fix it next year.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, I’m happy for my growth, even with the obstacles and challenges. I hope things get much better next year.&lt;/p&gt;

&lt;p&gt;Thank you for reading and wishing you all the very best in 2022!&lt;/p&gt;

</description>
      <category>career</category>
      <category>yearinreview</category>
      <category>2021</category>
    </item>
    <item>
      <title>Automating Terraform With Github Actions</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Fri, 03 Dec 2021 18:35:36 +0000</pubDate>
      <link>https://forem.com/mariehposa/automating-terraform-with-github-actions-1hc3</link>
      <guid>https://forem.com/mariehposa/automating-terraform-with-github-actions-1hc3</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;A project to demonstrate how to automate terraform workflow with Github Actions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to your AWS account and generate &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;After that, login to your Terraform Cloud account. Create a new workspace and select &lt;strong&gt;API-driven workflow&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Then navigate to the &lt;strong&gt;Variables&lt;/strong&gt; tab and click on &lt;strong&gt;Add variable&lt;/strong&gt;. Add &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; with their respective values.&lt;/li&gt;
&lt;li&gt;From your Terraform Cloud User Settings, click on &lt;strong&gt;Tokens&lt;/strong&gt; and generate an API token named &lt;code&gt;GitHub Actions&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the token to your Github repository as a secret. Name the secret &lt;code&gt;TF_API_TOKEN&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone and open your Github repo on your code editor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checkout to a new branch with &lt;code&gt;git checkout -b &amp;lt;branch-name&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add your changes with &lt;code&gt;git add .&lt;/code&gt; and commit the changes with a message using &lt;code&gt;git commit -m "&amp;lt;commit-message&amp;gt;"&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then push your changes with &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go back to the Github repository and generate a pull request from the new branch. You can view the status of the job through the pull request created, Actions tab or the Terraform Cloud workspace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then merge the pull request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;DIY Deployments&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mariehposa" rel="noopener noreferrer"&gt;
        mariehposa
      &lt;/a&gt; / &lt;a href="https://github.com/mariehposa/terraform-automation" rel="noopener noreferrer"&gt;
        terraform-automation
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Terraform Automation&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A project to demonstrate how to automate terraform workflow with Github Actions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Github Actions after creating a pull request
&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/33374159/143871982-d2972a02-f2fa-458e-8d79-3cde681cc7ed.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F143871982-d2972a02-f2fa-458e-8d79-3cde681cc7ed.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Github Actions after Merging to &lt;strong&gt;main&lt;/strong&gt; branch
&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/33374159/143872424-59e53e0e-6475-4b81-a853-c5c147ec645f.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F143872424-59e53e0e-6475-4b81-a853-c5c147ec645f.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;These instructions will get you a copy of the project up and running on your local machine for development purpose.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;To get started with this project you need a basic knowledge of the following.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;Version Control (Git)
Terraform
AWS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Automating Terraform with Github Actions&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Login to your AWS account and generate &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After that, login to your Terraform Cloud account. Create a new workspace and select &lt;strong&gt;API-driven workflow&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then navigate to the &lt;strong&gt;Variables&lt;/strong&gt; tab and click on &lt;strong&gt;Add variable&lt;/strong&gt;. Add &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; with their respective values.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From your Terraform Cloud User Settings, click on &lt;strong&gt;Tokens&lt;/strong&gt; and generate an API token named &lt;code&gt;GitHub Actions&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the token to your Github repository as a…&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mariehposa/terraform-automation" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>actionshackathon21</category>
      <category>actions</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>How To Set Up Continuous Integration And Deployment With CircleCI</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Mon, 29 Nov 2021 19:15:00 +0000</pubDate>
      <link>https://forem.com/mariehposa/how-to-set-up-continuous-integration-and-deployment-with-circleci-1pe9</link>
      <guid>https://forem.com/mariehposa/how-to-set-up-continuous-integration-and-deployment-with-circleci-1pe9</guid>
      <description>&lt;p&gt;In this tutorial, I will be demonstrating how to set up continuous integration and continuous deployment with CircleCI. At the end of this article, you would have deployed a Node application to Heroku and have subsequent builds automatically deployed on successful testing via CircleCI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CircleCI and why should you use it?
&lt;/h2&gt;

&lt;p&gt;CircleCI is a platform for continuous integration and continuous deployment which is used by developers to automate testing, building and deployment of applications. It is free and has a strong community, so finding support is not a problem.  CircleCI is also easily configured and I hope to prove this with this article, so please, read on ☺️.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;If you’d like to follow along with this tutorial, please make sure the following requirements are met:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A running Node app with its tests passing. If you don’t have one, you can fork this &lt;a href="https://github.com/mariehposa/circleci-test" rel="noopener noreferrer"&gt;project&lt;/a&gt; and follow its documentation to set it up.&lt;/li&gt;
&lt;li&gt;A CircleCI account. You can sign up &lt;a href="https://circleci.com/signup" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Heroku app. You can sign up &lt;a href="https://signup.heroku.com" rel="noopener noreferrer"&gt;here&lt;/a&gt; for the account and follow this &lt;a href="https://trailhead.salesforce.com/en/content/learn/projects/develop-heroku-applications/create-a-heroku-app" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; to create a Heroku app.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Now, let’s get started!&lt;/p&gt;

&lt;p&gt;The first step will be to log in to your CircleCI account. Successful login should display your account dashboard.&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%2Fuser-images.githubusercontent.com%2F33374159%2F118406392-ceaef980-b673-11eb-8fef-d10b650934fb.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406392-ceaef980-b673-11eb-8fef-d10b650934fb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we do any actual work, let’s connect the &lt;strong&gt;Node app&lt;/strong&gt; to CircleCI. &lt;/p&gt;

&lt;p&gt;On the left sidebar, click on &lt;strong&gt;Projects&lt;/strong&gt;, then click on the &lt;strong&gt;Setup project&lt;/strong&gt; button for the Node app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F118406463-1d5c9380-b674-11eb-82c2-b5f110283e3b.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406463-1d5c9380-b674-11eb-82c2-b5f110283e3b.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Write your own using our starter config.yml template&lt;/strong&gt; for the config.yml file and click on &lt;strong&gt;Let's Go&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then select &lt;strong&gt;Node&lt;/strong&gt; as a sample config for the project, and click on &lt;strong&gt;Commit and Run&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F118406554-3feeac80-b674-11eb-9030-0d74179874c0.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406554-3feeac80-b674-11eb-9030-0d74179874c0.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the Node app GitHub repo and merge the pull request from CircleCI.&lt;/p&gt;

&lt;p&gt;Now we need to add &lt;strong&gt;HEROKU_APP_NAME&lt;/strong&gt; and &lt;strong&gt;HEROKU_API_KEY&lt;/strong&gt; to the project environment variables so that CircleCI can connect to the Heroku app. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HEROKU_APP_NAME&lt;/strong&gt; is the name of your Heroku app. I named mine &lt;strong&gt;circleci-test-ma&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HEROKU_API_KEY&lt;/strong&gt; is your Heroku account API key.&lt;/p&gt;

&lt;p&gt;To get your &lt;strong&gt;HEROKU_API_KEY&lt;/strong&gt;, go to your &lt;strong&gt;Heroku Dashboard&lt;/strong&gt;, click on &lt;strong&gt;Account Settings&lt;/strong&gt;, then scroll down to the &lt;strong&gt;API Key section&lt;/strong&gt; and click on &lt;strong&gt;Reveal&lt;/strong&gt; to copy your &lt;strong&gt;API key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F118405857-a8885a00-b671-11eb-99b3-a253d3747c5e.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%2Fuser-images.githubusercontent.com%2F33374159%2F118405857-a8885a00-b671-11eb-99b3-a253d3747c5e.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, navigate back to the CircleCI dashboard. Click on the &lt;strong&gt;Project Settings&lt;/strong&gt; for the Node app, and then click on &lt;strong&gt;Environment Variables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Environment Variables&lt;/strong&gt; page, create two variables named &lt;strong&gt;HEROKU_APP_NAME&lt;/strong&gt; and &lt;strong&gt;HEROKU_API_KEY&lt;/strong&gt; and give them their respective values as gotten from your Heroku dashboard.&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%2Fuser-images.githubusercontent.com%2F33374159%2F118406301-62cc9100-b673-11eb-9ab2-a4e253a282c9.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406301-62cc9100-b673-11eb-9ab2-a4e253a282c9.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the Node app on your editor. Remove the default configuration inside the &lt;strong&gt;config.yml&lt;/strong&gt; file(config from CircleCI) and replace it with the following config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1
orbs:
  node: circleci/node@1.1.6
  heroku: circleci/heroku@0.0.10
workflows:
  heroku_deploy:
    jobs:
      - build
      - heroku/deploy-via-git:  
          requires:
            - build
          filters:
            branches:
              only: main
jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: Install dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules
      - run:
          name: Run test
          command: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s take a minute to break down this config file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;version 2.1&lt;/code&gt; is used to have access to &lt;code&gt;orbs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orbs:
  node: circleci/node@1.1.6
  heroku: circleci/heroku@0.0.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;orbs&lt;/code&gt; enable us to integrate with software just with a single line of code. For example, we made use of JavaScript, that is why we use an orb that points to that with &lt;code&gt;circleci/node@1.1.6&lt;/code&gt;. The orb &lt;code&gt;circleci/heroku@0.0.10&lt;/code&gt; points to Heroku since we’re also using that for deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
  heroku_deploy:
    jobs:
      - build
      - heroku/deploy-via-git:  
          requires:
            - build
          filters:
            branches:
              only: main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;workflow&lt;/code&gt; specifies how &lt;code&gt;jobs&lt;/code&gt; should be run. Here, we made the build run before deploying to Heroku. &lt;code&gt;heroku/deploy-via-git&lt;/code&gt; is used to deploy changes from GitHub to Heroku. &lt;code&gt;require&lt;/code&gt; is used inside &lt;code&gt;heroku/deploy-via-git&lt;/code&gt; to delay deployment until the build is done. The &lt;code&gt;filters&lt;/code&gt; block is used to specify the main branch for deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: Install dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules
      - run:
          name: Run test
          command: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;jobs&lt;/code&gt; are typically a series of steps. Here we use &lt;code&gt;restore_cache&lt;/code&gt; to restore the dependencies that were installed in the previous builds. Then we run &lt;code&gt;npm install&lt;/code&gt; to install new dependencies and cache them too to prevent having to re-install. We then run the &lt;code&gt;npm test&lt;/code&gt; command to run the unit tests.&lt;/p&gt;

&lt;p&gt;Commit the changes and push to GitHub. You can check the &lt;strong&gt;build&lt;/strong&gt; on CircleCI, it should return &lt;strong&gt;Success&lt;/strong&gt;, depending on whether your Node app passes all tests (you should be fine if you simply clone the repo and made no changes).&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%2Fuser-images.githubusercontent.com%2F33374159%2F118406254-226d1300-b673-11eb-9aa0-5afb8ae938cb.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406254-226d1300-b673-11eb-9aa0-5afb8ae938cb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also check out the deployed version of the Node app on your Heroku dashboard.&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%2Fuser-images.githubusercontent.com%2F33374159%2F118406043-978c1880-b672-11eb-95a9-2e38ad1effc8.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%2Fuser-images.githubusercontent.com%2F33374159%2F118406043-978c1880-b672-11eb-95a9-2e38ad1effc8.png" alt="circleci"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! At this point, any changes you make to the project should get deployed as soon as they are pushed to the branch we specified in the &lt;strong&gt;config file&lt;/strong&gt;. It’s always advisable to do sanity checks, so make sure to push a small change and see it deployed!&lt;/p&gt;

&lt;p&gt;If you found this article helpful, please leave a heart or a comment. If you have any questions, please let me know in the comment section.&lt;/p&gt;

&lt;p&gt;Also, don’t forget to follow me for more articles. Thank you.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>node</category>
      <category>heroku</category>
      <category>devops</category>
    </item>
    <item>
      <title>Hosting a Static Website with Amazon S3</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Sat, 26 Jun 2021 21:30:43 +0000</pubDate>
      <link>https://forem.com/mariehposa/hosting-a-static-website-with-amazon-s3-i5p</link>
      <guid>https://forem.com/mariehposa/hosting-a-static-website-with-amazon-s3-i5p</guid>
      <description>&lt;p&gt;In this article, I’d like to demonstrate how you can deploy a static website with AWS by uploading your website content into S3 bucket, configuring your bucket for website hosting and speeding up content delivery using AWS CloudFront.&lt;/p&gt;

&lt;p&gt;First of all, let me explain some of the terminologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Amazon S3?
&lt;/h2&gt;

&lt;p&gt;Amazon S3 (Simple Storage Service) is a service offered by AWS for object storage through a web service interface. It can be used to store or retrieve any amount of data such as documents, images, videos, etc.&lt;br&gt;
&lt;strong&gt;S3 bucket&lt;/strong&gt; is a resource in Amazon S3. It is a container where files and folders can be uploaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Amazon CloudFront?
&lt;/h2&gt;

&lt;p&gt;Amazon CloudFront is a content delivery network (CDN) service offered by AWS. It is used to speed up content delivery and can be integrated with Amazon S3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of using AWS S3 bucket
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Each object can contain up to 5TB of data.&lt;/li&gt;
&lt;li&gt;A resource can only be accessed by the owner until permission is granted to others which makes it more secure.&lt;/li&gt;
&lt;li&gt;It is cheap.&lt;/li&gt;
&lt;li&gt;You can enable Multi-Factor Authentication (MFA) delete on an S3 bucket to prevent accidental deletions and unintentional data loss.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;If you’d like to follow this tutorial, please make sure the following requirements are met.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS account. You can sign up &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and follow this &lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; in setting it up.&lt;/li&gt;
&lt;li&gt;A static website. If you don’t have one, you can clone this &lt;a href="https://github.com/mariehposa/aws-s3-demo" rel="noopener noreferrer"&gt;demo project&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ol&gt;
&lt;li&gt;Create an S3 bucket&lt;/li&gt;
&lt;li&gt;Upload web files to S3 bucket&lt;/li&gt;
&lt;li&gt;Secure S3 bucket through IAM policies&lt;/li&gt;
&lt;li&gt;Configure S3 bucket&lt;/li&gt;
&lt;li&gt;Serve content from S3 bucket with CloudFront&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let’s get into it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Create an S3 bucket &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;You will need to create an S3 bucket to put your website’s files and folders.&lt;/p&gt;

&lt;p&gt;To do this, login into your AWS management console and click on &lt;strong&gt;Services&lt;/strong&gt; on the top navbar. From the &lt;strong&gt;Services&lt;/strong&gt; drop-down, select &lt;strong&gt;S3&lt;/strong&gt; from the &lt;strong&gt;Storage&lt;/strong&gt; section. This should display the &lt;strong&gt;S3&lt;/strong&gt; dashboard.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119153245-fc67ba00-ba48-11eb-81dc-63968f5dcfd9.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%2Fuser-images.githubusercontent.com%2F33374159%2F119153245-fc67ba00-ba48-11eb-81dc-63968f5dcfd9.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the S3 dashboard, click on &lt;strong&gt;Create bucket&lt;/strong&gt;. Give the bucket a unique name, the name you choose must be globally unique (for best practice, attach your AWS account ID to the name). &lt;/p&gt;

&lt;p&gt;Next, choose your preferred &lt;strong&gt;AWS Region&lt;/strong&gt; from the drop-down. &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%2Fuser-images.githubusercontent.com%2F33374159%2F119145517-9f1c3a80-ba41-11eb-9c6b-f4a17a052e82.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%2Fuser-images.githubusercontent.com%2F33374159%2F119145517-9f1c3a80-ba41-11eb-9c6b-f4a17a052e82.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;Block Public Access settings for this bucket&lt;/strong&gt; section, uncheck the &lt;strong&gt;Block all public access&lt;/strong&gt; checkbox and accept the acknowledgement. This is done to make the bucket accessible to the public because you are going to host a website in 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%2Fuser-images.githubusercontent.com%2F33374159%2F119145647-c115bd00-ba41-11eb-8c50-b27cfa04fbbb.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%2Fuser-images.githubusercontent.com%2F33374159%2F119145647-c115bd00-ba41-11eb-8c50-b27cfa04fbbb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;disable&lt;/strong&gt; for Bucket Versioning.&lt;/p&gt;

&lt;p&gt;You can also &lt;strong&gt;Add tag&lt;/strong&gt; to the bucket for easy identification. &lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;Default encryption&lt;/strong&gt; section, click on &lt;strong&gt;disable&lt;/strong&gt; for Server-side encryption. &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%2Fuser-images.githubusercontent.com%2F33374159%2F119145920-076b1c00-ba42-11eb-8cfb-9bd28d352e10.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%2Fuser-images.githubusercontent.com%2F33374159%2F119145920-076b1c00-ba42-11eb-8cfb-9bd28d352e10.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on &lt;strong&gt;Create bucket&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F119146169-47ca9a00-ba42-11eb-9917-5c2fb5bb7802.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%2Fuser-images.githubusercontent.com%2F33374159%2F119146169-47ca9a00-ba42-11eb-9917-5c2fb5bb7802.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Upload web files to S3 bucket &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;After creating the bucket, you need to upload your website’s files and folders into it.&lt;/p&gt;

&lt;p&gt;From the &lt;strong&gt;S3&lt;/strong&gt; dashboard, click on the &lt;strong&gt;name&lt;/strong&gt; of the bucket you just created.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Objects&lt;/strong&gt; tab, you can see that the bucket is currently empty, click on the &lt;strong&gt;Upload&lt;/strong&gt; button.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119146402-806a7380-ba42-11eb-903e-c24995bae41c.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%2Fuser-images.githubusercontent.com%2F33374159%2F119146402-806a7380-ba42-11eb-903e-c24995bae41c.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should take you to the &lt;strong&gt;Upload&lt;/strong&gt; page. Click &lt;strong&gt;Add files&lt;/strong&gt; to add the website files and use &lt;strong&gt;Add folder&lt;/strong&gt; to add the website folders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The whole website folder shouldn’t be added at once. Instead, add its content one after the other. For example, with the demo project linked up top, I uploaded my &lt;strong&gt;signup.html&lt;/strong&gt; as a file, &lt;strong&gt;signup.js&lt;/strong&gt; as a file, &lt;strong&gt;css&lt;/strong&gt; as a folder and &lt;strong&gt;img&lt;/strong&gt; as a folder.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119146885-fcfd5200-ba42-11eb-835a-465703daa78b.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%2Fuser-images.githubusercontent.com%2F33374159%2F119146885-fcfd5200-ba42-11eb-835a-465703daa78b.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the necessary files and folders have been added, scroll down and click on &lt;strong&gt;Upload&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The uploading should be done in a few minutes depending on your network and content size. Also, please do not close the tab while the upload process is going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Secure S3 bucket through IAM policies &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now you need to add some policies to secure your bucket.&lt;/p&gt;

&lt;p&gt;From the &lt;strong&gt;S3&lt;/strong&gt; dashboard, click on the &lt;strong&gt;name&lt;/strong&gt; of the bucket, then click on &lt;strong&gt;Permissions&lt;/strong&gt; tab. Scroll down to the &lt;strong&gt;Bucket policy&lt;/strong&gt; section and click on its &lt;strong&gt;Edit&lt;/strong&gt; button.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119147505-93ca0e80-ba43-11eb-8af4-25792cedf124.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%2Fuser-images.githubusercontent.com%2F33374159%2F119147505-93ca0e80-ba43-11eb-8af4-25792cedf124.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following bucket policy to it and make sure to replace &lt;code&gt;bucket-name&lt;/code&gt; with the name of your bucket.&lt;/p&gt;

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

{
"Version":"2012-10-17",
"Statement":[
 {
   "Sid":"AddPerm",
   "Effect":"Allow",
   "Principal": "*",
   "Action":["s3:GetObject"],
   "Resource":["arn:aws:s3:::bucket-name/*"]
 }
]
}


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

&lt;/div&gt;

&lt;p&gt;Then scroll down and click on &lt;strong&gt;Save changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This should change the bucket &lt;strong&gt;access&lt;/strong&gt; to public, as shown below.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119148274-3da99b00-ba44-11eb-90b7-0997dc76b81a.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%2Fuser-images.githubusercontent.com%2F33374159%2F119148274-3da99b00-ba44-11eb-90b7-0997dc76b81a.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Configure S3 bucket &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;You need to specify the default page and error page for your website.&lt;/p&gt;

&lt;p&gt;From the &lt;strong&gt;S3&lt;/strong&gt; dashboard, click on the &lt;strong&gt;name&lt;/strong&gt; of the bucket, then click on the &lt;strong&gt;Properties&lt;/strong&gt; tab.&lt;/p&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Static website hosting&lt;/strong&gt; section and click on its &lt;strong&gt;Edit&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Enable&lt;/strong&gt; for Static website hosting.&lt;/p&gt;

&lt;p&gt;Also, select &lt;strong&gt;Host a static website&lt;/strong&gt; for the Hosting type.&lt;/p&gt;

&lt;p&gt;Enter the file for your &lt;strong&gt;Index document&lt;/strong&gt; and &lt;strong&gt;Error document&lt;/strong&gt;. The &lt;strong&gt;Error document&lt;/strong&gt; is optional. I used &lt;strong&gt;signup.html&lt;/strong&gt; for both &lt;strong&gt;Index document&lt;/strong&gt; and &lt;strong&gt;Error document&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Scroll down and click on &lt;strong&gt;Save Changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F119148824-cb858600-ba44-11eb-9556-73525506d83a.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%2Fuser-images.githubusercontent.com%2F33374159%2F119148824-cb858600-ba44-11eb-9556-73525506d83a.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After saving, If you click on the bucket website endpoint, it would display your website.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119149050-0982aa00-ba45-11eb-8e45-145fc9427508.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%2Fuser-images.githubusercontent.com%2F33374159%2F119149050-0982aa00-ba45-11eb-8e45-145fc9427508.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Serve content from S3 bucket with CloudFront &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;From the &lt;strong&gt;Services&lt;/strong&gt; drop-down, scroll down to &lt;strong&gt;Networking &amp;amp; Content Delivery&lt;/strong&gt; section and click on &lt;strong&gt;CloudFront&lt;/strong&gt;. This should take you to the CloudFront dashboard.&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Create Distribution&lt;/strong&gt;. On &lt;strong&gt;Select a delivery method for your content&lt;/strong&gt; page, click on &lt;strong&gt;Get Started&lt;/strong&gt; under the &lt;strong&gt;Web&lt;/strong&gt; section.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119149298-4babeb80-ba45-11eb-8550-b06a6642dd35.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%2Fuser-images.githubusercontent.com%2F33374159%2F119149298-4babeb80-ba45-11eb-8550-b06a6642dd35.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under the &lt;strong&gt;Origin Settings&lt;/strong&gt; section, click on the &lt;strong&gt;Origin Domain Name&lt;/strong&gt; field and select the S3 bucket you created earlier. In the &lt;strong&gt;Origin Path&lt;/strong&gt; field, enter &lt;strong&gt;/&lt;/strong&gt; to indicate root level.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Restrict Bucket Access&lt;/strong&gt;, select &lt;strong&gt;Yes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Origin Access Identity&lt;/strong&gt;, select &lt;strong&gt;Create a New Identity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Grant Read Permissions on Bucket&lt;/strong&gt;, select &lt;strong&gt;Yes, Update Bucket Policy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F119150705-9aa65080-ba46-11eb-8a75-dc2b14a53807.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%2Fuser-images.githubusercontent.com%2F33374159%2F119150705-9aa65080-ba46-11eb-8a75-dc2b14a53807.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Default Cache Behavior Settings&lt;/strong&gt; section. For &lt;strong&gt;Viewer Protocol Policy&lt;/strong&gt;, select &lt;strong&gt;Redirect HTTP to HTTPS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F119151046-e8bb5400-ba46-11eb-91e4-5883998b75d9.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%2Fuser-images.githubusercontent.com%2F33374159%2F119151046-e8bb5400-ba46-11eb-91e4-5883998b75d9.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, scroll down to the &lt;strong&gt;Distribution Settings&lt;/strong&gt; section. Inside the &lt;strong&gt;Default Root Object&lt;/strong&gt; field, enter the filename at the root level, which should be your landing page. I used &lt;strong&gt;signup.html&lt;/strong&gt; as my &lt;strong&gt;Default Root Object&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Leave the rest of the options as default and click on &lt;strong&gt;Create Distribution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F119151334-320ba380-ba47-11eb-9694-175a62505d7b.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%2Fuser-images.githubusercontent.com%2F33374159%2F119151334-320ba380-ba47-11eb-9694-175a62505d7b.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you can see the distribution you created from the CloudFront dashboard. It might take a few minutes for it to be deployed.&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%2Fuser-images.githubusercontent.com%2F33374159%2F119151828-a9413780-ba47-11eb-8363-f689ad363a21.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%2Fuser-images.githubusercontent.com%2F33374159%2F119151828-a9413780-ba47-11eb-8363-f689ad363a21.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the CloudFront distribution has been deployed, copy the URL from the Domain Name column and paste it into your browser. Yay!🎉 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%2Fuser-images.githubusercontent.com%2F33374159%2F119156002-afd1ae00-ba4b-11eb-9133-c652785ebcfc.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%2Fuser-images.githubusercontent.com%2F33374159%2F119156002-afd1ae00-ba4b-11eb-9133-c652785ebcfc.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you can access your website with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CloudFront domain name e.g d3450i4qtm1w2p.cloudfront.net&lt;/li&gt;
&lt;li&gt;Website endpoint e.g &lt;a href="http://demo-95581515414.s3-website-us-east-1.amazonaws.com" rel="noopener noreferrer"&gt;http://demo-95581515414.s3-website-us-east-1.amazonaws.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;S3 object URL e.g &lt;a href="https://demo-95581515414.s3.us-east-1.amazonaws.com/signup.html" rel="noopener noreferrer"&gt;https://demo-95581515414.s3.us-east-1.amazonaws.com/signup.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should now know how to host a static website with Amazon S3 and speed up the content delivery using AWS CloudFront. Even though you had to go through a few steps, you did it and you're awesome!&lt;/p&gt;

&lt;p&gt;If you’ve found this article helpful, please leave a heart or a comment. If you have any questions or constructive feedback, please let me know in the comment section.&lt;/p&gt;

&lt;p&gt;Also, don’t forget to follow me for more articles. Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to deploy an application to AWS EC2 Instance using Terraform and Ansible.</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Wed, 21 Apr 2021 22:46:55 +0000</pubDate>
      <link>https://forem.com/mariehposa/how-to-deploy-an-application-to-aws-ec2-instance-using-terraform-and-ansible-3e78</link>
      <guid>https://forem.com/mariehposa/how-to-deploy-an-application-to-aws-ec2-instance-using-terraform-and-ansible-3e78</guid>
      <description>&lt;p&gt;I had an opportunity to work on this recently, and had to combine different tutorials and articles before I was able to set this up successfully.&lt;/p&gt;

&lt;p&gt;So, I’m writing this article in hopes that it will make someone’s work easier and make things clearer for beginners who wish to learn this.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Infrastructure as Code?
&lt;/h2&gt;

&lt;p&gt;Infrastructure as Code (IaC) is the process of setting up and managing cloud infrastructure through machine-readable files as opposed to manually setting up the required infrastructure.&lt;/p&gt;

&lt;p&gt;After the files have been written, you run them using IaC tools to build and configure the cloud infrastructure. Needless to say, this is a much more palatable and easier process than manual setup.&lt;/p&gt;

&lt;p&gt;IaC tools include; Terraform, Ansible, Chef, AWS cloud formation, Puppet, Vagrant, and many others.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Infrastructure as Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;With IaC, infrastructure configuration and setup is much faster: all you do is run a script.&lt;/li&gt;
&lt;li&gt;Scripts can be easily reused at any time.&lt;/li&gt;
&lt;li&gt;It is also easier to make small modifications between different but similar setups.&lt;/li&gt;
&lt;li&gt;It increases site reliability.&lt;/li&gt;
&lt;li&gt;It reduces the possibility of errors in infrastructure set up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial, you will learn how to provision a server(AWS EC2) for a React app using Terraform and then configure them with necessary packages using Ansible.&lt;/p&gt;

&lt;p&gt;Let’s start by highlighting all the steps needed and then explaining them in detail below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure AWS CLI and AWS vault&lt;/li&gt;
&lt;li&gt;Create a Key-pair for the server&lt;/li&gt;
&lt;li&gt;Dockerize a React app&lt;/li&gt;
&lt;li&gt;Provision the server using terraform&lt;/li&gt;
&lt;li&gt;Create a security group for the server&lt;/li&gt;
&lt;li&gt;Configure the server using Ansible&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  My folder structure
&lt;/h2&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%2Fuser-images.githubusercontent.com%2F33374159%2F115626986-2fa61480-a2f6-11eb-985c-4cab8690d897.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%2Fuser-images.githubusercontent.com%2F33374159%2F115626986-2fa61480-a2f6-11eb-985c-4cab8690d897.png" alt="folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;If you’d like to follow this tutorial, please make sure the following requirements are met before doing so.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS account. You can create one &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you haven't already, and follow this &lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; in setting it up.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://github.com/99designs/aws-vault#readme" rel="noopener noreferrer"&gt;AWS vault&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/get-started/#download-and-install-docker" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; and &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Dockerhub&lt;/a&gt; account.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.hashicorp.com/tutorials/terraform/install-cli" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#selecting-an-ansible-version-to-install" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A demo React app. You can create one with this &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html#create-react-app" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s get to it!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Configure AWS CLI and AWS vault &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We’ll need to create a user on our AWS account to be able to configure the AWS CLI.&lt;/p&gt;

&lt;p&gt;To do this, login to your AWS account, go to &lt;strong&gt;Services&lt;/strong&gt;, then click on &lt;strong&gt;IAM&lt;/strong&gt;.  Click on &lt;strong&gt;User&lt;/strong&gt;, then &lt;strong&gt;Add a user&lt;/strong&gt;. Type in a &lt;strong&gt;Username&lt;/strong&gt;, then select &lt;strong&gt;Programmatic access&lt;/strong&gt; for AWS access type.&lt;/p&gt;

&lt;p&gt;Next, we’ll need to create a group for our user. Click on &lt;strong&gt;Create group&lt;/strong&gt; and give it &lt;strong&gt;Administrator access&lt;/strong&gt;. You can add &lt;strong&gt;Tags&lt;/strong&gt; (optional), click &lt;strong&gt;Next&lt;/strong&gt; to review the user details and then click on &lt;strong&gt;Create user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115628260-49e0f200-a2f8-11eb-87dd-429f01b39a8f.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%2Fuser-images.githubusercontent.com%2F33374159%2F115628260-49e0f200-a2f8-11eb-87dd-429f01b39a8f.png" alt="user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, a new screen would be displayed to download the user security credentials. Click on &lt;strong&gt;Download.csv&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, go back to the terminal and run the following command:&lt;/p&gt;

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

aws configure


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

&lt;/div&gt;

&lt;p&gt;Add the user &lt;strong&gt;Access key ID&lt;/strong&gt; and &lt;strong&gt;Secret Access Key&lt;/strong&gt; as prompted. Then enter your preferred &lt;strong&gt;AWS region&lt;/strong&gt; and &lt;strong&gt;Output&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Run the following command and make sure to replace &lt;code&gt;username&lt;/code&gt; with the user created previously from the AWS console. &lt;/p&gt;

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

aws-vault add &amp;lt;username&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Add the user &lt;strong&gt;Access key ID&lt;/strong&gt; and &lt;strong&gt;Secret Access Key&lt;/strong&gt; as prompted. This is done to store your AWS credentials in your machine local keystore.&lt;/p&gt;

&lt;p&gt;Then run the following command to authenticate yourself for a session.&lt;/p&gt;

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

aws-vault exec &amp;lt;username&amp;gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Create a Key-pair for the server &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We need a key pair to run our instance.&lt;/p&gt;

&lt;p&gt;To create one, go to your AWS console, select &lt;strong&gt;EC2&lt;/strong&gt; from &lt;strong&gt;Services&lt;/strong&gt; drop-down, click on &lt;strong&gt;Key pairs&lt;/strong&gt;, then click on &lt;strong&gt;Create key pair&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Enter a &lt;strong&gt;Name&lt;/strong&gt; for your key, select &lt;strong&gt;pem&lt;/strong&gt; for openSSH or &lt;strong&gt;ppk&lt;/strong&gt; for Putty and then click on &lt;strong&gt;Create key pair&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115628196-2b7af680-a2f8-11eb-8361-775ee38d8420.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%2Fuser-images.githubusercontent.com%2F33374159%2F115628196-2b7af680-a2f8-11eb-8361-775ee38d8420.png" alt="key pair"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the key and move it to your machine’s &lt;strong&gt;.ssh&lt;/strong&gt; folder. For Ubuntu and MacOS, this will most likely be &lt;strong&gt;~/.ssh&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Dockerize the app &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In the root directory of the &lt;strong&gt;react-app&lt;/strong&gt; folder, create a &lt;strong&gt;Dockerfile&lt;/strong&gt; and add the following lines:&lt;/p&gt;

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

FROM node:12.18.3

LABEL version="1.0"

LABEL description="This is the base docker image for my React app"

LABEL maintainer="abc@mail.com"

WORKDIR /usr/src/app

COPY ["package.json", "yarn.lock", "./"]

RUN yarn

COPY . .

EXPOSE 3000

CMD ["yarn", "start"]


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

&lt;/div&gt;

&lt;p&gt;Here is an overview of the commands:&lt;br&gt;
&lt;strong&gt;FROM&lt;/strong&gt; defines the image we’re using for our container. In this context, we’re using node:12.18.3&lt;br&gt;
&lt;strong&gt;LABEL&lt;/strong&gt; indicates the version, description and maintainer of the Dockerfile.&lt;br&gt;
&lt;strong&gt;WORKDIR&lt;/strong&gt; sets the working directory for the app, and create it if the directory did not exists.&lt;br&gt;
&lt;strong&gt;COPY&lt;/strong&gt; is used to copy file(s) from one destination to another. The last path is always the destination to copy the file(s) to.&lt;br&gt;
&lt;strong&gt;RUN&lt;/strong&gt; defines the command to be run by Docker. I used yarn here because I installed my React app with yarn, you can change yours to npm if it’s more applicable.&lt;br&gt;
&lt;strong&gt;EXPOSE&lt;/strong&gt; tells docker which port it should listen to when running the container.&lt;br&gt;
&lt;strong&gt;CMD&lt;/strong&gt; defines the command to start the container. I used yarn start as specified from my React app’s start script, you should make sure yours also correlates to your app’s start script.&lt;/p&gt;

&lt;p&gt;Now, you need to build a docker image from the Dockerfile. To achieve this, run the following command in the root directory of the &lt;strong&gt;react-app&lt;/strong&gt; folder:&lt;/p&gt;

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

docker build -t &amp;lt;image-name&amp;gt; .


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

&lt;/div&gt;

&lt;p&gt;Make sure you replace &lt;code&gt;image-name&lt;/code&gt; with the app’s image name.&lt;/p&gt;

&lt;p&gt;Now, run the following command to spin up a container from the image.&lt;/p&gt;

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

docker run -it -p 3000:3000 &amp;lt;image-name&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Go to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; on your browser to view the app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115626849-f8cffe80-a2f5-11eb-9f7d-ebbab37120c5.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%2Fuser-images.githubusercontent.com%2F33374159%2F115626849-f8cffe80-a2f5-11eb-9f7d-ebbab37120c5.png" alt="deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to your terminal and add a tag to the image using:&lt;/p&gt;

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

docker tag &amp;lt;image-name&amp;gt; &amp;lt;docker_hub_username&amp;gt;/&amp;lt;repo-name&amp;gt;:&amp;lt;tag-name&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Be sure to replace all variables with appropriate values.&lt;/p&gt;

&lt;p&gt;Next, login to your DockerHub account from your terminal using:&lt;/p&gt;

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

Docker login


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

&lt;/div&gt;

&lt;p&gt;Add your &lt;strong&gt;username&lt;/strong&gt; and &lt;strong&gt;password&lt;/strong&gt; as prompted.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115626915-10a78280-a2f6-11eb-9c4f-4db9115999f9.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%2Fuser-images.githubusercontent.com%2F33374159%2F115626915-10a78280-a2f6-11eb-9c4f-4db9115999f9.png" alt="docker login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then run the following command to push the image to Dockerhub.&lt;/p&gt;

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

docker push &amp;lt;docker_hub_username&amp;gt;/&amp;lt;repo-name&amp;gt;:&amp;lt;tag-name&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Once that is done, you should see your docker image in the repo created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115630118-629ed700-a2fb-11eb-8317-d9f3583f145d.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%2Fuser-images.githubusercontent.com%2F33374159%2F115630118-629ed700-a2fb-11eb-8317-d9f3583f145d.png" alt="dockerhub"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Provision the server using terraform &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In the root directory of the project folder, create a folder called &lt;strong&gt;terraform&lt;/strong&gt;. Inside the terraform folder, create a new folder and call it &lt;strong&gt;frontend&lt;/strong&gt;. We’ll be adding all the config files for our frontend in here. Next, create a file called &lt;strong&gt;main.tf&lt;/strong&gt; inside the frontend folder.&lt;/p&gt;

&lt;p&gt;Put the following code inside the &lt;strong&gt;main.tf&lt;/strong&gt; file.&lt;/p&gt;

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

provider "aws" {
    region = "us-east-1"
}

variable "name" {
    description = "Name the instance on deploy"
}

resource "aws_instance" "admin_frontend" {
    ami = "ami-042e8287309f5df03"
    instance_type = "t2.micro"
    key_name = "admin"

    tags = {
            Name = var.name
    }
}


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

&lt;/div&gt;

&lt;p&gt;Here, we’re creating an AWS ec2 instance using ubuntu server image (&lt;strong&gt;ami-042e8287309f5df03&lt;/strong&gt;), &lt;strong&gt;t2.micro&lt;/strong&gt; as our instance type and &lt;strong&gt;admin&lt;/strong&gt; as the name of the key-pair we created earlier. Make sure you replace &lt;strong&gt;region&lt;/strong&gt;, &lt;strong&gt;ami&lt;/strong&gt;, &lt;strong&gt;instance_type&lt;/strong&gt;, and &lt;strong&gt;key.name&lt;/strong&gt; with values from your setup.&lt;/p&gt;

&lt;p&gt;In your terminal, &lt;code&gt;cd&lt;/code&gt; into the &lt;strong&gt;frontend&lt;/strong&gt; folder and run the following command to initialize a working directory containing terraform configuration files.&lt;/p&gt;

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

terraform init


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627324-ba870f00-a2f6-11eb-8128-b62a2f15b9f1.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627324-ba870f00-a2f6-11eb-8128-b62a2f15b9f1.png" alt="terraform init"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, run the following command to verify that you've set it up correctly.&lt;/p&gt;

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

terraform plan


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

&lt;/div&gt;

&lt;p&gt;It will later prompt for a value, enter the instance name, &lt;code&gt;frontend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115627285-a3e0b800-a2f6-11eb-8de8-b778d95284f0.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627285-a3e0b800-a2f6-11eb-8de8-b778d95284f0.png" alt="terraform plan"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, run the following command to spin up your ec2 instance. &lt;/p&gt;

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

terraform apply


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

&lt;/div&gt;

&lt;p&gt;This should also prompt for a value, enter the instance name as &lt;code&gt;frontend&lt;/code&gt; again and at the next prompt, enter &lt;code&gt;yes&lt;/code&gt; to confirm.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627239-8ad80700-a2f6-11eb-8964-5ec98cd6ea39.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627239-8ad80700-a2f6-11eb-8964-5ec98cd6ea39.png" alt="terraform apply"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you check your running instances on the AWS console, it should be 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%2Fuser-images.githubusercontent.com%2F33374159%2F115627155-6e3bcf00-a2f6-11eb-9611-a9efd9176dfd.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627155-6e3bcf00-a2f6-11eb-9611-a9efd9176dfd.png" alt="running instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Create a security group for the server &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now we need to create a  security group for our &lt;strong&gt;frontend&lt;/strong&gt; instance.&lt;/p&gt;

&lt;p&gt;Go to AWS console, select &lt;strong&gt;EC2&lt;/strong&gt; from &lt;strong&gt;Services&lt;/strong&gt; dropdown, then click on &lt;strong&gt;Security groups&lt;/strong&gt;. Click on &lt;strong&gt;Create security group&lt;/strong&gt;, then add &lt;strong&gt;Security group name&lt;/strong&gt; and &lt;strong&gt;Description&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Inbound rules&lt;/strong&gt;, and click &lt;strong&gt;Add rule&lt;/strong&gt;. Select &lt;strong&gt;HTTP&lt;/strong&gt; for Type and &lt;strong&gt;Anywhere&lt;/strong&gt; for Source. Once that’s done, create yet another inbound rule with Type as  &lt;strong&gt;All TCP&lt;/strong&gt; and &lt;strong&gt;Anywhere&lt;/strong&gt; for Source. Create a last inbound rule with &lt;strong&gt;SSH&lt;/strong&gt; as Type and &lt;strong&gt;My IP&lt;/strong&gt; for Source. This makes a total of &lt;strong&gt;three&lt;/strong&gt; inbound rules&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627422-dee2eb80-a2f6-11eb-9ba4-98e3ea49dc3c.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627422-dee2eb80-a2f6-11eb-9ba4-98e3ea49dc3c.png" alt="inbound rules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leave the Outbound rule as &lt;strong&gt;All traffic&lt;/strong&gt; for Type and &lt;strong&gt;0.0.0.0/0&lt;/strong&gt; for Destination. Then click on &lt;strong&gt;Create security group&lt;/strong&gt;. You can read this &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html" rel="noopener noreferrer"&gt;article&lt;/a&gt; if you’re interested in learning more about security groups.&lt;/p&gt;

&lt;p&gt;Now, go back to the &lt;strong&gt;frontend&lt;/strong&gt; instance and attach the security group created to it. To do this,  select the &lt;strong&gt;frontend&lt;/strong&gt; instance, then  &lt;strong&gt;Actions&lt;/strong&gt; &amp;gt; &lt;strong&gt;Security&lt;/strong&gt; &amp;gt; &lt;strong&gt;Change security groups&lt;/strong&gt; &amp;gt; click on the &lt;strong&gt;search field&lt;/strong&gt; and choose the &lt;strong&gt;security group&lt;/strong&gt;, remove the &lt;strong&gt;default&lt;/strong&gt; security group, then &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F115627468-f326e880-a2f6-11eb-8570-3c73fba171df.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627468-f326e880-a2f6-11eb-8570-3c73fba171df.png" alt="security groups"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you can try and ssh into your server using the following command:&lt;/p&gt;

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

ssh -i "~/.ssh/&amp;lt;your_KeyPair&amp;gt;.pem" &amp;lt;ec2-user&amp;gt;@&amp;lt;public_IPv4_DNS&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Make sure to replace &lt;code&gt;ec2-user&lt;/code&gt; with AMI username, &lt;code&gt;public_IPv4_DNS&lt;/code&gt; with the instance public domain name, and &lt;code&gt;your_KeyPair&lt;/code&gt; with your key file name.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627791-83fdc400-a2f7-11eb-8aaa-9475ac307af2.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627791-83fdc400-a2f7-11eb-8aaa-9475ac307af2.png" alt="login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 — Configure the server using Ansible &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have our instance running, we need to install the necessary packages using Ansible. Before we do that, let’s add some settings to our ansible config file.&lt;/p&gt;

&lt;p&gt;Go to your terminal and run the following command to open up the config file. I use &lt;strong&gt;vim&lt;/strong&gt; but feel free to use any editor of your choice. &lt;/p&gt;

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

sudo vim /home/&amp;lt;username&amp;gt;/.ansible.cfg


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

&lt;/div&gt;

&lt;p&gt;Be sure to replace &lt;code&gt;username&lt;/code&gt; with your own username.&lt;/p&gt;

&lt;p&gt;Then insert the following, making sure to replace &lt;code&gt;your_KeyPair&lt;/code&gt; with your key name.&lt;/p&gt;

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

[defaults]
host_key_checking = False
private_key_file=~/.ssh/&amp;lt;your_KeyPair&amp;gt;.pem
inventory=/etc/ansible/hosts
remote_user = ubuntu

[ssh_connection]
control_path=%(directory)s/%%h-%%r
control_path_dir=~/.ansible/cp
#pipelining = True
scp_if_ssh = True


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

&lt;/div&gt;

&lt;p&gt;Now save and exit.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627864-9d067500-a2f7-11eb-8af0-e2326a75cdea.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627864-9d067500-a2f7-11eb-8af0-e2326a75cdea.png" alt="config"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also need to add our host into the ansible host file. To achieve that, open the ansible hosts file by running the following command:&lt;/p&gt;

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

sudo vim /etc/ansible/hosts


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

&lt;/div&gt;

&lt;p&gt;Then add these lines to the file. Make sure to replace &lt;code&gt;ec2-user&lt;/code&gt; with AMI username, &lt;code&gt;public_IPv4_DNS&lt;/code&gt; with the instance public domain name, and &lt;code&gt;your_KeyPair&lt;/code&gt; with your key name.&lt;/p&gt;

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

[frontend]                                                                                                                                                                                                                                                                                         ec2-user@public_IPv4_DNS ansible_ssh_private_key_file=~/.ssh/your_KeyPair.pem


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

&lt;/div&gt;

&lt;p&gt;Save and exit.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115627966-c3c4ab80-a2f7-11eb-82a3-6e55bfec891e.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%2Fuser-images.githubusercontent.com%2F33374159%2F115627966-c3c4ab80-a2f7-11eb-82a3-6e55bfec891e.png" alt="host"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, make sure your managed node can be reached by pinging it  using the following command:&lt;/p&gt;

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

sudo ansible all -m ping


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

&lt;/div&gt;

&lt;p&gt;If it cannot be reached, then you may have connectivity issues that need some debugging. If you get a green blob of json however, then you’re good to go.&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%2Fuser-images.githubusercontent.com%2F33374159%2F115628115-04242980-a2f8-11eb-9d10-063e690cedb0.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%2Fuser-images.githubusercontent.com%2F33374159%2F115628115-04242980-a2f8-11eb-9d10-063e690cedb0.png" alt="ping"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, go to the root of your project folder, create a folder and call it &lt;strong&gt;ansible&lt;/strong&gt;. Inside this &lt;strong&gt;ansible&lt;/strong&gt; folder, create a file and call it &lt;strong&gt;provision_frontend.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the following lines into the &lt;strong&gt;provision_frontend.yaml file&lt;/strong&gt;&lt;/p&gt;

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

---
- hosts: frontend
  become: yes
  become_method: sudo

  tasks:

  - name: Install pip
    apt:
      update_cache: yes
      name: python3-pip

  - name: Install aptitude using apt
    apt: name=aptitude state=latest update_cache=yes force_apt_get=yes

  - name: Install required system packages
    apt: name={{ item }} state=latest update_cache=yes
    loop: [ 'apt-transport-https', 'ca-certificates', 'curl', 'software-properties-common', 'python3-pip', 'virtualenv', 'python3-setuptools']

  - name: Add Docker GPG apt Key
    apt_key:
      url: https://download.docker.com/linux/ubuntu/gpg
      state: present

  - name: Add Docker Repository
    apt_repository:
      repo: deb https://download.docker.com/linux/ubuntu bionic stable
      state: present

  - name: Update apt and install docker-ce
    apt: update_cache=yes name=docker-ce state=latest

  - name: install docker-py
    pip: name=docker-py

  - name: enable Docker services
    service:
      name: "docker"
      state: started
      enabled: yes

  - name: Check if container is running
    shell: docker ps

  - name: run docker image
    shell: docker run -dit --name &amp;lt;repo-name&amp;gt; -p 3000:3000 &amp;lt;docker_hub_username&amp;gt;/&amp;lt;repo-name&amp;gt;:&amp;lt;tag-name&amp;gt;

  - name: show running images
    shell: docker images


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

&lt;/div&gt;

&lt;p&gt;Make sure to edit the shell command for running docker image, to match your setup. &lt;/p&gt;

&lt;p&gt;Then save.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hosts&lt;/strong&gt; defines the host upon which commands in a playbook operate.&lt;br&gt;
&lt;strong&gt;become_method&lt;/strong&gt; sets to root user.&lt;br&gt;
&lt;strong&gt;package&lt;/strong&gt; is for installing packages.&lt;br&gt;
&lt;strong&gt;service&lt;/strong&gt; is for controlling services on remote hosts.&lt;br&gt;
&lt;strong&gt;shell&lt;/strong&gt; is for running commands.&lt;/p&gt;

&lt;p&gt;In the terminal, navigate to the &lt;strong&gt;ansible&lt;/strong&gt; folder and run the playbook using the following command:&lt;/p&gt;

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

ansible-playbook provision_frontend.yaml


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F115628003-d50db800-a2f7-11eb-8cc5-64e37ec0e1eb.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%2Fuser-images.githubusercontent.com%2F33374159%2F115628003-d50db800-a2f7-11eb-8cc5-64e37ec0e1eb.png" alt="ansible"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, open your browser and enter the public address of the instance with &lt;strong&gt;3000&lt;/strong&gt; at the end.&lt;/p&gt;

&lt;p&gt;Yay! That’s it! This might have been a lot, but I hope it was able to help you along in your journey.&lt;/p&gt;

&lt;p&gt;If you would like to set up CI/CD for your app using &lt;strong&gt;Jenkins&lt;/strong&gt;, you can check out one of my other articles &lt;a href="https://dev.to/mariehposa/achieving-continuous-integration-and-deployment-with-jenkins-4d6k"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’ve found this article helpful, please leave a heart or a comment. If you have any questions or constructive feedback, please let me know in the comment section.&lt;br&gt;
Also, don’t forget to follow me for more articles. Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>docker</category>
      <category>ansible</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to create VPC, Subnets, Route tables, Security groups and Instances using AWS CLI</title>
      <dc:creator>Mariam Adedeji</dc:creator>
      <pubDate>Tue, 30 Mar 2021 15:24:07 +0000</pubDate>
      <link>https://forem.com/mariehposa/how-to-create-vpc-subnets-route-tables-security-groups-and-instances-using-aws-cli-14a4</link>
      <guid>https://forem.com/mariehposa/how-to-create-vpc-subnets-route-tables-security-groups-and-instances-using-aws-cli-14a4</guid>
      <description>&lt;p&gt;In this article, I will demonstrate how you can create a VPC, subnets, route tables, security groups and instances without leaving the terminal. After that, we'll install Apache on the instance, but, this is optional.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Create a VPC&lt;/li&gt;
&lt;li&gt;Create public and private subnets&lt;/li&gt;
&lt;li&gt;Create internet gateway for the VPC&lt;/li&gt;
&lt;li&gt;Create an elastic IP address for NAT gateway&lt;/li&gt;
&lt;li&gt;Create a NAT gateway&lt;/li&gt;
&lt;li&gt;Create a route table for each subnet&lt;/li&gt;
&lt;li&gt;Create routes&lt;/li&gt;
&lt;li&gt;Associate route table to subnet&lt;/li&gt;
&lt;li&gt;Create a security group for the VPC&lt;/li&gt;
&lt;li&gt;Create Key-pair&lt;/li&gt;
&lt;li&gt;Run an instance&lt;/li&gt;
&lt;li&gt;Start the instance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS account. You can sign up &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and follow this &lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; in setting it up.&lt;/li&gt;
&lt;li&gt;AWS CLI. You can set it up using this &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; and configure it using this &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html" rel="noopener noreferrer"&gt;article&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have those two set up, then you’re good to go. Now, let’s get started!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 1 — Create a VPC &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;VPC (Virtual Private Cloud) is a secure and isolated private cloud hosted within a public cloud environment. With VPC, you can set up subnets, IP ranges, and also define rules for your services.&lt;/p&gt;

&lt;p&gt;To create a VPC, open up  your terminal and enter the following command:&lt;/p&gt;

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

aws ec2 create-vpc --cidr-block 10.0.0.0/16


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

&lt;/div&gt;

&lt;p&gt;Your terminal should respond with a bunch of information about this new VPC you’ve just created. Part of this information should be the VPC id.&lt;/p&gt;

&lt;p&gt;You can decide to add a tag to your VPC to easily identify it once you start having multiple VPCs, to do this, run the command below:&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;vpc-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;cidr&lt;/strong&gt; stands for &lt;strong&gt;Classless Inter-Domain Routing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F112991594-33170780-915f-11eb-8ebe-5cc12c4ddffd.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%2Fuser-images.githubusercontent.com%2F33374159%2F112991594-33170780-915f-11eb-8ebe-5cc12c4ddffd.png" alt="1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 2 - Create public and private subnets &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Subnet (Subnetwork) splits large networks into a group of smaller interconnected networks in order to reduce traffic congestion and increase routing efficiency.&lt;/p&gt;

&lt;p&gt;We are going to create two subnets, a private and public subnet, then attach a tag to each one to differentiate between them.&lt;/p&gt;

&lt;p&gt;To create the public subnet, run the following command:&lt;/p&gt;

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

aws ec2 create-subnet --vpc-id &amp;lt;vpc-id&amp;gt; --cidr-block 10.0.1.0/24


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

&lt;/div&gt;

&lt;p&gt;Again, your terminal should respond with information about the subnet you’ve just made. Pick out the subnet id and add a tag to it just as we’ve done for the VPC itself:&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;subnet-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;And for the private subnet:&lt;/p&gt;

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

aws ec2 create-subnet --vpc-id &amp;lt;vpc-id&amp;gt; --cidr-block 10.0.2.0/24


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

&lt;/div&gt;

&lt;p&gt;And for the tag:&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;subnet-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;It’s also important to mention here that the commands for creating public and private subnets only differ in the &lt;code&gt;--cidr-block&lt;/code&gt; parameter, so be sure to pay attention to that as well.&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%2Fuser-images.githubusercontent.com%2F33374159%2F112991951-9e60d980-915f-11eb-9fc0-5323faa8abc3.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%2Fuser-images.githubusercontent.com%2F33374159%2F112991951-9e60d980-915f-11eb-9fc0-5323faa8abc3.png" alt="2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 3 - Create internet gateway for the VPC &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Internet gateway (IGW) is simply used to connect a VPC to the internet so that the VPC resources can access the internet and be accessed over the internet.&lt;/p&gt;

&lt;p&gt;To create an internet gateway, use the following command:&lt;/p&gt;

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

aws ec2 create-internet-gateway


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

&lt;/div&gt;

&lt;p&gt;If you want, you can add a tag to the internet gateway you’ve just created the way we’ve done it for all other resources:&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;internet-gateway-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Then attach the internet gateway to the VPC.&lt;/p&gt;

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

aws ec2 attach-internet-gateway --internet-gateway-id &amp;lt;internet-gateway-id&amp;gt; --vpc-id &amp;lt;vpc-id&amp;gt;


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112992286-f26bbe00-915f-11eb-83f0-27ac89cbd686.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%2Fuser-images.githubusercontent.com%2F33374159%2F112992286-f26bbe00-915f-11eb-83f0-27ac89cbd686.png" alt="3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 4 - Create an elastic IP address for NAT gateway &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;An elastic IP address is a reserved IPv4 public address that can be assigned to an instance in order to enable communication with the internet.&lt;/p&gt;

&lt;p&gt;In order for us to create a NAT gateway, we’ll need an elastic IP address. Run the following command to create an elastic IP address.&lt;/p&gt;

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

aws ec2 allocate-address --domain vpc


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112992643-41b1ee80-9160-11eb-9166-4e819757d599.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%2Fuser-images.githubusercontent.com%2F33374159%2F112992643-41b1ee80-9160-11eb-9166-4e819757d599.png" alt="4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 5 - Create a NAT gateway &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A NAT (Network Address Translation) Gateway is used to enable instances in a private subnet to connect to the internet or other AWS services but prevents the internet from connecting to those instances.&lt;/p&gt;

&lt;p&gt;To create a NAT gateway, we need to add the public subnet in which the NAT gateway will reside and also associate the elastic IP address with the NAT gateway. Run the following command to create a NAT gateway.&lt;/p&gt;

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

aws ec2 create-nat-gateway --subnet-id &amp;lt;public-subnet-id&amp;gt; --allocation-id &amp;lt;elastic-ip-address-id&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Then add a tag to the NAT gateway.&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;nat-gateway-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112992950-95243c80-9160-11eb-8f71-1d6b72549ad4.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%2Fuser-images.githubusercontent.com%2F33374159%2F112992950-95243c80-9160-11eb-8f71-1d6b72549ad4.png" alt="5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 6 - Create a route table for each subnet &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A route table contains a set of rules that is used to determine where the network traffic from the subnets or internet gateway will be directed.&lt;/p&gt;

&lt;p&gt;Now, we need two route tables, one for each subnet. The route tables would be created the same way but different tags would be used for each of them.&lt;/p&gt;

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

aws ec2 create-route-table --vpc-id &amp;lt;vpc-id&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Add a tag to each of the route tables.&lt;/p&gt;

&lt;p&gt;You can tag the first route table as public.&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;first-route-table-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Then tag the second route table as private.&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;second-route-table-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112993513-327f7080-9161-11eb-8240-5b106464aff3.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%2Fuser-images.githubusercontent.com%2F33374159%2F112993513-327f7080-9161-11eb-8240-5b106464aff3.png" alt="6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 7 - Create routes &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We’ll now be creating routes for the previously created route tables. &lt;/p&gt;

&lt;p&gt;We’ll first attach the route table created for the public subnet to the internet gateway. The route matches all IPv4 traffic (0.0.0.0/0) and routes it to the specified Internet gateway.&lt;/p&gt;

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

aws ec2 create-route --route-table-id &amp;lt;public-route-table-id&amp;gt; --destination-cidr-block 0.0.0.0/0 --gateway-id &amp;lt;internet-gateway-id&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Then attach the route table created for the private subnet to the NAT gateway. The route matches all IPv4 traffic (0.0.0.0/0) and routes it to the specified NAT gateway.&lt;/p&gt;

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

aws ec2 create-route --route-table-id &amp;lt;private-route-table-id&amp;gt; --destination-cidr-block 0.0.0.0/0 --gateway-id &amp;lt;nat-gateway-id&amp;gt;


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112994445-2942d380-9162-11eb-909f-edde596a6d12.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%2Fuser-images.githubusercontent.com%2F33374159%2F112994445-2942d380-9162-11eb-909f-edde596a6d12.png" alt="7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 8 - Associate route table to subnet &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Associate the public route table to the public subnet.&lt;/p&gt;

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

aws ec2 associate-route-table --route-table-id &amp;lt;public-route-table-id&amp;gt; --subnet-id &amp;lt;public-subnet-id&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Associate the private route table to the private subnet.&lt;/p&gt;

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

aws ec2 associate-route-table --route-table-id &amp;lt;private-route-table-id&amp;gt; --subnet-id &amp;lt;private-subnet-id&amp;gt;


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112994633-5beccc00-9162-11eb-85a9-b1e8d387d7ba.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%2Fuser-images.githubusercontent.com%2F33374159%2F112994633-5beccc00-9162-11eb-85a9-b1e8d387d7ba.png" alt="8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 9 - Create a security group for the VPC &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Security groups serve as a virtual firewall for instances to control incoming and outgoing traffic. Inbound rules control the incoming traffic to the instance, and outbound rules control the outgoing traffic from the instance.&lt;/p&gt;

&lt;p&gt;We can create a security group with the following command:&lt;/p&gt;

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

aws ec2 create-security-group --group-name &amp;lt;security-group-name&amp;gt; --description "&amp;lt;description&amp;gt;" --vpc-id &amp;lt;vpc-id&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Add a tag to the security group.&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;security-group-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Then we specify rules for the security group created. port 80 allows inbound HTTP access from all IPv4 addresses and port 22 allows inbound SSH access to instances from IPv4 IP addresses in your network. &lt;/p&gt;

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

aws ec2 authorize-security-group-ingress --group-id &amp;lt;security-group-id&amp;gt; --protocol tcp --port 22 --cidr 0.0.0.0/0


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

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

aws ec2 authorize-security-group-ingress --group-id &amp;lt;security-group-id&amp;gt; --protocol tcp --port 80 --cidr 0.0.0.0/0


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

&lt;/div&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%2Fuser-images.githubusercontent.com%2F33374159%2F112995026-b9811880-9162-11eb-9a9a-5f1121300792.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%2Fuser-images.githubusercontent.com%2F33374159%2F112995026-b9811880-9162-11eb-9a9a-5f1121300792.png" alt="9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 10 - Create Key-pair &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Before we can run an instance, we need a key-pair. Run the following command to create a key pair. &lt;code&gt;cli-keyPair&lt;/code&gt; is the name of the key and can be changed to any name. &lt;code&gt;--output text&lt;/code&gt; is used to pipe your private key directly into a file. &lt;/p&gt;

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

aws ec2 create-key-pair --key-name cli-keyPair --query 'KeyMaterial' --output text &amp;gt; cli-keyPair.pem


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

&lt;/div&gt;

&lt;p&gt;If you’re using PowerShell, run the following command instead.&lt;/p&gt;

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

aws ec2 create-key-pair --key-name cli-keyPair --query 'KeyMaterial' --output text | out-file -encoding ascii -filepath cli-keyPair.pem


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

&lt;/div&gt;

&lt;p&gt;Run the following command to protect your key.&lt;/p&gt;

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

chmod 400 cli-keyPair.pem


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 11 - Run an instance &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;An ec2 instance is simply a virtual server in Amazon's Elastic Compute Cloud (EC2) used for running applications on Amazon web services infrastructure.&lt;/p&gt;

&lt;p&gt;Let’s create an instance with the following command. &lt;/p&gt;

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

aws ec2 run-instances --image-id ami-0533f2ba8a1995cf9 --instance-type t2.micro --count 1 --subnet-id &amp;lt;public-subnet-id&amp;gt; --security-group-ids &amp;lt;security-group-id&amp;gt; --associate-public-ip-address --key-name cli-keyPair


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

&lt;/div&gt;

&lt;p&gt;Add a tag to the instance created.&lt;/p&gt;

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

aws ec2 create-tags --resources &amp;lt;instance-id&amp;gt; --tags Key=&amp;lt;tag-key&amp;gt;,Value=&amp;lt;tag-value&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Before we can print the instance public DNS name, we have to enable the DNS hostname for the VPC. From the AWS console, go to &lt;strong&gt;VPC&lt;/strong&gt;, click on &lt;strong&gt;Your VPCs&lt;/strong&gt;, select the &lt;strong&gt;VPC&lt;/strong&gt; you created from AWS CLI and click on &lt;strong&gt;Actions&lt;/strong&gt;. From the dropdown, click on &lt;strong&gt;Edit DNS hostnames&lt;/strong&gt;. Directly under &lt;strong&gt;DNS hostnames&lt;/strong&gt;, select &lt;strong&gt;Enable&lt;/strong&gt; and click on &lt;strong&gt;Save changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F33374159%2F112998519-04505f80-9166-11eb-992e-cc571c6d8de3.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%2Fuser-images.githubusercontent.com%2F33374159%2F112998519-04505f80-9166-11eb-992e-cc571c6d8de3.png" alt="enable vpc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Print out the instance public dns name with the following command:&lt;/p&gt;

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

aws ec2 describe-instances --instance-ids &amp;lt;instance-id&amp;gt; --query 'Reservations[].Instances[].PublicDnsName'


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ami-0533f2ba8a1995cf9&lt;/code&gt; is the AMI id used in launching the instance.&lt;br&gt;
&lt;code&gt;t2.micro&lt;/code&gt; is the instance type. You can read more about it &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;--count&lt;/code&gt; is used to specify the number of instances to launch.&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%2Fuser-images.githubusercontent.com%2F33374159%2F112995768-76737500-9163-11eb-879b-8022bca145c7.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%2Fuser-images.githubusercontent.com%2F33374159%2F112995768-76737500-9163-11eb-879b-8022bca145c7.png" alt="11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt; 

&lt;h2&gt;
  
  
  Step 12 - Start instance &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Login to the instance using:&lt;/p&gt;

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

ssh -i "cli-keyPair.pem" ec2-user@&amp;lt;instance-public-dns-name&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ec2-user&lt;/code&gt; is the AMI username.&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%2Fuser-images.githubusercontent.com%2F33374159%2F112999090-8c366980-9166-11eb-9b25-df80fccbf6e6.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%2Fuser-images.githubusercontent.com%2F33374159%2F112999090-8c366980-9166-11eb-9b25-df80fccbf6e6.png" alt="12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Optional]&lt;/strong&gt;&lt;br&gt;
After login in, install the Apache web server using: &lt;/p&gt;

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

sudo yum install httpd -y


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

&lt;/div&gt;

&lt;p&gt;Start the web server with the following command: &lt;/p&gt;

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

sudo service httpd start


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

&lt;/div&gt;

&lt;p&gt;Now, let’s move into the Apache default root folder and create index.html&lt;/p&gt;

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

cd /var/www/html


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

&lt;/div&gt;

&lt;p&gt;Write into the index.html folder using any text editor of your choice. I'll be using vim.&lt;/p&gt;

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

sudo vim index.html


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

&lt;/div&gt;

&lt;p&gt;Enter any text.&lt;/p&gt;

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

&amp;lt;h1&amp;gt;Hello there!&amp;lt;/h1&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Open &lt;strong&gt;&lt;a href="http://public_ipv4_dns" rel="noopener noreferrer"&gt;http://public_ipv4_dns&lt;/a&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;a href="http://public_ipv4" rel="noopener noreferrer"&gt;http://public_ipv4&lt;/a&gt;&lt;/strong&gt; on your browser to verify 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%2Fuser-images.githubusercontent.com%2F33374159%2F113000354-a6bd1280-9167-11eb-8f58-52ba7efd5423.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%2Fuser-images.githubusercontent.com%2F33374159%2F113000354-a6bd1280-9167-11eb-8f58-52ba7efd5423.png" alt="browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can learn more AWS CLI commands from this &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ec2/index.html" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you found this article helpful, please leave a heart or a comment. If you have any questions, please let me know in the comment section.&lt;/p&gt;

&lt;p&gt;Also, don’t forget to follow me for more articles. Thank you.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
