<?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: Rajeev</title>
    <description>The latest articles on DEV Community by Rajeev (@elonerajeev1).</description>
    <link>https://dev.to/elonerajeev1</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%2F2193964%2F11c3a6bc-8289-4da0-b0d2-12200216676b.png</url>
      <title>DEV Community: Rajeev</title>
      <link>https://dev.to/elonerajeev1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elonerajeev1"/>
    <language>en</language>
    <item>
      <title>How We Cut AWS Staging Costs by 87% With EventBridge Scheduler (Zero Code Changes)</title>
      <dc:creator>Rajeev</dc:creator>
      <pubDate>Mon, 24 Aug 2026 15:17:47 +0000</pubDate>
      <link>https://dev.to/elonerajeev1/how-we-cut-aws-staging-costs-by-87-with-eventbridge-scheduler-zero-code-changes-2k3c</link>
      <guid>https://dev.to/elonerajeev1/how-we-cut-aws-staging-costs-by-87-with-eventbridge-scheduler-zero-code-changes-2k3c</guid>
      <description>&lt;h1&gt;
  
  
  How We Cut AWS Staging Costs by 87% With EventBridge Scheduler
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;No code changes. No Lambda functions. No complex scripts. Just 4 schedulers and a realization that nobody uses staging at 3am.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Here's a question every engineering team should ask themselves:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"When was the last time someone actually used our staging environment at 2am?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For us? Never. Not once.&lt;/p&gt;

&lt;p&gt;Yet we were paying for it — EC2 running, ECS Fargate tasks spinning, compute burning money — every single hour of every single day, including weekends, holidays, and the 21 hours per day when nobody on our team was even awake.&lt;/p&gt;

&lt;p&gt;That's the hidden tax of staging environments. And most teams never fix it because the solution feels complicated.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;This is how we cut our staging compute costs by &lt;strong&gt;87.5%&lt;/strong&gt; — using AWS EventBridge Scheduler, zero Lambda functions, and zero lines of application code.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Staging Was Running 24/7 For No Reason
&lt;/h2&gt;

&lt;p&gt;Our staging environment had two resources running around the clock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EC2 instance&lt;/strong&gt; — our staging app server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS Fargate service&lt;/strong&gt; — our backend API container&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our team actively uses staging for roughly &lt;strong&gt;3 hours a day&lt;/strong&gt;. That's it.&lt;/p&gt;

&lt;p&gt;The math was embarrassing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Running:    24 hours/day
Used:        3 hours/day
Wasted:     21 hours/day = 87.5% of compute going nowhere
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monthly cost breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 + ECS Fargate (24x7):   ~$19.18/month
EC2 + ECS Fargate (3hr/day): ~$2.40/month

Monthly saving:  $16.78
Yearly saving:   $201.35
Reduction:       87.5%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;$201/year saved on staging compute alone&lt;/strong&gt; — with 45 minutes of setup and zero application code changes.&lt;/p&gt;

&lt;p&gt;Multiply that across dev environments, QA clusters, review apps, and load test environments. The savings compound fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: AWS EventBridge Scheduler
&lt;/h2&gt;

&lt;p&gt;Most engineers reach for Lambda when they need to automate AWS tasks on a schedule. That works — but it means writing code, managing runtimes, setting up CloudWatch Logs, and maintaining a function forever.&lt;/p&gt;

&lt;p&gt;EventBridge Scheduler is the better tool here. It lets you &lt;strong&gt;call any AWS SDK action directly on a cron schedule&lt;/strong&gt; — no Lambda, no code, no runtime to maintain.&lt;/p&gt;

&lt;p&gt;The mental model is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WHEN  →  cron expression (with native timezone support)
WHAT  →  any AWS API call (StartInstances, UpdateService, StopDBInstance...)
WHO   →  a dedicated IAM role with just enough permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire service. And it's free for the first 14 million invocations per month.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We Built: 4 Schedulers
&lt;/h2&gt;

&lt;p&gt;We created 4 EventBridge Schedulers targeting our staging resources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scheduler&lt;/th&gt;
&lt;th&gt;Fires At&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staging-ec2-start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9:00 PM IST daily&lt;/td&gt;
&lt;td&gt;Start staging EC2 instance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staging-ec2-stop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;12:00 AM IST daily&lt;/td&gt;
&lt;td&gt;Stop staging EC2 instance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staging-ecs-scale-up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9:00 PM IST daily&lt;/td&gt;
&lt;td&gt;ECS service desiredCount to 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staging-ecs-scale-down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;12:00 AM IST daily&lt;/td&gt;
&lt;td&gt;ECS service desiredCount to 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result:&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;Timeline (IST):
─────────────────────────────────────────────────────
12:00 AM  |████████████ OFF (21 hrs) ████████████| 9:00 PM
                                                  │
                                               9:00 PM
                                          ┌──────────────┐
                                          │ EC2 starts   │
                                          │ ECS → 1 task │
                                          └──────┬───────┘
                                                 │
                                          ┌──────▼───────┐
                                          │  RUNNING     │
                                          │  (3 hours)   │
                                          └──────┬───────┘
                                                 │
                                           12:00 AM
                                          ┌──────────────┐
                                          │ EC2 stops    │
                                          │ ECS → 0 tasks│
                                          └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Staging wakes up exactly when the team needs it. Goes dark at midnight. Every day. Automatically.&lt;/p&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS EventBridge Scheduler
│
├── staging-ec2-start    ──► 9 PM IST  ──► ec2:StartInstances
├── staging-ec2-stop     ──► 12 AM IST ──► ec2:StopInstances
├── staging-ecs-scale-up ──► 9 PM IST  ──► ecs:UpdateService (count=1)
└── staging-ecs-scale-down──► 12 AM IST ──► ecs:UpdateService (count=0)
         │
         └── All using: staging-scheduler-role (least privilege IAM)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One dedicated IAM role. Four schedulers. Zero Lambda functions.&lt;/p&gt;




&lt;h2&gt;
  
  
  EventBridge Scheduler vs Lambda + Cron
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Lambda + EventBridge Rule&lt;/th&gt;
&lt;th&gt;EventBridge Scheduler&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Code to write&lt;/td&gt;
&lt;td&gt;~30 lines per action&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Zero&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime maintenance&lt;/td&gt;
&lt;td&gt;Lambda versions, updates&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;None&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timezone handling&lt;/td&gt;
&lt;td&gt;Manual UTC math&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Built-in&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry on failure&lt;/td&gt;
&lt;td&gt;Manual implementation&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Built-in&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup time&lt;/td&gt;
&lt;td&gt;20-30 mins per action&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 mins per action&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;td&gt;CloudWatch Logs setup&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Native console&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For simple time-based AWS automation, EventBridge Scheduler removes an entire layer of complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Things to Know Before You Implement
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The IAM role is the foundation — and where most people get stuck.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EventBridge Scheduler needs a role with the correct trust principal. There's a very common mistake here — getting this one thing wrong means your schedulers silently do nothing. Scope the role permissions to specific resource ARNs only. A staging scheduler role should be physically incapable of touching production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cron expressions use UTC by default.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set the timezone parameter to your team's actual timezone. Forgetting this means your staging shuts down at the wrong time and your team spends 20 minutes debugging before realizing it's a UTC offset issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;desiredCount: 0&lt;/code&gt; is not the same as deleting the ECS service.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Setting desired count to zero stops all running tasks but preserves the full service definition, task definition, and all configuration. Scale back up to 1 and everything restarts exactly as before — same image, same env vars, same everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stopInstances&lt;/code&gt; is not &lt;code&gt;terminateInstances&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stopping preserves the EBS volume and all data. Terminating destroys it permanently. Our schedulers stop — never terminate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account for application warm-up time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EC2 boot + ECS task startup + application initialization can take 3-5 minutes total. Schedule your start 10-15 minutes before your team actually needs it. We start at 8:45 PM for a 9 PM working session.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Else Can You Schedule?
&lt;/h2&gt;

&lt;p&gt;Once you understand this pattern, every always-on non-production resource is a candidate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RDS instances&lt;/strong&gt; — stop during nights, save $15-50/month per instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DocumentDB clusters&lt;/strong&gt; — same pattern, significant savings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto Scaling Groups&lt;/strong&gt; — scale to minimum overnight&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Additional ECS services&lt;/strong&gt; — any non-prod service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElastiCache&lt;/strong&gt; — stop non-prod caches at night&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every resource running at 3am that nobody needs is costing you money right now.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEFORE:  $19.18/month  (24x7 always on)
AFTER:    $2.40/month  (3hrs/day scheduled)

Saving:  $16.78/month
         $201.35/year
         87.5% reduction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero code changes. Zero Lambda functions. Zero new infrastructure.&lt;/p&gt;

&lt;p&gt;Four schedulers calling two AWS APIs on a cron. That's it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Analyze your actual usage before setting the schedule.&lt;/strong&gt;&lt;br&gt;
We assumed our team used staging 9 AM to 6 PM. The access logs showed 9 PM to midnight. Data beats assumptions every single time. Check your logs first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. EventBridge Scheduler and EventBridge Rules are completely different services.&lt;/strong&gt;&lt;br&gt;
Scheduler is time-driven. Rules are event-driven. The IAM trust principal, console location, and configuration format are all different. If you Google EventBridge automation and follow a tutorial, make sure it's for Scheduler — not Rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Separate schedulers per resource type.&lt;/strong&gt;&lt;br&gt;
EC2 and ECS need different API targets. Keep them as separate schedulers — cleaner, easier to debug, independently adjustable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Weekend-only shutdown pushes savings higher.&lt;/strong&gt;&lt;br&gt;
If your team doesn't use staging on weekends, a single cron parameter change takes savings from 87.5% to ~94%. Worth knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Always have a manual override plan.&lt;/strong&gt;&lt;br&gt;
Sometimes you need staging at 2am — production incident, urgent hotfix, client demo. Know how to start resources manually in 30 seconds without waiting for the next scheduled start.&lt;/p&gt;




&lt;h2&gt;
  
  
  Non-Production Cost Checklist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Today:
☐ Identify all always-on non-production EC2 instances
☐ Identify all always-on non-production ECS services
☐ Calculate actual usage hours vs paid running hours

This week:
☐ Set up EventBridge Schedulers for staging resources
☐ Stop non-prod RDS during off-hours
☐ Remove unused Elastic IPs (charged even when unattached)

Next sprint:
☐ Right-size non-prod instances based on actual usage
☐ Audit unused snapshots, AMIs, old EBS volumes
☐ Check for idle NAT Gateways (~$32/month each, easy to forget)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;This isn't really about the $201.&lt;/p&gt;

&lt;p&gt;It's about the &lt;strong&gt;habit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every always-on non-production resource is a signal that your team treats cloud infrastructure like physical servers — provision once, leave forever. That habit is slightly expensive at small scale. At growth scale, it becomes a serious line item that nobody owns.&lt;/p&gt;

&lt;p&gt;EventBridge Scheduler is the simplest tool to break that habit. Set it up once, forget it, and let AWS enforce the discipline automatically every single night.&lt;/p&gt;

&lt;p&gt;Applied across all your non-production environments, teams typically see &lt;strong&gt;40-70% reduction&lt;/strong&gt; in total non-production AWS spend.&lt;/p&gt;

&lt;p&gt;The cost of doing this: 45 minutes.&lt;br&gt;
The cost of not doing this: compounding waste, every month, forever.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Implementing something similar or have a different approach? Drop it in the comments — I read everything.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this saved you money, share it with someone still paying for an always-on staging environment.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;#AWS&lt;/code&gt; &lt;code&gt;#DevOps&lt;/code&gt; &lt;code&gt;#CloudCost&lt;/code&gt; &lt;code&gt;#ECS&lt;/code&gt; &lt;code&gt;#EventBridge&lt;/code&gt; &lt;code&gt;#CostOptimization&lt;/code&gt; &lt;code&gt;#Fargate&lt;/code&gt; &lt;code&gt;#EC2&lt;/code&gt; &lt;code&gt;#FinOps&lt;/code&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>costreduction</category>
    </item>
    <item>
      <title>We Ditched MongoDB Atlas for AWS DocumentDB — Here's Exactly How We Did It</title>
      <dc:creator>Rajeev</dc:creator>
      <pubDate>Mon, 10 Aug 2026 15:02:24 +0000</pubDate>
      <link>https://dev.to/elonerajeev1/we-ditched-mongodb-atlas-for-aws-documentdb-heres-exactly-how-we-did-it-with-real-commands-3aak</link>
      <guid>https://dev.to/elonerajeev1/we-ditched-mongodb-atlas-for-aws-documentdb-heres-exactly-how-we-did-it-with-real-commands-3aak</guid>
      <description>&lt;h1&gt;
  
  
  We Ditched MongoDB Atlas for AWS DocumentDB — Here's Exactly How We Did It
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;One connection string change. Zero downtime. One very long night. Here's the full story.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I want to tell you something most engineering blogs won't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrations are messy.&lt;/strong&gt; They go sideways at 11pm. They reveal assumptions you didn't know you had. And the "5-minute fix" always takes 3 hours.&lt;/p&gt;

&lt;p&gt;This is the real story of how we migrated our production MongoDB database from Atlas to AWS DocumentDB — every command, every mistake, every fix, and every lesson learned the hard way.&lt;/p&gt;

&lt;p&gt;If you're planning a similar migration, read this before you start. It will save you hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why We Even Did This
&lt;/h2&gt;

&lt;p&gt;Our stack was already 100% on AWS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ECS Fargate&lt;/strong&gt; running our Node.js backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2&lt;/strong&gt; for our app server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDS PostgreSQL&lt;/strong&gt; for relational data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3&lt;/strong&gt; for file storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALB&lt;/strong&gt; for load balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then there was &lt;strong&gt;MongoDB Atlas&lt;/strong&gt; — sitting outside AWS, on MongoDB's cloud, billed separately, with data crossing the public internet every single request.&lt;/p&gt;

&lt;p&gt;The CTO asked a simple question: &lt;em&gt;"Why are we paying Atlas when we're already on AWS?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That question started this migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goals were clear:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consolidate to one cloud provider&lt;/li&gt;
&lt;li&gt;Cut cross-cloud data transfer costs&lt;/li&gt;
&lt;li&gt;Put the database inside our VPC (zero public internet exposure)&lt;/li&gt;
&lt;li&gt;One bill, one security boundary, one team managing everything&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What We Were Working With
&lt;/h2&gt;

&lt;p&gt;Before writing a single command, we mapped the full picture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source — MongoDB Atlas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~32 collections&lt;/li&gt;
&lt;li&gt;~2,400 documents (and growing daily)&lt;/li&gt;
&lt;li&gt;Used by 2 ECS services (prod + staging) and an EC2 backend&lt;/li&gt;
&lt;li&gt;Publicly accessible via &lt;code&gt;mongodb+srv://&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Target — Amazon DocumentDB:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB 5.0 compatible&lt;/li&gt;
&lt;li&gt;Lives inside a &lt;strong&gt;private VPC&lt;/strong&gt; (no public endpoint — this matters, a lot)&lt;/li&gt;
&lt;li&gt;Managed by AWS (auto backups, failover, CloudWatch)&lt;/li&gt;
&lt;li&gt;Tight integration with IAM, VPC Security Groups, KMS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The architecture we were building toward:&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;┌──────────────────────────────────────────────────┐
│                  AWS VPC (private)               │
│                                                  │
│  ┌─────────────────┐      ┌──────────────────┐  │
│  │  ECS Fargate    │      │  EC2 App Server  │  │
│  │  prod + staging │      │  Public IP       │  │
│  └────────┬────────┘      └────────┬─────────┘  │
│           │                        │             │
│           └──────────┬─────────────┘             │
│                      │ private network            │
│           ┌──────────▼──────────┐               │
│           │   Amazon DocumentDB  │               │
│           │   port 27017        │               │
│           │   encrypted at rest │               │
│           └─────────────────────┘               │
└──────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Secure. Everything private. No data crossing the public internet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Migration Strategy
&lt;/h2&gt;

&lt;p&gt;We had three options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Downtime&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS DMS (live CDC)&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Large DBs, can't afford downtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mongodump + mongorestore&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Minutes&lt;/td&gt;
&lt;td&gt;Small-medium DBs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom change streams script&lt;/td&gt;
&lt;td&gt;Very High&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Custom transformations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We chose &lt;strong&gt;mongodump + mongorestore&lt;/strong&gt;. Here's why:&lt;/p&gt;

&lt;p&gt;Our database was under 1GB. Our staging environment would absorb the testing. And &lt;code&gt;mongodump/mongorestore&lt;/code&gt; is the most battle-tested MongoDB migration tool in existence — boring is good when it comes to production data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 1: Infrastructure Setup (The Foundation)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 — DocumentDB Subnet Group
&lt;/h3&gt;

&lt;p&gt;DocumentDB needs subnets across &lt;strong&gt;at least 2 availability zones&lt;/strong&gt; for redundancy. We used our existing private subnets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws docdb create-db-subnet-group &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-subnet-group-name&lt;/span&gt; myapp-docdb-subnet-group &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-subnet-group-description&lt;/span&gt; &lt;span class="s2"&gt;"Subnet group for DocumentDB"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--subnet-ids&lt;/span&gt; subnet-xxxxxxxx subnet-yyyyyyyy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-south-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Security Group (Port 27017, VPC Only)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Never open 27017 to the internet.&lt;/strong&gt; VPC CIDR only:&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;# Create security group&lt;/span&gt;
aws ec2 create-security-group &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-name&lt;/span&gt; myapp-docdb-sg &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"DocumentDB security group"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vpc-id&lt;/span&gt; vpc-xxxxxxxxxx

&lt;span class="c"&gt;# Allow port 27017 from VPC only&lt;/span&gt;
aws ec2 authorize-security-group-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-id&lt;/span&gt; sg-xxxxxxxxxx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--protocol&lt;/span&gt; tcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 27017 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cidr&lt;/span&gt; 10.0.0.0/16

&lt;span class="c"&gt;# Also allow from your ECS security group&lt;/span&gt;
aws ec2 authorize-security-group-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-id&lt;/span&gt; sg-xxxxxxxxxx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--protocol&lt;/span&gt; tcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 27017 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--source-group&lt;/span&gt; sg-your-ecs-sg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Create the Cluster + Instance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create cluster (encrypted at rest by default)&lt;/span&gt;
aws docdb create-db-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-cluster-identifier&lt;/span&gt; myapp-docdb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--engine&lt;/span&gt; docdb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--master-username&lt;/span&gt; admin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--master-user-password&lt;/span&gt; &lt;span class="s2"&gt;"YourStrongPassword123!"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-subnet-group-name&lt;/span&gt; myapp-docdb-subnet-group &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vpc-security-group-ids&lt;/span&gt; sg-xxxxxxxxxx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--storage-encrypted&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-south-1

&lt;span class="c"&gt;# Add an instance to the cluster&lt;/span&gt;
aws docdb create-db-instance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-instance-identifier&lt;/span&gt; myapp-docdb-instance-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-cluster-identifier&lt;/span&gt; myapp-docdb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-instance-class&lt;/span&gt; db.t3.medium &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--engine&lt;/span&gt; docdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⏱️ &lt;strong&gt;Wait 8-10 minutes&lt;/strong&gt; for the cluster to become available. Grab a coffee.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 2: The Migration — Where It Gets Interesting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem Nobody Warns You About
&lt;/h3&gt;

&lt;p&gt;Here's what I wish someone had told me before I started:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DocumentDB has no public endpoint.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It lives inside your VPC. Period. You cannot run &lt;code&gt;mongorestore&lt;/code&gt; from your laptop to DocumentDB. You need a machine inside the VPC to act as a bridge.&lt;/p&gt;

&lt;p&gt;The architecture looks 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;Your Laptop
    │
    │ 1. mongodump ──► reads Atlas
    ▼
/tmp/dump/ (BSON files on your machine)
    │
    │ 2. scp ──► copies files to EC2
    ▼
EC2 Instance (inside VPC) ◄── this is your bridge
    │
    │ 3. mongorestore ──► writes to DocumentDB
    ▼
Amazon DocumentDB (private, inside VPC) ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used our existing EC2 app server as the bridge. No new infrastructure needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Dump Everything from Atlas
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Full database dump&lt;/span&gt;
mongodump &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mongodb+srv://user:password@cluster.mongodb.net/mydb"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/myapp_backup

&lt;span class="c"&gt;# Verify the dump&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; /tmp/myapp_backup/mydb/
&lt;span class="c"&gt;# You should see .bson + .metadata.json for every collection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Transfer to EC2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Copy all dump files to EC2&lt;/span&gt;
scp &lt;span class="nt"&gt;-i&lt;/span&gt; your-keypair.pem &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /tmp/myapp_backup/ &lt;span class="se"&gt;\&lt;/span&gt;
  ubuntu@&amp;lt;ec2-public-ip&amp;gt;:/tmp/myapp_backup/

&lt;span class="c"&gt;# Verify files arrived&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; your-keypair.pem ubuntu@&amp;lt;ec2-ip&amp;gt; &lt;span class="s2"&gt;"ls /tmp/myapp_backup/mydb/ | wc -l"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6 — Download TLS Certificate on EC2
&lt;/h3&gt;

&lt;p&gt;DocumentDB requires TLS. The cert needs to be on the machine running &lt;code&gt;mongorestore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="c"&gt;# Inside EC2:&lt;/span&gt;
wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7 — Restore to DocumentDB
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run this inside EC2&lt;/span&gt;
mongorestore &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mongodb://admin:password@myapp-docdb.cluster-xxxxx.region.docdb.amazonaws.com:27017/mydb?tls=true&amp;amp;tlsCAFile=global-bundle.pem&amp;amp;replicaSet=rs0&amp;amp;retryWrites=false"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mydb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/myapp_backup/mydb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--drop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--drop&lt;/code&gt; flag is crucial — it drops each collection before restoring. This makes the command &lt;strong&gt;idempotent&lt;/strong&gt; (safe to re-run if something goes wrong).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8 — Verify Every Collection Count
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Never skip this step.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Atlas counts&lt;/span&gt;
mongosh &lt;span class="s2"&gt;"atlas-connection-string"&lt;/span&gt; &lt;span class="nt"&gt;--quiet&lt;/span&gt; &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"db.getCollectionNames().forEach(c =&amp;gt; print(db[c].countDocuments() + '&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;' + c))"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;

&lt;span class="c"&gt;# Check DocumentDB counts (from EC2)&lt;/span&gt;
mongosh &lt;span class="s2"&gt;"docdb-connection-string"&lt;/span&gt; &lt;span class="nt"&gt;--quiet&lt;/span&gt; &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"db.getCollectionNames().forEach(c =&amp;gt; print(db[c].countDocuments() + '&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;' + c))"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every single number must match. If one doesn't — fix it before moving on.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 3: The Connection String — The Devil Is In The Details
&lt;/h2&gt;

&lt;p&gt;This is where most migrations break silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atlas string:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongodb+srv://user:pass@cluster.mongodb.net/mydb?retryWrites&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;w&lt;span class="o"&gt;=&lt;/span&gt;majority
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DocumentDB string:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongodb://user:pass@myapp-docdb.cluster-xxxxx.docdb.amazonaws.com:27017/mydb?tls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;tlsAllowInvalidCertificates&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;replicaSet&lt;span class="o"&gt;=&lt;/span&gt;rs0&amp;amp;retryWrites&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&amp;amp;authMechanism&lt;span class="o"&gt;=&lt;/span&gt;SCRAM-SHA-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical differences:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Atlas&lt;/th&gt;
&lt;th&gt;DocumentDB&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mongodb+srv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mongodb://&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SRV not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;retryWrites&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;false&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DocumentDB doesn't support it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;replicaSet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;not needed&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;rs0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Required for DocumentDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port&lt;/td&gt;
&lt;td&gt;auto (SRV)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;27017&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Must be explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TLS cert&lt;/td&gt;
&lt;td&gt;automatic&lt;/td&gt;
&lt;td&gt;manual&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;global-bundle.pem&lt;/code&gt; needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Miss any of these and your app either crashes silently or throws cryptic errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 4: Application Switchover
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Always Staging First. Always.
&lt;/h3&gt;

&lt;p&gt;We updated the ECS task definition environment variable:&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;# Register new task definition revision with updated MONGODB_URI&lt;/span&gt;
aws ecs register-task-definition &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--family&lt;/span&gt; myapp-backend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--container-definitions&lt;/span&gt; &lt;span class="s1"&gt;'[{
    "name": "backend",
    "environment": [
      {
        "name": "MONGODB_URI",
        "value": "mongodb://user:pass@docdb-endpoint:27017/mydb?tls=true&amp;amp;tlsAllowInvalidCertificates=true&amp;amp;replicaSet=rs0&amp;amp;retryWrites=false&amp;amp;authMechanism=SCRAM-SHA-1&amp;amp;maxPoolSize=10&amp;amp;minPoolSize=2&amp;amp;connectTimeoutMS=5000&amp;amp;socketTimeoutMS=30000&amp;amp;serverSelectionTimeoutMS=5000"
      }
    ]
  }]'&lt;/span&gt;

&lt;span class="c"&gt;# Deploy to staging ONLY first&lt;/span&gt;
aws ecs update-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cluster&lt;/span&gt; myapp-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--service&lt;/span&gt; myapp-staging &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--task-definition&lt;/span&gt; myapp-backend:NEW_REVISION &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--force-new-deployment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch the logs until you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚀 Server running on port 5000
MongoDB connected successfully ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Phase 5: The 504 Nightmare
&lt;/h2&gt;

&lt;p&gt;After switching staging to DocumentDB — &lt;strong&gt;login started taking 3-5 seconds.&lt;/strong&gt; Users were getting 504 Gateway Timeout errors.&lt;/p&gt;

&lt;p&gt;This one hurt.&lt;/p&gt;

&lt;p&gt;The root cause: &lt;strong&gt;DocumentDB connection latency is higher than Atlas.&lt;/strong&gt; Without connection pool configuration, every request was creating a new DB connection from scratch. Cold connections on DocumentDB take 3-5 seconds.&lt;/p&gt;

&lt;p&gt;The fix was adding connection pool parameters to the URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;maxPoolSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;minPoolSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;connectTimeoutMS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5000&lt;/span&gt;
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;socketTimeoutMS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;30000&lt;/span&gt;
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;serverSelectionTimeoutMS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5000&lt;/span&gt;
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="py"&gt;heartbeatFrequencyMS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full optimized string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongodb://user:pass@docdb-endpoint:27017/mydb?tls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;tlsAllowInvalidCertificates&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;replicaSet&lt;span class="o"&gt;=&lt;/span&gt;rs0&amp;amp;retryWrites&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&amp;amp;authMechanism&lt;span class="o"&gt;=&lt;/span&gt;SCRAM-SHA-1&amp;amp;maxPoolSize&lt;span class="o"&gt;=&lt;/span&gt;10&amp;amp;minPoolSize&lt;span class="o"&gt;=&lt;/span&gt;2&amp;amp;connectTimeoutMS&lt;span class="o"&gt;=&lt;/span&gt;5000&amp;amp;socketTimeoutMS&lt;span class="o"&gt;=&lt;/span&gt;30000&amp;amp;serverSelectionTimeoutMS&lt;span class="o"&gt;=&lt;/span&gt;5000&amp;amp;heartbeatFrequencyMS&lt;span class="o"&gt;=&lt;/span&gt;10000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: Login went from 3-5 seconds → under 500ms.&lt;/strong&gt; ✅&lt;/p&gt;

&lt;p&gt;&lt;code&gt;minPoolSize=2&lt;/code&gt; is the key — it keeps 2 warm connections alive at all times, so the first request never has to wait for a cold connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 6: The Re-sync Problem
&lt;/h2&gt;

&lt;p&gt;We migrated on Day 1. We deployed to staging on Day 3. We did a final check on Day 16.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atlas had 157 new documents that DocumentDB didn't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is normal and expected. Any live database will accumulate new data between your migration and your cutover date. The fix is a re-sync run right before prod switchover:&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;# Step 1: Fresh dump from Atlas&lt;/span&gt;
mongodump &lt;span class="nt"&gt;--uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"atlas-uri"&lt;/span&gt; &lt;span class="nt"&gt;--out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/resync

&lt;span class="c"&gt;# Step 2: Transfer to EC2&lt;/span&gt;
scp &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/resync/ ubuntu@ec2-ip:/tmp/

&lt;span class="c"&gt;# Step 3: Restore with --drop (fully safe, idempotent)&lt;/span&gt;
mongorestore &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"docdb-uri"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/resync/mydb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--drop&lt;/span&gt;

&lt;span class="c"&gt;# Step 4: Verify counts again&lt;/span&gt;
&lt;span class="c"&gt;# Atlas count == DocumentDB count? ✅ Good to go.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this re-sync as close to prod cutover as possible — ideally within hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Different in DocumentDB vs Atlas
&lt;/h2&gt;

&lt;p&gt;Before you migrate — test these in your app:&lt;/p&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;Atlas&lt;/th&gt;
&lt;th&gt;DocumentDB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic CRUD&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mongoose ODM&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;$lookup&lt;/code&gt; aggregation&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transactions&lt;/td&gt;
&lt;td&gt;✅ Full ACID&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change streams&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atlas Search&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;retryWrites=true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ Must be false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text search&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;If your app uses basic Mongoose CRUD — you're fine.&lt;/strong&gt; If you rely heavily on complex aggregations, transactions, or Atlas Search — test everything on staging before touching prod.&lt;/p&gt;




&lt;h2&gt;
  
  
  Developer Access After Migration
&lt;/h2&gt;

&lt;p&gt;This confused our dev team at first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atlas:&lt;/strong&gt; Anyone with the connection string can connect from anywhere.&lt;br&gt;
&lt;strong&gt;DocumentDB:&lt;/strong&gt; Private VPC. Can't connect from outside without a tunnel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dev Laptop ──► SSH Tunnel ──► EC2 ──► DocumentDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSH tunnel command:&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;# Keep this running in a terminal&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; your-keypair.pem &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-L&lt;/span&gt; 27017:docdb-endpoint:27017 &lt;span class="se"&gt;\&lt;/span&gt;
  ubuntu@ec2-public-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then connect to &lt;code&gt;127.0.0.1:27017&lt;/code&gt; from your app or MongoDB Compass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our recommendation:&lt;/strong&gt; Keep Atlas for local development. Use DocumentDB for prod/staging only. Zero friction, cleanest separation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rollback Plan (Non-Negotiable)
&lt;/h2&gt;

&lt;p&gt;Before every prod migration, write your rollback plan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If DocumentDB fails:
1. Update ECS task def → revert MONGODB_URI to Atlas string
2. aws ecs update-service --force-new-deployment
3. Back on Atlas in under 5 minutes

Rule: Never delete Atlas until DocumentDB runs in prod for 30+ days.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;We kept Atlas running as a safety net the entire time.&lt;/strong&gt; This is not optional.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before (Atlas)&lt;/th&gt;
&lt;th&gt;After (DocumentDB)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cross-cloud data transfer&lt;/td&gt;
&lt;td&gt;Charged per GB&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Free&lt;/strong&gt; (same VPC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public internet exposure&lt;/td&gt;
&lt;td&gt;✅ DB accessible publicly&lt;/td&gt;
&lt;td&gt;❌ DB fully private&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security surface&lt;/td&gt;
&lt;td&gt;Atlas IP whitelist&lt;/td&gt;
&lt;td&gt;AWS Security Groups + VPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Atlas UI&lt;/td&gt;
&lt;td&gt;CloudWatch + Alerts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backup&lt;/td&gt;
&lt;td&gt;Atlas managed&lt;/td&gt;
&lt;td&gt;AWS automated + S3 cron&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login response time (after pool fix)&lt;/td&gt;
&lt;td&gt;~200ms&lt;/td&gt;
&lt;td&gt;~450ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Complete Migration Checklist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFRASTRUCTURE
☐ DocumentDB subnet group (private subnets, 2+ AZs)
☐ Security group (port 27017, VPC only)
☐ Allow ECS + EC2 security groups in DocDB SG
☐ DocumentDB cluster (storage encrypted)
☐ DocumentDB instance (right size for workload)

MIGRATION
☐ mongodump full backup from Atlas
☐ Verify dump files exist for all collections
☐ scp files to EC2
☐ Download global-bundle.pem on EC2
☐ mongorestore with --drop flag
☐ Verify doc counts match on EVERY collection

APPLICATION
☐ New MONGODB_URI with all required params
☐ Add connection pool params to URI
☐ Deploy to staging first
☐ Watch logs for "MongoDB connected successfully"
☐ Test all critical API endpoints on staging
☐ Monitor for 24h on staging before touching prod
☐ Re-sync Atlas → DocumentDB right before prod cutover
☐ Deploy to prod
☐ Monitor prod logs and CloudWatch

POST-MIGRATION
☐ Set up daily mongodump → S3 backup cron
☐ Configure CloudWatch alarms (connections, CPU, latency)
☐ Keep Atlas alive for 30 days minimum
☐ Delete Atlas cluster only after team sign-off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;&lt;strong&gt;1. The bridge EC2 pattern is your best friend.&lt;/strong&gt;&lt;br&gt;
DocumentDB's private-only design is a feature. Use your existing EC2 as the migration bridge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Connection pool tuning is not optional.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;minPoolSize=2&lt;/code&gt; alone will save you from 504 nightmares. Add it from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Always staging first.&lt;/strong&gt;&lt;br&gt;
We caught the 504 issue on staging before it ever touched prod. This is why staging exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Plan for re-sync.&lt;/strong&gt;&lt;br&gt;
Your live database never stops growing. Always re-sync within hours of prod cutover, not days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Keep Atlas longer than you think you need to.&lt;/strong&gt;&lt;br&gt;
The cost of one extra month of Atlas is nothing compared to the cost of a production incident with no rollback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Your app code changes nothing.&lt;/strong&gt;&lt;br&gt;
With Mongoose, only the &lt;code&gt;MONGODB_URI&lt;/code&gt; env var changes. Zero code changes required.&lt;/p&gt;




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

&lt;p&gt;Moving from Atlas to DocumentDB is fundamentally a security and infrastructure consolidation play. Your data moves from the public internet into a private VPC. Your costs consolidate to one provider. Your team manages one less external service.&lt;/p&gt;

&lt;p&gt;The technical work is real — but it's manageable. The hardest part isn't the commands. It's the patience to test everything on staging, verify every collection count, and resist the urge to rush to prod.&lt;/p&gt;

&lt;p&gt;Do it right, and your app code never knows the difference.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have questions about your own migration? Drop them in the comments — happy to help.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this saved you time, consider sharing it with someone who's about to go through the same thing.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;#AWS&lt;/code&gt; &lt;code&gt;#MongoDB&lt;/code&gt; &lt;code&gt;#DocumentDB&lt;/code&gt; &lt;code&gt;#DevOps&lt;/code&gt; &lt;code&gt;#DatabaseMigration&lt;/code&gt; &lt;code&gt;#BackendEngineering&lt;/code&gt; &lt;code&gt;#CloudArchitecture&lt;/code&gt; &lt;code&gt;#NodeJS&lt;/code&gt; &lt;code&gt;#ECS&lt;/code&gt; &lt;code&gt;#SoftwareEngineering&lt;/code&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>mongodb</category>
      <category>devops</category>
      <category>database</category>
    </item>
    <item>
      <title>💻 AWS RDS Services: Comprehensive Guide</title>
      <dc:creator>Rajeev</dc:creator>
      <pubDate>Sun, 02 Mar 2025 05:40:43 +0000</pubDate>
      <link>https://dev.to/elonerajeev1/-aws-rds-services-comprehensive-guide-19i4</link>
      <guid>https://dev.to/elonerajeev1/-aws-rds-services-comprehensive-guide-19i4</guid>
      <description>&lt;p&gt;AWS Relational Database Service (&lt;strong&gt;RDS&lt;/strong&gt;) is a managed service for setting up, operating, and scaling relational databases in the cloud. This guide will help you understand RDS theoretically and implement it practically.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;What is AWS RDS?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AWS RDS is a &lt;strong&gt;fully managed relational database service&lt;/strong&gt; designed to simplify database management tasks like setup, scaling, patching, and backups while providing high availability and durability. It supports popular database engines such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Aurora&lt;/strong&gt; (PostgreSQL and MySQL-compatible)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MariaDB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft SQL Server&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📋 &lt;strong&gt;Key Features of RDS&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Managed Service&lt;/strong&gt;: Automates database administration tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-AZ Deployment&lt;/strong&gt;: Ensures high availability and automatic failover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Easy to scale storage and compute capacity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup and Recovery&lt;/strong&gt;: Automated backups, manual snapshots, and point-in-time recovery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Encryption at rest and in transit, IAM integration, and VPC support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: Integrated with CloudWatch for performance metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for Read Replicas&lt;/strong&gt;: Improves read performance by replicating data across multiple instances.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠️ &lt;strong&gt;Practical Guide: Getting Started with RDS&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Part 1: Create an RDS Instance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log in to AWS Console&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;RDS Dashboard&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Click on "Create Database"&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Standard Create&lt;/strong&gt; for advanced configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose Database Engine&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select an engine like &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;PostgreSQL&lt;/strong&gt;, or &lt;strong&gt;Amazon Aurora&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Specify Instance Details&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DB Instance Class&lt;/strong&gt;: Choose based on your workload (e.g., db.t2.micro for testing).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt;: Allocate storage (default: 20 GB).
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Connectivity&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC&lt;/strong&gt;: Choose a VPC or create a new one.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public Access&lt;/strong&gt;: Enable or disable based on your requirements.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;: Ensure proper inbound/outbound rules.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Additional Settings&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;Multi-AZ Deployment&lt;/strong&gt; for production environments.
&lt;/li&gt;
&lt;li&gt;Set up automated backups and specify a backup retention period.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Launch the Instance&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review and click &lt;strong&gt;"Create Database"&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Part 2: Connect to the RDS Instance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retrieve Connection Information&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the RDS dashboard, select your instance, and copy the &lt;strong&gt;Endpoint&lt;/strong&gt; and &lt;strong&gt;Port&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access via a SQL Client&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a client like MySQL Workbench, pgAdmin, or any terminal-based tool.
&lt;/li&gt;
&lt;li&gt;Example for MySQL:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; mysql &lt;span class="nt"&gt;-h&lt;/span&gt; &amp;lt;endpoint&amp;gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;username&amp;gt; &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test the Connection&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create and query a sample database:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;testdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;testdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
 &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&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="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'John Doe'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Part 3: Enable Read Replicas for Scalability&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a Read Replica&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the RDS instance details.
&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;"Create Read Replica"&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure the Replica&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specify instance class and storage.
&lt;/li&gt;
&lt;li&gt;Assign a unique identifier and launch it.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use the Replica for Read Operations&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect to the replica using its endpoint for read-only queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Part 4: Automate Backup and Recovery&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automated Backups&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enabled by default. Modify settings under &lt;strong&gt;Backup Configuration&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manual Snapshots&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the RDS dashboard, select your instance, and click &lt;strong&gt;"Take Snapshot"&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Restore from Snapshot&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to Snapshots, choose a snapshot, and click &lt;strong&gt;"Restore Snapshot"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🔒 &lt;strong&gt;RDS Security Best Practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VPC Isolation&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy RDS instances within private subnets of a VPC.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IAM Policies&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restrict access to RDS resources based on roles.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable encryption for data at rest using AWS KMS.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access Control&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use security groups to define inbound/outbound traffic rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📊 &lt;strong&gt;Monitoring and Optimization&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CloudWatch Metrics&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor CPU utilization, IOPS, connections, and latency.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performance Insights&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS RDS Performance Insights for analyzing query performance.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scaling&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modify the instance class or use &lt;strong&gt;Aurora Serverless&lt;/strong&gt; for automatic scaling.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠️ &lt;strong&gt;AWS CLI Commands for RDS&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create RDS Instance&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws rds create-db-instance &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--db-instance-identifier&lt;/span&gt; mydbinstance &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--db-instance-class&lt;/span&gt; db.t2.micro &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--engine&lt;/span&gt; mysql &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--allocated-storage&lt;/span&gt; 20 &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--master-username&lt;/span&gt; admin &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--master-user-password&lt;/span&gt; mypassword &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--backup-retention-period&lt;/span&gt; 7 &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; us-east-1a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;List RDS Instances&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws rds describe-db-instances
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Delete RDS Instance&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws rds delete-db-instance &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--db-instance-identifier&lt;/span&gt; mydbinstance &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--skip-final-snapshot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔗 &lt;strong&gt;Use Cases of AWS RDS&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Web Applications&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store application data for websites built with frameworks like Django, Laravel, or Spring.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Warehousing&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use read replicas to offload analytical queries.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ERP and CRM Systems&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Host relational data for enterprise-grade systems.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📂 &lt;strong&gt;Additional Resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/rds/" rel="noopener noreferrer"&gt;AWS RDS Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://calculator.aws/#/" rel="noopener noreferrer"&gt;AWS Pricing Calculator&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Start leveraging &lt;strong&gt;AWS RDS&lt;/strong&gt; for your database needs to save time, increase scalability, and ensure data reliability. 🚀  &lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>aws</category>
      <category>rds</category>
      <category>database</category>
    </item>
    <item>
      <title>🚀 Learn AWS EC2: Ultimate Beginner's Guide 🌐</title>
      <dc:creator>Rajeev</dc:creator>
      <pubDate>Sun, 02 Mar 2025 05:39:08 +0000</pubDate>
      <link>https://dev.to/elonerajeev1/learn-aws-ec2-ultimate-beginners-guide-30l5</link>
      <guid>https://dev.to/elonerajeev1/learn-aws-ec2-ultimate-beginners-guide-30l5</guid>
      <description>&lt;p&gt;Welcome to the &lt;strong&gt;AWS EC2 Tutorial&lt;/strong&gt;! This guide will take you through everything you need to know about Amazon Elastic Compute Cloud (&lt;strong&gt;EC2&lt;/strong&gt;)—from launching instances to hosting your first webpage!  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;What is AWS EC2?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Amazon EC2 is a web service that provides resizable compute capacity in the cloud. It enables businesses to deploy applications quickly without hardware investments.  &lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt;
🌟 Why Learn EC2?
&lt;/li&gt;
&lt;li&gt;
🚀 Getting Started
&lt;/li&gt;
&lt;li&gt;
📦 EC2 Instance Types
&lt;/li&gt;
&lt;li&gt;
⚙️ Launching an EC2 Instance
&lt;/li&gt;
&lt;li&gt;
🌐 Hosting a Simple Webpage
&lt;/li&gt;
&lt;li&gt;
🔒 Security Best Practices
&lt;/li&gt;
&lt;li&gt;
📈 Monitoring and Scaling
&lt;/li&gt;
&lt;li&gt;
🎉 Conclusion
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🌟 &lt;strong&gt;Why Learn EC2?&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🚀 Cloud Computing Mastery&lt;/strong&gt;: EC2 is the backbone of AWS services.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💼 Career Growth&lt;/strong&gt;: EC2 knowledge is crucial for DevOps, cloud engineers, and developers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🌍 Real-World Applications&lt;/strong&gt;: Use EC2 to host websites, deploy applications, or run data pipelines.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Getting Started&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;p&gt;Before you begin, ensure you have:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ An &lt;strong&gt;AWS account&lt;/strong&gt; (free-tier eligible).
&lt;/li&gt;
&lt;li&gt;✅ Basic knowledge of cloud computing.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 &lt;strong&gt;EC2 Instance Types&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AWS EC2 offers various instance types tailored for different workloads:  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;General&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Balanced performance&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;t2.micro&lt;/code&gt;, &lt;code&gt;t3.small&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-performance computing&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c5.large&lt;/code&gt;, &lt;code&gt;c6i.xlarge&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Memory-intensive apps&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;r5.large&lt;/code&gt;, &lt;code&gt;r6g.xlarge&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data-heavy workloads&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;i3.large&lt;/code&gt;, &lt;code&gt;i4i.xlarge&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Machine learning, gaming&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g5.large&lt;/code&gt;, &lt;code&gt;p3.2xlarge&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚙️ &lt;strong&gt;Launching an EC2 Instance&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Follow these steps to launch your first EC2 instance:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Login to AWS Console&lt;/strong&gt; 🖥️  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;EC2&lt;/strong&gt; under the "Compute" section.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Click "Launch Instance"&lt;/strong&gt; 🚀  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide a name for your instance.
&lt;/li&gt;
&lt;li&gt;Select an &lt;strong&gt;AMI (Amazon Machine Image)&lt;/strong&gt; like &lt;strong&gt;Ubuntu&lt;/strong&gt;, &lt;strong&gt;Amazon Linux&lt;/strong&gt;, or &lt;strong&gt;Windows Server&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose an Instance Type&lt;/strong&gt; 🖱️  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For beginners, choose &lt;code&gt;t2.micro&lt;/code&gt; (free-tier eligible).
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Security Groups&lt;/strong&gt; 🔒  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add rules to allow inbound traffic for &lt;strong&gt;HTTP (port 80)&lt;/strong&gt; and &lt;strong&gt;SSH (port 22)&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key Pair&lt;/strong&gt; 🗝️  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create or select an existing key pair for secure access.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Launch Your Instance&lt;/strong&gt; 🎉  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Launch Instance&lt;/strong&gt; and wait for it to initialize.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🌐 &lt;strong&gt;Hosting a Simple Webpage&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s how you can host a basic &lt;code&gt;index.html&lt;/code&gt; file on your EC2 instance.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install a Web Server
&lt;/h3&gt;

&lt;p&gt;Log into your EC2 instance via SSH and run the following commands to install a web server:&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;# Update the package manager&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update  

&lt;span class="c"&gt;# Install Apache2&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apache2 &lt;span class="nt"&gt;-y&lt;/span&gt;  

&lt;span class="c"&gt;# Start Apache2 service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start apache2  

&lt;span class="c"&gt;# Enable Apache2 to start on boot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;apache2  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create Your Webpage
&lt;/h3&gt;

&lt;p&gt;Navigate to the default web server directory and create an &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Navigate to the default directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/html  

&lt;span class="c"&gt;# Create or edit the index.html file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano index.html  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following content to your &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome to My Webpage&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;🚀 Welcome to My First AWS EC2 Hosted Webpage!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is a simple webpage hosted on an EC2 instance.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit (&lt;code&gt;Ctrl+O&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;, &lt;code&gt;Ctrl+X&lt;/code&gt;).  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Open Your Webpage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In your browser, navigate to:
&lt;code&gt;http://&amp;lt;Public_IP_of_EC2_Instance&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should see your &lt;code&gt;index.html&lt;/code&gt; webpage live! 🎉  &lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 &lt;strong&gt;Security Best Practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Security Groups&lt;/strong&gt;: Restrict inbound traffic to only required ports.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Management&lt;/strong&gt;: Keep your &lt;code&gt;.pem&lt;/code&gt; file secure.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Roles&lt;/strong&gt;: Assign least privilege roles to your instances.
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎉 &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With this guide, you’ve:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launched your first EC2 instance.
&lt;/li&gt;
&lt;li&gt;Installed a web server.
&lt;/li&gt;
&lt;li&gt;Hosted your first &lt;code&gt;index.html&lt;/code&gt; webpage.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Continue exploring AWS to enhance your cloud computing skills!  &lt;/p&gt;

&lt;h3&gt;
  
  
  Need Help? Reach out on &lt;a href="https://forums.aws.amazon.com/" rel="noopener noreferrer"&gt;AWS Forums&lt;/a&gt; or join the &lt;a href="https://aws.amazon.com/community/" rel="noopener noreferrer"&gt;AWS Community&lt;/a&gt;.
&lt;/h3&gt;




&lt;p&gt;&lt;strong&gt;Happy Hosting!&lt;/strong&gt; 🚀&lt;/p&gt;



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

By Rajeev Kumar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>aws</category>
      <category>ec2</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
