<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rajesh</title>
    <description>The latest articles on DEV Community by Rajesh (@rajdevx).</description>
    <link>https://dev.to/rajdevx</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4006757%2F0a1c16ee-8a34-4868-bb0b-9c7e7024b1a6.png</url>
      <title>DEV Community: Rajesh</title>
      <link>https://dev.to/rajdevx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rajdevx"/>
    <language>en</language>
    <item>
      <title>AWS VPC Peering: How to Connect Two VPCs Privately</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Fri, 30 Oct 2026 17:25:03 +0000</pubDate>
      <link>https://dev.to/rajdevx/aws-vpc-peering-how-to-connect-two-vpcs-privately-159h</link>
      <guid>https://dev.to/rajdevx/aws-vpc-peering-how-to-connect-two-vpcs-privately-159h</guid>
      <description>&lt;h1&gt;
  
  
  Connecting Two AWS VPCs Using VPC Peering 🚀
&lt;/h1&gt;

&lt;p&gt;Imagine you have two different VPCs in AWS.&lt;/p&gt;

&lt;p&gt;One VPC has your application, and the other has your database.&lt;/p&gt;

&lt;p&gt;Now your application needs to get data from the database. How can these two VPCs talk to each other?&lt;/p&gt;

&lt;p&gt;AWS provides a feature called &lt;strong&gt;VPC Peering&lt;/strong&gt; to solve this problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is VPC Peering?
&lt;/h2&gt;

&lt;p&gt;VPC Peering is simply a way to connect two VPCs so that they can communicate privately.&lt;/p&gt;

&lt;p&gt;For example, let's say we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VPC A – &lt;code&gt;10.0.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;VPC B – &lt;code&gt;10.1.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can connect these two VPCs and allow resources inside them to communicate using their private IP addresses.&lt;/p&gt;

&lt;p&gt;No public IP address is needed for communication between the VPCs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can we connect two VPCs?
&lt;/h2&gt;

&lt;p&gt;Let's do it step by step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, create two VPCs in your AWS account.&lt;/li&gt;
&lt;li&gt;Make sure both VPCs have different IP address ranges.&lt;/li&gt;
&lt;li&gt;Open the VPC service in the AWS Console.&lt;/li&gt;
&lt;li&gt;Go to Peering Connections and create a new connection.&lt;/li&gt;
&lt;li&gt;Select the VPCs you want to connect.&lt;/li&gt;
&lt;li&gt;Accept the connection request.&lt;/li&gt;
&lt;li&gt;Add the required routes in both VPC route tables.&lt;/li&gt;
&lt;li&gt;Update the security groups to allow communication.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now your VPCs are ready to communicate!&lt;/p&gt;

&lt;h2&gt;
  
  
  One important thing to remember
&lt;/h2&gt;

&lt;p&gt;Creating a peering connection alone is not enough.&lt;/p&gt;

&lt;p&gt;You must also update the route tables on both sides.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In VPC A, add a route for &lt;code&gt;10.1.0.0/16&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In VPC B, add a route for &lt;code&gt;10.0.0.0/16&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both VPCs need to know where to send the traffic.&lt;/p&gt;

&lt;p&gt;Also, check the security groups and network ACLs if communication is not working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can three VPCs communicate through Peering?
&lt;/h2&gt;

&lt;p&gt;Let's say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VPC A is connected to VPC B.&lt;/li&gt;
&lt;li&gt;VPC B is connected to VPC C.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Can VPC A directly communicate with VPC C through VPC B?&lt;/p&gt;

&lt;p&gt;No!&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;non-transitive peering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If A needs to communicate with C, you must create another direct peering connection between them.&lt;/p&gt;

&lt;p&gt;If you have many VPCs, AWS Transit Gateway can make network management easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important points to know
&lt;/h2&gt;

&lt;p&gt;Before using VPC Peering, remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two VPCs cannot have overlapping IP ranges.&lt;/li&gt;
&lt;li&gt;Peering connections are not transitive.&lt;/li&gt;
&lt;li&gt;Both sides need proper route table entries.&lt;/li&gt;
&lt;li&gt;Security groups must allow the required traffic.&lt;/li&gt;
&lt;li&gt;You cannot use a peer VPC's NAT Gateway or Internet Gateway through peering.&lt;/li&gt;
&lt;li&gt;Data transfer charges apply.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When should we use VPC Peering?
&lt;/h2&gt;

&lt;p&gt;Here are a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An application in one VPC needs to access a database in another VPC.&lt;/li&gt;
&lt;li&gt;Two different AWS accounts need private communication.&lt;/li&gt;
&lt;li&gt;Development and testing environments need to share resources.&lt;/li&gt;
&lt;li&gt;Applications running in different AWS Regions need private connectivity.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>networking</category>
      <category>devops</category>
    </item>
    <item>
      <title>AWS NAT Gateway: Giving Private Subnets Safe Internet Access</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Thu, 29 Oct 2026 18:00:00 +0000</pubDate>
      <link>https://dev.to/rajdevx/aws-nat-gateway-giving-private-subnets-safe-internet-access-3o9j</link>
      <guid>https://dev.to/rajdevx/aws-nat-gateway-giving-private-subnets-safe-internet-access-3o9j</guid>
      <description>&lt;h3&gt;
  
  
  Why do we need a NAT Gateway?
&lt;/h3&gt;

&lt;p&gt;In the last session, we created a custom VPC with a private subnet to lock down backend databases and application servers. Nobody on the internet could reach them.&lt;/p&gt;

&lt;p&gt;Network isolation is great for security, but it creates a real problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How does your private EC2 server download security updates (&lt;code&gt;apt update&lt;/code&gt; or &lt;code&gt;dnf update&lt;/code&gt;)?&lt;/li&gt;
&lt;li&gt;How does it download packages or call external APIs like Stripe, Twilio, or GitHub?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you attach an Internet Gateway directly to the private subnet, it is no longer private—anyone on the internet can scan your ports.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;NAT Gateway&lt;/strong&gt; solves this problem. It allows private servers to reach out to the internet, while completely blocking the internet from starting connections back into your private servers.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What is NAT (Network Address Translation)?
&lt;/h2&gt;

&lt;p&gt;Think of an office with a &lt;strong&gt;receptionist&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When an employee wants to call a client, the receptionist dials out using the office main phone number.&lt;/li&gt;
&lt;li&gt;The client outside only sees the office company number, never the employee's personal desk extension.&lt;/li&gt;
&lt;li&gt;When the client replies on that same call, the receptionist connects them back to the employee.&lt;/li&gt;
&lt;li&gt;But if someone outside tries to call an employee directly without an active outbound call, the receptionist blocks the call.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ Private Subnet ]                         [ Public Subnet ]                 [ Internet ]
  Private EC2 (10.0.2.15)                   NAT Gateway (Elastic IP)          GitHub / External API
          │                                         │                                │
          │── Outbound: dnf update ────────────────►│── Outbound: Source = NAT EIP ─►│
          │                                         │                                │
          │◄── Inbound Reply ───────────────────────│◄── Inbound Reply ──────────────│
          │                                         │                                │
          │                                         │◄── Outside Inbound Probe ──────│ (Blocked ✗)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How the packets travel:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Your private EC2 (&lt;code&gt;10.0.2.15&lt;/code&gt;) wants to download software from the internet.&lt;/li&gt;
&lt;li&gt;The private route table sends &lt;code&gt;0.0.0.0/0&lt;/code&gt; to the &lt;strong&gt;NAT Gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The NAT Gateway replaces the private IP (&lt;code&gt;10.0.2.15&lt;/code&gt;) with its own &lt;strong&gt;Elastic IP&lt;/strong&gt;. It keeps track of this in its connection table.&lt;/li&gt;
&lt;li&gt;The packet goes through the Internet Gateway (IGW) out to the internet.&lt;/li&gt;
&lt;li&gt;When the website sends the data back, the NAT Gateway checks its table, swaps the destination IP back to &lt;code&gt;10.0.2.15&lt;/code&gt;, and hands the data to your private server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any outside connection coming in that was not started by your private server is immediately dropped.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Internet Gateway (IGW) vs. NAT Gateway
&lt;/h2&gt;

&lt;p&gt;Both handle internet traffic, but they do completely different jobs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What to look at&lt;/th&gt;
&lt;th&gt;Internet Gateway (IGW)&lt;/th&gt;
&lt;th&gt;NAT Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Traffic Direction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inbound and Outbound (Two-way)&lt;/td&gt;
&lt;td&gt;Outbound only + replies come back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Public subnets&lt;/td&gt;
&lt;td&gt;Private subnets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Needs a Public IP on EC2?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (EC2 only needs a private IP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IP Translation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 to 1 (One public IP for one EC2)&lt;/td&gt;
&lt;td&gt;Many to 1 (Many private EC2s share 1 NAT Elastic IP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where do you put it?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attached to the whole VPC&lt;/td&gt;
&lt;td&gt;Sits inside a &lt;strong&gt;Public Subnet&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;Automatic (up to 100 Gbps)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Hourly charge + per-GB data fee&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  3. How the Route Tables Work
&lt;/h2&gt;

&lt;p&gt;For a NAT Gateway to work, you need two route tables set up like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public Subnet Route Table (Where NAT Gateway lives)
Destination     Target
10.0.0.0/16     local
0.0.0.0/0       igw-0abc123  (Internet Gateway)

Private Subnet Route Table
Destination     Target
10.0.0.0/16     local
0.0.0.0/0       nat-0def456  (NAT Gateway)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The #1 Mistake:&lt;/strong&gt; You &lt;strong&gt;must&lt;/strong&gt; create your NAT Gateway inside a &lt;strong&gt;Public Subnet&lt;/strong&gt;. If you place it inside a private subnet, the NAT Gateway cannot reach the Internet Gateway, and nothing will connect.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. NAT Gateway vs. NAT Instance
&lt;/h2&gt;

&lt;p&gt;Before AWS had managed NAT Gateways, engineers launched a small EC2 instance running Linux to do the job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS NAT Gateway (Managed):&lt;/strong&gt; Works out of the box, auto-scales up to 100 Gbps, and AWS handles all patching and hardware redundancy inside the AZ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT Instance (EC2 you manage):&lt;/strong&gt; Cheaper for quick student tests, but you have to disable &lt;code&gt;Source/Destination Check&lt;/code&gt;, configure the Linux firewall yourself, and if that single EC2 instance stops or crashes, your whole private subnet loses internet access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is a Private NAT Gateway?
&lt;/h3&gt;

&lt;p&gt;When creating a NAT Gateway in the AWS console, you will see two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public:&lt;/strong&gt; Has an Elastic IP. Used to give private subnets internet access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private:&lt;/strong&gt; Has no Elastic IP. It is used when connecting two private networks (like on-premises to AWS via Transit Gateway) that have overlapping IP addresses. It cannot reach the internet.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. High Availability (HA) &amp;amp; Saving Money
&lt;/h2&gt;

&lt;p&gt;A NAT Gateway is redundant inside one Availability Zone (AZ), but it does &lt;strong&gt;not&lt;/strong&gt; protect you across multiple AZs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-AZ Setup (Production)
&lt;/h3&gt;

&lt;p&gt;If you run workloads in both &lt;code&gt;AZ-a&lt;/code&gt; and &lt;code&gt;AZ-b&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put &lt;strong&gt;one NAT Gateway in AZ-a&lt;/strong&gt; (public subnet).&lt;/li&gt;
&lt;li&gt;Put &lt;strong&gt;one NAT Gateway in AZ-b&lt;/strong&gt; (public subnet).&lt;/li&gt;
&lt;li&gt;Point private subnets in AZ-a to NAT Gateway A, and private subnets in AZ-b to NAT Gateway B.&lt;/li&gt;
&lt;li&gt;This prevents an outage in one AZ from cutting off your entire backend, and avoids cross-AZ data transfer fees.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Availability Zone A                       Availability Zone B
┌─────────────────────────────────┐       ┌─────────────────────────────────┐
│ [Public Subnet A]               │       │ [Public Subnet B]               │
│  NAT Gateway A (EIP A)          │       │  NAT Gateway B (EIP B)          │
│       ▲                         │       │       ▲                         │
│ [Private Subnet A]              │       │ [Private Subnet B]              │
│  App EC2 (Routes to NAT A)      │       │  App EC2 (Routes to NAT B)      │
└─────────────────────────────────┘       └─────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to avoid surprise bills:
&lt;/h3&gt;

&lt;p&gt;NAT Gateways charge an hourly uptime fee plus a per-GB fee for all data passing through them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use free VPC Gateway Endpoints for S3 &amp;amp; DynamoDB:&lt;/strong&gt; S3 Gateway Endpoints are &lt;strong&gt;100% free&lt;/strong&gt;. If your private servers pull gigabytes of files or backups from S3 through a NAT Gateway, you pay data processing on every gigabyte. Adding a Gateway Endpoint routes that traffic directly to S3 within AWS at zero cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete it when done with labs:&lt;/strong&gt; Always delete your NAT Gateway and &lt;strong&gt;release the Elastic IP&lt;/strong&gt; when you finish testing.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Hands-On Practice &amp;amp; Console Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here is the step-by-step walkthrough to set up a NAT Gateway and give your private EC2 instance outbound internet access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the NAT Gateway
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;VPC Console&lt;/strong&gt; → click &lt;strong&gt;NAT Gateways&lt;/strong&gt; → click &lt;strong&gt;Create NAT gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name tag: &lt;code&gt;lab-nat-gw&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Subnet: Select your &lt;strong&gt;public subnet&lt;/strong&gt; (&lt;code&gt;public-subnet-1a&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Connectivity type: Select &lt;strong&gt;Public&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Elastic IP allocation ID: Click &lt;strong&gt;Allocate Elastic IP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create NAT gateway&lt;/strong&gt;. It takes about 1–2 minutes for the status to turn from &lt;em&gt;Pending&lt;/em&gt; to &lt;strong&gt;Available&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![NAT Gateway Created in Public Subnet](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk7cvv425zp0ebkgjkf4z.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk7cvv425zp0ebkgjkf4z.png" alt=" " width="800" height="370"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 1: NAT Gateway created in &lt;code&gt;public-subnet-1a&lt;/code&gt; with an allocated Elastic IP.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2: Route the Private Subnet to the NAT Gateway
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Route tables&lt;/strong&gt; → select your private route table (&lt;code&gt;private-rt&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Routes&lt;/strong&gt; tab → click &lt;strong&gt;Edit routes&lt;/strong&gt; → &lt;strong&gt;Add route&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Destination:&lt;/strong&gt; &lt;code&gt;0.0.0.0/0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target:&lt;/strong&gt; Select &lt;strong&gt;NAT Gateway&lt;/strong&gt; → pick &lt;code&gt;lab-nat-gw&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save changes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![Private Route Table Pointing to NAT Gateway](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5nv16jtbr3i1ubnoei6.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5nv16jtbr3i1ubnoei6.png" alt=" " width="800" height="363"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 2: Routing all outbound internet traffic (0.0.0.0/0) to the NAT Gateway.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 3: Test from the Private Instance
&lt;/h3&gt;

&lt;p&gt;Log into your private EC2 instance (using AWS Systems Manager Session Manager or jumping through your public EC2):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Check your public IP from the private instance:&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://checkip.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It prints the &lt;strong&gt;NAT Gateway's Elastic IP&lt;/strong&gt;, not the EC2 private IP!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 2. Test downloading packages:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf update &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Packages now download and install with no problem through the NAT Gateway.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Verify Outside Inbound Traffic is Blocked
&lt;/h3&gt;

&lt;p&gt;From your local computer terminal, try reaching the private instance through the NAT Gateway's Elastic IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://13.234.112.45
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; key.pem ec2-user@13.234.112.45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
Both commands time out. Nobody on the internet can connect directly to your private instance through the NAT Gateway.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Clean Up (Avoid Surprise Bills!)
&lt;/h3&gt;

&lt;p&gt;NAT Gateways charge money every hour they run. Once you finish:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;NAT Gateways&lt;/strong&gt; → select &lt;code&gt;lab-nat-gw&lt;/code&gt; → &lt;strong&gt;Actions&lt;/strong&gt; → &lt;strong&gt;Delete NAT gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Route tables&lt;/strong&gt; → edit your private route table and delete the &lt;code&gt;0.0.0.0/0 -&amp;gt; nat&lt;/code&gt; route.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Elastic IPs&lt;/strong&gt; → select the allocated Elastic IP → &lt;strong&gt;Actions&lt;/strong&gt; → &lt;strong&gt;Release Elastic IP addresses&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Today's big takeaway was solving the private subnet internet problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Private subnets stay private, but can still download packages and call external APIs.&lt;/li&gt;
&lt;li&gt;Always put your NAT Gateway in a &lt;strong&gt;public subnet&lt;/strong&gt; with an Internet Gateway route.&lt;/li&gt;
&lt;li&gt;For production, run one NAT Gateway per Availability Zone.&lt;/li&gt;
&lt;li&gt;Use free S3 Gateway Endpoints to save money on data transfer fees.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>networking</category>
      <category>devops</category>
    </item>
    <item>
      <title>AWS VPC: Public &amp; Private Subnets with EC2 &amp; Docker</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Wed, 28 Oct 2026 17:23:34 +0000</pubDate>
      <link>https://dev.to/rajdevx/aws-vpc-public-private-subnets-with-ec2-docker-30ml</link>
      <guid>https://dev.to/rajdevx/aws-vpc-public-private-subnets-with-ec2-docker-30ml</guid>
      <description>&lt;h3&gt;
  
  
  Why do we need a custom VPC &amp;amp; Subnets?
&lt;/h3&gt;

&lt;p&gt;Without network isolation, every server you launch sits on a shared network accessible to anyone on the internet. &lt;/p&gt;

&lt;p&gt;A Virtual Private Cloud (VPC) gives you your own isolated private data center in the cloud. You decide which servers face the public internet and which backend databases stay completely shielded inside private subnets where no outsider can touch them.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The VPC (Virtual Private Cloud) &amp;amp; CIDR Planning
&lt;/h2&gt;

&lt;p&gt;Think of a VPC as a private gated apartment complex inside the giant AWS city. You decide the boundary walls, the internal road layout, and who gets through the gate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Region Scope:&lt;/strong&gt; A VPC lives inside one AWS Region and spans across all Availability Zones in that Region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIDR Block:&lt;/strong&gt; You assign your VPC an IPv4 range (between &lt;code&gt;/16&lt;/code&gt; with 65,536 IPs down to &lt;code&gt;/28&lt;/code&gt; with 16 IPs) using private IP standards (like &lt;code&gt;10.0.0.0/16&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIDR Math in Plain English:&lt;/strong&gt; The number after the slash tells you how many network bits are locked. A smaller number means a bigger network:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/16&lt;/code&gt; = 65,536 addresses (standard for a company VPC).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/24&lt;/code&gt; = 256 addresses (standard for a subnet).&lt;/li&gt;
&lt;li&gt;Always plan IP ranges across dev, staging, and prod so they don't overlap if you need to connect them later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Subnets &amp;amp; The 5 Reserved AWS IPs
&lt;/h2&gt;

&lt;p&gt;Subnets are slices of your VPC tied to &lt;strong&gt;one specific Availability Zone&lt;/strong&gt; (building).&lt;/p&gt;

&lt;p&gt;Inside every subnet you create, &lt;strong&gt;AWS automatically reserves 5 IP addresses&lt;/strong&gt; for internal networking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.0&lt;/code&gt; — Network address.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.1&lt;/code&gt; — VPC router / gateway.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.2&lt;/code&gt; — AWS DNS resolver.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.3&lt;/code&gt; — Reserved by AWS for future use.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.255&lt;/code&gt; — Network broadcast address.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt; When you create a &lt;code&gt;/24&lt;/code&gt; subnet (which mathematically has 256 IPs), you will only get &lt;strong&gt;251 usable IPs&lt;/strong&gt; for your EC2 instances and databases (&lt;code&gt;256 - 5 = 251&lt;/code&gt;). Notice how AWS explicitly displays &lt;strong&gt;"IP addresses available: 251"&lt;/strong&gt; in the subnet details.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Route Tables: What Actually Makes a Subnet "Public"?
&lt;/h2&gt;

&lt;p&gt;There is no special checkbox on AWS that makes a subnet public. Naming a subnet &lt;code&gt;public-subnet&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; make it public!&lt;/p&gt;

&lt;p&gt;A subnet is &lt;strong&gt;Public&lt;/strong&gt; if and only if its Route Table has a default route sending all outbound internet traffic (&lt;code&gt;0.0.0.0/0&lt;/code&gt;) to an &lt;strong&gt;Internet Gateway (IGW)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public Subnet Route Table             Private Subnet Route Table
Destination     Target                Destination     Target
10.0.0.0/16     local                 10.0.0.0/16     local
0.0.0.0/0       igw-0abc123           (No internet route - completely isolated)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a subnet has only the &lt;code&gt;local&lt;/code&gt; route, instances inside it can talk to other servers in the VPC, but the outside internet has zero way in.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Internet Gateway (IGW)
&lt;/h2&gt;

&lt;p&gt;The Internet Gateway is the front security gate connecting your VPC to the public internet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One IGW per VPC. It is horizontally scaled, highly available, and completely free.&lt;/li&gt;
&lt;li&gt;It does 1:1 NAT translation between your instance's public IP and private IP.&lt;/li&gt;
&lt;li&gt;When you run &lt;code&gt;ip addr&lt;/code&gt; inside an EC2 instance, you will only see its private IP (&lt;code&gt;10.0.1.x&lt;/code&gt;). The IGW handles the public IP translation seamlessly on the way in and out.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Security Groups vs. Network ACLs (NACLs)
&lt;/h2&gt;

&lt;p&gt;AWS provides two layers of firewalls with very different rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet Traffic ──► [ Network ACL (Subnet Guard) ] ──► [ Security Group (Instance Guard) ] ──► EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Security Group (SG)&lt;/th&gt;
&lt;th&gt;Network ACL (NACL)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Protects&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Individual EC2 instance / ENI&lt;/td&gt;
&lt;td&gt;The entire Subnet boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Allow rules only (default deny)&lt;/td&gt;
&lt;td&gt;Allow AND Deny rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Stateful:&lt;/strong&gt; If traffic is allowed in, the reply is automatically allowed out.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Stateless:&lt;/strong&gt; You must explicitly allow both inbound and outbound return traffic!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Evaluation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Evaluates all rules before deciding&lt;/td&gt;
&lt;td&gt;Evaluates rules in strict number order (100, 200... lowest number wins)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The 3-Tier Security Group Trick:&lt;/strong&gt; Instead of hardcoding changing IP addresses into firewall rules, reference the Security Group ID directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;web-sg&lt;/code&gt;: Inbound HTTP (80/443) from &lt;code&gt;0.0.0.0/0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app-sg&lt;/code&gt;: Inbound port 8080 &lt;strong&gt;only from &lt;code&gt;web-sg&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db-sg&lt;/code&gt;: Inbound port 5432 (Postgres) &lt;strong&gt;only from &lt;code&gt;app-sg&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Official VPC Multi-Tier Architecture
&lt;/h2&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%2Fsg7ovthe3k6fxr51iu1p.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%2Fsg7ovthe3k6fxr51iu1p.png" alt="Official AWS VPC Architecture with Public and Private Subnets" width="611" height="481"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(Reference: Official AWS VPC User Guide Architecture)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Public subnets host your load balancers and front-facing web servers.&lt;/li&gt;
&lt;li&gt;Private subnets host application workers and internal microservices.&lt;/li&gt;
&lt;li&gt;Isolated private subnets hold databases so no internet route ever touches your customer data.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Hands-On Practice &amp;amp; Console Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here is the step-by-step lab to build a custom VPC with public and private subnets, an Internet Gateway, and custom route tables in your AWS account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the Custom VPC (&lt;code&gt;lab-vpc&lt;/code&gt;)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the VPC Console, go to &lt;strong&gt;Your VPCs&lt;/strong&gt; → click &lt;strong&gt;Create VPC&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;VPC only&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name tag: &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;IPv4 CIDR block: &lt;code&gt;10.0.0.0/16&lt;/code&gt; (gives us 65,536 total internal IPs).&lt;/li&gt;
&lt;li&gt;Leave Tenancy as &lt;strong&gt;Default&lt;/strong&gt; and click &lt;strong&gt;Create VPC&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![Creating Custom VPC lab-vpc](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fazjtnp1w7js5q8r3lkdp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fazjtnp1w7js5q8r3lkdp.png" alt=" " width="800" height="583"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 1: Creating my custom VPC &lt;code&gt;lab-vpc&lt;/code&gt; with CIDR 10.0.0.0/16.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Create Public &amp;amp; Private Subnets
&lt;/h3&gt;

&lt;p&gt;Next, we divide the VPC into two separate subnets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Subnets&lt;/strong&gt; → &lt;strong&gt;Create subnet&lt;/strong&gt; → select &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnet 1 (Public):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Subnet name: &lt;code&gt;public-subnet-1a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Availability Zone: &lt;code&gt;Europe (Stockholm) / eun1-az1 (eu-north-1a)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;IPv4 subnet CIDR block: &lt;code&gt;10.0.1.0/24&lt;/code&gt; (251 usable IPs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add new subnet&lt;/strong&gt; for &lt;strong&gt;Subnet 2 (Private):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Subnet name: &lt;code&gt;private-subnet-1a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Availability Zone: &lt;code&gt;Europe (Stockholm) / eun1-az1 (eu-north-1a)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;IPv4 subnet CIDR block: &lt;code&gt;10.0.2.0/24&lt;/code&gt; (251 usable IPs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create subnet&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![Configuring Public and Private Subnets](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa1pdrhtb98dijffvlkjj.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa1pdrhtb98dijffvlkjj.png" alt=" " width="800" height="611"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 2: Setting up &lt;code&gt;public-subnet-1a&lt;/code&gt; and &lt;code&gt;private-subnet-1a&lt;/code&gt; inside &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Create &amp;amp; Attach the Internet Gateway (&lt;code&gt;lab-igw&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;A VPC is completely cut off from the internet by default. We need an Internet Gateway to open the front door:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Internet Gateways&lt;/strong&gt; → click &lt;strong&gt;Create internet gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name tag: &lt;code&gt;lab-igw&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Once created, click &lt;strong&gt;Actions&lt;/strong&gt; → &lt;strong&gt;Attach to VPC&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;lab-vpc&lt;/code&gt; and click &lt;strong&gt;Attach internet gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![Internet Gateway Attached to VPC](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrzkswcw5b54l3o8wu6z.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrzkswcw5b54l3o8wu6z.png" alt=" " width="799" height="361"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 3: Internet Gateway &lt;code&gt;lab-igw&lt;/code&gt; created and attached to &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Create the Public Route Table (&lt;code&gt;public-rt&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Now we connect the public subnet to our Internet Gateway using a custom Route Table:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Route tables&lt;/strong&gt; → click &lt;strong&gt;Create route table&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name tag: &lt;code&gt;public-rt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;VPC: Select &lt;code&gt;lab-vpc&lt;/code&gt; and click &lt;strong&gt;Create route table&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Routes&lt;/strong&gt; tab → click &lt;strong&gt;Edit routes&lt;/strong&gt; → &lt;strong&gt;Add route&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Destination:&lt;/strong&gt; &lt;code&gt;0.0.0.0/0&lt;/code&gt; (any IPv4 traffic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target:&lt;/strong&gt; Select &lt;strong&gt;Internet Gateway&lt;/strong&gt; (&lt;code&gt;lab-igw&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save changes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Subnet associations&lt;/strong&gt; tab → &lt;strong&gt;Edit subnet associations&lt;/strong&gt; → select &lt;code&gt;public-subnet-1a&lt;/code&gt; and save.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;(The &lt;code&gt;private-subnet-1a&lt;/code&gt; stays connected to the default main route table with only the &lt;code&gt;10.0.0.0/16 local&lt;/code&gt; route, so it remains isolated).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;![Public Route Table Creation](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0nbmo3hf1pefeot6rwdk.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0nbmo3hf1pefeot6rwdk.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 4: Creating &lt;code&gt;public-rt&lt;/code&gt; and linking it to &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Launching an EC2 Instance into the Custom VPC
&lt;/h3&gt;

&lt;p&gt;Finally, launch an EC2 instance directly inside your custom network:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;EC2&lt;/strong&gt; → click &lt;strong&gt;Launch instance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Network settings&lt;/strong&gt;, click &lt;strong&gt;Edit&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; Select &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnet:&lt;/strong&gt; Select &lt;code&gt;public-subnet-1a&lt;/code&gt;. Notice that AWS confirms &lt;code&gt;251&lt;/code&gt; available IPs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-assign public IP:&lt;/strong&gt; Set to &lt;strong&gt;Enable&lt;/strong&gt; if you want to reach it directly via SSH or web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall (security groups):&lt;/strong&gt; Create a new security group allowing SSH (port 22) or HTTP (port 80).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Launch instance&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![EC2 Network Settings in Custom Subnet](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdyem25yjwfeekc0ztt76.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdyem25yjwfeekc0ztt76.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 5: Placing our EC2 instance into &lt;code&gt;lab-vpc&lt;/code&gt; and &lt;code&gt;public-subnet-1a&lt;/code&gt; with 251 available IPs.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Clean Up (Avoid Surprise Bills!)
&lt;/h3&gt;

&lt;p&gt;Once you finish testing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Terminate the &lt;strong&gt;EC2 instance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Internet Gateways&lt;/strong&gt; → detach &lt;code&gt;lab-igw&lt;/code&gt; from &lt;code&gt;lab-vpc&lt;/code&gt;, then delete it.&lt;/li&gt;
&lt;li&gt;Delete the custom route table &lt;code&gt;public-rt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Delete the subnets and delete the VPC &lt;code&gt;lab-vpc&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




</description>
      <category>aws</category>
      <category>cloud</category>
      <category>devops</category>
      <category>networking</category>
    </item>
    <item>
      <title>Compute &amp; Load Balancing</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Tue, 27 Oct 2026 18:13:17 +0000</pubDate>
      <link>https://dev.to/rajdevx/compute-load-balancing-40ch</link>
      <guid>https://dev.to/rajdevx/compute-load-balancing-40ch</guid>
      <description>&lt;h3&gt;
  
  
  Why do we need Load Balancing &amp;amp; Managed Compute?
&lt;/h3&gt;

&lt;p&gt;A single server has hard limits: when CPU or memory runs out, your website crashes. If that single server reboots or fails, your entire business goes offline. &lt;/p&gt;

&lt;p&gt;Elastic Load Balancing (ELB) and scalable EC2 instances solve this by distributing user traffic across multiple healthy servers in different Availability Zones, so if one server dies, your users never even notice.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Scaling Up vs. Scaling Out
&lt;/h2&gt;

&lt;p&gt;Think of running a busy kitchen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scale Up (Vertical):&lt;/strong&gt; Buying a bigger stove. You replace your small server with a massive 64-CPU machine. It's easy, but it has a physical ceiling and still represents a single point of failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale Out (Horizontal):&lt;/strong&gt; Hiring more cooks with more stoves. You run five 2-CPU servers behind a load balancer. When one breaks, the other four keep cooking. You can add more anytime without restarting.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vertical Scaling (Scale Up)       Horizontal Scaling (Scale Out)
     [ Bigger Server ]                   [ Load Balancer ]
                                          /      |      \
                                     [App 1]  [App 2]  [App 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Load Balancing Algorithms
&lt;/h2&gt;

&lt;p&gt;How does a load balancer decide which backend server gets the next request?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Round Robin:&lt;/strong&gt; Takes turns in order (1, 2, 3, 1, 2, 3...). Perfect when requests are short and servers are identical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weighted Round Robin:&lt;/strong&gt; Sends more requests to beefier servers (e.g., 50% to App 1, 30% to App 2, 20% to App 3). Great for canary deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least Connections:&lt;/strong&gt; Forwards the next request to whichever server currently has the fewest active connections. Best for long-running jobs (like video processing or WebSockets).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source / IP Hash:&lt;/strong&gt; Hashes the client's IP address to map them consistently to the same server without needing cookies.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Health Checks: Catching Dead Servers
&lt;/h2&gt;

&lt;p&gt;A load balancer must never send traffic to a dead server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; The load balancer sends a background check (e.g., &lt;code&gt;GET /health&lt;/code&gt;) every few seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thresholds:&lt;/strong&gt; If a server fails 3 times in a row (&lt;code&gt;unhealthy threshold&lt;/code&gt;), it is pulled out of rotation. Once it passes 2 checks in a row (&lt;code&gt;healthy threshold&lt;/code&gt;), it gets traffic again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failsafe:&lt;/strong&gt; If all servers are marked unhealthy, the load balancer "fails open" and routes traffic to all of them as a last resort instead of dropping 100% of requests.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. The 3 AWS Elastic Load Balancers (ALB, NLB, GWLB)
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkdaocwgf48xxdc39p4u.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkdaocwgf48xxdc39p4u.png" alt="Application Load Balancer Component Architecture" width="555" height="243"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(Reference: Official AWS Application Load Balancer Architecture)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AWS provides three modern managed load balancers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Application Load Balancer (ALB) — Layer 7:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Reads HTTP and HTTPS paths, headers, hostnames, and cookies.&lt;/li&gt;
&lt;li&gt;Can route &lt;code&gt;/api/*&lt;/code&gt; to your API servers and &lt;code&gt;/images/*&lt;/code&gt; to an S3/storage target.&lt;/li&gt;
&lt;li&gt;Supports TLS termination, redirects (HTTP to HTTPS), and fixed 403/404 responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Load Balancer (NLB) — Layer 4:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ultra-fast, handles millions of requests per second at ultra-low latency.&lt;/li&gt;
&lt;li&gt;Routes raw TCP and UDP traffic (gaming, IoT feeds, databases).&lt;/li&gt;
&lt;li&gt;Provides a static IP address or Elastic IP per Availability Zone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway Load Balancer (GWLB) — Layer 3:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Routes raw IP packets to a fleet of third-party security firewalls or inspection appliances using the GENEVE protocol.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  5. Listeners, Rules &amp;amp; Target Groups
&lt;/h2&gt;

&lt;p&gt;Inside an Application Load Balancer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Listener:&lt;/strong&gt; Listens on a specific port and protocol (e.g., &lt;code&gt;HTTP:80&lt;/code&gt; or &lt;code&gt;HTTPS:443&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules:&lt;/strong&gt; If-then conditions evaluated in priority order. For example: &lt;code&gt;IF path is /api/* THEN forward to tg-api&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target Group:&lt;/strong&gt; A logical pool of backend servers with their own health check rules. Target types can be EC2 Instance IDs, IP addresses, or AWS Lambda functions.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client Request
      │
      ▼
 [ ALB Listener: 443 ]
      ├── Rule 1: path /api/*  ──► [ Target Group: API ]  ──► (EC2 in AZ-a, AZ-b)
      └── Default Rule         ──► [ Target Group: Web ]  ──► (EC2 in AZ-a, AZ-b)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Cross-Zone Load Balancing &amp;amp; Connection Draining
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbxlitkuufdei3b7jjorv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbxlitkuufdei3b7jjorv.png" alt="Cross-Zone Load Balancing Enabled" width="392" height="359"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(Reference: Official AWS Cross-Zone Load Balancing Guide)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Zone Balancing:&lt;/strong&gt; If AZ-a has 2 servers and AZ-b has 8 servers, cross-zone balancing ensures every server across both AZs receives an equal 10% of the traffic. On ALB, it is enabled by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection Draining (Deregistration Delay):&lt;/strong&gt; When removing an instance for updates or deployment, AWS stops sending new requests but allows in-flight requests to finish gracefully (default 300 seconds, customizable down to 30s).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky Sessions:&lt;/strong&gt; Uses an &lt;code&gt;AWSALB&lt;/code&gt; cookie to tie a visitor to one specific server. (Best practice: keep apps stateless using Redis so you don't need sticky sessions).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  7. EC2 Networking: Public vs. Private IPs &amp;amp; Elastic IPs
&lt;/h2&gt;

&lt;p&gt;Every EC2 instance in a VPC gets assigned IP addresses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private IP:&lt;/strong&gt; Permanent internal IP (e.g., &lt;code&gt;10.0.1.25&lt;/code&gt;) that stays with the instance for its entire life.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public IP (Auto-assigned):&lt;/strong&gt; Random public IP from Amazon's pool. &lt;strong&gt;Warning:&lt;/strong&gt; If you stop and restart the instance, this IP changes!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic IP (EIP):&lt;/strong&gt; A fixed, permanent public IPv4 address that you own until you release it. You can re-associate it between standby servers in seconds.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  8. Connecting to EC2 Without Open SSH Keys
&lt;/h2&gt;

&lt;p&gt;Leaving port 22 open to &lt;code&gt;0.0.0.0/0&lt;/code&gt; invites continuous bot attacks. AWS gives us three ways to connect:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Traditional SSH Key Pairs:&lt;/strong&gt; Connect using &lt;code&gt;ssh -i key.pem ec2-user@&amp;lt;ip&amp;gt;&lt;/code&gt;. Requires port 22 open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instance Connect:&lt;/strong&gt; Pushes a temporary, one-time public key valid for only 60 seconds. No private key files to manage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Systems Manager (SSM) Session Manager (Recommended):&lt;/strong&gt; Opens an interactive browser terminal using the outbound SSM agent. &lt;strong&gt;Requires ZERO open inbound ports in your Security Group!&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  9. Amazon EBS (Elastic Block Store) &amp;amp; Instance Store
&lt;/h2&gt;

&lt;p&gt;Where does EC2 store its files?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EBS:&lt;/strong&gt; Detachable virtual disks (like a USB drive for cloud).

&lt;ul&gt;
&lt;li&gt;Lives in one specific Availability Zone.&lt;/li&gt;
&lt;li&gt;Survives instance stops and reboots.&lt;/li&gt;
&lt;li&gt;Types: &lt;strong&gt;gp3&lt;/strong&gt; (General Purpose SSD - default), &lt;strong&gt;io2&lt;/strong&gt; (Provisioned IOPS for high-speed databases), and &lt;strong&gt;st1/sc1&lt;/strong&gt; (cold HDDs).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EBS Snapshots:&lt;/strong&gt; Point-in-time, incremental backups stored securely in S3. You can restore a snapshot into a new EBS volume in a different AZ or copy it to another AWS Region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance Store (Ephemeral):&lt;/strong&gt; Physical NVMe disks built directly into the host server. Blazing fast IOPS, but &lt;strong&gt;data is permanently wiped&lt;/strong&gt; if the instance stops or terminates. Perfect for caches and scratch data.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Hands-On Practice &amp;amp; Console Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here is the step-by-step lab to launch two EC2 servers in different AZs and put an Application Load Balancer in front.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Launch EC2 Web Instance
&lt;/h3&gt;

&lt;p&gt;I launched an EC2 instance (&lt;code&gt;t3.micro&lt;/code&gt; in &lt;code&gt;eu-north-1b&lt;/code&gt;) and pasted this user-data script so Nginx installs and starts automatically on boot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
dnf &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello from &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h1&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /usr/share/nginx/html/index.html
systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; nginx
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F67xj6c53uk2g5exxcotv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F67xj6c53uk2g5exxcotv.png" alt="EC2 Instance Running in AWS" width="800" height="368"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 1: EC2 instance running in my AWS account.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2: Configure Security Groups (&lt;code&gt;ec2-web-sg&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;I opened port 80 (HTTP) so the Load Balancer can talk to Nginx, and left outbound open for updates.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3o4w2mh5ujtoteyy0jc0.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3o4w2mh5ujtoteyy0jc0.png" alt="Security Group Configuration" width="800" height="364"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 2: Security group configuration (&lt;code&gt;ec2-web-sg&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 3: Create Target Group (&lt;code&gt;ec2-users&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;I created a target group pointing to port 80 with &lt;code&gt;/&lt;/code&gt; as the health check path and registered the instance.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foqny39g1e7x7jumfznbu.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foqny39g1e7x7jumfznbu.png" alt="Target Group Configuration" width="800" height="356"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 3: Target group &lt;code&gt;ec2-users&lt;/code&gt; created for routing traffic.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 4: Create the Application Load Balancer (&lt;code&gt;alb&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;I created an internet-facing ALB named &lt;code&gt;alb&lt;/code&gt;, enabled both &lt;code&gt;eu-north-1a&lt;/code&gt; and &lt;code&gt;eu-north-1b&lt;/code&gt; subnets, and pointed the port 80 listener to &lt;code&gt;ec2-users&lt;/code&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F64okt0t07m4fa8y28oyc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F64okt0t07m4fa8y28oyc.png" alt="Application Load Balancer Details" width="800" height="368"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 4: Application Load Balancer active with its public DNS address.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 5: Local HAProxy &amp;amp; Failover Test
&lt;/h3&gt;

&lt;p&gt;Before testing with multiple cloud instances, I ran a basic local test with 3 apps (&lt;code&gt;app1&lt;/code&gt;, &lt;code&gt;app2&lt;/code&gt;, &lt;code&gt;app3&lt;/code&gt;) to see how round-robin and health checks work in real-time when a server crashes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python lb_demo.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is my actual terminal output:&lt;/p&gt;

&lt;p&gt;![HAProxy / Python Load Balancer Terminal Run](&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frurz89d7e9t50j22tcw8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frurz89d7e9t50j22tcw8.png" alt=" " width="800" height="367"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 5: My terminal showing round-robin in Demo 1, and traffic instantly dropping app3 in Demo 2 when it failed.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Clean Up
&lt;/h3&gt;

&lt;p&gt;Don't forget to delete resources when finished so you don't get billed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deleted the ALB (&lt;code&gt;alb&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Deleted the target group (&lt;code&gt;ec2-users&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Terminated the EC2 instance&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Cloud foundations &amp; IAM</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Mon, 26 Oct 2026 17:40:10 +0000</pubDate>
      <link>https://dev.to/rajdevx/cloud-foundations-iam-1dnk</link>
      <guid>https://dev.to/rajdevx/cloud-foundations-iam-1dnk</guid>
      <description>&lt;h3&gt;
  
  
  Why do we go for AWS?
&lt;/h3&gt;

&lt;p&gt;Setting up your own physical servers means spending lakhs up front on hardware, electricity, cooling, and guessing how many servers you need. &lt;/p&gt;

&lt;p&gt;AWS lets you rent computers and storage over the internet in seconds and pay only for the exact minutes or hours you use.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Cloud computing
&lt;/h2&gt;

&lt;p&gt;Instead of buying and keeping bulky computers in your office room, you rent virtual machines and storage from huge data centres run by Amazon. &lt;/p&gt;

&lt;p&gt;It works just like electricity at home: you don't build your own power station to turn on a fan, you just plug in and pay the monthly bill for the units you used.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Service models: IaaS, PaaS, SaaS
&lt;/h2&gt;

&lt;p&gt;Think of how you eat dinner to understand how much you manage versus how much AWS manages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IaaS (Infrastructure as a Service):&lt;/strong&gt; Renting an empty kitchen. AWS gives you the physical server and network; you install the OS, setup Python/Node, and run your code.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;strong&gt;Amazon EC2&lt;/strong&gt;, &lt;strong&gt;Amazon VPC&lt;/strong&gt;, &lt;strong&gt;Amazon EBS&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PaaS (Platform as a Service):&lt;/strong&gt; Getting a meal kit with pre-chopped ingredients. You just write your app code and hand it over; AWS handles the OS, patching, and scaling.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;strong&gt;AWS App Runner&lt;/strong&gt;, &lt;strong&gt;AWS Elastic Beanstalk&lt;/strong&gt;, &lt;strong&gt;Amazon RDS&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaS (Software as a Service):&lt;/strong&gt; Sitting at a restaurant and eating food. Everything is fully built and managed; you just log in and use it.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;strong&gt;Amazon QuickSight&lt;/strong&gt;, &lt;strong&gt;Amazon Connect&lt;/strong&gt; (or Gmail and Slack outside AWS).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless (FaaS):&lt;/strong&gt; Buying a snack from a vending machine. You write a single function and pay only when that function runs.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;strong&gt;AWS Lambda&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Regions
&lt;/h2&gt;

&lt;p&gt;A Region is a specific physical geographic location in the world where AWS operates a cluster of data centres (like Mumbai &lt;code&gt;ap-south-1&lt;/code&gt; or Singapore &lt;code&gt;ap-southeast-1&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Each Region is completely independent. Your data stays in that Region and never leaves unless you intentionally copy or replicate it out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to choose a Region:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compliance / Data laws:&lt;/strong&gt; If your government rules say customer data must stay in India, pick Mumbai or Hyderabad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency:&lt;/strong&gt; Choose the location closest to your users so the site opens fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Available services:&lt;/strong&gt; Brand new AWS services often arrive in &lt;code&gt;us-east-1&lt;/code&gt; (N. Virginia) first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price:&lt;/strong&gt; Resource prices differ slightly across countries based on local taxes and power costs.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. Availability Zones (AZs)
&lt;/h2&gt;

&lt;p&gt;Inside every Region, AWS builds separate data centre clusters called &lt;strong&gt;Availability Zones (AZs)&lt;/strong&gt; (for example: &lt;code&gt;ap-south-1a&lt;/code&gt;, &lt;code&gt;ap-south-1b&lt;/code&gt;, and &lt;code&gt;ap-south-1c&lt;/code&gt; in Mumbai).&lt;/p&gt;

&lt;p&gt;An AZ is made of one or more physical data centres with redundant power, backup generators, and cooling. They sit miles apart from each other so a flood or local power cut in one building doesn't hurt the other, but they are linked by super-fast private fibre cables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Region: ap-south-1 (Mumbai)
 ├── ap-south-1a [Data Centre 1 + Data Centre 2]
 ├── ap-south-1b [Data Centre 3 + Data Centre 4]
 └── ap-south-1c [Data Centre 5 + Data Centre 6]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The 3 Core AZ Rules &amp;amp; Limitations:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Minimum 3 AZs per Region:&lt;/strong&gt; Every standard AWS Region gives you at least 3 AZs for high availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AZ-Scoped Services:&lt;/strong&gt; Certain resources live strictly inside one single AZ. An EC2 instance, an EBS volume, and a VPC Subnet can only exist in one AZ at a time. If that AZ goes dark and you don't have a backup in another AZ, your app goes down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AZ Names are Random per Account:&lt;/strong&gt; The name &lt;code&gt;ap-south-1a&lt;/code&gt; in your account might actually map to a different physical building than your friend's &lt;code&gt;ap-south-1a&lt;/code&gt; (to balance traffic across AWS buildings). The permanent true ID is the &lt;strong&gt;Zone ID&lt;/strong&gt; (like &lt;code&gt;aps1-az1&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  5. Edge locations &amp;amp; Caching
&lt;/h2&gt;

&lt;p&gt;Edge locations are hundreds of smaller branch offices in major cities (like Chennai, Bengaluru, Delhi, Frankfurt, New York) sitting right next to end-users.&lt;/p&gt;

&lt;p&gt;They don't run heavy virtual servers. Instead, they run &lt;strong&gt;Amazon CloudFront&lt;/strong&gt; (Content Delivery Network) and &lt;strong&gt;Amazon Route 53&lt;/strong&gt; (DNS). &lt;/p&gt;

&lt;p&gt;When a user in Chennai asks for an image stored in a server in Ireland, CloudFront fetches it once and saves a local copy in Chennai's cache. The next user in Chennai gets the image in 10ms instead of waiting 250ms across the ocean.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. IAM: Authentication, Authorisation, Root User, Users &amp;amp; Groups
&lt;/h2&gt;

&lt;p&gt;AWS Identity and Access Management (&lt;strong&gt;IAM&lt;/strong&gt;) is the free global security guard for your entire cloud account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       [ Human / Developer ]
                 │
                 ▼ (Member of)
             [ Group ]
                 │
                 ▼ (Has Attached)
          [ JSON Policies ] ◄──── Sets rules (Effect, Action, Resource)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authentication vs. Authorisation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication (Who are you?):&lt;/strong&gt; Checking your credentials. At a building gate, this is the security guard looking at your photo ID card or checking your password and MFA code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorisation (What can you do?):&lt;/strong&gt; Checking the rulebook. Can your badge open the server room door? Or are you only allowed in the lobby? In AWS, IAM checks if you have permission to run &lt;code&gt;s3:GetObject&lt;/code&gt; or &lt;code&gt;ec2:StartInstances&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Root User
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The root user is the primary email address used to create the AWS account.&lt;/li&gt;
&lt;li&gt;It has absolute god-mode access and can delete everything. You cannot restrict root using normal IAM policies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best practice:&lt;/strong&gt; Lock root with Multi-Factor Authentication (MFA), delete any root access keys, and never use root for daily work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IAM Users
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A unique personal login created for one specific person or application.&lt;/li&gt;
&lt;li&gt;Each user gets their own password for the AWS console or access keys (&lt;code&gt;AKIA...&lt;/code&gt;) for the CLI.&lt;/li&gt;
&lt;li&gt;If a team member leaves, you disable only their IAM user without breaking anyone else's access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IAM Groups
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A collection of IAM users (like a &lt;code&gt;developers&lt;/code&gt; or &lt;code&gt;finance&lt;/code&gt; department).&lt;/li&gt;
&lt;li&gt;Instead of adding policies to 20 users one by one, attach the policy to the group. Anyone added to the group automatically gets those rights.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Note:&lt;/em&gt; Groups cannot be nested inside other groups.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Policies (JSON)
&lt;/h2&gt;

&lt;p&gt;An IAM Policy is a simple JSON document that writes down permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AllowReadCompanyReports"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::company-reports"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::company-reports/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Bool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"aws:MultiFactorAuthPresent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Anatomy of a Policy:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version:&lt;/strong&gt; Always use &lt;code&gt;"2012-10-17"&lt;/code&gt; (the current policy language version).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effect:&lt;/strong&gt; Either &lt;code&gt;"Allow"&lt;/code&gt; or &lt;code&gt;"Deny"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; The exact API call you are allowing or blocking (e.g. &lt;code&gt;s3:GetObject&lt;/code&gt;, &lt;code&gt;ec2:RunInstances&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource:&lt;/strong&gt; The ARN (Amazon Resource Name) of the target. Notice the S3 difference:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;arn:aws:s3:::company-reports&lt;/code&gt; = the bucket itself (needed to list bucket contents).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;arn:aws:s3:::company-reports/*&lt;/code&gt; = the files inside the bucket (needed to download files).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Condition:&lt;/strong&gt; Extra safety checks (e.g., only allow if MFA is turned on, or only from office IP).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. How AWS evaluates a request: Deny always wins!
&lt;/h2&gt;

&lt;p&gt;When you click a button or type a CLI command, IAM checks all policies attached to you using a strict order:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl809lccueynj1p1lf3z7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl809lccueynj1p1lf3z7.png" alt="AWS Policy Evaluation" width="800" height="1345"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(Reference: Official AWS IAM Evaluation Guide)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       Incoming Request (e.g. s3:DeleteObject)
                         │
                         ▼
             Is there an Explicit DENY?
                   /           \
                 YES            NO
                 /                \
          [ DENY Access ]     Is there an Explicit ALLOW?
                                 /           \
                               YES            NO
                               /                \
                       [ ALLOW Access ]    [ DENY Access ]
                                           (Default Deny)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Default is Deny:&lt;/strong&gt; Everything starts completely locked. If no policy mentions your action, you are blocked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Allow:&lt;/strong&gt; If a policy says &lt;code&gt;"Allow"&lt;/code&gt;, you get access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Deny ALWAYS Trumps:&lt;/strong&gt; If any policy anywhere says &lt;code&gt;"Deny"&lt;/code&gt;, that request is instantly blocked. An explicit Deny kills any Allow, every single time.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  9. Roles and STS: Temporary logins
&lt;/h2&gt;

&lt;p&gt;Why do we need &lt;strong&gt;Roles&lt;/strong&gt; if we already have IAM users? &lt;/p&gt;

&lt;p&gt;Because storing permanent access keys (&lt;code&gt;AKIA...&lt;/code&gt;) on EC2 servers or in &lt;code&gt;.env&lt;/code&gt; files is dangerous. If code leaks to GitHub, bots grab those keys in seconds and run up huge bills.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ EC2 Server / Lambda / GitHub Actions ]
                   │
                   ▼ (Calls sts:AssumeRole)
        [ AWS STS (Token Service) ]
                   │
                   ▼ (Generates)
    [ Temporary Access Keys (ASIA...) ]
      • Valid for 15 mins to 12 hours
      • Rotates automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How Roles Work:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Role&lt;/strong&gt; is an identity that has no password and no permanent secret key.&lt;/li&gt;
&lt;li&gt;When an EC2 server or Lambda function needs to read an S3 bucket, it asks &lt;strong&gt;AWS STS (Security Token Service)&lt;/strong&gt; to assume the role.&lt;/li&gt;
&lt;li&gt;STS hands back &lt;strong&gt;temporary credentials&lt;/strong&gt; (starts with &lt;code&gt;ASIA...&lt;/code&gt;) that expire automatically in minutes or hours.&lt;/li&gt;
&lt;li&gt;The AWS SDK rotates them automatically behind the scenes. No permanent keys ever sit on your server disk.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Two Sides of Every Role:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trust Policy (Who can wear the badge?):&lt;/strong&gt; Specifies which service or account is allowed to assume the role (e.g., &lt;code&gt;ec2.amazonaws.com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions Policy (What can you do while wearing it?):&lt;/strong&gt; The normal JSON policy specifying allowed actions (e.g., read files from S3).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Hands-On Practice &amp;amp; Console Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here is the exact hands-on practice I did today inside my AWS account, along with the console setups and CLI steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting up an IAM User, Group &amp;amp; Policy (Console)
&lt;/h3&gt;

&lt;p&gt;First, I went to the IAM console so I don't work as root anymore.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Created an IAM User:&lt;/strong&gt; Gave it console access with a custom password and required password reset.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Created an IAM Group:&lt;/strong&gt; Named it &lt;code&gt;developers&lt;/code&gt; and attached the &lt;code&gt;ReadOnlyAccess&lt;/code&gt; policy to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Added User to Group:&lt;/strong&gt; Put my new user into the &lt;code&gt;developers&lt;/code&gt; group.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyv3g3d7durwi3606rpf.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyv3g3d7durwi3606rpf.png" alt="Creating my new IAM user inside the AWS Console" width="799" height="367"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 1: Creating a dedicated IAM user with console access and custom password.&lt;/em&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fupp5f62vqlotgx7h7r3d.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fupp5f62vqlotgx7h7r3d.png" alt="Adding user to the developers group with ReadOnly policy" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 2: Adding the user to the &lt;code&gt;developers&lt;/code&gt; user group with ReadOnlyAccess policy attached.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2: Creating an IAM Role for Testing
&lt;/h3&gt;

&lt;p&gt;Next, I created an IAM Role named &lt;code&gt;lab-s3-reader&lt;/code&gt; to test temporary access:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Chose &lt;strong&gt;AWS account&lt;/strong&gt; as the trusted entity so my current user can assume it.&lt;/li&gt;
&lt;li&gt;Attached &lt;code&gt;AmazonS3ReadOnlyAccess&lt;/code&gt; to the role.&lt;/li&gt;
&lt;li&gt;Verified the trust relationship policy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw1v462gs8rgqtopydy4r.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw1v462gs8rgqtopydy4r.png" alt="Role trust policy and attached permissions" width="800" height="361"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 3: Setting up the IAM role trust policy and testing permissions.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 3: Terminal POC (Testing with AWS CLI)
&lt;/h3&gt;

&lt;p&gt;Before running commands from your local computer's terminal, you need credentials for the CLI:&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Generating Your Access Key
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In the IAM Console, go to &lt;strong&gt;Users&lt;/strong&gt; → click your user name → open the &lt;strong&gt;Security credentials&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Scroll down to &lt;strong&gt;Access keys&lt;/strong&gt; and click &lt;strong&gt;Create access key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Command Line Interface (CLI)&lt;/strong&gt;, acknowledge the recommendation, and click next.&lt;/li&gt;
&lt;li&gt;AWS will give you two values:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access key ID:&lt;/strong&gt; A public identifier starting with &lt;code&gt;AKIA...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret access key:&lt;/strong&gt; A private string.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important Warning from AWS:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you lose or forget your secret access key, you cannot retrieve it again. Instead, you must delete or deactivate the old key and create a new one. Download the &lt;code&gt;.csv&lt;/code&gt; file or keep it safe.&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5t6bnqwpva216cy7o6w.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5t6bnqwpva216cy7o6w.png" alt="Access keys section in IAM Security Credentials tab" width="800" height="362"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Fig 4: Generating and managing Access Keys inside the Security Credentials tab.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Configure AWS CLI
&lt;/h4&gt;

&lt;p&gt;In your local terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste your &lt;strong&gt;Access Key ID&lt;/strong&gt;, &lt;strong&gt;Secret Access Key&lt;/strong&gt;, default region (e.g., &lt;code&gt;ap-south-1&lt;/code&gt;), and default output format (&lt;code&gt;json&lt;/code&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Test your connection
&lt;/h4&gt;

&lt;p&gt;Check who you are logged in as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws sts get-caller-identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints your Account ID, User ID, and user ARN so you know your keys are active.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Create a test S3 bucket in Mumbai and upload a file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# S3 bucket names must be globally unique, so we add a random number&lt;/span&gt;
aws s3 mb s3://my-test-bucket-&lt;span class="nv"&gt;$RANDOM&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-south-1

&lt;span class="c"&gt;# Make a small test text file and copy it to your bucket&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Session 1 complete"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; test.txt
aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;test.txt s3://&amp;lt;your-bucket-name&amp;gt;/

&lt;span class="c"&gt;# List the files inside your bucket&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;ls &lt;/span&gt;s3://&amp;lt;your-bucket-name&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Clean up before closing
&lt;/h4&gt;

&lt;p&gt;Always delete test buckets right after you finish so your account stays tidy and free:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 rb s3://&amp;lt;your-bucket-name&amp;gt;/ &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Session 1 Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Things I made sure to check off today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locked my root account with an MFA app right away and stopped using it for daily work.&lt;/li&gt;
&lt;li&gt;Created a $5 budget alert in AWS Budgets so I get an email before any surprise bill hits.&lt;/li&gt;
&lt;li&gt;Remembered the golden IAM rule: if even one policy has an explicit &lt;code&gt;Deny&lt;/code&gt;, it immediately blocks the request no matter what else says &lt;code&gt;Allow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Stopped putting secret access keys into code or server folders—using IAM Roles with STS temporary tokens instead.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>iam</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Configure Inter-Region VPC Peering</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Fri, 14 Aug 2026 18:26:15 +0000</pubDate>
      <link>https://dev.to/rajdevx/how-to-configure-inter-region-vpc-peering-k36</link>
      <guid>https://dev.to/rajdevx/how-to-configure-inter-region-vpc-peering-k36</guid>
      <description>&lt;p&gt;If you have servers running in different AWS Regions, you may need to allow the workloads on those servers to communicate privately.&lt;/p&gt;

&lt;p&gt;For example, an application running in Hyderabad might need to communicate with a database running in Sydney using private IPs.&lt;/p&gt;

&lt;p&gt;In this how-to, I'll show you how I peered two VPCs in different AWS Regions and connected them using VPC Peering.&lt;/p&gt;




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

&lt;p&gt;Assume for this lab that the following architecture is required to be configured:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Region A&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;vpc-a-peering-connection (CIDR: 10.0.0.0/16)&lt;/p&gt;

&lt;p&gt;subnet: 10.0.1.0/24&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Region B&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;vpc-b-peering-connection (CIDR: 10.1.0.0/16)&lt;/p&gt;

&lt;p&gt;subnet: 10.1.1.0/24&lt;/p&gt;

&lt;p&gt;Make sure that the CIDR ranges do not overlap on the VPCs as you can't peer VPCs with overlapping CIDRs&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Creating the VPCs and instances
&lt;/h1&gt;

&lt;p&gt;I first proceeded to create the VPCs and launched instances in them&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigating to Hyderabad region, I created a vpc-a-peering-connection VPC, public subnet, internet gateway, and a route table. Then I launched a simple Ubuntu EC2 instance in the region&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our region A VPC is created:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqdi37xao65sxctz213vw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqdi37xao65sxctz213vw.png" alt="VPC Setup Region A" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The public subnet that I created in Hyderabad region:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fde4wagr7wgnrfmngvgwh.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fde4wagr7wgnrfmngvgwh.png" alt="Subnets Region A" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Internet Gateway attached to my Hyderabad VPC:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F77ohibrrs2ws0oeopg5g.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F77ohibrrs2ws0oeopg5g.png" alt="Internet Gateway Region A" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then switched to Sydney region and created similar resources in that region as well&lt;/p&gt;

&lt;p&gt;The Sydney VPC is created:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrwj6ixlgu0yj4ymfwln.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrwj6ixlgu0yj4ymfwln.png" alt="VPC Setup Region B" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The subnet in Sydney region:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6qt3mi94tc19aucapcop.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6qt3mi94tc19aucapcop.png" alt="Subnets Region B" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Internet Gateway attached to my Sydney VPC:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fki3zabumme7qyx5mfj3p.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fki3zabumme7qyx5mfj3p.png" alt="Internet Gateway Region B" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this lab, I launched my EC2 instances in public subnets so that they can be easily accessed for testing. The VPC peering connection does not require the subnet to be public or VPC to have an Internet Gateway&lt;/p&gt;

&lt;p&gt;At this point, a ping from the Hyderabad instance to the Sydney instance will fail because there is no route between the two VPCs yet.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Creating the peering connection
&lt;/h1&gt;

&lt;p&gt;Now, I proceeded to create the peering connection&lt;/p&gt;

&lt;p&gt;I navigated to VPC Dashboard in Hyderabad region, clicked Peering connections, and created a new one&lt;/p&gt;

&lt;p&gt;I gave it a name VPC-A to VPC-B, chose my vpc-a-peering-connection as the Requester, and another region as Accepter and Sydney as the region&lt;/p&gt;

&lt;p&gt;I chose the vpc-b-peering-connection as the accepter VPC and clicked create&lt;/p&gt;

&lt;p&gt;The peering connection request was sent and is awaiting approval:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fotilph5h3vg4gynlp15l.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fotilph5h3vg4gynlp15l.png" alt="Peering Request Hyderabad" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Accepting the connection
&lt;/h1&gt;

&lt;p&gt;Switching to Sydney region, I navigated to Peering connections and accepted the request:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7saewlvpddlee3ir34p4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7saewlvpddlee3ir34p4.png" alt="Peering Acceptance Sydney" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now see that the peering connection is active. The next thing to do is to update the route tables&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Updating the route tables
&lt;/h1&gt;

&lt;p&gt;I navigated to Route Tables and selected the route table associated with the subnet where I launched my EC2 Instance&lt;/p&gt;

&lt;p&gt;I added a route to the Sydney VPC:&lt;/p&gt;

&lt;p&gt;Destination: 10.1.0.0/16&lt;/p&gt;

&lt;p&gt;Target: Peering Connection (selected the PCX created earlier)&lt;/p&gt;

&lt;p&gt;I did the same thing in the Sydney region to route traffic back to Hyderabad:&lt;/p&gt;

&lt;p&gt;Destination: 10.0.0.0/16&lt;/p&gt;

&lt;p&gt;Target: Peering Connection&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsimdw32y06mc6jnbf11a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsimdw32y06mc6jnbf11a.png" alt="Route Table Updates Hyderabad" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This route table in Hyderabad now has a route to the Sydney VPC via the peering connection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb3g67vxcj4i6b8x6hhx7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb3g67vxcj4i6b8x6hhx7.png" alt="Route Table Updates Sydney" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Sydney route table now has a route back to the Hyderabad VPC&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Updating the security groups
&lt;/h1&gt;

&lt;p&gt;The route tables are now updated, but we also need to allow ICMP traffic in the security groups for the ping test to work.&lt;/p&gt;

&lt;p&gt;In the security group of my EC2 instance in Hyderabad region, I updated the Inbound rules to explicitly allow All ICMP - IPv4 from the source 10.1.0.0/16:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxedby4vmtla5k70h61pq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxedby4vmtla5k70h61pq.png" alt="Security Group Inbound Hyderabad" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Note: In the above image, there is a TCP rule from another lab. For ICMP traffic, we need the All ICMP - IPv4 inbound traffic rule)&lt;/p&gt;

&lt;p&gt;Similarly, in the security group in Sydney, I updated the Inbound rules to allow All ICMP - IPv4 from the source 10.0.0.0/16:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjhd6wfm5ffe9ry7buvm8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjhd6wfm5ffe9ry7buvm8.png" alt="Security Group Inbound Sydney" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I explicitly allowed the inbound ICMP rules in Sydney. If you have the default outbound rule (All traffic - 0.0.0.0/0) as Allow, there is no need to add an outbound rule for this ping test&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Testing the connection
&lt;/h1&gt;

&lt;p&gt;I then SSH'd back into my instance in Hyderabad region and did a ping to the private IP address of the instance in Sydney region. It worked after updating the security group:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjl0ac7zgujowl3pbpnud.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjl0ac7zgujowl3pbpnud.png" alt="Successful Ping" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the two instances can communicate with each other over the AWS network via private IPs&lt;/p&gt;




&lt;h2&gt;
  
  
  Things to note
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can't establish a VPC Peering connection between VPCs with overlapping IPv4 or IPv6 CIDR blocks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VPC Peering is not transitive.&lt;/strong&gt; If VPC A is peered with VPC B, and VPC B is peered with VPC C, VPC A cannot communicate with VPC C through VPC B. You need a separate peering connection between A and C. If you have many VPCs, AWS Transit Gateway can provide a centralized way to connect them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you know how to configure inter-Region VPC peering. The peering connection provides the path between the VPCs, but you still need the correct route table entries and security group rules on both sides.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>EC2 in Real Life: A Simple Blog Note for Beginners</title>
      <dc:creator>Rajesh</dc:creator>
      <pubDate>Sun, 28 Jun 2026 17:00:33 +0000</pubDate>
      <link>https://dev.to/rajdevx/ec2-in-real-life-a-simple-blog-note-for-beginners-4edd</link>
      <guid>https://dev.to/rajdevx/ec2-in-real-life-a-simple-blog-note-for-beginners-4edd</guid>
      <description>&lt;p&gt;I wrote this like I would explain to a junior in a lab session. No heavy words, no theory overload. Just what matters when you actually create and use an EC2 machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small intro
&lt;/h2&gt;

&lt;p&gt;When we say "EC2," think of one thing: a computer on rent. You do not buy hardware. You open AWS, pick a machine size, and start using it.&lt;/p&gt;

&lt;p&gt;That is why most people start cloud learning with EC2.&lt;/p&gt;




&lt;h2&gt;
  
  
  1) What is EC2?
&lt;/h2&gt;

&lt;p&gt;EC2 stands for Elastic Compute Cloud.&lt;/p&gt;

&lt;p&gt;Simple meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is a virtual server in AWS.&lt;/li&gt;
&lt;li&gt;You can install software in it like your own laptop.&lt;/li&gt;
&lt;li&gt;You can run website, backend API, database, scripts, anything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why "Elastic"?&lt;br&gt;
Because you can scale up or down based on traffic.&lt;/p&gt;

&lt;p&gt;If today only 10 users come, small server is enough.&lt;br&gt;
If tomorrow 10,000 users come, you can move to bigger machine or add more machines.&lt;/p&gt;


&lt;h2&gt;
  
  
  2) EC2 pricing model (the part everyone asks first)
&lt;/h2&gt;

&lt;p&gt;AWS gives multiple payment options. Choose based on your situation.&lt;/p&gt;
&lt;h3&gt;
  
  
  On-Demand
&lt;/h3&gt;

&lt;p&gt;Use and pay. No long commitment.&lt;br&gt;
Best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;li&gt;Testing new features&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Reserved Instances
&lt;/h3&gt;

&lt;p&gt;You commit for long term (usually 1 or 3 years).&lt;br&gt;
Cost is lower than on-demand.&lt;br&gt;
Best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stable production apps&lt;/li&gt;
&lt;li&gt;Predictable workloads&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Spot Instances
&lt;/h3&gt;

&lt;p&gt;Very cheap (sometimes huge discount), but AWS can reclaim it.&lt;br&gt;
Best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Batch jobs&lt;/li&gt;
&lt;li&gt;Video processing&lt;/li&gt;
&lt;li&gt;Non-critical tasks
Not best for always-on production.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Savings Plans
&lt;/h3&gt;

&lt;p&gt;You commit to a certain usage/spend level over time.&lt;br&gt;
Good discount and some flexibility.&lt;/p&gt;

&lt;p&gt;Quick student rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New to AWS -&amp;gt; start On-Demand.&lt;/li&gt;
&lt;li&gt;Predictable long-term app -&amp;gt; compare Reserved/Savings.&lt;/li&gt;
&lt;li&gt;Cost-first experiments -&amp;gt; try Spot.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3) Instance families (machine categories)
&lt;/h2&gt;

&lt;p&gt;All EC2 machines are not same. AWS groups them by purpose.&lt;/p&gt;
&lt;h3&gt;
  
  
  General purpose
&lt;/h3&gt;

&lt;p&gt;Balanced CPU + RAM.&lt;br&gt;
Example family: T series, M series.&lt;br&gt;
Good for normal web apps and learning.&lt;/p&gt;
&lt;h3&gt;
  
  
  Compute optimized
&lt;/h3&gt;

&lt;p&gt;More CPU power.&lt;br&gt;
Example family: C series.&lt;br&gt;
Good for CPU-heavy tasks like rendering, transforms, game servers.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory optimized
&lt;/h3&gt;

&lt;p&gt;More RAM.&lt;br&gt;
Example family: R series.&lt;br&gt;
Good for cache/database memory-heavy apps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Storage optimized
&lt;/h3&gt;

&lt;p&gt;Fast/high-throughput disk access.&lt;br&gt;
Example family: I series.&lt;br&gt;
Good for data-intensive workloads.&lt;/p&gt;

&lt;p&gt;A common beginner pick is &lt;code&gt;t3.micro&lt;/code&gt; or &lt;code&gt;t2.micro&lt;/code&gt; style instance (based on region/free-tier rules).&lt;/p&gt;


&lt;h2&gt;
  
  
  4) What is AMI image?
&lt;/h2&gt;

&lt;p&gt;AMI means Amazon Machine Image.&lt;/p&gt;

&lt;p&gt;AMI is like a prebuilt template used to launch an EC2 instance.&lt;br&gt;
It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OS (Ubuntu, Amazon Linux, Windows, etc.)&lt;/li&gt;
&lt;li&gt;Base config&lt;/li&gt;
&lt;li&gt;Sometimes preinstalled tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two common types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public AMI: provided by AWS or marketplace/community&lt;/li&gt;
&lt;li&gt;Private AMI: custom image prepared by your org/team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Easy memory trick: AMI is the "starter pack" for your EC2 machine.&lt;/p&gt;


&lt;h2&gt;
  
  
  5) SSH, public key, private key (important)
&lt;/h2&gt;

&lt;p&gt;When you connect to Linux EC2, usually you use SSH.&lt;/p&gt;

&lt;p&gt;You create/use a key pair:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public key -&amp;gt; placed on server side&lt;/li&gt;
&lt;li&gt;Private key (&lt;code&gt;.pem&lt;/code&gt;) -&amp;gt; stays only with you&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never share private key. Ever.&lt;br&gt;
If private key leaks, server access risk is high.&lt;/p&gt;

&lt;p&gt;Basic command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; mykey.pem ubuntu@&amp;lt;EC2_PUBLIC_IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common usernames:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu AMI -&amp;gt; &lt;code&gt;ubuntu&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Amazon Linux -&amp;gt; &lt;code&gt;ec2-user&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If permission issue comes for key file, set strict permission:&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;chmod &lt;/span&gt;400 mykey.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6) Install Nginx and host first static file in /var/www/html
&lt;/h2&gt;

&lt;p&gt;Assume Ubuntu EC2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install and start Nginx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Put first static page
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;My first EC2 static page&amp;lt;/h1&amp;gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;EC2_PUBLIC_IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If port 80 is open in Security Group, page will load.&lt;/p&gt;




&lt;h2&gt;
  
  
  7) Flask Hello World host on port 8080 + Security Group
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install Python + Flask
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; python3 python3-pip
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create app.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World from Flask running on EC2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Group for port 8080
&lt;/h3&gt;

&lt;p&gt;In AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EC2 -&amp;gt; Instances -&amp;gt; select your instance&lt;/li&gt;
&lt;li&gt;Security -&amp;gt; click Security Group&lt;/li&gt;
&lt;li&gt;Inbound rules -&amp;gt; Edit inbound rules&lt;/li&gt;
&lt;li&gt;Add rule:

&lt;ul&gt;
&lt;li&gt;Type: Custom TCP&lt;/li&gt;
&lt;li&gt;Port: 8080&lt;/li&gt;
&lt;li&gt;Source: 0.0.0.0/0 (only for demo/testing)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now test in browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;EC2_PUBLIC_IP&amp;gt;:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your hello message.&lt;/p&gt;

&lt;p&gt;Production note:&lt;br&gt;
Do not keep wide-open rules forever. Restrict CIDR, use reverse proxy, and enable HTTPS.&lt;/p&gt;




&lt;h2&gt;
  
  
  One-page final summary
&lt;/h2&gt;

&lt;p&gt;EC2 is a cloud server you can rent in minutes.&lt;br&gt;
You choose pricing model based on your budget and stability needs.&lt;br&gt;
Instance families help you pick the right machine for CPU, memory, or storage focus.&lt;br&gt;
AMI is the base image used to launch the instance.&lt;br&gt;
SSH key pair is how you securely log in.&lt;br&gt;
Nginx helps you host static pages from &lt;code&gt;/var/www/html&lt;/code&gt;.&lt;br&gt;
Flask can run on port 8080, and you must allow that port in Security Group.&lt;/p&gt;

&lt;p&gt;If you can do these steps once by yourself, you already have strong EC2 fundamentals.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
