<?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: Anupa Supul</title>
    <description>The latest articles on DEV Community by Anupa Supul (@anupa_supul).</description>
    <link>https://dev.to/anupa_supul</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%2F4019275%2F0a668de2-77e3-4beb-91c3-91f0f8ca4b63.jpeg</url>
      <title>DEV Community: Anupa Supul</title>
      <link>https://dev.to/anupa_supul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anupa_supul"/>
    <language>en</language>
    <item>
      <title>How Do Large Applications Process Work in the Background? Understanding Amazon SQS, SNS &amp; EventBridge</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Tue, 20 Oct 2026 05:08:16 +0000</pubDate>
      <link>https://dev.to/anupa_supul/how-do-large-applications-process-work-in-the-background-understanding-amazon-sqs-sns--1a5f</link>
      <guid>https://dev.to/anupa_supul/how-do-large-applications-process-work-in-the-background-understanding-amazon-sqs-sns--1a5f</guid>
      <description>&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%2F1a1ny1n9iyw4jjrjh4a0.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%2F1a1ny1n9iyw4jjrjh4a0.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I started learning AWS, I focused mainly on deploying applications, building APIs, and connecting databases.&lt;/p&gt;

&lt;p&gt;But then I started thinking about something interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when an application needs to perform several tasks without making the user wait for everything to finish?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine ordering a product from an online store. After placing the order, the system might need to update inventory, send a confirmation email, generate an invoice, and notify the delivery team.&lt;/p&gt;

&lt;p&gt;Should the customer wait until every single task is completed?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;This is where event-driven architecture and messaging services become useful.&lt;/p&gt;

&lt;p&gt;In this article, I'll explore three AWS services that help applications communicate and process work more efficiently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon SQS&lt;/strong&gt; — queues messages for processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon SNS&lt;/strong&gt; — distributes messages to multiple subscribers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EventBridge&lt;/strong&gt; — routes events to targets based on rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Why Do Applications Need Background Processing?
&lt;/h2&gt;

&lt;p&gt;Consider a simple application where every operation happens inside one request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer places an order
          |
          v
      Save order
          |
          v
   Update inventory
          |
          v
   Send confirmation
          |
          v
   Generate invoice
          |
          v
   Return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If each operation runs sequentially, the customer may need to wait for all of them. If an external email service is slow, the entire request could take longer.&lt;/p&gt;

&lt;p&gt;It also creates tight coupling: a problem in one dependency can affect the main request.&lt;/p&gt;

&lt;p&gt;Instead, we can separate the immediate operation from background work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer places an order
          |
          v
       Save order
          |
          v
   Queue background work
          |
          v
  Return response to customer
          |
          v
   Process tasks separately
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the application can respond after completing the necessary synchronous work, while other operations happen independently.&lt;/p&gt;

&lt;p&gt;This is one of the main ideas behind &lt;strong&gt;asynchronous processing&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Amazon SQS — Let Messages Wait in a Queue
&lt;/h2&gt;

&lt;p&gt;Amazon Simple Queue Service (SQS) is a managed message queuing service.&lt;/p&gt;

&lt;p&gt;Think of it as a waiting line for tasks. A producer sends a message to the queue, and a consumer retrieves and processes it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order API
    |
    v
Amazon SQS Queue
    |
    v
Order Processing Worker
    |
    v
Update Inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API doesn't need to wait for the worker to finish processing the message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is SQS useful?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It helps decouple application components.&lt;/li&gt;
&lt;li&gt;Messages can wait until consumers are ready to process them.&lt;/li&gt;
&lt;li&gt;It helps absorb temporary traffic spikes.&lt;/li&gt;
&lt;li&gt;Failed messages can be retried.&lt;/li&gt;
&lt;li&gt;Dead-letter queues can isolate messages that repeatedly fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQS offers &lt;strong&gt;Standard queues&lt;/strong&gt; and &lt;strong&gt;FIFO queues&lt;/strong&gt;. Standard queues provide high throughput with at-least-once delivery, so consumers should be designed to handle duplicate messages. FIFO queues support ordering within message groups and deduplication features, with their own throughput and configuration considerations.&lt;/p&gt;

&lt;p&gt;One important concept is the &lt;strong&gt;visibility timeout&lt;/strong&gt;. When a consumer receives a message, the message becomes temporarily invisible to other consumers. If processing succeeds, the consumer deletes it. If the message isn't deleted before the visibility timeout expires, it can become available again.&lt;/p&gt;

&lt;p&gt;That is why reliable message processing needs error handling and idempotency.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Amazon SNS — Send One Message to Multiple Subscribers
&lt;/h2&gt;

&lt;p&gt;Amazon Simple Notification Service (SNS) is a managed publish/subscribe messaging service.&lt;/p&gt;

&lt;p&gt;Instead of placing work in a queue for one consumer pattern, SNS can distribute a published message to multiple subscribers.&lt;/p&gt;

&lt;p&gt;Imagine an order has been placed. Several systems need to react:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A notification service sends a confirmation.&lt;/li&gt;
&lt;li&gt;An analytics service records the event.&lt;/li&gt;
&lt;li&gt;Another service starts a fulfilment workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SNS can help distribute the notification to these subscribers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Order Service
                    |
                    v
                 Amazon SNS
                    |
          +---------+---------+
          |         |         |
          v         v         v
        SQS A     Lambda    Email
      Queue       Function  Endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SNS supports different subscription types, including SQS queues, Lambda functions, HTTP/S endpoints, and email, depending on the configuration and use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is SNS useful?
&lt;/h3&gt;

&lt;p&gt;SNS is a good fit when multiple subscribers need to receive a notification about the same event.&lt;/p&gt;

&lt;p&gt;For example, an order service can publish an &lt;code&gt;OrderPlaced&lt;/code&gt; notification without needing to know the internal implementation of every subscriber.&lt;/p&gt;

&lt;p&gt;That reduces direct dependencies between services.&lt;/p&gt;

&lt;p&gt;A key distinction: &lt;strong&gt;SNS distributes messages; it is not a general-purpose durable work queue in the same way SQS is.&lt;/strong&gt; Combining SNS with SQS can be useful when multiple consumers need their own queues and independent processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Amazon EventBridge — Route Events Based on Rules
&lt;/h2&gt;

&lt;p&gt;Amazon EventBridge is a serverless event bus service that routes events to targets using rules.&lt;/p&gt;

&lt;p&gt;An event describes something that happened, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An order being placed.&lt;/li&gt;
&lt;li&gt;A payment succeeding.&lt;/li&gt;
&lt;li&gt;A file being uploaded to Amazon S3.&lt;/li&gt;
&lt;li&gt;A scheduled task reaching its execution time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EventBridge can inspect an event and route it to the targets whose rules match.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       OrderPlaced Event
               |
               v
       Amazon EventBridge
               |
        +------+------+
        |             |
        v             v
   Order Processor  Analytics
       Lambda        Target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can define rules that match event attributes and send matching events to supported targets.&lt;/p&gt;

&lt;p&gt;EventBridge is particularly useful for reacting to events from AWS services, your own applications, and supported SaaS integrations.&lt;/p&gt;

&lt;p&gt;It also supports scheduled and time-based event patterns through its scheduling capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should you use EventBridge?
&lt;/h3&gt;

&lt;p&gt;Use it when you want to route events based on what happened, without tightly connecting the event producer to every downstream service.&lt;/p&gt;

&lt;p&gt;For example, an application could react differently to &lt;code&gt;OrderPlaced&lt;/code&gt;, &lt;code&gt;PaymentFailed&lt;/code&gt;, and &lt;code&gt;OrderCancelled&lt;/code&gt; events.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. SQS vs SNS vs EventBridge
&lt;/h2&gt;

&lt;p&gt;These services can work together, but they solve different problems.&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;Amazon SQS&lt;/th&gt;
&lt;th&gt;Amazon SNS&lt;/th&gt;
&lt;th&gt;Amazon EventBridge&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Main purpose&lt;/td&gt;
&lt;td&gt;Queue messages for processing&lt;/td&gt;
&lt;td&gt;Distribute messages to subscribers&lt;/td&gt;
&lt;td&gt;Route events using rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Core pattern&lt;/td&gt;
&lt;td&gt;Queue and consumer&lt;/td&gt;
&lt;td&gt;Publish/subscribe&lt;/td&gt;
&lt;td&gt;Event bus and targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use&lt;/td&gt;
&lt;td&gt;Background jobs&lt;/td&gt;
&lt;td&gt;Notifications to multiple subscribers&lt;/td&gt;
&lt;td&gt;Reacting to application or AWS events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message handling&lt;/td&gt;
&lt;td&gt;Consumers poll or use supported integrations&lt;/td&gt;
&lt;td&gt;Pushes notifications to subscribers&lt;/td&gt;
&lt;td&gt;Routes matching events to targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Useful feature&lt;/td&gt;
&lt;td&gt;Visibility timeout and dead-letter queues&lt;/td&gt;
&lt;td&gt;Multiple subscribers and filtering&lt;/td&gt;
&lt;td&gt;Event pattern matching and routing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here's the simple mental model I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQS:&lt;/strong&gt; "Process this work when you're ready."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS:&lt;/strong&gt; "Send this notification to these subscribers."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge:&lt;/strong&gt; "When this event happens, route it to the appropriate target."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. How They Work Together in a Real Application
&lt;/h2&gt;

&lt;p&gt;Let's return to our online store.&lt;/p&gt;

&lt;p&gt;After a customer places an order, the API saves the order and publishes an event. Different services can then handle different responsibilities.&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/REPLACE_WITH_UPLOADED_IMAGE_URL" 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/REPLACE_WITH_UPLOADED_IMAGE_URL" alt="AWS event-driven architecture showing API Gateway, Lambda, DynamoDB, SQS, SNS, and EventBridge" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;An e-commerce application can use queues for background processing, notifications for multiple subscribers, and event rules to route events.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is a simplified architecture diagram in text form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React Frontend
      |
      v
API Gateway
      |
      v
AWS Lambda
      |
      v
Save Order in DynamoDB
      |
      v
Publish OrderPlaced Event
      |
      v
Amazon EventBridge
      |
      +-------------------+
      |                   |
      v                   v
Order Processing       Analytics
      |
      v
Amazon SQS
      |
      v
Background Worker
      |
      v
Update Inventory / Fulfil Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A separate notification workflow could use SNS to distribute an order notification to multiple subscribers.&lt;/p&gt;

&lt;p&gt;The exact architecture depends on the requirements. For example, an SQS queue can be an EventBridge target, allowing the event to be routed to a durable queue for later processing.&lt;/p&gt;

&lt;p&gt;This architecture separates the order API from slower background tasks. It also lets different components scale and fail independently to a degree, provided that retries, error handling, and downstream dependencies are designed correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when the order is placed?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The React frontend sends a request to API Gateway.&lt;/li&gt;
&lt;li&gt;Lambda validates the request and saves the order in DynamoDB.&lt;/li&gt;
&lt;li&gt;The application publishes an order event.&lt;/li&gt;
&lt;li&gt;EventBridge evaluates its rules and routes matching events to configured targets.&lt;/li&gt;
&lt;li&gt;Background processing runs independently, potentially through SQS and a worker.&lt;/li&gt;
&lt;li&gt;SNS can distribute notifications to subscribers when needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One important production consideration: don't assume that saving an order and publishing an event are automatically one atomic operation. If the database write succeeds but event publishing fails, the system may need a reliable publishing strategy, such as the transactional outbox pattern, to avoid losing important events.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Reliability: Retries, Dead-Letter Queues, and Duplicate Messages
&lt;/h2&gt;

&lt;p&gt;Asynchronous systems are powerful, but they introduce their own challenges.&lt;/p&gt;

&lt;p&gt;What happens if a worker crashes while processing a message? What if a message is delivered more than once?&lt;/p&gt;

&lt;p&gt;These are normal distributed-system problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retries
&lt;/h3&gt;

&lt;p&gt;Temporary failures may be resolved by retrying the operation. However, retries should be configured carefully to avoid overwhelming a failing dependency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dead-letter queues
&lt;/h3&gt;

&lt;p&gt;A dead-letter queue (DLQ) can hold messages that exceed the configured retry or receive-count threshold. This gives you a way to investigate and recover messages that repeatedly fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotency
&lt;/h3&gt;

&lt;p&gt;An operation is idempotent when repeating it produces the same intended result rather than performing the effect multiple times.&lt;/p&gt;

&lt;p&gt;For example, if a worker receives the same order-processing message twice, it should not deduct inventory twice unintentionally.&lt;/p&gt;

&lt;p&gt;SQS Standard queues can deliver duplicate messages, and other event-driven workflows can also retry delivery. Design consumers with this possibility in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring
&lt;/h3&gt;

&lt;p&gt;CloudWatch metrics, logs, and alarms can help identify growing queue backlogs, processing failures, throttling, and other problems.&lt;/p&gt;

&lt;p&gt;The goal isn't to assume messages will never fail. It's to design the application so failures can be detected and handled safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. When Should You Use Each Service?
&lt;/h2&gt;

&lt;p&gt;Choose the service based on the communication problem you're trying to solve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Amazon SQS when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work needs to wait until a consumer is ready.&lt;/li&gt;
&lt;li&gt;You want to separate request handling from background processing.&lt;/li&gt;
&lt;li&gt;You need to buffer traffic spikes.&lt;/li&gt;
&lt;li&gt;Consumers need to retry processing failed messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Amazon SNS when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One message needs to reach multiple subscribers.&lt;/li&gt;
&lt;li&gt;You want a publish/subscribe communication pattern.&lt;/li&gt;
&lt;li&gt;Multiple systems need to react to the same notification.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Amazon EventBridge when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Events need to be routed based on their content.&lt;/li&gt;
&lt;li&gt;AWS services or applications generate events.&lt;/li&gt;
&lt;li&gt;Different event types need different processing workflows.&lt;/li&gt;
&lt;li&gt;You want event-driven integration without hardcoding every destination into the producer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are common patterns, not strict boundaries. Real architectures often combine these services.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. My Main Takeaways
&lt;/h2&gt;

&lt;p&gt;As I continue learning AWS, I'm realizing that building a reliable application involves more than deploying a backend and connecting a database.&lt;/p&gt;

&lt;p&gt;It also means understanding how different components communicate, how failures are handled, and how background work can be processed without slowing down the user experience.&lt;/p&gt;

&lt;p&gt;Here is the mental model I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon SQS&lt;/strong&gt; queues work for consumers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon SNS&lt;/strong&gt; distributes messages to subscribers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EventBridge&lt;/strong&gt; routes events using rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Lambda&lt;/strong&gt; can execute event-driven processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon DynamoDB&lt;/strong&gt; can store application data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon CloudWatch&lt;/strong&gt; helps monitor and troubleshoot the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key lesson is that these services solve different communication problems. Choosing the right one depends on whether you need a queue, a notification mechanism, or event-based routing.&lt;/p&gt;

&lt;p&gt;And in production, retries, duplicate handling, permissions, monitoring, and cost still matter.&lt;/p&gt;

&lt;p&gt;I'm documenting my AWS learning journey one concept at a time. If you're learning cloud computing too, I'd love to hear what you're building and which AWS services you're exploring.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>devops</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Can You Build a Backend Without Managing Servers? Understanding Amazon API Gateway, AWS Lambda &amp; DynamoDB</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:56:12 +0000</pubDate>
      <link>https://dev.to/anupa_supul/can-you-build-a-backend-without-managing-servers-understanding-amazon-api-gateway-aws-lambda--d1n</link>
      <guid>https://dev.to/anupa_supul/can-you-build-a-backend-without-managing-servers-understanding-amazon-api-gateway-aws-lambda--d1n</guid>
      <description>&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%2Fz20iybv9228amfwwdof0.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%2Fz20iybv9228amfwwdof0.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first started learning AWS, I thought deploying a backend meant creating an EC2 instance, installing Node.js, configuring a web server, and keeping everything running.&lt;/p&gt;

&lt;p&gt;That approach works. But what if you could build an API without managing the underlying servers yourself?&lt;/p&gt;

&lt;p&gt;That is where &lt;strong&gt;serverless architecture&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;In this article, I’ll explore three AWS services that work well together to build serverless backends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon API Gateway&lt;/strong&gt; — receives and manages API requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Lambda&lt;/strong&gt; — executes backend code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon DynamoDB&lt;/strong&gt; — stores and retrieves data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll also look at how these services connect, explore a small Node.js example, and discuss when serverless makes sense in a real application.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Does Serverless Actually Mean?
&lt;/h2&gt;

&lt;p&gt;Serverless does not mean there are no servers.&lt;/p&gt;

&lt;p&gt;Servers still exist. The difference is that AWS manages much of the underlying infrastructure, including server provisioning and infrastructure availability for these services.&lt;/p&gt;

&lt;p&gt;Instead of managing a server yourself, you focus more on writing application code and defining how the services should work together.&lt;/p&gt;

&lt;p&gt;For example, imagine you are building a task management application.&lt;/p&gt;

&lt;p&gt;Users should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a task.&lt;/li&gt;
&lt;li&gt;View their tasks.&lt;/li&gt;
&lt;li&gt;Update a task.&lt;/li&gt;
&lt;li&gt;Delete a task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a traditional backend, you might deploy a Node.js application on EC2 or ECS.&lt;/p&gt;

&lt;p&gt;With a serverless approach, you could use API Gateway, Lambda, and DynamoDB.&lt;/p&gt;

&lt;p&gt;The basic flow 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;User / React Frontend
         |
         v
   API Gateway
         |
         v
      Lambda
         |
         v
    DynamoDB
         |
         v
    JSON Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each service has a specific responsibility. This separation makes the architecture easier to understand and lets you scale different parts of the application according to their needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Amazon API Gateway — The Entry Point for Your API
&lt;/h2&gt;

&lt;p&gt;Imagine your React frontend needs to request a list of tasks from your backend.&lt;/p&gt;

&lt;p&gt;It might send a request such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /tasks
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But where should that request go?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon API Gateway&lt;/strong&gt; provides an API entry point that clients can call. It can route requests to backend services such as Lambda functions.&lt;/p&gt;

&lt;p&gt;It also supports capabilities such as authorization, request validation, throttling, and monitoring integrations, depending on the API type and configuration.&lt;/p&gt;

&lt;p&gt;For example, you might define these routes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HTTP Method&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tasks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retrieve tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tasks/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retrieve one task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tasks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tasks/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update a task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tasks/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a task&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each route can be connected to a suitable Lambda function.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /tasks
    |
    v
getTasks Lambda

POST /tasks
    |
    v
createTask Lambda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;API Gateway can also help protect an API from excessive requests through throttling and integrate with supported authorization mechanisms.&lt;/p&gt;

&lt;p&gt;One important point: API Gateway is not your database, and it does not automatically make every API secure. Authentication, authorization, validation, and appropriate access policies still need to be configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. AWS Lambda — Run Backend Code Without Managing Servers
&lt;/h2&gt;

&lt;p&gt;Now let's look at the service that executes our backend logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Lambda&lt;/strong&gt; runs code in response to events. An API Gateway request can trigger a Lambda function, which processes the request and returns a response.&lt;/p&gt;

&lt;p&gt;You don't need to manage an EC2 instance just to keep this function available.&lt;/p&gt;

&lt;p&gt;For example, a &lt;code&gt;createTask&lt;/code&gt; Lambda function might:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive the incoming request.&lt;/li&gt;
&lt;li&gt;Read the task details.&lt;/li&gt;
&lt;li&gt;Validate the input.&lt;/li&gt;
&lt;li&gt;Store the task in DynamoDB.&lt;/li&gt;
&lt;li&gt;Return a response to the client.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simplified flow 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;API Gateway
     |
     v
Lambda Function
     |
     +--&amp;gt; Validate request
     |
     +--&amp;gt; Execute business logic
     |
     +--&amp;gt; Save data in DynamoDB
     |
     v
Return JSON response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda supports multiple runtimes, including Node.js and Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  A simple Node.js Lambda example
&lt;/h3&gt;

&lt;p&gt;Here is a minimal Lambda handler that returns a JSON response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from AWS Lambda!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestContext&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example assumes an API Gateway HTTP API using its payload format that exposes the HTTP method under &lt;code&gt;requestContext.http.method&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When API Gateway invokes the function, Lambda returns a response that API Gateway can send back to the client.&lt;/p&gt;

&lt;p&gt;This is only a demonstration. A production API would also need suitable error handling, input validation, authentication, and logging.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when traffic increases?
&lt;/h3&gt;

&lt;p&gt;Suppose your application normally receives 20 requests per minute, but suddenly receives thousands.&lt;/p&gt;

&lt;p&gt;Lambda can scale the number of concurrent function executions in response to incoming demand, subject to account quotas, concurrency settings, and other service limits.&lt;/p&gt;

&lt;p&gt;You don't manually create more EC2 instances just to handle every increase in traffic.&lt;/p&gt;

&lt;p&gt;However, scaling is not unlimited or instantaneous in every situation. Concurrency quotas, downstream database capacity, throttling, and cold starts can affect performance.&lt;/p&gt;

&lt;p&gt;That's why serverless applications still require thoughtful design.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Amazon DynamoDB — Store Application Data
&lt;/h2&gt;

&lt;p&gt;Our backend now has an entry point and a way to execute code. But where should the application store its data?&lt;/p&gt;

&lt;p&gt;For this example, we'll use &lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;DynamoDB is a managed NoSQL database service that supports key-value and document data models.&lt;/p&gt;

&lt;p&gt;Unlike a traditional relational database, DynamoDB does not require you to design every relationship around SQL tables and joins. Instead, you design tables and indexes around the access patterns your application needs.&lt;/p&gt;

&lt;p&gt;Imagine storing tasks with fields such as:&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;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user-123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"taskId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"task-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Learn AWS Lambda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A DynamoDB table could use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;userId&lt;/code&gt; as the partition key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;taskId&lt;/code&gt; as the sort key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This key design makes it possible to retrieve tasks belonging to a particular user using a query on that user's partition key.&lt;/p&gt;

&lt;p&gt;The actual design should depend on the application's access patterns. If you need to search tasks by status, due date, or another attribute, you may need additional indexes or a different key design.&lt;/p&gt;

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

&lt;p&gt;Some useful characteristics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managed infrastructure.&lt;/li&gt;
&lt;li&gt;Flexible scaling options.&lt;/li&gt;
&lt;li&gt;Low-latency access for suitable key-based access patterns.&lt;/li&gt;
&lt;li&gt;Integration with Lambda and other AWS services.&lt;/li&gt;
&lt;li&gt;On-demand capacity options for workloads where usage is difficult to predict.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But DynamoDB is not automatically the best database for every application.&lt;/p&gt;

&lt;p&gt;If your application relies heavily on relational joins, complex SQL queries, or relational constraints, Amazon RDS or Amazon Aurora may be more suitable.&lt;/p&gt;

&lt;p&gt;The important lesson is to choose a database based on your data model and access patterns, not simply because it is serverless.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Connecting the Architecture
&lt;/h2&gt;

&lt;p&gt;Let's put the three services together.&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/REPLACE_WITH_YOUR_UPLOADED_IMAGE_URL" 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/REPLACE_WITH_YOUR_UPLOADED_IMAGE_URL" alt="Serverless AWS architecture: React frontend, API Gateway, Lambda, and DynamoDB" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Architecture overview: the frontend sends an API request, API Gateway routes it to Lambda, and Lambda interacts with DynamoDB before returning a response.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the same architecture as a text diagram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 USER
                  |
                  v
            REACT FRONTEND
                  |
             HTTPS Request
                  |
                  v
           AMAZON API GATEWAY
                  |
           Route to Lambda
                  |
                  v
             AWS LAMBDA
                  |
          Validate and Process
                  |
                  v
             AMAZON DYNAMODB
                  |
             Query / Write
                  |
                  v
             AWS LAMBDA
                  |
            JSON Response
                  |
                  v
            API GATEWAY
                  |
                  v
            REACT FRONTEND
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through a request to create a task.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user fills out a form in the React application.&lt;/li&gt;
&lt;li&gt;The frontend sends a &lt;code&gt;POST /tasks&lt;/code&gt; request.&lt;/li&gt;
&lt;li&gt;API Gateway receives the request and invokes the configured Lambda function.&lt;/li&gt;
&lt;li&gt;Lambda validates the input and executes the business logic.&lt;/li&gt;
&lt;li&gt;Lambda writes the task to DynamoDB using the AWS SDK.&lt;/li&gt;
&lt;li&gt;Lambda returns a response.&lt;/li&gt;
&lt;li&gt;API Gateway sends the response to the frontend.&lt;/li&gt;
&lt;li&gt;React updates the interface to show the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture separates the frontend, API entry point, application logic, and database responsibilities.&lt;/p&gt;

&lt;p&gt;For a small application, it can be a straightforward way to build and deploy a backend. As the application grows, you'll need to think more carefully about permissions, observability, data access patterns, and failure handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. A Practical Node.js Example: Saving a Task to DynamoDB
&lt;/h2&gt;

&lt;p&gt;Let's make the example a little more realistic.&lt;/p&gt;

&lt;p&gt;Suppose we have a DynamoDB table named &lt;code&gt;Tasks&lt;/code&gt; with &lt;code&gt;userId&lt;/code&gt; as its partition key and &lt;code&gt;taskId&lt;/code&gt; as its sort key.&lt;/p&gt;

&lt;p&gt;The Lambda function below creates a task using the AWS SDK for JavaScript v3.&lt;/p&gt;

&lt;p&gt;Install the required package in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file named &lt;code&gt;index.mjs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;randomUUID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/client-dynamodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;DynamoDBDocumentClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PutCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/lib-dynamodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DynamoDBClient&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamoDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBDocumentClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TABLE_NAME is not configured&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId and title are required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamoDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PutCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attribute_not_exists(userId) AND attribute_not_exists(taskId)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to create task:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unable to create task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example demonstrates the basic flow, but there are a few important details to understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, the table name comes from an environment variable.&lt;/strong&gt; Configure &lt;code&gt;TABLE_NAME&lt;/code&gt; in the Lambda function's environment settings rather than hardcoding the table name throughout your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, the function uses the AWS SDK's default credential provider chain.&lt;/strong&gt; When deployed to Lambda, it can obtain temporary credentials from the function's execution role. You generally should not put permanent AWS access keys in your application code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third, the conditional expression prevents overwriting an item with the same composite primary key.&lt;/strong&gt; Because this example generates a UUID for each new task, a collision is extremely unlikely, but the condition still makes the intended behavior explicit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fourth, the example is simplified.&lt;/strong&gt; It accepts a &lt;code&gt;userId&lt;/code&gt; from the request body for demonstration. In a real multi-user application, derive the user's identity from a verified authentication mechanism rather than trusting a client-supplied user ID. Otherwise, a user might attempt to create or access another user's data.&lt;/p&gt;

&lt;p&gt;Also, the catch block returns a generic error to the client while logging the underlying error for troubleshooting. Production applications should distinguish expected client errors from unexpected server failures and avoid exposing internal details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important: configure IAM permissions
&lt;/h3&gt;

&lt;p&gt;The Lambda execution role needs permission to write to the intended DynamoDB table.&lt;/p&gt;

&lt;p&gt;A tightly scoped policy should grant only the required action, such as &lt;code&gt;dynamodb:PutItem&lt;/code&gt;, on the specific table ARN. If the function later needs to query or update tasks, grant only those additional actions.&lt;/p&gt;

&lt;p&gt;Avoid giving the function broad permissions such as &lt;code&gt;dynamodb:*&lt;/code&gt; on every table in the account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important: configure the DynamoDB table
&lt;/h3&gt;

&lt;p&gt;The table must exist before this function can use it. Its primary key must match the attributes in the item:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Partition key: &lt;code&gt;userId&lt;/code&gt; (String).&lt;/li&gt;
&lt;li&gt;Sort key: &lt;code&gt;taskId&lt;/code&gt; (String).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure the &lt;code&gt;TABLE_NAME&lt;/code&gt; environment variable with the table's actual name.&lt;/p&gt;

&lt;p&gt;This code is a handler example, not a complete deployment tutorial. You still need to create the table, configure the Lambda runtime and execution role, connect the function to API Gateway, and test the request and response formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. What About Authentication and Security?
&lt;/h2&gt;

&lt;p&gt;A serverless backend still needs security. AWS managing the infrastructure does not automatically secure your application's business logic or data.&lt;/p&gt;

&lt;p&gt;Here are some services and controls that may be useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS IAM
&lt;/h3&gt;

&lt;p&gt;IAM controls which AWS resources and actions an identity can access.&lt;/p&gt;

&lt;p&gt;For this architecture, the Lambda execution role should grant only the permissions the function needs, such as writing to one DynamoDB table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon Cognito or another authentication provider
&lt;/h3&gt;

&lt;p&gt;If users need to sign in, you need an authentication mechanism.&lt;/p&gt;

&lt;p&gt;Amazon Cognito can provide user sign-up, sign-in, and token-based authentication capabilities. API Gateway can be configured to validate supported authorization tokens, depending on the API type and setup.&lt;/p&gt;

&lt;p&gt;Authentication identifies the caller. Your application must still enforce authorization: a signed-in user should not automatically have access to every other user's tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Secrets Manager
&lt;/h3&gt;

&lt;p&gt;If the application needs external API credentials or other secrets, Secrets Manager can store and manage them.&lt;/p&gt;

&lt;p&gt;DynamoDB access through the Lambda execution role generally does not require a database password. Avoid adding unnecessary credentials simply because other backend architectures use them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon CloudWatch
&lt;/h3&gt;

&lt;p&gt;CloudWatch can collect Lambda logs, metrics, and alarms. These help you investigate errors, monitor latency, and detect unusual invocation or throttling patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  A simple security model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   |
   v
API Gateway
   |
   +--&amp;gt; Validate authentication
   |
   v
Lambda Execution Role
   |
   +--&amp;gt; Only required DynamoDB actions
   |
   v
DynamoDB Table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact configuration depends on the application's requirements, but the core principle stays the same: &lt;strong&gt;grant only the permissions required, and verify who is allowed to access each user's data.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. What Happens When Traffic Increases?
&lt;/h2&gt;

&lt;p&gt;One reason serverless architecture is attractive is that it can reduce the amount of infrastructure management required as demand changes.&lt;/p&gt;

&lt;p&gt;However, each component has its own limits and scaling behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  API Gateway
&lt;/h3&gt;

&lt;p&gt;API Gateway can handle API traffic and supports configurable throttling and quotas. Your API may still receive throttling responses if configured limits or service quotas are exceeded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda
&lt;/h3&gt;

&lt;p&gt;Lambda can increase concurrent executions as demand grows, within applicable concurrency quotas and account limits.&lt;/p&gt;

&lt;p&gt;But more concurrent Lambda executions can also increase pressure on downstream services. If a function triggers expensive database operations, scaling the function alone will not solve the underlying bottleneck.&lt;/p&gt;

&lt;h3&gt;
  
  
  DynamoDB
&lt;/h3&gt;

&lt;p&gt;DynamoDB offers on-demand and provisioned capacity modes. The appropriate choice depends on traffic patterns, predictability, and cost requirements.&lt;/p&gt;

&lt;p&gt;Your key design and indexes also matter. A poorly designed access pattern can create hot partitions or inefficient queries even when the database itself is managed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about cold starts?
&lt;/h3&gt;

&lt;p&gt;A cold start can occur when Lambda needs to initialize a new execution environment before processing a request. This may add latency.&lt;/p&gt;

&lt;p&gt;The effect depends on factors such as runtime, initialization work, dependencies, memory configuration, and the execution environment.&lt;/p&gt;

&lt;p&gt;For many applications, occasional cold starts are acceptable. For latency-sensitive workloads, measure actual performance and evaluate options such as reducing initialization work or using provisioned concurrency where appropriate.&lt;/p&gt;

&lt;p&gt;Serverless makes infrastructure management easier in many cases, but it doesn't remove the need for performance testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Serverless Is Not Always Cheaper
&lt;/h2&gt;

&lt;p&gt;This is an important lesson: &lt;strong&gt;serverless is a deployment model, not a guarantee of lower cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Lambda, costs can depend on request volume, execution duration, configured memory, and other applicable charges.&lt;/p&gt;

&lt;p&gt;API Gateway pricing depends on the API type and usage. DynamoDB costs depend on the capacity mode, requests, storage, and additional features.&lt;/p&gt;

&lt;p&gt;For a small application with occasional requests, a serverless design can be cost-effective because you don't need to maintain an always-running application server for every request.&lt;/p&gt;

&lt;p&gt;For a high-volume application with predictable, sustained workloads, another architecture might be more economical. You need to compare actual usage and current pricing rather than assume one model always wins.&lt;/p&gt;

&lt;p&gt;Remember to consider supporting services, logging volume, data transfer, provisioned capacity, and other configuration choices when estimating costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Lambda vs EC2 vs ECS/Fargate
&lt;/h2&gt;

&lt;p&gt;Since I've been learning EC2, Docker, Amazon ECR, ECS, and Fargate, I find it useful to compare these approaches.&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;AWS Lambda&lt;/th&gt;
&lt;th&gt;EC2&lt;/th&gt;
&lt;th&gt;ECS with Fargate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure management&lt;/td&gt;
&lt;td&gt;AWS manages the execution infrastructure&lt;/td&gt;
&lt;td&gt;You manage the instances and operating system&lt;/td&gt;
&lt;td&gt;AWS manages the underlying compute infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application model&lt;/td&gt;
&lt;td&gt;Event-driven functions&lt;/td&gt;
&lt;td&gt;Applications or services on virtual machines&lt;/td&gt;
&lt;td&gt;Containerized applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;Based on invocations and concurrency settings&lt;/td&gt;
&lt;td&gt;Configure scaling for instances and workloads&lt;/td&gt;
&lt;td&gt;Configure service/task scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-running processes&lt;/td&gt;
&lt;td&gt;Subject to function execution limits&lt;/td&gt;
&lt;td&gt;Suitable&lt;/td&gt;
&lt;td&gt;Suitable, subject to task and service configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime control&lt;/td&gt;
&lt;td&gt;Supported Lambda runtimes and execution model&lt;/td&gt;
&lt;td&gt;High control&lt;/td&gt;
&lt;td&gt;Container-level control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operational effort&lt;/td&gt;
&lt;td&gt;Often lower for suitable workloads&lt;/td&gt;
&lt;td&gt;Often higher&lt;/td&gt;
&lt;td&gt;Moderate, depending on the application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good fit&lt;/td&gt;
&lt;td&gt;APIs, event handlers, scheduled tasks&lt;/td&gt;
&lt;td&gt;Custom server environments and broad workloads&lt;/td&gt;
&lt;td&gt;Containerized APIs, workers, and services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Lambda is especially useful when work can be broken into event-driven executions.&lt;/p&gt;

&lt;p&gt;EC2 is useful when you need control over the virtual machine and its environment.&lt;/p&gt;

&lt;p&gt;ECS with Fargate is useful when you want to run containers without managing the underlying EC2 instances yourself.&lt;/p&gt;

&lt;p&gt;These services are not mutually exclusive. A real application can use Lambda for event-driven operations and ECS/Fargate for a long-running API or worker.&lt;/p&gt;

&lt;p&gt;Choose based on the workload, operational requirements, performance expectations, and cost—not just which service sounds newer.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. What I Would Consider Before Deploying to Production
&lt;/h2&gt;

&lt;p&gt;Before deploying a serverless API for real users, I would check the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Configure API routes and appropriate authorization.&lt;/li&gt;
&lt;li&gt;[ ] Validate request bodies and query parameters.&lt;/li&gt;
&lt;li&gt;[ ] Derive user identity from verified authentication rather than trusting client-supplied identity fields.&lt;/li&gt;
&lt;li&gt;[ ] Use a least-privilege Lambda execution role.&lt;/li&gt;
&lt;li&gt;[ ] Design DynamoDB keys and indexes around real access patterns.&lt;/li&gt;
&lt;li&gt;[ ] Configure environment variables and manage any required secrets safely.&lt;/li&gt;
&lt;li&gt;[ ] Add useful logs, metrics, alarms, and tracing where appropriate.&lt;/li&gt;
&lt;li&gt;[ ] Handle errors and retries carefully.&lt;/li&gt;
&lt;li&gt;[ ] Make operations safe to retry where duplicate processing is possible.&lt;/li&gt;
&lt;li&gt;[ ] Set suitable timeouts, concurrency limits, and throttling.&lt;/li&gt;
&lt;li&gt;[ ] Test under realistic traffic and estimate costs.&lt;/li&gt;
&lt;li&gt;[ ] Deploy through a repeatable infrastructure-as-code and CI/CD process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One detail worth emphasizing is &lt;strong&gt;idempotency&lt;/strong&gt;. Distributed systems can retry requests or events after failures. If a repeated operation would create duplicate records, charge a customer twice, or trigger the same action repeatedly, the application needs a strategy to prevent that.&lt;/p&gt;

&lt;p&gt;For asynchronous workflows, services such as Amazon SQS can help decouple components. But queue-based processing also requires careful retry handling, dead-letter queues where appropriate, and idempotent consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. When Should You Use This Architecture?
&lt;/h2&gt;

&lt;p&gt;A serverless API built with API Gateway, Lambda, and DynamoDB is worth considering when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are building a small or medium-sized API.&lt;/li&gt;
&lt;li&gt;Traffic is variable or difficult to predict.&lt;/li&gt;
&lt;li&gt;You want to reduce server administration.&lt;/li&gt;
&lt;li&gt;Your application fits DynamoDB's data model and access patterns.&lt;/li&gt;
&lt;li&gt;You want to integrate backend operations with events from other AWS services.&lt;/li&gt;
&lt;li&gt;You prefer managed services for the initial deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It may be less suitable when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your application depends heavily on relational queries and complex joins.&lt;/li&gt;
&lt;li&gt;You need sustained, long-running processing beyond Lambda's execution limits.&lt;/li&gt;
&lt;li&gt;You require very predictable low latency and have not accounted for initialization behavior.&lt;/li&gt;
&lt;li&gt;Your workload has steady high utilization and another compute model may offer better economics.&lt;/li&gt;
&lt;li&gt;You need operating-system or runtime control that the chosen serverless service does not provide.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are trade-offs, not absolute rules. The best architecture depends on the actual requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. My Main Takeaways
&lt;/h2&gt;

&lt;p&gt;After learning about API Gateway, Lambda, and DynamoDB, I think the biggest benefit of serverless is the change in focus.&lt;/p&gt;

&lt;p&gt;Instead of spending as much time managing servers, you can spend more time designing APIs, writing business logic, securing data access, and understanding how application components interact.&lt;/p&gt;

&lt;p&gt;Here is the mental model I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt; receives and routes API requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda&lt;/strong&gt; executes backend logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt; stores and retrieves data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM&lt;/strong&gt; controls AWS permissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognito or another identity provider&lt;/strong&gt; can support authentication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt; helps monitor and troubleshoot the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQS&lt;/strong&gt; can decouple asynchronous work when the application needs it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But serverless does not mean architecture disappears. You still need to design for security, failures, retries, performance, and cost.&lt;/p&gt;

&lt;p&gt;That is what makes learning AWS interesting: the goal isn't simply to learn what each service does. It's to understand how to combine the services to solve a real problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next?
&lt;/h3&gt;

&lt;p&gt;I'm continuing my AWS learning journey by exploring how these services fit into real application architectures, from containerized backends to serverless APIs and automated deployments.&lt;/p&gt;

&lt;p&gt;If you're also learning AWS, I'd love to hear what you're building and which services you're exploring.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>cloudcomputing</category>
      <category>devops</category>
    </item>
    <item>
      <title>Stop Hardcoding Secrets: How Production Applications Manage Credentials on AWS</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Mon, 12 Oct 2026 05:50:35 +0000</pubDate>
      <link>https://dev.to/anupa_supul/stop-hardcoding-secrets-how-production-applications-manage-credentials-on-aws-2280</link>
      <guid>https://dev.to/anupa_supul/stop-hardcoding-secrets-how-production-applications-manage-credentials-on-aws-2280</guid>
      <description>&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%2F1va78l3fj343wvdpzhnr.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%2F1va78l3fj343wvdpzhnr.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're building a Node.js backend using Express and MongoDB.&lt;/p&gt;

&lt;p&gt;During development, you might have a &lt;code&gt;.env&lt;/code&gt; file containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=5000
MONGO_URI=mongodb+srv://...
JWT_SECRET=...
API_KEY=...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application works perfectly.&lt;/p&gt;

&lt;p&gt;But now imagine pushing the project to GitHub, deploying it through a CI/CD pipeline, and running it on AWS.&lt;/p&gt;

&lt;p&gt;Where should those secrets live?&lt;/p&gt;

&lt;p&gt;Should we put them directly inside the source code? Add them to the Docker image? Store them in GitHub? Or let every developer manage their own copies?&lt;/p&gt;

&lt;p&gt;These questions become important when an application moves from a local development environment to production.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore how &lt;strong&gt;AWS Secrets Manager, Systems Manager Parameter Store, and IAM&lt;/strong&gt; help us manage application configuration and credentials more securely.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Why Hardcoding Secrets Is Dangerous
&lt;/h2&gt;

&lt;p&gt;Let's start with a simple example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-super-secret-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwtSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-jwt-secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may look convenient, but it creates a serious security problem.&lt;/p&gt;

&lt;p&gt;Anyone who can access the source code may also be able to access the credentials.&lt;/p&gt;

&lt;p&gt;If we push these values to a public repository, the secrets could be exposed. Even a private repository can have too many people or automated systems with access.&lt;/p&gt;

&lt;p&gt;There is another problem: what happens when a password changes?&lt;/p&gt;

&lt;p&gt;We may need to modify the code, rebuild the Docker image, and deploy the application again just to update a credential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application code and sensitive configuration should be managed separately.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the principle behind secure secrets management.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What About the &lt;code&gt;.env&lt;/code&gt; File?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;.env&lt;/code&gt; file is useful during local development.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=5000
MONGO_URI=your_database_connection_string
JWT_SECRET=your_jwt_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Node.js application can load these values using a package such as &lt;code&gt;dotenv&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MONGO_URI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps configuration out of the source code itself.&lt;/p&gt;

&lt;p&gt;However, a &lt;code&gt;.env&lt;/code&gt; file is not automatically a secure secrets management system.&lt;/p&gt;

&lt;p&gt;For local development, we should keep it out of Git using &lt;code&gt;.gitignore&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.env
.env.*
!.env.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An &lt;code&gt;.env.example&lt;/code&gt; file can document the required variable names without containing real credentials.&lt;/p&gt;

&lt;p&gt;For production, we need a controlled way to provide those values to our running application.&lt;/p&gt;

&lt;p&gt;That's where AWS services come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. AWS Secrets Manager — Store Sensitive Information
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS Secrets Manager&lt;/strong&gt; is designed to store, retrieve, and manage sensitive information such as database credentials, API keys, and other application secrets.&lt;/p&gt;

&lt;p&gt;For example, we could store a secret containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secret name: production/my-backend

MONGO_URI: ...
JWT_SECRET: ...
THIRD_PARTY_API_KEY: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application retrieves the required secret when it needs it, provided it has the appropriate IAM permissions.&lt;/p&gt;

&lt;p&gt;A simplified 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;Developer
    |
    v
AWS Secrets Manager
    |
    | Authorized access
    v
Application on ECS / Fargate
    |
    v
Connect to Database / External API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that the sensitive values do not need to be hardcoded into our application source code or baked into the Docker image.&lt;/p&gt;

&lt;p&gt;Secrets Manager also supports secret rotation workflows, including integrations and rotation configurations for supported services.&lt;/p&gt;

&lt;p&gt;Rotation still needs to be configured correctly; storing a secret in Secrets Manager does not automatically mean every secret will rotate itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Systems Manager Parameter Store — Manage Configuration
&lt;/h2&gt;

&lt;p&gt;Not every configuration value is a secret.&lt;/p&gt;

&lt;p&gt;Consider these examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_ENV=production
LOG_LEVEL=info
MAX_RETRIES=3
API_BASE_URL=https://api.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These values may need to change between development, testing, and production, but they are not necessarily confidential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Systems Manager Parameter Store&lt;/strong&gt; provides a central place to store application configuration and parameters.&lt;/p&gt;

&lt;p&gt;It supports different parameter types, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;String&lt;/code&gt; — ordinary configuration values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StringList&lt;/code&gt; — comma-separated string values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SecureString&lt;/code&gt; — sensitive values encrypted using AWS KMS.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/my-app/production/LOG_LEVEL
/my-app/production/API_BASE_URL
/my-app/production/DB_PASSWORD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameter Store can help organize configuration by application and environment.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;SecureString&lt;/code&gt; can be useful for encrypted parameters, while Secrets Manager is often a better fit when managed secret lifecycle and rotation features are important.&lt;/p&gt;

&lt;p&gt;The choice depends on the requirements rather than one service being universally better.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Secrets Manager vs Parameter Store
&lt;/h2&gt;

&lt;p&gt;This is where many developers get confused.&lt;/p&gt;

&lt;p&gt;Both services can store sensitive configuration, but their strengths differ.&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;Secrets Manager&lt;/th&gt;
&lt;th&gt;Parameter Store&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Main purpose&lt;/td&gt;
&lt;td&gt;Secret lifecycle management&lt;/td&gt;
&lt;td&gt;Configuration and parameter management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database credentials&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Can store encrypted values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypted values&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, using &lt;code&gt;SecureString&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secret rotation&lt;/td&gt;
&lt;td&gt;Built-in rotation capabilities and integrations&lt;/td&gt;
&lt;td&gt;Usually requires a separate rotation workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ordinary configuration&lt;/td&gt;
&lt;td&gt;Possible&lt;/td&gt;
&lt;td&gt;A natural fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost considerations&lt;/td&gt;
&lt;td&gt;Generally charged for secrets and API usage&lt;/td&gt;
&lt;td&gt;Standard parameters have a free tier; advanced features can incur charges&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example, I might choose Secrets Manager for database credentials that require a managed rotation workflow and Parameter Store for ordinary application settings.&lt;/p&gt;

&lt;p&gt;Both can be useful in the same application.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. IAM — Who Is Allowed to Read the Secrets?
&lt;/h2&gt;

&lt;p&gt;Storing secrets securely is only half of the problem.&lt;/p&gt;

&lt;p&gt;We also need to decide &lt;strong&gt;who or what is allowed to access them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is where AWS Identity and Access Management (IAM) comes in.&lt;/p&gt;

&lt;p&gt;IAM controls access to AWS resources through identities, policies, and roles.&lt;/p&gt;

&lt;p&gt;Imagine our Node.js backend is running as an ECS task on Fargate.&lt;/p&gt;

&lt;p&gt;We want it to retrieve one database secret from Secrets Manager.&lt;/p&gt;

&lt;p&gt;We should not give the application unrestricted access to every secret in the AWS account.&lt;/p&gt;

&lt;p&gt;Instead, we can grant the task permission to retrieve only the required secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS Task
   |
   v
Task Role
   |
   v
IAM Policy
   |
   v
Allowed Secret Only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This follows the &lt;strong&gt;principle of least privilege&lt;/strong&gt;: give each component only the permissions it needs.&lt;/p&gt;

&lt;p&gt;For ECS, there are two roles worth distinguishing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task execution role:&lt;/strong&gt; Used by ECS/Fargate for operations such as pulling private images from ECR and sending logs to supported destinations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task role:&lt;/strong&gt; Provides AWS permissions to the application code running inside the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the application itself calls Secrets Manager, its task role generally needs the appropriate permission.&lt;/p&gt;

&lt;p&gt;If ECS retrieves secrets and injects them into a container as environment variables, the task execution role needs the relevant permissions instead.&lt;/p&gt;

&lt;p&gt;Getting this distinction right helps avoid unnecessary permissions and deployment failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. How Does This Work with Docker and ECS?
&lt;/h2&gt;

&lt;p&gt;Let's connect secrets management to the previous article about Docker, ECR, ECS, and Fargate.&lt;/p&gt;

&lt;p&gt;A common mistake is putting production credentials directly into the Dockerfile.&lt;/p&gt;

&lt;p&gt;For example, this is a bad idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; JWT_SECRET=my-production-secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the value can become part of the image configuration and may be exposed to anyone who can inspect the image.&lt;/p&gt;

&lt;p&gt;Instead, the image should contain the application, while production configuration is supplied separately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Docker Build
                     |
                     v
              Application Image
                     |
                     v
                 Amazon ECR
                     |
                     v
                ECS / Fargate
                     |
                     v
           Runtime Configuration
                     |
           +---------+----------+
           |                    |
           v                    v
     Secrets Manager       Parameter Store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, an ECS task definition can reference a secret stored in Secrets Manager and make it available to the container at startup.&lt;/p&gt;

&lt;p&gt;The application can then read the value through its environment.&lt;/p&gt;

&lt;p&gt;One important detail: when ECS injects a secret into an environment variable, the value is retrieved when the container starts. If the secret changes later, an already-running container does not automatically receive the updated value. A new task deployment or restart may be needed.&lt;/p&gt;

&lt;p&gt;Also, environment variables are convenient, but they can be exposed through debugging tools, process inspection, or logs if handled carelessly. They should never be printed unnecessarily.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Example: A Node.js Backend on AWS
&lt;/h2&gt;

&lt;p&gt;Imagine we deploy a Node.js application using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions for CI/CD.&lt;/li&gt;
&lt;li&gt;Docker for packaging.&lt;/li&gt;
&lt;li&gt;Amazon ECR for storing the image.&lt;/li&gt;
&lt;li&gt;Amazon ECS with Fargate for running the backend.&lt;/li&gt;
&lt;li&gt;Amazon RDS for the database.&lt;/li&gt;
&lt;li&gt;AWS Secrets Manager for database credentials.&lt;/li&gt;
&lt;li&gt;IAM for controlling access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application flow 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;Users
  |
  v
Application Load Balancer
  |
  v
ECS / Fargate
  |
  +-------&amp;gt; Secrets Manager
  |          Database Credentials
  |
  +-------&amp;gt; Amazon RDS
              Application Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend needs permission to retrieve the secret and network access to connect to the database.&lt;/p&gt;

&lt;p&gt;The database should normally be placed in private subnets, with security group rules that allow connections only from the appropriate application tasks.&lt;/p&gt;

&lt;p&gt;Secrets Manager handles secret storage, IAM controls authorization, and the VPC and security groups control network access.&lt;/p&gt;

&lt;p&gt;These are separate security layers working together.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. What About GitHub Actions and CI/CD?
&lt;/h2&gt;

&lt;p&gt;Our previous article explained how GitHub Actions can build Docker images, push them to ECR, and deploy them to ECS.&lt;/p&gt;

&lt;p&gt;The pipeline also needs secure access to AWS.&lt;/p&gt;

&lt;p&gt;A recommended approach is to configure &lt;strong&gt;OpenID Connect (OIDC)&lt;/strong&gt; so GitHub Actions can assume an IAM role and obtain temporary AWS credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Actions
       |
       v
      OIDC
       |
       v
    AWS IAM Role
       |
       v
     Amazon ECR
       |
       v
     Amazon ECS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow role should have only the permissions required for its deployment responsibilities.&lt;/p&gt;

&lt;p&gt;This is different from the IAM task role used by the application after deployment.&lt;/p&gt;

&lt;p&gt;We should also avoid printing secret values in CI logs or passing credentials through command-line arguments unnecessarily.&lt;/p&gt;

&lt;p&gt;The goal is to secure both the deployment process and the application runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. What Should We Choose?
&lt;/h2&gt;

&lt;p&gt;Here is a practical way to decide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Secrets Manager when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need centralized storage for sensitive credentials.&lt;/li&gt;
&lt;li&gt;You need secret rotation capabilities.&lt;/li&gt;
&lt;li&gt;Your application needs controlled access to database passwords or API keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Parameter Store when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need centralized application configuration.&lt;/li&gt;
&lt;li&gt;You want to organize settings by environment.&lt;/li&gt;
&lt;li&gt;You need encrypted parameters and don't require the full Secrets Manager lifecycle features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use IAM when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to control which users, services, or workloads can access AWS resources.&lt;/li&gt;
&lt;li&gt;You want applications to use roles instead of hardcoded AWS access keys.&lt;/li&gt;
&lt;li&gt;You want to enforce least-privilege permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These services are complementary, not direct replacements for one another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Cheat Sheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Main Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local application configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prevents local environment files from being committed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Secrets Manager&lt;/td&gt;
&lt;td&gt;Stores and manages sensitive secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Systems Manager Parameter Store&lt;/td&gt;
&lt;td&gt;Stores configuration and parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SecureString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encrypted Parameter Store value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM Role&lt;/td&gt;
&lt;td&gt;Grants AWS permissions to an identity or workload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS Task Role&lt;/td&gt;
&lt;td&gt;Permissions used by application code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS Task Execution Role&lt;/td&gt;
&lt;td&gt;Permissions used by ECS/Fargate for task startup and related operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub OIDC&lt;/td&gt;
&lt;td&gt;Provides a way for GitHub Actions to obtain temporary AWS credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS KMS&lt;/td&gt;
&lt;td&gt;Manages encryption keys used by supported AWS services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Moving an application to AWS is not just about getting it to run.&lt;/p&gt;

&lt;p&gt;We also need to think about where its credentials live, who can access them, how they are updated, and what happens when those credentials change.&lt;/p&gt;

&lt;p&gt;A local &lt;code&gt;.env&lt;/code&gt; file can be useful during development, but production applications need a more controlled approach.&lt;/p&gt;

&lt;p&gt;Secrets Manager, Parameter Store, and IAM help separate application code from sensitive configuration and enforce controlled access.&lt;/p&gt;

&lt;p&gt;The key lesson is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't hardcode secrets. Don't give every component unrestricted access. Keep configuration, permissions, and application code separate.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I continue learning AWS, I'm finding that production engineering is not only about deploying applications. It's also about making sure they remain secure, maintainable, and reliable after deployment.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>devops</category>
      <category>amazon</category>
    </item>
    <item>
      <title>What Happens When You Push Code to Production? Understanding AWS CI/CD with GitHub Actions, Docker, ECR &amp; ECS</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Mon, 12 Oct 2026 05:43:14 +0000</pubDate>
      <link>https://dev.to/anupa_supul/what-happens-when-you-push-code-to-production-understanding-aws-cicd-with-github-actions-docker-1j5k</link>
      <guid>https://dev.to/anupa_supul/what-happens-when-you-push-code-to-production-understanding-aws-cicd-with-github-actions-docker-1j5k</guid>
      <description>&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%2F5gc499xa5yhbqt4jf0wk.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%2F5gc499xa5yhbqt4jf0wk.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have finished building a Node.js backend. Everything works on your laptop, and you are ready to deploy it.&lt;/p&gt;

&lt;p&gt;Traditionally, you might connect to a server, pull the latest code, install dependencies, restart the application, and hope nothing breaks.&lt;/p&gt;

&lt;p&gt;But what happens when you need to do this every week? Every day? Or several times a day?&lt;/p&gt;

&lt;p&gt;Manually repeating those steps becomes slow, error-prone, and difficult to manage.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;CI/CD&lt;/strong&gt; becomes important.&lt;/p&gt;

&lt;p&gt;After learning Docker, Amazon ECR, ECS, and Fargate, the next question is how to connect them into an automated deployment pipeline.&lt;/p&gt;

&lt;p&gt;Let's follow a simple example: deploying a Node.js application to AWS whenever new code is pushed to GitHub.&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/INSERT_YOUR_UPLOADED_IMAGE_URL_HERE" 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/INSERT_YOUR_UPLOADED_IMAGE_URL_HERE" alt="What Happens When You Push Code to Production? AWS CI/CD with GitHub Actions, Docker, ECR, ECS, and Fargate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. First, What Is CI/CD?
&lt;/h2&gt;

&lt;p&gt;CI/CD is a set of practices that helps developers build, test, and deliver software more reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt; means regularly integrating code changes and automatically checking whether the application still works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Delivery (CD)&lt;/strong&gt; means keeping the application ready for release. With Continuous Deployment, changes that pass the required checks can be deployed automatically to production.&lt;/p&gt;

&lt;p&gt;Think about a team working on the same backend.&lt;/p&gt;

&lt;p&gt;One developer fixes a login bug. Another adds a new API endpoint. Someone else updates the database integration.&lt;/p&gt;

&lt;p&gt;Without automation, every change needs manual checking and deployment.&lt;/p&gt;

&lt;p&gt;With CI/CD, a pipeline can automatically test the changes, build the application, package it into a Docker image, and deploy a new version.&lt;/p&gt;

&lt;p&gt;The basic idea is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write code → Test it → Build it → Deploy it&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Complete AWS CI/CD Architecture
&lt;/h2&gt;

&lt;p&gt;Here is the architecture we will use throughout this article.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 DEVELOPER
                     |
                     v
                   GitHub
                     |
                     v
              GitHub Actions
                     |
              +------+------+
              |             |
              v             v
          Install         Run Tests
         Dependencies       |
              |             |
              +------+------+
                     |
                     v
               Build Docker Image
                     |
                     v
                Amazon ECR
             (Image Registry)
                     |
                     v
                Amazon ECS
                     |
                     v
                AWS Fargate
                     |
                     v
               Running Tasks
                     |
                     v
               Production App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pipeline separates the deployment process into clear responsibilities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; stores the source code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; automates the workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; packages the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon ECR&lt;/strong&gt; stores the container image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon ECS&lt;/strong&gt; manages the deployment and running tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Fargate&lt;/strong&gt; runs the containers without requiring us to manage the underlying EC2 servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each component solves a different problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Step One: Push Code to GitHub
&lt;/h2&gt;

&lt;p&gt;Let's say we update our backend.&lt;/p&gt;

&lt;p&gt;We add a new endpoint, fix a bug, or improve an existing feature.&lt;/p&gt;

&lt;p&gt;After committing the changes, we push them to GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
    |
    v
Local Code Changes
    |
    v
Git Commit
    |
    v
Git Push
    |
    v
GitHub Repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub becomes the starting point for our deployment workflow.&lt;/p&gt;

&lt;p&gt;But pushing code to GitHub does not automatically mean that the code is safe to deploy. We still need to check it.&lt;/p&gt;

&lt;p&gt;That is the responsibility of the next stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Step Two: GitHub Actions Runs the Pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; is a CI/CD automation platform built into GitHub.&lt;/p&gt;

&lt;p&gt;We can define a workflow that runs when someone pushes code to a particular branch or opens a pull request.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code pushed to main
        |
        v
GitHub Actions starts
        |
        v
Install dependencies
        |
        v
Run automated tests
        |
        v
Continue if checks pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A workflow is defined in a YAML file inside the repository, usually under:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;A simplified workflow might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Backend CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example focuses on continuous integration. It checks the code and runs tests, but it does not yet build or deploy the Docker image.&lt;/p&gt;

&lt;p&gt;If the tests fail, we can configure the pipeline to stop before deployment.&lt;/p&gt;

&lt;p&gt;That is important because &lt;strong&gt;automation should prevent broken code from reaching production, not just deploy faster&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Step Three: Build the Docker Image
&lt;/h2&gt;

&lt;p&gt;Once the required checks pass, the next stage is packaging the application.&lt;/p&gt;

&lt;p&gt;This is where Docker connects with the pipeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source Code
     |
     v
Dockerfile
     |
     v
Docker Build
     |
     v
Docker Image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker image contains the application code, its dependencies, and the instructions needed to run it.&lt;/p&gt;

&lt;p&gt;For example, a Node.js backend might use a Dockerfile like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:22&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simplified example. A production Dockerfile should also consider security, image size, dependency management, and which files should be excluded using &lt;code&gt;.dockerignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important point is that the pipeline can build a new image whenever the application changes.&lt;/p&gt;

&lt;p&gt;Instead of manually preparing a server for every release, we produce a consistent application package.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Step Four: Push the Image to Amazon ECR
&lt;/h2&gt;

&lt;p&gt;Now we have a Docker image. Where should it go?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon Elastic Container Registry (ECR)&lt;/strong&gt; is AWS's managed container image registry.&lt;/p&gt;

&lt;p&gt;GitHub Actions can authenticate with AWS, build the image, tag it, and push it to an ECR repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Actions
      |
      v
Docker Image
      |
      v
Amazon ECR
      |
      v
Versioned Image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, we might tag images using the Git commit SHA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-backend:a1b2c3d
my-backend:d4e5f6a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each tag identifies a particular build. This makes it easier to identify which version is running and to deploy a previous version when needed.&lt;/p&gt;

&lt;p&gt;For production, avoid relying only on the mutable &lt;code&gt;latest&lt;/code&gt; tag. Use explicit version tags and, where appropriate, immutable image digests.&lt;/p&gt;

&lt;p&gt;One important security detail: GitHub Actions needs permission to access ECR. A recommended approach is to use &lt;strong&gt;AWS IAM roles with GitHub Actions OpenID Connect (OIDC)&lt;/strong&gt;, so the workflow can obtain temporary AWS credentials without storing long-lived AWS access keys in GitHub secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Step Five: Deploy the New Image to Amazon ECS
&lt;/h2&gt;

&lt;p&gt;The image is now stored in ECR, but it is not running yet.&lt;/p&gt;

&lt;p&gt;We need ECS to deploy it.&lt;/p&gt;

&lt;p&gt;Amazon ECS manages our container workloads. An ECS task definition describes how a container should run, including its image, CPU, memory, ports, and configuration.&lt;/p&gt;

&lt;p&gt;When we deploy a new application version, the pipeline can register or reference an updated task definition and ask the ECS service to deploy it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Docker Image
       |
       v
Amazon ECR
       |
       v
Updated Task Definition
       |
       v
Amazon ECS Service
       |
       v
New Running Tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ECS then manages the deployment according to the service's configuration.&lt;/p&gt;

&lt;p&gt;If we use Fargate, AWS manages the underlying compute infrastructure for the tasks.&lt;/p&gt;

&lt;p&gt;We still need to configure the task's networking, IAM permissions, resource requirements, logging, and other application settings.&lt;/p&gt;

&lt;p&gt;The benefit is that we no longer need to manually log into an EC2 instance to install the application and restart the process after every release.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Step Six: How Does the New Version Reach Users?
&lt;/h2&gt;

&lt;p&gt;Imagine our backend currently has three running tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS SERVICE — VERSION 1

Task 1  ── Version 1
Task 2  ── Version 1
Task 3  ── Version 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we deploy Version 2.&lt;/p&gt;

&lt;p&gt;ECS can use a rolling deployment to gradually replace the old tasks with new ones, according to the service's deployment settings.&lt;br&gt;
&lt;/p&gt;

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

Task 1  ── Version 2
Task 2  ── Version 1
Task 3  ── Version 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task 1  ── Version 2
Task 2  ── Version 2
Task 3  ── Version 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;br&gt;
&lt;/p&gt;

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

Task 1  ── Version 2
Task 2  ── Version 2
Task 3  ── Version 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An Application Load Balancer can route requests to healthy registered targets while the deployment progresses.&lt;/p&gt;

&lt;p&gt;However, a rolling deployment does not automatically guarantee zero downtime. That depends on settings such as health checks, minimum healthy capacity, maximum deployment capacity, and whether the new application version is compatible with existing clients and data.&lt;/p&gt;

&lt;p&gt;This is why deployment configuration matters just as much as the pipeline itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. What If the New Deployment Fails?
&lt;/h2&gt;

&lt;p&gt;Suppose Version 2 contains a bug.&lt;/p&gt;

&lt;p&gt;The application starts, but an API endpoint returns errors.&lt;/p&gt;

&lt;p&gt;A reliable deployment process should not assume that a successful Docker build means the application is healthy.&lt;/p&gt;

&lt;p&gt;We need checks at different stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated tests before building or deploying.&lt;/li&gt;
&lt;li&gt;Container startup and health checks.&lt;/li&gt;
&lt;li&gt;ECS service and deployment status.&lt;/li&gt;
&lt;li&gt;Application logs and metrics.&lt;/li&gt;
&lt;li&gt;Post-deployment smoke tests that verify important endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ECS can replace unhealthy tasks, but replacing a task is not the same as detecting every application bug. A task might be running while its business logic is broken.&lt;/p&gt;

&lt;p&gt;For deployments that fail, ECS deployment circuit breaker settings can help detect failures and optionally roll back to a previous deployment. The pipeline can also stop or trigger further action when post-deployment checks fail.&lt;/p&gt;

&lt;p&gt;The goal is to detect problems quickly and reduce the impact on users.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. CI/CD Is More Than Just Deployment
&lt;/h2&gt;

&lt;p&gt;A common misconception is that CI/CD simply means automatically uploading code to a server.&lt;/p&gt;

&lt;p&gt;A good pipeline should help us deliver changes safely and consistently.&lt;/p&gt;

&lt;p&gt;A more complete workflow might look 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;Developer Pushes Code
          |
          v
   Automated Tests
          |
          v
   Code / Security Checks
          |
          v
    Build Docker Image
          |
          v
     Push Image to ECR
          |
          v
    Deploy to ECS
          |
          v
   Health / Smoke Tests
          |
          v
      Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the project, we might also include dependency vulnerability scanning, infrastructure validation, manual approval before production, and notifications when a deployment succeeds or fails.&lt;/p&gt;

&lt;p&gt;Not every project needs the same pipeline. The right setup depends on the application's risk, team size, compliance requirements, and deployment frequency.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. What About Secrets and Permissions?
&lt;/h2&gt;

&lt;p&gt;Automation needs access to AWS resources, but giving a pipeline unrestricted access is dangerous.&lt;/p&gt;

&lt;p&gt;For example, GitHub Actions may need to push images to ECR and update an ECS service.&lt;/p&gt;

&lt;p&gt;It should not automatically receive permission to modify every resource in the AWS account.&lt;/p&gt;

&lt;p&gt;A safer design uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IAM:&lt;/strong&gt; Grants only the permissions the workflow needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub OIDC:&lt;/strong&gt; Allows GitHub Actions to assume an AWS role using temporary credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Manager or Parameter Store:&lt;/strong&gt; Stores application secrets and configuration where appropriate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS task roles:&lt;/strong&gt; Allow the running application to access specific AWS services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups and VPC networking:&lt;/strong&gt; Restrict network communication between the load balancer, application tasks, and database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is also important to distinguish the deployment pipeline's permissions from the permissions of the running application. They serve different purposes and should be configured separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. The Complete Deployment Architecture
&lt;/h2&gt;

&lt;p&gt;Let's connect the pieces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    DEVELOPER
                        |
                        v
                      GitHub
                        |
                        v
                 GitHub Actions
                        |
              +---------+---------+
              |                   |
              v                   v
          Run Tests          Build Image
                                  |
                                  v
                             Amazon ECR
                                  |
                                  v
                             Amazon ECS
                                  |
                                  v
                             AWS Fargate
                                  |
                                  v
                          Running ECS Tasks
                                  |
                                  v
                                  ALB
                                  |
                                  v
                               USERS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This diagram shows the deployment pipeline and the running application, but they are two different flows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment flow:&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;Code → GitHub Actions → Docker → ECR → ECS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Application request flow:&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;Users → ALB → ECS Tasks → RDS / S3 / Other Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a complete web application, Route 53 and CloudFront can sit in front of the application, while networking, security, monitoring, and scaling support the system.&lt;/p&gt;

&lt;p&gt;The CI/CD pipeline changes how we deliver application versions. It doesn't replace the architecture that serves user requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. GitHub Actions vs AWS CodePipeline
&lt;/h2&gt;

&lt;p&gt;One question worth asking is whether we must use AWS CodePipeline.&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;GitHub Actions can handle CI/CD workflows directly from a GitHub repository. It can run tests, build Docker images, push them to ECR, and trigger ECS deployments.&lt;/p&gt;

&lt;p&gt;AWS CodePipeline is another option for orchestrating release workflows using AWS services.&lt;/p&gt;

&lt;p&gt;The choice depends on the existing development workflow and operational requirements.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GitHub Actions&lt;/th&gt;
&lt;th&gt;AWS CodePipeline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Integrated with GitHub repositories&lt;/td&gt;
&lt;td&gt;Integrated with AWS deployment workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses workflow YAML files&lt;/td&gt;
&lt;td&gt;Uses pipeline stages and actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can build and deploy to AWS&lt;/td&gt;
&lt;td&gt;Can orchestrate AWS and supported external actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convenient when source code is already on GitHub&lt;/td&gt;
&lt;td&gt;Useful when a team wants an AWS-centered pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither is automatically the better choice. A team should consider its existing tools, access controls, deployment process, and maintenance needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model I Keep Now
&lt;/h2&gt;

&lt;p&gt;Before learning CI/CD, my deployment mental model was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Code
    |
    v
Deploy Manually
    |
    v
Restart Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I think about the process as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code
 |
 v
GitHub
 |
 v
Automated Checks
 |
 v
Docker Image
 |
 v
Amazon ECR
 |
 v
Amazon ECS
 |
 v
AWS Fargate
 |
 v
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage has a responsibility.&lt;/p&gt;

&lt;p&gt;GitHub stores the code. GitHub Actions automates the workflow. Docker packages the application. ECR stores the image. ECS manages the deployment. Fargate runs the containers.&lt;/p&gt;

&lt;p&gt;That is the connection between development and production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Cheat Sheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Main Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;Source code management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;CI/CD workflow automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;td&gt;Integrate changes and run checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CD&lt;/td&gt;
&lt;td&gt;Prepare or deliver changes to production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Package the application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECR&lt;/td&gt;
&lt;td&gt;Store container images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;Manage container workloads and deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task Definition&lt;/td&gt;
&lt;td&gt;Describes how a task should run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS Service&lt;/td&gt;
&lt;td&gt;Maintains desired tasks and manages deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fargate&lt;/td&gt;
&lt;td&gt;Runs containers without managing EC2 hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;td&gt;Routes requests to healthy targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch&lt;/td&gt;
&lt;td&gt;Logs, metrics, dashboards, and alarms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM + OIDC&lt;/td&gt;
&lt;td&gt;Control pipeline access to AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;The biggest lesson for me is that deploying an application shouldn't depend on someone remembering a long list of manual steps.&lt;/p&gt;

&lt;p&gt;A well-designed CI/CD pipeline makes those steps repeatable, testable, and easier to monitor.&lt;/p&gt;

&lt;p&gt;It also connects the tools developers use every day with the AWS services that run their applications in production.&lt;/p&gt;

&lt;p&gt;Docker taught me how to package an application. ECR gave that package a place to live. ECS and Fargate showed me how to run it on AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD connects all of them into a repeatable delivery process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's an important step toward understanding not just cloud infrastructure, but how modern software is delivered and operated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The next time you push code to GitHub, think about everything that could happen automatically before that code reaches your users.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code → Test → Build → Package → Deploy → Verify.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>amazonwebservices</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Stopped Managing Servers Manually — Understanding Docker, Amazon ECR, ECS &amp; Fargate</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Tue, 15 Sep 2026 04:59:23 +0000</pubDate>
      <link>https://dev.to/anupa_supul/i-stopped-managing-servers-manually-understanding-docker-amazon-ecr-ecs-fargate-46cn</link>
      <guid>https://dev.to/anupa_supul/i-stopped-managing-servers-manually-understanding-docker-amazon-ecr-ecs-fargate-46cn</guid>
      <description>&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%2Fwed48rnec2sy9shh1txr.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%2Fwed48rnec2sy9shh1txr.png" alt=" " width="800" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  I Stopped Managing Servers Manually — Understanding Docker, Amazon ECR, ECS &amp;amp; Fargate
&lt;/h1&gt;

&lt;p&gt;I had already learned how a web application can be built on AWS using EC2, Load Balancers, Auto Scaling, RDS, S3, SQS, and other services.&lt;/p&gt;

&lt;p&gt;But there was still one question I kept coming back to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if I don't want to manage the server itself?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With EC2, I am still responsible for things like the operating system, installed software, runtime environment, and server configuration.&lt;/p&gt;

&lt;p&gt;But modern applications are increasingly built around &lt;strong&gt;containers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That led me to the next part of my AWS learning journey:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker → Amazon ECR → Amazon ECS → AWS Fargate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And once I understood how these four pieces connect, container deployment on AWS started making much more sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  First, What Problem Are Containers Solving?
&lt;/h2&gt;

&lt;p&gt;Imagine I build a Node.js application on my laptop.&lt;/p&gt;

&lt;p&gt;It works perfectly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js version: 22
Express: installed
Dependencies: installed
Environment: configured
Application: running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I give the application to another developer.&lt;/p&gt;

&lt;p&gt;Suddenly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It works on my machine.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe they have a different Node.js version.&lt;/p&gt;

&lt;p&gt;Maybe a dependency is missing.&lt;/p&gt;

&lt;p&gt;Maybe an environment variable isn't configured.&lt;/p&gt;

&lt;p&gt;Maybe the operating system behaves differently.&lt;/p&gt;

&lt;p&gt;This is one of the problems containers help solve.&lt;/p&gt;

&lt;p&gt;Instead of only shipping our application code, we can package the application together with the environment it needs to run.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Docker&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Docker — Package the Application
&lt;/h1&gt;

&lt;p&gt;Docker allows us to package an application into a &lt;strong&gt;container image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a Node.js backend, the image can contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js
Application code
Dependencies
Configuration needed to run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simplified flow 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;Application Code
       │
       ▼
   Dockerfile
       │
       ▼
 Docker Image
       │
       ▼
   Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important distinction is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image = packaged blueprint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container = running instance of that image&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker Image
     │
     ├── Container 1
     ├── Container 2
     └── Container 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it much easier to run the same application consistently across different environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Dockerfile — The Instructions for the Image
&lt;/h1&gt;

&lt;p&gt;A Docker image is usually created from a &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A simplified Node.js example could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:22&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't need to manually install Node.js on every server.&lt;/p&gt;

&lt;p&gt;The Docker image already defines what the application needs.&lt;/p&gt;

&lt;p&gt;So instead of saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Please configure a server exactly like my development machine.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Run this container.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much more repeatable deployment model.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. But Where Does the Docker Image Go?
&lt;/h1&gt;

&lt;p&gt;Now we have a Docker image.&lt;/p&gt;

&lt;p&gt;But AWS needs somewhere to store it.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Amazon Elastic Container Registry (ECR)&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;ECR is AWS's managed container image registry.&lt;/p&gt;

&lt;p&gt;The flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
    │
    ▼
Dockerfile
    │
    ▼
Docker Build
    │
    ▼
Docker Image
    │
    ▼
Amazon ECR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of ECR as a &lt;strong&gt;private warehouse for container images&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, we might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-backend
my-worker
my-payment-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;inside an ECR repository.&lt;/p&gt;

&lt;p&gt;When we build a new version of the application, we can push a new image to ECR.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. ECR Doesn't Run Our Application
&lt;/h1&gt;

&lt;p&gt;This distinction is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECR stores the image.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It doesn't run the application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECR
 │
 │ stores
 ▼
Docker Image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We still need a service that can take that image and actually run it.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Amazon ECS&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Amazon ECS — Running Containers on AWS
&lt;/h1&gt;

&lt;p&gt;Amazon Elastic Container Service, or &lt;strong&gt;ECS&lt;/strong&gt;, is a container orchestration service.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ECS manages running containers for our application.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The architecture now starts looking like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code
  │
  ▼
Docker Image
  │
  ▼
ECR
  │
  ▼
ECS
  │
  ▼
Running Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But ECS introduces a few concepts that are worth understanding.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. ECS Cluster
&lt;/h1&gt;

&lt;p&gt;An &lt;strong&gt;ECS Cluster&lt;/strong&gt; is a logical grouping of resources used to run our ECS workloads.&lt;/p&gt;

&lt;p&gt;Think of it as the environment where our services run.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production Cluster
       │
       ├── Backend Service
       ├── Worker Service
       └── Payment Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cluster itself isn't simply “one server.”&lt;/p&gt;

&lt;p&gt;It's more useful to think of it as a logical home for our container workloads.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. ECS Task Definition
&lt;/h1&gt;

&lt;p&gt;Now ECS needs to know &lt;strong&gt;how our container should run&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's where a &lt;strong&gt;Task Definition&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;It can describe things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which Docker image?
How much CPU?
How much memory?
Which port?
Environment variables?
IAM permissions?
Logging configuration?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Definition
       │
       ├── Image → ECR
       ├── CPU
       ├── Memory
       ├── Port
       └── Environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is similar to giving ECS a set of instructions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is the container I want you to run, and this is how it should run.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  8. ECS Service — Keeping Containers Running
&lt;/h1&gt;

&lt;p&gt;A task definition tells ECS &lt;strong&gt;how&lt;/strong&gt; to run a container.&lt;/p&gt;

&lt;p&gt;But what if I want three copies of my backend running continuously?&lt;/p&gt;

&lt;p&gt;That's where an &lt;strong&gt;ECS Service&lt;/strong&gt; comes in.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS Service
     │
     ├── Task 1
     ├── Task 2
     └── Task 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service maintains the desired number of tasks.&lt;/p&gt;

&lt;p&gt;If a running task fails, ECS can replace it.&lt;/p&gt;

&lt;p&gt;This is one of the important differences between simply running a container and having a container orchestration system manage it.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Where Does the Container Actually Run?
&lt;/h1&gt;

&lt;p&gt;This is where &lt;strong&gt;AWS Fargate&lt;/strong&gt; becomes interesting.&lt;/p&gt;

&lt;p&gt;ECS can run containers using different compute options.&lt;/p&gt;

&lt;p&gt;One option is managing the underlying EC2 instances yourself.&lt;/p&gt;

&lt;p&gt;Another option is &lt;strong&gt;AWS Fargate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Fargate is a serverless compute engine for containers.&lt;/p&gt;

&lt;p&gt;With Fargate, AWS manages the underlying infrastructure required to run the containers.&lt;/p&gt;

&lt;p&gt;So instead of thinking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS
 ↓
EC2
 ↓
Operating System
 ↓
Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS
 ↓
Fargate
 ↓
Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We still define the container's CPU, memory, networking, and other configuration, but we don't have to manage the underlying EC2 servers ourselves.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. ECS + Fargate Architecture
&lt;/h1&gt;

&lt;p&gt;Now our application starts looking 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;                         USERS
                           │
                           ▼
                       Route 53
                           │
                           ▼
                      CloudFront
                           │
                           ▼
                          ALB
                           │
                           ▼
                     ECS Service
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
          Fargate       Fargate      Fargate
           Task          Task          Task
              │            │            │
              └────────────┼────────────┘
                           │
                           ▼
                           RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ALB distributes requests between the running ECS tasks.&lt;/p&gt;

&lt;p&gt;If one task becomes unhealthy, the service can replace it.&lt;/p&gt;

&lt;p&gt;If traffic increases, we can increase the desired number of tasks.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. What Happens When We Deploy a New Version?
&lt;/h1&gt;

&lt;p&gt;This is where the whole model becomes really powerful.&lt;/p&gt;

&lt;p&gt;Suppose we update our Node.js application.&lt;/p&gt;

&lt;p&gt;We make some changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Version 1
    ↓
Code changes
    ↓
Version 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then build a new Docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source Code
     │
     ▼
Docker Build
     │
     ▼
New Docker Image
     │
     ▼
Amazon ECR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ECS can then deploy the new version.&lt;/p&gt;

&lt;p&gt;The simplified flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
    │
    ▼
GitHub
    │
    ▼
Build Docker Image
    │
    ▼
Amazon ECR
    │
    ▼
ECS Service
    │
    ▼
New Tasks
    │
    ▼
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the foundation for modern container-based CI/CD pipelines.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. What About the Database?
&lt;/h1&gt;

&lt;p&gt;Containers are designed to be replaceable.&lt;/p&gt;

&lt;p&gt;That means we generally shouldn't treat the container itself as the permanent place for important application data.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECS / Fargate
      │
      ├── Application
      │
      ▼
     RDS
      │
      ▼
Persistent Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a container disappears and ECS starts a new one, the application data remains in RDS.&lt;/p&gt;

&lt;p&gt;The same principle applies to files.&lt;/p&gt;

&lt;p&gt;Instead of storing uploaded files inside the container:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;we can use:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
    │
    ├── Database → RDS
    ├── Files → S3
    ├── Cache → ElastiCache
    └── Jobs → SQS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation is extremely important when designing scalable applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. Security Still Matters
&lt;/h1&gt;

&lt;p&gt;Moving from EC2 to containers doesn't mean security disappears.&lt;/p&gt;

&lt;p&gt;We still need to think about:&lt;/p&gt;

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

&lt;p&gt;ECS tasks can use IAM roles to access AWS services without hardcoding AWS credentials into the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Groups
&lt;/h3&gt;

&lt;p&gt;We can control network communication between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALB
 ↓
ECS
 ↓
RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Secrets Manager
&lt;/h3&gt;

&lt;p&gt;Sensitive values such as database credentials and API secrets can be stored securely instead of being hardcoded into the image.&lt;/p&gt;

&lt;h3&gt;
  
  
  VPC
&lt;/h3&gt;

&lt;p&gt;Our ECS tasks can run inside private subnets while the ALB remains publicly reachable.&lt;/p&gt;

&lt;p&gt;So the architecture can still follow a secure pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
    │
    ▼
   ALB
    │
    ▼
Private ECS Tasks
    │
    ├── RDS
    ├── S3
    └── Other AWS Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  14. What Happens When Traffic Increases?
&lt;/h1&gt;

&lt;p&gt;Let's say our application normally runs three tasks:&lt;br&gt;
&lt;/p&gt;

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

Task 1
Task 2
Task 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suddenly, traffic increases.&lt;/p&gt;

&lt;p&gt;We can configure ECS Service Auto Scaling to increase the number of running tasks.&lt;br&gt;
&lt;/p&gt;

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

Task 1
Task 2
Task 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

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

Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ALB distributes traffic across the available healthy tasks.&lt;/p&gt;

&lt;p&gt;This gives us a scalable container architecture without manually logging into servers and starting applications ourselves.&lt;/p&gt;




&lt;h1&gt;
  
  
  15. ECS vs EC2 — What's the Difference?
&lt;/h1&gt;

&lt;p&gt;This was one of the comparisons that helped me understand the purpose of ECS.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;EC2&lt;/th&gt;
&lt;th&gt;ECS + Fargate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manage virtual servers&lt;/td&gt;
&lt;td&gt;Manage containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS management required&lt;/td&gt;
&lt;td&gt;AWS manages underlying infrastructure with Fargate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install runtime manually&lt;/td&gt;
&lt;td&gt;Runtime packaged in container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server-focused&lt;/td&gt;
&lt;td&gt;Container-focused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;More infrastructure control&lt;/td&gt;
&lt;td&gt;Less infrastructure management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling servers&lt;/td&gt;
&lt;td&gt;Scaling container tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither is automatically “better.”&lt;/p&gt;

&lt;p&gt;The right choice depends on the application's requirements, team experience, control requirements, and operational needs.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. ECS vs Lambda
&lt;/h1&gt;

&lt;p&gt;Another useful comparison is ECS vs Lambda.&lt;/p&gt;

&lt;p&gt;Lambda is excellent for event-driven, short-lived workloads where we don't want to manage servers or containers directly.&lt;/p&gt;

&lt;p&gt;ECS is useful when we want more control over a containerized application and its runtime.&lt;/p&gt;

&lt;p&gt;A simplified comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ECS&lt;/th&gt;
&lt;th&gt;Lambda&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container-based&lt;/td&gt;
&lt;td&gt;Function-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-running services are common&lt;/td&gt;
&lt;td&gt;Event-driven execution is common&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;More runtime control&lt;/td&gt;
&lt;td&gt;Less infrastructure management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good for containerized APIs/workers&lt;/td&gt;
&lt;td&gt;Good for many event-driven workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Again, neither service replaces the other.&lt;/p&gt;

&lt;p&gt;The architecture should determine the choice.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. The Complete Flow
&lt;/h1&gt;

&lt;p&gt;Now we can connect everything together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         USER
                           │
                           ▼
                       Route 53
                           │
                           ▼
                      CloudFront
                           │
                           ▼
                          ALB
                           │
                           ▼
                    ECS Service
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
          Fargate       Fargate      Fargate
           Task          Task          Task
              │            │            │
              └────────────┼────────────┘
                           │
             ┌─────────────┼─────────────┐
             ▼             ▼             ▼
            RDS           S3        ElastiCache
         Database      File Storage      Cache
                           │
                           │
                           ▼
                          SQS
                           │
                           ▼
                     Worker Tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the deployment side looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
    │
    ▼
GitHub
    │
    ▼
CI/CD Pipeline
    │
    ▼
Docker Build
    │
    ▼
Amazon ECR
    │
    ▼
Amazon ECS
    │
    ▼
Fargate
    │
    ▼
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have two important flows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application flow&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;User → ALB → ECS → AWS Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deployment flow&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;Code → Docker → ECR → ECS → Fargate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction made the whole architecture much easier for me to understand.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Mental Model I Keep Now
&lt;/h1&gt;

&lt;p&gt;I don't think of ECS, ECR, and Fargate as three unrelated AWS services anymore.&lt;/p&gt;

&lt;p&gt;I think of them as a chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker
   │
   │ Packages
   ▼
ECR
   │
   │ Stores
   ▼
ECS
   │
   │ Manages
   ▼
Fargate
   │
   │ Runs
   ▼
Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In simple words:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; → Package my application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECR&lt;/strong&gt; → Store my image&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECS&lt;/strong&gt; → Manage my containers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fargate&lt;/strong&gt; → Run those containers without managing the underlying servers&lt;/p&gt;

&lt;p&gt;That mental model is much easier to remember than four separate definitions.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Changed My Perspective?
&lt;/h1&gt;

&lt;p&gt;Before learning containers, my mental model was mostly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code
 ↓
EC2
 ↓
Run application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it looks more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code
 ↓
Docker
 ↓
Container Image
 ↓
ECR
 ↓
ECS
 ↓
Fargate
 ↓
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when we connect that with the architecture from my previous AWS article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
Route 53
  ↓
CloudFront
  ↓
ALB
  ↓
ECS / Fargate
  ↓
RDS / S3 / SQS / ElastiCache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS starts looking less like a collection of services and more like a complete platform for running applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  Quick Cheat Sheet
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology / Service&lt;/th&gt;
&lt;th&gt;Main Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Packages applications into containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;Defines how an image is built&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker Image&lt;/td&gt;
&lt;td&gt;Packaged application blueprint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Running instance of an image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECR&lt;/td&gt;
&lt;td&gt;Stores container images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;Orchestrates containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task Definition&lt;/td&gt;
&lt;td&gt;Defines how containers should run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS Service&lt;/td&gt;
&lt;td&gt;Maintains desired running tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fargate&lt;/td&gt;
&lt;td&gt;Runs containers without managing servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;td&gt;Distributes traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDS&lt;/td&gt;
&lt;td&gt;Stores relational data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;td&gt;Stores files and objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQS&lt;/td&gt;
&lt;td&gt;Handles asynchronous jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElastiCache&lt;/td&gt;
&lt;td&gt;Caches frequently accessed data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;td&gt;Controls permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPC&lt;/td&gt;
&lt;td&gt;Provides network isolation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;The biggest shift in my AWS learning wasn't memorizing more services.&lt;/p&gt;

&lt;p&gt;It was learning to ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What problem is this service solving, and where does it fit in the architecture?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I started thinking that way, AWS stopped feeling like a huge list of unrelated services.&lt;/p&gt;

&lt;p&gt;Instead, it started looking like a set of building blocks.&lt;/p&gt;

&lt;p&gt;And when those building blocks are combined properly, we can build applications that are &lt;strong&gt;scalable, secure, highly available, and easier to operate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That, for me, is where learning AWS started becoming much more interesting.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>awsecs</category>
      <category>cloudcomputing</category>
      <category>ecs</category>
    </item>
    <item>
      <title>How a Real Website Works on AWS — Complete AWS Architecture</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Fri, 04 Sep 2026 09:16:17 +0000</pubDate>
      <link>https://dev.to/anupa_supul/how-a-real-website-works-on-aws-complete-aws-architecture-201m</link>
      <guid>https://dev.to/anupa_supul/how-a-real-website-works-on-aws-complete-aws-architecture-201m</guid>
      <description>&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%2Fxu4d7eeb0uxlfsfhynse.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%2Fxu4d7eeb0uxlfsfhynse.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Let’s imagine we are building a &lt;strong&gt;MERN web application&lt;/strong&gt; with a React frontend, Node.js/Express backend, database, file uploads, authentication, and thousands of users.&lt;/p&gt;

&lt;p&gt;This is what the architecture could look like.&lt;/p&gt;


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


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         USERS
                           │
                           ▼
                       Route 53
                           │
                           ▼
                      CloudFront
                       /       \
                      /         \
                     ▼           ▼
                  S3             ALB
             React Frontend      │
                                 ▼
                           Auto Scaling
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
                   EC2          EC2          EC2
                    │            │            │
                    └────────────┼────────────┘
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
                   RDS       ElastiCache      SQS
                Database        Cache        Queue
                    │                         │
                    │                         ▼
                    │                       Worker
                    │
                    ▼
                   S3
              File Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At first, this diagram can look complicated.&lt;/p&gt;

&lt;p&gt;But the important thing is that &lt;strong&gt;each service has a specific responsibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of thinking about AWS as one giant system, think of it as a collection of specialized building blocks.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. What Happens When You Open a Website?
&lt;/h2&gt;

&lt;p&gt;Let's say a user types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.mywebsite.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into their browser.&lt;/p&gt;

&lt;p&gt;The request doesn't simply jump directly to an EC2 server.&lt;/p&gt;

&lt;p&gt;It goes through several layers.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;Route 53&lt;/strong&gt; helps the browser find where the domain should go. The request can then reach &lt;strong&gt;CloudFront&lt;/strong&gt;, AWS's content delivery network.&lt;/p&gt;

&lt;p&gt;CloudFront decides where the request should be served from.&lt;/p&gt;

&lt;p&gt;If the user requests a React file such as JavaScript, CSS, or an image, CloudFront can retrieve it from &lt;strong&gt;Amazon S3&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the request is something like:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;CloudFront can send it toward the backend through an &lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So even before our backend receives the request, AWS has already handled DNS, content delivery, and traffic routing.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Route 53 — Finding Our Website
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Amazon Route 53&lt;/strong&gt; is AWS's DNS service.&lt;/p&gt;

&lt;p&gt;DNS is basically the system that translates a human-friendly domain name into a destination.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.mywebsite.com
        ↓
     DNS lookup
        ↓
   CloudFront
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without DNS, users would need to remember an IP address instead of a domain name.&lt;/p&gt;

&lt;p&gt;Route 53 therefore acts like the &lt;strong&gt;phone book of our website&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It doesn't run our frontend or backend. Its job is mainly to help users find the correct destination.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. CloudFront — Bringing Content Closer to Users
&lt;/h2&gt;

&lt;p&gt;Once Route 53 points the request toward CloudFront, CloudFront can handle the delivery of content.&lt;/p&gt;

&lt;p&gt;CloudFront is a &lt;strong&gt;CDN (Content Delivery Network)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine our application is hosted in a region far away from a user. Sending every image, JavaScript file, and CSS file all the way from our origin would add unnecessary latency.&lt;/p&gt;

&lt;p&gt;CloudFront solves this by caching content at locations around the world called &lt;strong&gt;edge locations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So a simplified flow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  │
  ▼
CloudFront Edge Location
  │
  ├── Cached content → Return immediately
  │
  └── Not cached → Ask the origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful for static content such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React JavaScript files&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Videos&lt;/li&gt;
&lt;li&gt;Documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can also sit in front of our API and work with services such as AWS WAF.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. React Frontend — Where Users Interact
&lt;/h2&gt;

&lt;p&gt;Our React application is the part users actually see.&lt;/p&gt;

&lt;p&gt;The frontend contains things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login page
Dashboard
Profile
Products
Buttons
Forms
Images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because a React production build consists largely of static files, we don't necessarily need an EC2 server just to serve those files.&lt;/p&gt;

&lt;p&gt;We can store the built frontend in &lt;strong&gt;Amazon S3&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React Project
     │
     ▼
npm run build
     │
     ▼
HTML + CSS + JS
     │
     ▼
Amazon S3
     │
     ▼
CloudFront
     │
     ▼
Users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the first things that changed how I looked at AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not everything needs a traditional server.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Application Load Balancer — Sending Users to the Right Server
&lt;/h2&gt;

&lt;p&gt;Now suppose the frontend calls our backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/login
GET /api/products
POST /api/orders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't want every user connecting directly to one EC2 instance.&lt;/p&gt;

&lt;p&gt;Instead, requests can go through an &lt;strong&gt;Application Load Balancer (ALB)&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;                  ALB
                   │
        ┌──────────┼──────────┐
        ▼          ▼          ▼
       EC2        EC2        EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ALB distributes incoming requests across healthy backend instances.&lt;/p&gt;

&lt;p&gt;It also performs &lt;strong&gt;health checks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, if one EC2 instance stops responding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 #1 → Healthy
EC2 #2 → Healthy
EC2 #3 → Unhealthy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ALB can stop sending new requests to the unhealthy instance.&lt;/p&gt;

&lt;p&gt;This is much more reliable than depending on a single server.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. EC2 + Auto Scaling — Running the Backend
&lt;/h2&gt;

&lt;p&gt;Our Node.js and Express backend can run on &lt;strong&gt;Amazon EC2&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React
  │
  ▼
API Request
  │
  ▼
ALB
  │
  ├── EC2 #1
  ├── EC2 #2
  └── EC2 #3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what happens when traffic suddenly increases?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;EC2 Auto Scaling&lt;/strong&gt; becomes important.&lt;/p&gt;

&lt;p&gt;During normal traffic:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;During heavy traffic:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;During extremely high traffic:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The exact numbers depend on how we configure the scaling policy.&lt;/p&gt;

&lt;p&gt;The important idea is that &lt;strong&gt;Auto Scaling adjusts computing capacity based on demand&lt;/strong&gt;, while the ALB distributes traffic between the available instances.&lt;/p&gt;

&lt;p&gt;These two services solve different problems:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Main Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;td&gt;Distributes requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto Scaling&lt;/td&gt;
&lt;td&gt;Adjusts number of EC2 instances&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;td&gt;Runs our application&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  7. RDS — Where Our Application Data Lives
&lt;/h2&gt;

&lt;p&gt;Our backend needs somewhere to store permanent data.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Orders
Products
Payments
Messages
Profiles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where &lt;strong&gt;Amazon RDS&lt;/strong&gt; can be used.&lt;/p&gt;

&lt;p&gt;Instead of installing and maintaining a database manually on an EC2 server, RDS provides a managed relational database environment.&lt;/p&gt;

&lt;p&gt;The backend might perform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React
  ↓
ALB
  ↓
EC2
  ↓
RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, when a user creates an account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User submits signup form
        ↓
React sends API request
        ↓
Backend receives request
        ↓
Backend validates data
        ↓
Backend writes user to RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database should normally be placed in &lt;strong&gt;private subnets&lt;/strong&gt;, rather than being directly exposed to the public internet.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. S3 — Not Just for the Frontend
&lt;/h2&gt;

&lt;p&gt;One thing that can easily confuse beginners is S3.&lt;/p&gt;

&lt;p&gt;S3 is &lt;strong&gt;object storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It can store much more than React files.&lt;/p&gt;

&lt;p&gt;Our application might allow users to upload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Profile pictures
PDF files
Documents
Product images
Videos
Reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of putting these large files inside the database, we can store them in S3.&lt;/p&gt;

&lt;p&gt;The database can then store information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User ID
File name
S3 object key
Upload date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can think of it like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RDS → Application data
S3  → Files / Objects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation makes the architecture easier to scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. SQS — When Everything Doesn't Need to Happen Immediately
&lt;/h2&gt;

&lt;p&gt;Some operations don't need to happen while the user is waiting.&lt;/p&gt;

&lt;p&gt;Imagine a user uploads a video.&lt;/p&gt;

&lt;p&gt;Our application might need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save the file&lt;/li&gt;
&lt;li&gt;Generate thumbnails&lt;/li&gt;
&lt;li&gt;Process the video&lt;/li&gt;
&lt;li&gt;Send an email&lt;/li&gt;
&lt;li&gt;Update another system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing everything inside the original request could make the application slow.&lt;/p&gt;

&lt;p&gt;Instead, we can use &lt;strong&gt;Amazon SQS&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;User
 │
 ▼
Backend
 │
 ▼
SQS Queue
 │
 ▼
Worker
 │
 ├── Process file
 ├── Send email
 └── Perform background task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend can put a message into the queue and respond to the user.&lt;/p&gt;

&lt;p&gt;A worker can process the job separately.&lt;/p&gt;

&lt;p&gt;This creates &lt;strong&gt;decoupling&lt;/strong&gt; between different parts of the system.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. ElastiCache — Making Frequent Requests Faster
&lt;/h2&gt;

&lt;p&gt;Not every piece of data needs to be fetched from the database every time.&lt;/p&gt;

&lt;p&gt;Imagine thousands of users are requesting the same popular information.&lt;/p&gt;

&lt;p&gt;Instead of repeatedly doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 → RDS → Return data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can cache frequently accessed data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2
 │
 ▼
ElastiCache
 │
 ├── Data found → Return quickly
 │
 └── Data missing → Query RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ElastiCache&lt;/strong&gt; can provide an in-memory cache using technologies such as Redis/Valkey or Memcached.&lt;/p&gt;

&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Database = persistent source of data&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Cache = fast temporary copy of frequently used data&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caching is an optimization, so it isn't required for every application.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Security — Protecting the Architecture
&lt;/h2&gt;

&lt;p&gt;Now we have a working architecture, but putting everything on the internet would be a terrible idea.&lt;/p&gt;

&lt;p&gt;Security needs to exist at multiple layers.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;AWS IAM&lt;/strong&gt; controls who or what can access AWS resources.&lt;/p&gt;

&lt;p&gt;For example, instead of putting AWS access keys directly inside our Node.js code, we can give an EC2 instance an appropriate &lt;strong&gt;IAM role&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;EC2
 │
 ▼
IAM Role
 │
 ▼
Allowed AWS Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application gets only the permissions it actually needs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Security Groups
&lt;/h3&gt;

&lt;p&gt;Security Groups act like virtual firewalls around AWS resources.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
   │
   ▼
  ALB
   │
   ▼
  EC2
   │
   ▼
  RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can configure rules such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet → ALB       ✅
ALB → EC2             ✅
EC2 → RDS             ✅
Internet → RDS        ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much safer than exposing the database directly to the internet.&lt;/p&gt;




&lt;h3&gt;
  
  
  AWS WAF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AWS WAF&lt;/strong&gt; protects web applications by inspecting incoming HTTP/HTTPS requests.&lt;/p&gt;

&lt;p&gt;It can help block things such as malicious or unwanted web requests based on configured rules.&lt;/p&gt;

&lt;p&gt;A simplified security flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
   │
   ▼
  WAF
   │
   ▼
CloudFront
   │
   ▼
  ALB
   │
   ▼
  EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Secrets Manager
&lt;/h3&gt;

&lt;p&gt;Our application also needs sensitive information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database password
API keys
Application secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These shouldn't simply be written directly inside source code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Secrets Manager&lt;/strong&gt; provides a safer place to store and retrieve secrets.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. VPC — The Network Behind Everything
&lt;/h2&gt;

&lt;p&gt;All of these services don't just randomly exist on the internet.&lt;/p&gt;

&lt;p&gt;Our backend architecture can be placed inside an &lt;strong&gt;Amazon VPC (Virtual Private Cloud)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A simple design could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    VPC
                     │
          ┌──────────┴──────────┐
          │                     │
    Public Subnets        Private Subnets
          │                     │
         ALB              EC2 / RDS / Cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The public and private subnet design helps control which resources can be reached from the internet.&lt;/p&gt;

&lt;p&gt;For a production architecture, we would normally distribute resources across multiple &lt;strong&gt;Availability Zones&lt;/strong&gt; to improve availability.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Monitoring — Knowing What Is Happening
&lt;/h2&gt;

&lt;p&gt;Building the infrastructure isn't enough.&lt;/p&gt;

&lt;p&gt;We also need to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is the application healthy?&lt;/p&gt;

&lt;p&gt;Are servers running out of resources?&lt;/p&gt;

&lt;p&gt;Are requests failing?&lt;/p&gt;

&lt;p&gt;Is traffic increasing?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where &lt;strong&gt;Amazon CloudWatch&lt;/strong&gt; becomes useful.&lt;/p&gt;

&lt;p&gt;CloudWatch can provide metrics, logs, dashboards, and alarms.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU usage &amp;gt; threshold
        ↓
CloudWatch Alarm
        ↓
Auto Scaling / Notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For auditing AWS API activity, &lt;strong&gt;CloudTrail&lt;/strong&gt; records account and API activity.&lt;/p&gt;

&lt;p&gt;So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CloudWatch → Monitoring &amp;amp; Logs
CloudTrail  → AWS Activity &amp;amp; Auditing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. HTTPS — Encrypting Communication
&lt;/h2&gt;

&lt;p&gt;When users access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.mywebsite.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;their communication should be encrypted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Certificate Manager (ACM)&lt;/strong&gt; can provide and manage TLS certificates for supported AWS services.&lt;/p&gt;

&lt;p&gt;So instead of sending sensitive information over plain HTTP, we use HTTPS.&lt;/p&gt;

&lt;p&gt;This is especially important for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login credentials&lt;/li&gt;
&lt;li&gt;Personal information&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;API requests&lt;/li&gt;
&lt;li&gt;Session information&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  15. Putting Everything Together
&lt;/h2&gt;

&lt;p&gt;Now the individual services should make much more sense.&lt;/p&gt;

&lt;p&gt;The complete request path can be summarized 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;                         USER
                           │
                           ▼
                       Route 53
                           │
                           ▼
                      CloudFront
                       /       \
                      /         \
                     ▼           ▼
                  S3             ALB
             React Frontend      │
                                 ▼
                           Auto Scaling
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
                   EC2          EC2          EC2
                    │            │            │
                    └────────────┼────────────┘
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
                   RDS       ElastiCache      SQS
                Database        Cache        Queue
                    │                         │
                    │                         ▼
                    │                       Worker
                    │
                    ▼
                   S3
              File Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And around this architecture we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IAM
Security Groups
WAF
Secrets Manager
ACM
CloudWatch
CloudTrail
VPC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These aren't just extra AWS services added to make the diagram look impressive.&lt;/p&gt;

&lt;p&gt;Each one solves a different operational problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Most Important Thing I Learned
&lt;/h1&gt;

&lt;p&gt;When I first started learning AWS, I looked at services individually.&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
S3 = Storage
RDS = Database
Route 53 = DNS
CloudFront = CDN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is useful for getting started.&lt;/p&gt;

&lt;p&gt;But real cloud architecture is about understanding &lt;strong&gt;how those services work together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A real application isn't just:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
 ↓
DNS
 ↓
CDN
 ↓
Load Balancer
 ↓
Application Servers
 ↓
Database / Cache / Queue / Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And surrounding all of that are networking, security, monitoring, and scaling mechanisms.&lt;/p&gt;

&lt;p&gt;That's when AWS started making much more sense to me.&lt;/p&gt;




&lt;h1&gt;
  
  
  Quick Cheat Sheet
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;AWS Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Domain / DNS&lt;/td&gt;
&lt;td&gt;Route 53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN&lt;/td&gt;
&lt;td&gt;CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React static files&lt;/td&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load balancing&lt;/td&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic scaling&lt;/td&gt;
&lt;td&gt;Auto Scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relational database&lt;/td&gt;
&lt;td&gt;RDS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File storage&lt;/td&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background jobs&lt;/td&gt;
&lt;td&gt;SQS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;td&gt;ElastiCache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions&lt;/td&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network isolation&lt;/td&gt;
&lt;td&gt;VPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firewall rules&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web protection&lt;/td&gt;
&lt;td&gt;WAF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets&lt;/td&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTPS certificates&lt;/td&gt;
&lt;td&gt;ACM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;CloudWatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS activity auditing&lt;/td&gt;
&lt;td&gt;CloudTrail&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;The biggest shift in my AWS learning wasn't memorizing more services.&lt;/p&gt;

&lt;p&gt;It was learning to ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What problem is this service solving, and where does it fit in the architecture?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I started thinking that way, AWS stopped feeling like a huge list of unrelated services.&lt;/p&gt;

&lt;p&gt;Instead, it started looking like a set of building blocks.&lt;/p&gt;

&lt;p&gt;And when those building blocks are combined properly, we can build applications that are &lt;strong&gt;scalable, secure, highly available, and easier to operate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That, for me, is where learning AWS started becoming much more interesting.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amzon</category>
      <category>cloudcomputing</category>
      <category>amazonarchtecture</category>
    </item>
    <item>
      <title>Where Does My Website Actually Store Its Data? Understanding Amazon RDS</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Mon, 17 Aug 2026 04:56:29 +0000</pubDate>
      <link>https://dev.to/anupa_supul/where-does-my-website-actually-store-its-data-understanding-amazon-rds-47oo</link>
      <guid>https://dev.to/anupa_supul/where-does-my-website-actually-store-its-data-understanding-amazon-rds-47oo</guid>
      <description>&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%2Fsqfuvh8beqrtns53tlax.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%2Fsqfuvh8beqrtns53tlax.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After learning how to run applications on EC2, I started thinking about something I had never really questioned before.&lt;/p&gt;

&lt;p&gt;Where does all the data actually go?&lt;/p&gt;

&lt;p&gt;When a user creates an account, where is that account stored?&lt;/p&gt;

&lt;p&gt;When someone places an order, where does the order information live?&lt;/p&gt;

&lt;p&gt;When I update my profile, how does the application remember that change the next time I log in?&lt;/p&gt;

&lt;p&gt;As a MERN developer, I already understood the idea of a database.&lt;/p&gt;

&lt;p&gt;I had worked with MongoDB and Mongoose.&lt;/p&gt;

&lt;p&gt;But AWS made me think about the bigger question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How do you run and manage a database reliably in the cloud?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's when I started learning about &lt;strong&gt;Amazon RDS&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem I Started With
&lt;/h2&gt;

&lt;p&gt;Imagine I deploy my backend on an EC2 instance.&lt;/p&gt;

&lt;p&gt;My application is running perfectly.&lt;/p&gt;

&lt;p&gt;A user signs up.&lt;/p&gt;

&lt;p&gt;Their information needs to be saved somewhere.&lt;/p&gt;

&lt;p&gt;So my application needs a database.&lt;/p&gt;

&lt;p&gt;The basic idea 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;User
  │
  ▼
Backend
  │
  ▼
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, this seems simple.&lt;/p&gt;

&lt;p&gt;But then I started thinking about everything that comes with managing a real database.&lt;/p&gt;

&lt;p&gt;Someone has to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the database&lt;/li&gt;
&lt;li&gt;Configure it&lt;/li&gt;
&lt;li&gt;Manage updates&lt;/li&gt;
&lt;li&gt;Take backups&lt;/li&gt;
&lt;li&gt;Monitor it&lt;/li&gt;
&lt;li&gt;Handle failures&lt;/li&gt;
&lt;li&gt;Protect it&lt;/li&gt;
&lt;li&gt;Recover it when something goes wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a lot of responsibility.&lt;/p&gt;

&lt;p&gt;And this is where managed database services become useful.&lt;/p&gt;




&lt;h1&gt;
  
  
  So What Is Amazon RDS?
&lt;/h1&gt;

&lt;p&gt;The simplest way I understand Amazon RDS is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Amazon RDS is a managed relational database service from AWS.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of manually setting up and maintaining a relational database server yourself, AWS manages much of the underlying database infrastructure for you.&lt;/p&gt;

&lt;p&gt;RDS supports database engines such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;MariaDB&lt;/li&gt;
&lt;li&gt;Oracle&lt;/li&gt;
&lt;li&gt;SQL Server&lt;/li&gt;
&lt;li&gt;Amazon Aurora&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of spending most of my time managing the database server itself, I can focus more on my application and the data.&lt;/p&gt;




&lt;h1&gt;
  
  
  Running a Database Yourself vs RDS
&lt;/h1&gt;

&lt;p&gt;This comparison helped me understand the difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  If I Manage Everything Myself
&lt;/h3&gt;

&lt;p&gt;Imagine I launch an EC2 instance and install MySQL manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2
 │
 ├── Operating System
 ├── MySQL
 ├── Configuration
 ├── Updates
 ├── Backups
 └── Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I'm responsible for all of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  With Amazon RDS
&lt;/h3&gt;

&lt;p&gt;With RDS, the architecture becomes much simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     │
     ▼
Amazon RDS
     │
     ▼
Relational Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS handles much of the underlying infrastructure.&lt;/p&gt;

&lt;p&gt;That doesn't mean I have no responsibility.&lt;/p&gt;

&lt;p&gt;I still need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database design&lt;/li&gt;
&lt;li&gt;Queries&lt;/li&gt;
&lt;li&gt;Users and permissions&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Application configuration&lt;/li&gt;
&lt;li&gt;Cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But AWS takes care of many infrastructure-level tasks.&lt;/p&gt;




&lt;h1&gt;
  
  
  A Real-World Example
&lt;/h1&gt;

&lt;p&gt;Imagine I build an online store.&lt;/p&gt;

&lt;p&gt;A customer creates an account.&lt;/p&gt;

&lt;p&gt;Then they add a product to their cart.&lt;/p&gt;

&lt;p&gt;Finally, they place an order.&lt;/p&gt;

&lt;p&gt;The application needs to store information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
    │
    ├── Account
    │
    ├── Orders
    │
    ├── Products
    │
    └── Inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A relational database is useful for this kind of structured data.&lt;/p&gt;

&lt;p&gt;The application architecture could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  │
  ▼
Frontend
  │
  ▼
Backend API
  │
  ▼
Amazon RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend doesn't directly communicate with the database.&lt;/p&gt;

&lt;p&gt;The backend handles that communication.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Shouldn't Users Connect Directly to the Database?
&lt;/h1&gt;

&lt;p&gt;This was another thing that became clear to me while learning AWS.&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet Users
      │
      ▼
   Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would be a terrible architecture.&lt;/p&gt;

&lt;p&gt;You don't want random internet users connecting directly to your database.&lt;/p&gt;

&lt;p&gt;Instead, we want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet Users
      │
      ▼
   Frontend
      │
      ▼
  Backend API
      │
      ▼
  Amazon RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend controls how the application communicates with the database.&lt;/p&gt;

&lt;p&gt;Security Groups can also be configured so the database only accepts connections from the backend resources that actually need access.&lt;/p&gt;

&lt;p&gt;That creates a much safer architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Happens If the Database Fails?
&lt;/h1&gt;

&lt;p&gt;This is where managing databases gets interesting.&lt;/p&gt;

&lt;p&gt;Imagine my application has thousands of users.&lt;/p&gt;

&lt;p&gt;Everything is working.&lt;/p&gt;

&lt;p&gt;Then suddenly, the database server experiences a failure.&lt;/p&gt;

&lt;p&gt;What happens to the application?&lt;/p&gt;

&lt;p&gt;If I manually manage the database, I have to think about how to recover it.&lt;/p&gt;

&lt;p&gt;RDS provides features designed to improve database availability and recovery.&lt;/p&gt;

&lt;p&gt;One important feature is &lt;strong&gt;Multi-AZ deployment&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Multi-AZ
&lt;/h1&gt;

&lt;p&gt;With Multi-AZ, AWS can maintain a standby database instance in another Availability Zone.&lt;/p&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 AWS Region
                     │
          ┌──────────┴──────────┐
          │                     │
          ▼                     ▼
 Availability Zone A      Availability Zone B
          │                     │
          ▼                     ▼
     Primary RDS            Standby RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application normally communicates with the primary database.&lt;/p&gt;

&lt;p&gt;If a failure occurs, AWS can fail over to the standby.&lt;/p&gt;

&lt;p&gt;What I found interesting here is that high availability isn't simply about having a backup file.&lt;/p&gt;

&lt;p&gt;It's about designing the system so it can continue operating when something goes wrong.&lt;/p&gt;




&lt;h1&gt;
  
  
  What About Backups?
&lt;/h1&gt;

&lt;p&gt;Another thing I started appreciating about managed databases is backups.&lt;/p&gt;

&lt;p&gt;Imagine I accidentally delete important data.&lt;/p&gt;

&lt;p&gt;Without a backup strategy, recovering it could become a nightmare.&lt;/p&gt;

&lt;p&gt;RDS provides automated backup capabilities and supports database snapshots.&lt;/p&gt;

&lt;p&gt;So instead of thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'll configure backups later."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can make backups part of the infrastructure from the beginning.&lt;/p&gt;

&lt;p&gt;That was another important mindset shift for me.&lt;/p&gt;




&lt;h1&gt;
  
  
  What If My Application Gets Bigger?
&lt;/h1&gt;

&lt;p&gt;Let's say my application starts with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then it grows to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And eventually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,000,000 users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database now has much more work to handle.&lt;/p&gt;

&lt;p&gt;Eventually, database scaling becomes its own engineering problem.&lt;/p&gt;

&lt;p&gt;Depending on the workload, there are different ways to improve database performance and capacity.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Increasing the database instance size&lt;/li&gt;
&lt;li&gt;Using read replicas&lt;/li&gt;
&lt;li&gt;Adding caching&lt;/li&gt;
&lt;li&gt;Optimizing queries&lt;/li&gt;
&lt;li&gt;Choosing the right database architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So scaling isn't only about EC2.&lt;/p&gt;

&lt;p&gt;The database needs to scale too.&lt;/p&gt;




&lt;h1&gt;
  
  
  RDS With Everything I've Learned So Far
&lt;/h1&gt;

&lt;p&gt;This was probably the most useful part for me.&lt;/p&gt;

&lt;p&gt;I've already learned about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Route 53&lt;/li&gt;
&lt;li&gt;CloudFront&lt;/li&gt;
&lt;li&gt;Elastic Load Balancer&lt;/li&gt;
&lt;li&gt;EC2&lt;/li&gt;
&lt;li&gt;Auto Scaling&lt;/li&gt;
&lt;li&gt;Security Groups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now I can finally see where the database fits into the bigger picture.&lt;/p&gt;

&lt;p&gt;A simplified AWS architecture could look 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;Users
  │
  ▼
Route 53
  │
  ▼
CloudFront
  │
  ▼
Load Balancer
  │
  ▼
Auto Scaling Group
  │
  ▼
EC2 Instances
  │
  ▼
Amazon RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each service has a different responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route 53&lt;/strong&gt; helps users find the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CloudFront&lt;/strong&gt; helps deliver content efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load Balancer&lt;/strong&gt; distributes incoming traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto Scaling&lt;/strong&gt; adjusts the number of EC2 instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2&lt;/strong&gt; runs the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RDS&lt;/strong&gt; stores the relational data.&lt;/p&gt;

&lt;p&gt;Seeing all these pieces together made AWS feel much less like a list of services and more like an actual system.&lt;/p&gt;




&lt;h1&gt;
  
  
  One Thing I Finally Understood
&lt;/h1&gt;

&lt;p&gt;Before learning AWS, I mostly thought about databases from the application developer's perspective.&lt;/p&gt;

&lt;p&gt;I would:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Database
      ↓
Connect Backend
      ↓
Write Queries
      ↓
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But production systems are different.&lt;/p&gt;

&lt;p&gt;Now I have to ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What happens if it fails?
        ↓
How are backups handled?
        ↓
Who can access it?
        ↓
Can it scale?
        ↓
How do I keep it available?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those questions become increasingly important as an application grows.&lt;/p&gt;




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

&lt;p&gt;After learning EC2, ELB, Auto Scaling, and RDS, I started seeing cloud architecture differently.&lt;/p&gt;

&lt;p&gt;It's not about memorizing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"EC2 does this."&lt;/p&gt;

&lt;p&gt;"RDS does that."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's about understanding how the pieces work together.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Users
                      │
                      ▼
                  Route 53
                      │
                      ▼
                 CloudFront
                      │
                      ▼
              Load Balancer
                      │
                      ▼
              Auto Scaling
                 │      │
                 ▼      ▼
               EC2     EC2
                 │      │
                 └──┬───┘
                    │
                    ▼
                Amazon RDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the architecture actually tells a story.&lt;/p&gt;

&lt;p&gt;Users arrive.&lt;/p&gt;

&lt;p&gt;Traffic is routed.&lt;/p&gt;

&lt;p&gt;Content is delivered.&lt;/p&gt;

&lt;p&gt;Requests are distributed.&lt;/p&gt;

&lt;p&gt;Servers scale.&lt;/p&gt;

&lt;p&gt;The application runs.&lt;/p&gt;

&lt;p&gt;Data is stored.&lt;/p&gt;

&lt;p&gt;That's when AWS started making much more sense to me.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Changed My Perspective
&lt;/h1&gt;

&lt;p&gt;Before learning AWS, I thought about databases mainly as something my application connects to.&lt;/p&gt;

&lt;p&gt;Now I understand that the database itself is an important part of the architecture.&lt;/p&gt;

&lt;p&gt;Questions like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens if the database fails?&lt;/p&gt;

&lt;p&gt;How do I protect it?&lt;/p&gt;

&lt;p&gt;How do I back it up?&lt;/p&gt;

&lt;p&gt;How will it handle more users?&lt;/p&gt;

&lt;p&gt;How do I make it highly available?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These aren't just database questions.&lt;/p&gt;

&lt;p&gt;They're &lt;strong&gt;system design questions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's probably the biggest thing RDS taught me.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;When I first started learning AWS, EC2 was exciting because I could actually see my application running on a cloud server.&lt;/p&gt;

&lt;p&gt;But RDS taught me something different.&lt;/p&gt;

&lt;p&gt;Running an application is only one part of the system.&lt;/p&gt;

&lt;p&gt;The application also needs somewhere reliable to store the information that makes it useful.&lt;/p&gt;

&lt;p&gt;And managing that database involves much more than simply creating a database and connecting to it.&lt;/p&gt;

&lt;p&gt;That's where managed services like Amazon RDS become valuable.&lt;/p&gt;

&lt;p&gt;For me, the biggest lesson was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A database isn't just where data lives. It's part of the architecture that needs to be designed for security, availability, backups, and growth.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more I learn AWS, the more I realize that building software isn't only about making the application work.&lt;/p&gt;

&lt;p&gt;It's about making sure the entire system can keep working when real users start depending on it.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 What I'm Learning Next
&lt;/h3&gt;

&lt;p&gt;The more AWS services I learn, the more I realize that each one solves a different piece of the same puzzle.&lt;/p&gt;

&lt;p&gt;EC2 taught me where applications can run.&lt;/p&gt;

&lt;p&gt;ELB taught me how traffic can be distributed.&lt;/p&gt;

&lt;p&gt;Auto Scaling taught me how applications can adapt to demand.&lt;/p&gt;

&lt;p&gt;And RDS taught me where the application's important data can live reliably.&lt;/p&gt;

&lt;p&gt;The next step is understanding how these pieces work together in a real application.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm continuing to document my AWS learning journey by taking the concepts I learn and explaining them in the simplest way I can.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're learning AWS too, I hope this made Amazon RDS a little easier to understand.&lt;/em&gt;&lt;/p&gt;

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

</description>
      <category>aws</category>
      <category>amzon</category>
      <category>cloudcomputing</category>
      <category>rds</category>
    </item>
    <item>
      <title>Why Doesn't My Website Crash When Thousands of People Visit? Understanding Amazon EC2</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Fri, 31 Jul 2026 10:16:11 +0000</pubDate>
      <link>https://dev.to/anupa_supul/why-doesnt-my-website-crash-when-thousands-of-people-visit-understanding-amazon-ec2-3o7c</link>
      <guid>https://dev.to/anupa_supul/why-doesnt-my-website-crash-when-thousands-of-people-visit-understanding-amazon-ec2-3o7c</guid>
      <description>&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%2Ftmaztz6gozt9stwo0l4j.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%2Ftmaztz6gozt9stwo0l4j.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first started learning AWS, I assumed that if a website became popular, the solution was simple.&lt;/p&gt;

&lt;p&gt;Buy a bigger server.&lt;/p&gt;

&lt;p&gt;More CPU.&lt;/p&gt;

&lt;p&gt;More RAM.&lt;/p&gt;

&lt;p&gt;More storage.&lt;/p&gt;

&lt;p&gt;Problem solved.&lt;/p&gt;

&lt;p&gt;But then I started thinking about websites like Netflix, Amazon, and Instagram.&lt;/p&gt;

&lt;p&gt;Millions of people visit them every day.&lt;/p&gt;

&lt;p&gt;Sometimes millions of users are online at exactly the same time.&lt;/p&gt;

&lt;p&gt;Surely they don't keep buying one giant server every time traffic increases.&lt;/p&gt;

&lt;p&gt;So how do they handle sudden spikes in visitors without crashing?&lt;/p&gt;

&lt;p&gt;That question introduced me to &lt;strong&gt;Amazon EC2 Auto Scaling&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;Imagine I build my own portfolio website.&lt;/p&gt;

&lt;p&gt;Normally, around 100 people visit it each day.&lt;/p&gt;

&lt;p&gt;Everything works perfectly.&lt;/p&gt;

&lt;p&gt;Then one day, someone with a huge social media following shares my website.&lt;/p&gt;

&lt;p&gt;Within minutes...&lt;/p&gt;

&lt;p&gt;10,000 people try to open it.&lt;/p&gt;

&lt;p&gt;What happens?&lt;/p&gt;

&lt;p&gt;If I only have &lt;strong&gt;one EC2 instance&lt;/strong&gt;, that single server now has to handle every request.&lt;/p&gt;

&lt;p&gt;Soon it becomes overloaded.&lt;/p&gt;

&lt;p&gt;Pages load slowly.&lt;/p&gt;

&lt;p&gt;Some users get errors.&lt;/p&gt;

&lt;p&gt;Eventually...&lt;/p&gt;

&lt;p&gt;The website crashes.&lt;br&gt;
&lt;/p&gt;

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

Users --&amp;gt; EC2

style EC2 fill:#ff9999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clearly, one server isn't enough.&lt;/p&gt;




&lt;h1&gt;
  
  
  My First Thought
&lt;/h1&gt;

&lt;p&gt;My first solution was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just buy a bigger server.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Upgrade from&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 GB RAM&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;16 GB RAM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called &lt;strong&gt;Vertical Scaling&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;flowchart LR

SmallEC2["Small EC2"]

--&amp;gt;LargeEC2["Bigger EC2"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works...&lt;/p&gt;

&lt;p&gt;But only up to a point.&lt;/p&gt;

&lt;p&gt;Eventually, even the biggest server has limits.&lt;/p&gt;




&lt;h1&gt;
  
  
  AWS Had a Better Idea
&lt;/h1&gt;

&lt;p&gt;Instead of buying one huge server...&lt;/p&gt;

&lt;p&gt;Why not create &lt;strong&gt;more servers&lt;/strong&gt; whenever they're needed?&lt;/p&gt;

&lt;p&gt;That's exactly what Auto Scaling does.&lt;/p&gt;

&lt;p&gt;Instead of this:&lt;br&gt;
&lt;/p&gt;

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

Users --&amp;gt; OneServer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS can do this:&lt;br&gt;
&lt;/p&gt;

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

Users

--&amp;gt;ELB

ELB--&amp;gt;EC21

ELB--&amp;gt;EC22

ELB--&amp;gt;EC23

ELB--&amp;gt;EC24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the workload is shared across multiple EC2 instances.&lt;/p&gt;

&lt;p&gt;Each server handles only part of the traffic.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Is Amazon EC2 Auto Scaling?
&lt;/h1&gt;

&lt;p&gt;Amazon EC2 Auto Scaling automatically launches or removes EC2 instances depending on your application's traffic.&lt;/p&gt;

&lt;p&gt;Simply put:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;More visitors ➜ More servers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fewer visitors ➜ Fewer servers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No manual work required.&lt;/p&gt;




&lt;h1&gt;
  
  
  Scale Out
&lt;/h1&gt;

&lt;p&gt;Suppose your website suddenly becomes popular.&lt;/p&gt;

&lt;p&gt;Traffic increases.&lt;/p&gt;

&lt;p&gt;Auto Scaling detects the increase.&lt;/p&gt;

&lt;p&gt;It automatically launches additional EC2 instances.&lt;br&gt;
&lt;/p&gt;

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

Traffic

--&amp;gt;AutoScaling

AutoScaling

--&amp;gt;EC21

AutoScaling

--&amp;gt;EC22

AutoScaling

--&amp;gt;EC23

AutoScaling

--&amp;gt;EC24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This process is called &lt;strong&gt;Scale Out&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Scale In
&lt;/h1&gt;

&lt;p&gt;Now imagine it's midnight.&lt;/p&gt;

&lt;p&gt;Most users leave.&lt;/p&gt;

&lt;p&gt;You no longer need four servers.&lt;/p&gt;

&lt;p&gt;Keeping them running would waste money.&lt;/p&gt;

&lt;p&gt;Auto Scaling automatically terminates the extra EC2 instances.&lt;br&gt;
&lt;/p&gt;

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

TrafficDrops

--&amp;gt;AutoScaling

AutoScaling

--&amp;gt;EC21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called &lt;strong&gt;Scale In&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You only pay for what you actually use.&lt;/p&gt;




&lt;h1&gt;
  
  
  Auto Scaling Group
&lt;/h1&gt;

&lt;p&gt;Auto Scaling doesn't create random servers.&lt;/p&gt;

&lt;p&gt;Instead, it manages them inside something called an &lt;strong&gt;Auto Scaling Group (ASG).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An ASG follows rules that you define.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Minimum Instances → 2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desired Instances → 3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maximum Instances → 10&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If traffic increases, AWS can grow from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3 → 4 → 5 → 6 → ... → 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If traffic decreases, it can shrink back down.&lt;/p&gt;

&lt;p&gt;Everything happens automatically.&lt;/p&gt;




&lt;h1&gt;
  
  
  Auto Scaling + Elastic Load Balancer
&lt;/h1&gt;

&lt;p&gt;One thing finally clicked for me.&lt;/p&gt;

&lt;p&gt;Auto Scaling creates servers.&lt;/p&gt;

&lt;p&gt;But...&lt;/p&gt;

&lt;p&gt;How do users know which server to use?&lt;/p&gt;

&lt;p&gt;That's where the &lt;strong&gt;Elastic Load Balancer (ELB)&lt;/strong&gt; comes in.&lt;br&gt;
&lt;/p&gt;

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

Users

--&amp;gt;ELB

ELB--&amp;gt;EC21

ELB--&amp;gt;EC22

ELB--&amp;gt;EC23

ELB--&amp;gt;EC24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Load Balancer distributes traffic.&lt;/p&gt;

&lt;p&gt;Auto Scaling creates or removes servers.&lt;/p&gt;

&lt;p&gt;Together, they make applications highly available.&lt;/p&gt;




&lt;h1&gt;
  
  
  Real-World Examples
&lt;/h1&gt;

&lt;p&gt;Auto Scaling is useful almost everywhere.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Black Friday shopping&lt;/li&gt;
&lt;li&gt; Concert ticket sales&lt;/li&gt;
&lt;li&gt; Online gaming events&lt;/li&gt;
&lt;li&gt; Netflix releasing a new season&lt;/li&gt;
&lt;li&gt; Viral social media applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traffic suddenly increases.&lt;/p&gt;

&lt;p&gt;Instead of crashing...&lt;/p&gt;

&lt;p&gt;AWS automatically adds more servers.&lt;/p&gt;

&lt;p&gt;Once traffic drops, it removes the extra servers.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why This Saves Money
&lt;/h1&gt;

&lt;p&gt;Without Auto Scaling, you might keep ten servers running all day.&lt;/p&gt;

&lt;p&gt;Even when only one server is needed.&lt;/p&gt;

&lt;p&gt;That's expensive.&lt;/p&gt;

&lt;p&gt;With Auto Scaling:&lt;/p&gt;

&lt;p&gt;Busy hours:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Quiet hours:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;AWS adjusts automatically.&lt;/p&gt;

&lt;p&gt;You only pay for the servers you actually need.&lt;/p&gt;




&lt;h1&gt;
  
  
  Benefits of Auto Scaling
&lt;/h1&gt;

&lt;p&gt;Handles sudden traffic spikes&lt;/p&gt;

&lt;p&gt;Improves application availability&lt;/p&gt;

&lt;p&gt;Prevents server overload&lt;/p&gt;

&lt;p&gt;Automatically adds or removes EC2 instances&lt;/p&gt;

&lt;p&gt;Reduces infrastructure costs&lt;/p&gt;

&lt;p&gt;Works seamlessly with Elastic Load Balancers&lt;/p&gt;




&lt;h1&gt;
  
  
  What Changed My Perspective
&lt;/h1&gt;

&lt;p&gt;Before learning Auto Scaling, I thought handling more users meant buying a more powerful server.&lt;/p&gt;

&lt;p&gt;Now I understand that's only one approach.&lt;/p&gt;

&lt;p&gt;Sometimes the better solution isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A bigger server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;More servers working together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That small mindset shift completely changed how I think about scalable applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;When I first heard the term &lt;strong&gt;Amazon EC2 Auto Scaling&lt;/strong&gt;, I imagined it was just another AWS feature.&lt;/p&gt;

&lt;p&gt;Now I realize it's one of the key reasons modern cloud applications stay online during sudden traffic spikes.&lt;/p&gt;

&lt;p&gt;Instead of guessing how many servers you'll need...&lt;/p&gt;

&lt;p&gt;AWS watches your traffic for you.&lt;/p&gt;

&lt;p&gt;When demand increases, it automatically adds more servers.&lt;/p&gt;

&lt;p&gt;When demand decreases, it removes the extras.&lt;/p&gt;

&lt;p&gt;That's one of the biggest advantages of cloud computing.&lt;/p&gt;

&lt;p&gt;You don't have to build for your busiest day.&lt;/p&gt;

&lt;p&gt;AWS scales with you.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Auto Scaling automatically launches and removes EC2 instances.&lt;/li&gt;
&lt;li&gt;Scale Out adds more servers during high traffic.&lt;/li&gt;
&lt;li&gt;Scale In removes servers when traffic decreases.&lt;/li&gt;
&lt;li&gt;Auto Scaling Groups manage EC2 instances using rules.&lt;/li&gt;
&lt;li&gt;Elastic Load Balancer distributes traffic across all instances.&lt;/li&gt;
&lt;li&gt;Together, ELB and Auto Scaling build highly available applications.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;*&lt;em&gt;Thanks for reading! *&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amazon</category>
      <category>cloudcomputing</category>
      <category>ec2</category>
    </item>
    <item>
      <title>How Does AWS Know Which Website I'm Trying to Visit? Understanding Amazon Route 53</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Fri, 31 Jul 2026 09:57:57 +0000</pubDate>
      <link>https://dev.to/anupa_supul/how-does-aws-know-which-website-im-trying-to-visit-understanding-amazon-route-53-2mco</link>
      <guid>https://dev.to/anupa_supul/how-does-aws-know-which-website-im-trying-to-visit-understanding-amazon-route-53-2mco</guid>
      <description>&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%2Fldkutdelstc2amo835hf.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%2Fldkutdelstc2amo835hf.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first started learning web development, opening a website felt almost magical.&lt;/p&gt;

&lt;p&gt;I would type something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.amazon.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A few seconds later, the website appeared.&lt;/p&gt;

&lt;p&gt;I never stopped to think about what actually happened.&lt;/p&gt;

&lt;p&gt;How did my computer know where Amazon's servers were?&lt;/p&gt;

&lt;p&gt;How did it find the correct server among millions connected to the internet?&lt;/p&gt;

&lt;p&gt;And why don't we type an IP address like:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;instead of simply typing:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Those questions eventually led me to one of the first networking services in AWS:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Amazon Route 53&lt;/strong&gt;
&lt;/h1&gt;




&lt;h1&gt;
  
  
  The Question That Made Me Curious
&lt;/h1&gt;

&lt;p&gt;Imagine I build my own MERN application.&lt;/p&gt;

&lt;p&gt;I deploy it on an EC2 instance.&lt;/p&gt;

&lt;p&gt;AWS gives me a public IP address like:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Technically, people can visit my application using that IP.&lt;/p&gt;

&lt;p&gt;But let's be honest...&lt;/p&gt;

&lt;p&gt;Nobody wants to remember numbers like that.&lt;/p&gt;

&lt;p&gt;It's much easier to visit:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;That made me wonder:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How does my computer know that "myapp.com" actually means "18.142.120.54"?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The Phone Contact Analogy
&lt;/h1&gt;

&lt;p&gt;This example made everything click for me.&lt;/p&gt;

&lt;p&gt;Imagine your best friend has this phone number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+94 71 123 4567
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you memorize the number?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;Instead, you save it as:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now whenever you want to call him, you simply tap:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Your phone automatically finds the correct phone number.&lt;/p&gt;

&lt;p&gt;You don't need to remember it.&lt;/p&gt;

&lt;p&gt;The internet works almost the same way.&lt;/p&gt;

&lt;p&gt;Instead of remembering:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;we simply remember:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Something translates that easy-to-read name into the server's IP address.&lt;/p&gt;

&lt;p&gt;That "something" is called &lt;strong&gt;DNS (Domain Name System).&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What Is Amazon Route 53?
&lt;/h1&gt;

&lt;p&gt;Amazon Route 53 is AWS's managed &lt;strong&gt;DNS service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its job is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Convert human-friendly domain names into IP addresses that computers understand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of this:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We simply type:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Route 53 performs the translation and sends us to the correct server.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Actually Happens?
&lt;/h1&gt;

&lt;p&gt;Let's say I open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.myportfolio.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what happens behind the scenes.&lt;br&gt;
&lt;/p&gt;

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

A[User Types myportfolio.com]

--&amp;gt;B[Browser]

--&amp;gt;C[Amazon Route53 DNS Lookup]

--&amp;gt;D[Returns IP Address]

--&amp;gt;E[EC2 Server]

--&amp;gt;F[Website Loads]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entire process usually takes only milliseconds.&lt;/p&gt;




&lt;h1&gt;
  
  
  A Real AWS Example
&lt;/h1&gt;

&lt;p&gt;Suppose I host my MERN application on an EC2 instance in Singapore.&lt;/p&gt;

&lt;p&gt;Its public IP address is:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Without Route 53, users would have to visit:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;With Route 53:&lt;br&gt;
&lt;/p&gt;

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

A[myportfolio.com]

--&amp;gt;B[Amazon Route53]

--&amp;gt;C[18.xxx.xxx.xxx]

--&amp;gt;D[EC2 Instance]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much easier.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Is It Called Route 53?
&lt;/h1&gt;

&lt;p&gt;One thing that caught my attention was the number &lt;strong&gt;53&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's actually named after &lt;strong&gt;Port 53&lt;/strong&gt;, the standard network port used for DNS communication.&lt;/p&gt;

&lt;p&gt;A small detail, but one I found interesting.&lt;/p&gt;




&lt;h1&gt;
  
  
  Route 53 Does More Than DNS
&lt;/h1&gt;

&lt;p&gt;Initially, I thought Route 53 only converted domain names into IP addresses.&lt;/p&gt;

&lt;p&gt;But it can also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Route traffic globally&lt;/li&gt;
&lt;li&gt; Perform Health Checks&lt;/li&gt;
&lt;li&gt; Fail over to healthy resources&lt;/li&gt;
&lt;li&gt; Route traffic intelligently&lt;/li&gt;
&lt;li&gt; Improve application availability&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Where Route 53 Fits in AWS
&lt;/h1&gt;

&lt;p&gt;As I learned more AWS services, I realized Route 53 is usually the very first AWS service involved when someone opens a website.&lt;br&gt;
&lt;/p&gt;

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

User

--&amp;gt;Route53

--&amp;gt;CloudFront

--&amp;gt;LoadBalancer

--&amp;gt;EC2

--&amp;gt;Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every service has its own responsibility.&lt;/p&gt;

&lt;p&gt;Route 53 simply helps users find the right destination.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Route 53 Matters
&lt;/h1&gt;

&lt;p&gt;Without DNS:&lt;/p&gt;

&lt;p&gt;Users must remember IP addresses.&lt;/p&gt;

&lt;p&gt;With Route 53:&lt;/p&gt;

&lt;p&gt;Easy-to-remember domain names&lt;/p&gt;

&lt;p&gt;Highly available DNS&lt;/p&gt;

&lt;p&gt;Faster routing&lt;/p&gt;

&lt;p&gt;Health monitoring&lt;/p&gt;

&lt;p&gt;Traffic routing policies&lt;/p&gt;

&lt;p&gt;Works with almost every AWS service&lt;/p&gt;




&lt;h1&gt;
  
  
  What Changed My Perspective
&lt;/h1&gt;

&lt;p&gt;Before learning AWS, I thought typing a website name directly connected me to the server.&lt;/p&gt;

&lt;p&gt;Now I understand there's an important translation happening first.&lt;/p&gt;

&lt;p&gt;Someone has to convert:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;into&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;That's exactly what DNS does.&lt;/p&gt;

&lt;p&gt;And in AWS, that job belongs to &lt;strong&gt;Amazon Route 53&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;When I first heard the name &lt;strong&gt;Route 53&lt;/strong&gt;, I had no idea what it actually did.&lt;/p&gt;

&lt;p&gt;Now I think of it much more simply.&lt;/p&gt;

&lt;p&gt;It's like the contact list on my phone.&lt;/p&gt;

&lt;p&gt;I don't remember phone numbers.&lt;/p&gt;

&lt;p&gt;I remember names.&lt;/p&gt;

&lt;p&gt;Similarly, my browser doesn't magically know where a website lives.&lt;/p&gt;

&lt;p&gt;Route 53 translates a human-friendly domain name into the server's actual address.&lt;/p&gt;

&lt;p&gt;Sometimes the most important AWS services are the ones quietly working behind the scenes.&lt;/p&gt;

&lt;p&gt;And Route 53 is definitely one of them.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Route 53 is AWS's managed DNS service.&lt;/li&gt;
&lt;li&gt;It converts domain names into IP addresses.&lt;/li&gt;
&lt;li&gt;It makes websites easier to access.&lt;/li&gt;
&lt;li&gt;It supports health checks and intelligent routing.&lt;/li&gt;
&lt;li&gt;It's usually the first AWS service involved when visiting a website.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;*&lt;em&gt;Thanks for reading! *&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>amazon</category>
      <category>route</category>
    </item>
    <item>
      <title>Why Is Netflix So Fast Everywhere? Understanding Amazon CloudFront</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:27:13 +0000</pubDate>
      <link>https://dev.to/anupa_supul/why-is-netflix-so-fast-everywhere-understanding-amazon-cloudfront-1bnh</link>
      <guid>https://dev.to/anupa_supul/why-is-netflix-so-fast-everywhere-understanding-amazon-cloudfront-1bnh</guid>
      <description>&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%2Frcr40kvdavbwxh0cgyp3.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%2Frcr40kvdavbwxh0cgyp3.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first started learning AWS, I thought website speed mostly depended on one thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A powerful server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More CPU.&lt;/p&gt;

&lt;p&gt;More memory.&lt;/p&gt;

&lt;p&gt;Better hardware.&lt;/p&gt;

&lt;p&gt;Problem solved.&lt;/p&gt;

&lt;p&gt;Or at least that's what I thought.&lt;/p&gt;

&lt;p&gt;Then a question hit me.&lt;/p&gt;

&lt;p&gt;Netflix loads quickly.&lt;/p&gt;

&lt;p&gt;YouTube loads quickly.&lt;/p&gt;

&lt;p&gt;Amazon loads quickly.&lt;/p&gt;

&lt;p&gt;But their servers aren't sitting in my room.&lt;/p&gt;

&lt;p&gt;In fact, many of them are located thousands of kilometers away.&lt;/p&gt;

&lt;p&gt;So why doesn't every click feel slow?&lt;/p&gt;

&lt;p&gt;That question eventually led me to &lt;strong&gt;Amazon CloudFront&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Thought That Started It
&lt;/h2&gt;

&lt;p&gt;Imagine I host a website on AWS in Singapore.&lt;/p&gt;

&lt;p&gt;Now imagine someone opens that website from Sri Lanka.&lt;/p&gt;

&lt;p&gt;Every image.&lt;/p&gt;

&lt;p&gt;Every CSS file.&lt;/p&gt;

&lt;p&gt;Every JavaScript file.&lt;/p&gt;

&lt;p&gt;Every request.&lt;/p&gt;

&lt;p&gt;Has to travel all the way to Singapore and back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[User in Sri Lanka]
    SERVER[AWS Server in Singapore]

    USER --&amp;gt; SERVER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That doesn't sound very efficient.&lt;/p&gt;

&lt;p&gt;And it gets even worse when thousands or millions of users are involved.&lt;/p&gt;

&lt;p&gt;So I started wondering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do global companies deliver content so quickly to people all around the world?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Concept That Finally Clicked
&lt;/h2&gt;

&lt;p&gt;The simplest way I understand CloudFront is this:&lt;/p&gt;

&lt;p&gt;Imagine there is only one library in an entire country.&lt;/p&gt;

&lt;p&gt;Every student has to travel there to borrow a book.&lt;/p&gt;

&lt;p&gt;It works.&lt;/p&gt;

&lt;p&gt;But it's slow.&lt;/p&gt;

&lt;p&gt;Now imagine small branches of that library are opened across different cities.&lt;/p&gt;

&lt;p&gt;Students can get popular books from a nearby branch instead of traveling to the main library.&lt;/p&gt;

&lt;p&gt;That's basically what CloudFront does.&lt;/p&gt;

&lt;p&gt;Instead of forcing every user to communicate with the original server, AWS places copies of content closer to users.&lt;/p&gt;




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

&lt;p&gt;Amazon CloudFront is AWS's Content Delivery Network (CDN).&lt;/p&gt;

&lt;p&gt;Its job is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deliver content from the location closest to the user whenever possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rather than always requesting files from the original server, CloudFront stores frequently requested content in locations around the world called &lt;strong&gt;Edge Locations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a user requests that content again, it can be delivered from a nearby Edge Location instead of the original AWS Region.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Example
&lt;/h2&gt;

&lt;p&gt;Suppose I host a portfolio website.&lt;/p&gt;

&lt;p&gt;The website contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;CSS files&lt;/li&gt;
&lt;li&gt;JavaScript files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without CloudFront:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[User]
    SERVER[Singapore Server]

    USER --&amp;gt; SERVER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every request makes the full journey.&lt;/p&gt;




&lt;p&gt;With CloudFront:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[User]

    EDGE[CloudFront Edge Location]

    SERVER[Singapore Server]

    USER --&amp;gt; EDGE
    EDGE --&amp;gt; SERVER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the content is already cached, CloudFront delivers it immediately.&lt;/p&gt;

&lt;p&gt;Fewer long-distance trips.&lt;/p&gt;

&lt;p&gt;Faster loading times.&lt;/p&gt;

&lt;p&gt;Better experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Edge Locations?
&lt;/h2&gt;

&lt;p&gt;While learning AWS Global Infrastructure, I came across three important concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regions&lt;/li&gt;
&lt;li&gt;Availability Zones&lt;/li&gt;
&lt;li&gt;Edge Locations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CloudFront uses Edge Locations to serve content closer to users.&lt;/p&gt;

&lt;p&gt;Think of them as small delivery centers spread around the world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
    USER[User]

    EDGE[Nearest Edge Location]

    ORIGIN[Origin Server]

    USER --&amp;gt; EDGE
    EDGE --&amp;gt; ORIGIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When content is already available at the Edge Location, users get it much faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Before learning CloudFront, I thought performance was mainly about the server.&lt;/p&gt;

&lt;p&gt;Now I realize distance is part of the equation too.&lt;/p&gt;

&lt;p&gt;Even a powerful server can't overcome physics.&lt;/p&gt;

&lt;p&gt;Data still needs to travel.&lt;/p&gt;

&lt;p&gt;CloudFront helps reduce that distance from the user's perspective.&lt;/p&gt;

&lt;p&gt;And when you're serving users across different countries, that makes a huge difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  CloudFront + S3
&lt;/h2&gt;

&lt;p&gt;One of the most common AWS architectures combines CloudFront with Amazon S3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[Users]

    CF[CloudFront]

    S3[Amazon S3 Bucket]

    USER --&amp;gt; CF
    CF --&amp;gt; S3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup is commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static websites&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Downloads&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Portfolio sites&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CloudFront + Modern Web Applications
&lt;/h2&gt;

&lt;p&gt;CloudFront can also work with dynamic applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[Users]

    CF[CloudFront]

    ELB[Load Balancer]

    EC2[EC2 Instances]

    USER --&amp;gt; CF
    CF --&amp;gt; ELB
    ELB --&amp;gt; EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seeing architectures like this helped me realize that AWS services aren't isolated tools.&lt;/p&gt;

&lt;p&gt;They work together to solve larger problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is Netflix So Fast?
&lt;/h2&gt;

&lt;p&gt;This was the original question that made me curious.&lt;/p&gt;

&lt;p&gt;Streaming platforms serve enormous amounts of content every second.&lt;/p&gt;

&lt;p&gt;Imagine if every user had to fetch videos directly from a single server.&lt;/p&gt;

&lt;p&gt;The experience would be terrible.&lt;/p&gt;

&lt;p&gt;Instead, content is distributed closer to users.&lt;/p&gt;

&lt;p&gt;Popular files are cached.&lt;/p&gt;

&lt;p&gt;Travel distance is reduced.&lt;/p&gt;

&lt;p&gt;Latency drops.&lt;/p&gt;

&lt;p&gt;The result is a much smoother experience.&lt;/p&gt;

&lt;p&gt;While Netflix has a far more complex infrastructure than this simplified example, the underlying idea is very similar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bring content closer to users.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Benefits of Amazon CloudFront
&lt;/h2&gt;

&lt;p&gt;After learning about CloudFront, these are the biggest benefits that stood out to me:&lt;/p&gt;

&lt;p&gt;✅ Faster content delivery&lt;/p&gt;

&lt;p&gt;✅ Lower latency&lt;/p&gt;

&lt;p&gt;✅ Better user experience&lt;/p&gt;

&lt;p&gt;✅ Reduced load on origin servers&lt;/p&gt;

&lt;p&gt;✅ Global content distribution&lt;/p&gt;

&lt;p&gt;✅ Improved scalability&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed My Perspective
&lt;/h2&gt;

&lt;p&gt;Before learning AWS, I thought website performance was mostly about powerful servers.&lt;/p&gt;

&lt;p&gt;Then I learned about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load Balancers&lt;/li&gt;
&lt;li&gt;Auto Scaling&lt;/li&gt;
&lt;li&gt;CloudFront&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I realized something.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes the fastest solution isn't a bigger server.&lt;/p&gt;

&lt;p&gt;It's bringing content closer to the user.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That simple idea is what made CloudFront click for me.&lt;/p&gt;




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

&lt;p&gt;When I first heard about Amazon CloudFront, it sounded like just another AWS service.&lt;/p&gt;

&lt;p&gt;Now I see it differently.&lt;/p&gt;

&lt;p&gt;It's AWS's answer to a simple problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you make a website feel fast for users all around the world?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not by making people travel farther.&lt;/p&gt;

&lt;p&gt;By bringing content closer to them.&lt;/p&gt;

&lt;p&gt;And honestly, that's not something I ever thought about when I first started learning web development.&lt;/p&gt;




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

</description>
      <category>cloudcomputing</category>
      <category>aws</category>
      <category>cloudfront</category>
      <category>devops</category>
    </item>
    <item>
      <title>How AWS Security Groups Finally Made Sense to Me</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:11:43 +0000</pubDate>
      <link>https://dev.to/anupa_supul/how-aws-security-groups-finally-made-sense-to-me-5770</link>
      <guid>https://dev.to/anupa_supul/how-aws-security-groups-finally-made-sense-to-me-5770</guid>
      <description>&lt;h1&gt;
  
  
  🔐 How AWS Security Groups Finally Made Sense to Me
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;The AWS feature that taught me security isn't just about passwords and encryption.&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%2Fa98qqsrzp17rue7kcjue.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%2Fa98qqsrzp17rue7kcjue.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I launched my first EC2 instance, AWS asked me to configure something called a &lt;strong&gt;Security Group&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At the time, I didn't think much about it.&lt;/p&gt;

&lt;p&gt;I simply opened the ports AWS recommended, launched the server, and moved on.&lt;/p&gt;

&lt;p&gt;The application worked.&lt;/p&gt;

&lt;p&gt;The website loaded.&lt;/p&gt;

&lt;p&gt;Everything seemed fine.&lt;/p&gt;

&lt;p&gt;But as I continued learning AWS, I kept seeing Security Groups appear everywhere.&lt;/p&gt;

&lt;p&gt;EC2 instances had them.&lt;/p&gt;

&lt;p&gt;Databases had them.&lt;/p&gt;

&lt;p&gt;Load Balancers used them.&lt;/p&gt;

&lt;p&gt;That's when I started wondering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What exactly are Security Groups, and why are they so important?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Mistake Most Beginners Make
&lt;/h2&gt;

&lt;p&gt;When I first heard the word &lt;em&gt;security&lt;/em&gt;, I immediately thought about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passwords&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Antivirus software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security Groups are different.&lt;/p&gt;

&lt;p&gt;They answer a much simpler question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Who is allowed to communicate with my AWS resources?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And surprisingly, that single question is incredibly important.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Real Scenario: Hosting a Website
&lt;/h2&gt;

&lt;p&gt;Imagine I deploy a MERN application on an EC2 instance.&lt;/p&gt;

&lt;p&gt;Users need to access the website through their browsers.&lt;/p&gt;

&lt;p&gt;For that to happen, the server must allow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP (Port 80)&lt;/li&gt;
&lt;li&gt;HTTPS (Port 443)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
    U[User]
    SG[Security Group]
    EC2[EC2 Instance]

    U --&amp;gt; SG
    SG --&amp;gt; EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without those ports being open, nobody can access the application.&lt;/p&gt;

&lt;p&gt;Even if the server is running perfectly, it remains unreachable.&lt;/p&gt;

&lt;p&gt;This was my first realization:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Security Groups don't make resources public.&lt;/p&gt;

&lt;p&gt;They decide whether traffic is allowed to reach them.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  So What Is a Security Group?
&lt;/h2&gt;

&lt;p&gt;The simplest explanation I found is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A Security Group acts as a virtual firewall for AWS resources.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It controls two types of traffic:&lt;/p&gt;

&lt;h3&gt;
  
  
  Inbound Rules
&lt;/h3&gt;

&lt;p&gt;Traffic coming into a resource.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users visiting a website&lt;/li&gt;
&lt;li&gt;Developers connecting through SSH&lt;/li&gt;
&lt;li&gt;Applications calling APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Outbound Rules
&lt;/h3&gt;

&lt;p&gt;Traffic leaving a resource.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calling external APIs&lt;/li&gt;
&lt;li&gt;Downloading updates&lt;/li&gt;
&lt;li&gt;Connecting to databases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every request is checked against these rules.&lt;/p&gt;

&lt;p&gt;If a rule allows it, traffic passes.&lt;/p&gt;

&lt;p&gt;If not, AWS blocks it automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  The SSH Example
&lt;/h2&gt;

&lt;p&gt;This is where Security Groups became very practical for me.&lt;/p&gt;

&lt;p&gt;Suppose I want to connect to my EC2 instance using SSH.&lt;/p&gt;

&lt;p&gt;SSH uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port 22&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;flowchart TD
    DEV[Developer]
    SSH[SSH Port 22]
    SG[Security Group]
    EC2[EC2 Instance]

    DEV --&amp;gt; SSH
    SSH --&amp;gt; SG
    SG --&amp;gt; EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A common beginner mistake is allowing:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Which means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anyone on the internet can attempt to connect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works.&lt;/p&gt;

&lt;p&gt;But it's not ideal.&lt;/p&gt;

&lt;p&gt;A safer approach is allowing only your own public IP address.&lt;/p&gt;

&lt;p&gt;That way, only you can access the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Database Scenario That Made Everything Click
&lt;/h2&gt;

&lt;p&gt;This was the example that finally made Security Groups click for me.&lt;/p&gt;

&lt;p&gt;Imagine a simple application architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
    USER[Users]

    FE[Frontend]

    API[Backend API]

    DB[(Database)]

    USER --&amp;gt; FE
    FE --&amp;gt; API
    API --&amp;gt; DB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now ask yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should internet users connect directly to the database?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Definitely not.&lt;/p&gt;

&lt;p&gt;The database should only accept requests from the backend server.&lt;/p&gt;

&lt;p&gt;Instead of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
    INTERNET[Internet Users]
    DB[(Database)]

    INTERNET -. Blocked ❌ .-&amp;gt; DB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TD
    FE[Frontend]
    API[Backend API]
    DB[(Database)]

    FE --&amp;gt; API
    API --&amp;gt; DB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security Groups make this possible by controlling exactly who can communicate with what.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Security Groups Are Stateful
&lt;/h2&gt;

&lt;p&gt;One AWS concept that surprised me was that Security Groups are &lt;strong&gt;stateful&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine a user sends a request to an EC2 instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    USER[User]

    SG[Security Group]

    EC2[EC2 Instance]

    USER --&amp;gt; SG
    SG --&amp;gt; EC2

    EC2 --&amp;gt; USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the inbound request is allowed, the response is automatically allowed back.&lt;/p&gt;

&lt;p&gt;You don't need to create a separate return rule.&lt;/p&gt;

&lt;p&gt;AWS handles that automatically.&lt;/p&gt;

&lt;p&gt;This makes Security Groups much easier to manage.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Real-World AWS Architecture
&lt;/h2&gt;

&lt;p&gt;A simple production setup might look 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;flowchart TD
    USER[Users]

    SG1[Web Security Group]

    EC2[Backend Server]

    SG2[Database Security Group]

    DB[(Database)]

    USER --&amp;gt; SG1
    SG1 --&amp;gt; EC2

    EC2 --&amp;gt; SG2
    SG2 --&amp;gt; DB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users can access the backend server.&lt;/li&gt;
&lt;li&gt;The backend server can access the database.&lt;/li&gt;
&lt;li&gt;Users cannot access the database directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the most common security patterns you'll see in AWS architectures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security Is Not Just About Applications
&lt;/h2&gt;

&lt;p&gt;Before learning AWS, I thought security mostly happened inside the application.&lt;/p&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Password hashing&lt;/li&gt;
&lt;li&gt;JWT tokens&lt;/li&gt;
&lt;li&gt;Role-based access control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are still important.&lt;/p&gt;

&lt;p&gt;But AWS taught me something else:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Security also exists at the infrastructure level.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even a perfectly written application can become vulnerable if network access isn't configured properly.&lt;/p&gt;

&lt;p&gt;Security Groups provide one of the first layers of defense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed My Perspective
&lt;/h2&gt;

&lt;p&gt;The first time I configured a Security Group, it felt like just another setup step before launching an instance.&lt;/p&gt;

&lt;p&gt;Now I see it differently.&lt;/p&gt;

&lt;p&gt;Every rule is answering a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Who should be allowed to communicate with this resource?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more I learn AWS, the more I realize that cloud security isn't about blocking everything.&lt;/p&gt;

&lt;p&gt;It's about allowing only what is necessary.&lt;/p&gt;

&lt;p&gt;And Security Groups are one of the simplest and most effective tools AWS provides for doing exactly that.&lt;/p&gt;




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

&lt;p&gt;Security Groups looked complicated when I first encountered them.&lt;/p&gt;

&lt;p&gt;Today, I think of them much more simply.&lt;/p&gt;

&lt;p&gt;They're the gatekeepers of AWS resources.&lt;/p&gt;

&lt;p&gt;They decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who can enter&lt;/li&gt;
&lt;li&gt;What traffic is allowed&lt;/li&gt;
&lt;li&gt;What traffic should be blocked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And understanding that concept helped me appreciate why Security Groups appear in almost every AWS architecture diagram.&lt;/p&gt;

&lt;p&gt;Sometimes the most important AWS services aren't the most exciting ones.&lt;/p&gt;

&lt;p&gt;They're the ones quietly protecting everything behind the scenes.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>Why Doesn't Everyone Connect to the Same Server? Understanding AWS Elastic Load Balancer (ELB)</title>
      <dc:creator>Anupa Supul</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:51:01 +0000</pubDate>
      <link>https://dev.to/anupa_supul/why-doesnt-everyone-connect-to-the-same-server-understanding-aws-elastic-load-balancer-elb-2c33</link>
      <guid>https://dev.to/anupa_supul/why-doesnt-everyone-connect-to-the-same-server-understanding-aws-elastic-load-balancer-elb-2c33</guid>
      <description>&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%2F8aab24m3v30rf3ypxs3v.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%2F8aab24m3v30rf3ypxs3v.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While learning AWS, I noticed something interesting.&lt;/p&gt;

&lt;p&gt;In almost every AWS architecture diagram, there was a service sitting in front of multiple servers.&lt;/p&gt;

&lt;p&gt;It looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
   │
   ▼
Load Balancer
   │
 ┌─┴─┐
 ▼   ▼
EC2 EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, I didn't understand why it was there.&lt;/p&gt;

&lt;p&gt;I kept thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why can't users just connect directly to the server?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After all, if the server is running my application, shouldn't users talk to it directly?&lt;/p&gt;

&lt;p&gt;The more I learned, the more I realized that this simple service solves a huge problem.&lt;/p&gt;

&lt;p&gt;And that's how I discovered AWS Elastic Load Balancer (ELB).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Question That Made Me Curious
&lt;/h2&gt;

&lt;p&gt;Imagine I build a website.&lt;/p&gt;

&lt;p&gt;On a normal day, maybe &lt;strong&gt;100 people&lt;/strong&gt; visit it.&lt;/p&gt;

&lt;p&gt;One server is enough.&lt;/p&gt;

&lt;p&gt;Everything works smoothly.&lt;/p&gt;

&lt;p&gt;Now imagine my website suddenly goes viral.&lt;/p&gt;

&lt;p&gt;Thousands of people start visiting at the same time.&lt;/p&gt;

&lt;p&gt;What happens?&lt;/p&gt;

&lt;p&gt;Every request goes to the same server.&lt;/p&gt;

&lt;p&gt;Eventually, that server becomes overwhelmed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pages become slow&lt;/li&gt;
&lt;li&gt;Users start waiting&lt;/li&gt;
&lt;li&gt;Requests fail&lt;/li&gt;
&lt;li&gt;Visitors leave&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's when I realized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The problem isn't just having servers.&lt;/p&gt;

&lt;p&gt;It's deciding how traffic should be shared between them.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Coffee Shop Analogy
&lt;/h2&gt;

&lt;p&gt;This was the example that made everything click for me.&lt;/p&gt;

&lt;p&gt;Imagine a coffee shop with only one cashier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500 Customers
      │
      ▼
  1 Cashier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line becomes huge.&lt;/p&gt;

&lt;p&gt;Customers wait.&lt;/p&gt;

&lt;p&gt;Some leave before getting served.&lt;/p&gt;

&lt;p&gt;Now imagine adding three more cashiers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500 Customers
      │
      ▼
 ┌─────────┐
 │ Manager │
 └─────────┘
  │  │  │  │
  ▼  ▼  ▼  ▼
 C1 C2 C3 C4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The manager directs customers to whichever cashier is available.&lt;/p&gt;

&lt;p&gt;Nobody has to choose a cashier manually.&lt;/p&gt;

&lt;p&gt;The workload gets distributed automatically.&lt;/p&gt;

&lt;p&gt;That manager is basically what a Load Balancer does.&lt;/p&gt;




&lt;h2&gt;
  
  
  So... What Is an Elastic Load Balancer?
&lt;/h2&gt;

&lt;p&gt;The simplest way I understand it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An Elastic Load Balancer automatically distributes incoming traffic across multiple servers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of sending every user to one server, AWS spreads the requests across several servers.&lt;/p&gt;

&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved performance&lt;/li&gt;
&lt;li&gt;Higher availability&lt;/li&gt;
&lt;li&gt;Better fault tolerance&lt;/li&gt;
&lt;li&gt;Handling traffic spikes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Without a Load Balancer
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 Users
      │
      ▼
     EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One server has to handle everything.&lt;/p&gt;

&lt;p&gt;If it fails, the application becomes unavailable.&lt;/p&gt;




&lt;h2&gt;
  
  
  With a Load Balancer
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 Users
       │
       ▼
 Load Balancer
   │    │    │
   ▼    ▼    ▼
 EC2  EC2  EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traffic gets shared.&lt;/p&gt;

&lt;p&gt;Each server handles a smaller amount of work.&lt;/p&gt;

&lt;p&gt;The application stays responsive.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens If a Server Fails?
&lt;/h2&gt;

&lt;p&gt;Without a Load Balancer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  │
  ▼
Failed Server ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Website unavailable.&lt;/p&gt;

&lt;p&gt;With a Load Balancer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  │
  ▼
Load Balancer
 │     │     │
 ▼     ▼     ▼
❌    EC2   EC2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traffic automatically moves to healthy servers.&lt;/p&gt;

&lt;p&gt;Most users never notice anything happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  How ELB Works With Auto Scaling
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet Users
       │
       ▼
 Load Balancer
       │
 ┌─────┼─────┐
 ▼     ▼     ▼
EC2   EC2   EC2
       │
       ▼
 Auto Scaling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Auto Scaling decides how many servers exist.&lt;/li&gt;
&lt;li&gt;ELB decides where traffic goes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they keep applications scalable and highly available.&lt;/p&gt;




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

&lt;p&gt;When I first saw Elastic Load Balancer in AWS diagrams, it looked like just another service with a complicated name.&lt;/p&gt;

&lt;p&gt;Now I see it much more simply.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If thousands of users arrive at the same time, who decides where each request should go?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's exactly the problem ELB solves.&lt;/p&gt;

&lt;p&gt;And for me, it was another reminder that cloud computing isn't just about servers.&lt;/p&gt;

&lt;p&gt;It's about designing systems that continue working even when demand grows.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>softwareengineering</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
