<?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: Danh Hoang Hieu Nghi</title>
    <description>The latest articles on DEV Community by Danh Hoang Hieu Nghi (@nghidanh2005).</description>
    <link>https://dev.to/nghidanh2005</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%2F2291246%2F1b96d6e5-aacd-491b-979b-fab986bcef97.jpg</url>
      <title>DEV Community: Danh Hoang Hieu Nghi</title>
      <link>https://dev.to/nghidanh2005</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nghidanh2005"/>
    <language>en</language>
    <item>
      <title>AWS GuardDuty vs OpenSearch Security Analytics: Building a Real SIEM Pipeline on AWS</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Tue, 28 Jul 2026 16:00:37 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/aws-guardduty-vs-opensearch-security-analytics-building-a-real-siem-pipeline-on-aws-i3e</link>
      <guid>https://dev.to/nghidanh2005/aws-guardduty-vs-opensearch-security-analytics-building-a-real-siem-pipeline-on-aws-i3e</guid>
      <description>&lt;p&gt;&lt;em&gt;Comparing AWS GuardDuty and OpenSearch Security Analytics for AWS &lt;a href="https://aws.amazon.com/marketplace/solutions/security/siem" rel="noopener noreferrer"&gt;SIEM&lt;/a&gt; architecture, and why centralizing AWS security findings usually means running both, not choosing one.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's 2am and &lt;strong&gt;PagerDuty&lt;/strong&gt; just fired. &lt;strong&gt;GuardDuty&lt;/strong&gt; flagged an anomalous &lt;code&gt;UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration&lt;/code&gt; finding in one account.&lt;/p&gt;

&lt;p&gt;Meanwhile your WAF logs, three on-prem firewalls, and a fleet of custom application logs sit in a completely different system that has no idea the IAM finding exists. You need to answer one question — "has this IP touched anything else we own in the last 30 days?" — and you can't, because the answer is split across five tools with five different query languages, and none of them talk to each other.&lt;/p&gt;

&lt;p&gt;This is the visibility problem every team running more than a handful of AWS accounts eventually hits. GuardDuty tells you &lt;em&gt;something bad happened&lt;/em&gt;, but it wasn't built to be the place you go searching for &lt;em&gt;everything that happened&lt;/em&gt;. That's a separate job, and AWS gives you a separate tool for it: Security Analytics on Amazon OpenSearch Service. The two get talked about as competitors more often than they should be — in practice, they're stages in the same pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each service actually is
&lt;/h2&gt;

&lt;p&gt;Amazon GuardDuty is a fully managed threat detection service — you turn it on and it starts analyzing immediately, with no infrastructure to provision or patch. It automatically ingests CloudTrail management events, VPC Flow Logs, and DNS logs, and you can layer on optional protection plans for S3 data events, EKS audit logs, RDS login activity, Lambda network activity, and Runtime Monitoring (OS, network, and file-level events on EC2, ECS on Fargate, and EKS). Detection comes from AWS-curated threat intelligence feeds combined with ML models trained across AWS's own telemetry. You don't write the rules; AWS does. It scales cleanly across an organization too — a delegated administrator account can auto-enable GuardDuty for every existing and new member account without anyone touching individual accounts by hand.&lt;/p&gt;

&lt;p&gt;OpenSearch Security Analytics is a different animal. It's a feature layered on top of an OpenSearch Service domain that you provision, scale, and pay for like any other cluster. Nothing shows up automatically — you build the ingestion pipeline yourself, typically with Data Prepper, Kinesis Data Firehose, or Logstash, feeding in whatever you want: Windows event logs, NetFlow, CloudTrail, DNS logs, Active Directory/LDAP, custom application logs, even on-prem network gear. Detection rules are written in Sigma, an open and community-maintained format, which means you can write, tune, and share your own detections instead of relying on a fixed catalog. When a detector matches a rule against an incoming log event, it generates a finding, and alerting runs through OpenSearch's Alerting/Notifications plugin — which supports Amazon SNS as a channel alongside Slack, Chime, and custom webhooks. Underneath all of that, it's still a search engine, so you get real full-text and structured log search — the one thing GuardDuty categorically does not offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where they genuinely differ
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Amazon GuardDuty&lt;/th&gt;
&lt;th&gt;OpenSearch Security Analytics&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Operational model&lt;/td&gt;
&lt;td&gt;Fully managed, zero infrastructure&lt;/td&gt;
&lt;td&gt;Self-managed OpenSearch domain — you size, scale, and patch it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data sources&lt;/td&gt;
&lt;td&gt;Fixed set: CloudTrail, VPC Flow Logs, DNS, plus optional S3, EKS, RDS, Lambda, Runtime Monitoring&lt;/td&gt;
&lt;td&gt;Anything you pipe in — AWS logs, on-prem, custom apps, network devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detection logic&lt;/td&gt;
&lt;td&gt;AWS-curated threat intel + ML, closed finding types&lt;/td&gt;
&lt;td&gt;Sigma rules, open format, fully customizable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log search&lt;/td&gt;
&lt;td&gt;None — findings only, no raw log query&lt;/td&gt;
&lt;td&gt;Native full-text/structured search across all ingested data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-account&lt;/td&gt;
&lt;td&gt;Native AWS Organizations delegated admin, auto-enable&lt;/td&gt;
&lt;td&gt;Manual per-pipeline setup; no built-in org construct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention&lt;/td&gt;
&lt;td&gt;Findings retained ~90 days (via Security Hub)&lt;/td&gt;
&lt;td&gt;You control retention — as long as storage allows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost driver&lt;/td&gt;
&lt;td&gt;Pay per GB of data analyzed, no cluster to run&lt;/td&gt;
&lt;td&gt;Pay for the OpenSearch domain (instances, storage) plus ingestion pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern in that table is consistent: GuardDuty trades flexibility for zero operational overhead, and OpenSearch Security Analytics trades operational overhead for flexibility and depth. Neither trade is wrong — they're just optimized for different jobs. GuardDuty is built to catch the AWS-specific attack patterns AWS itself has the best visibility into (credential exfiltration, crypto-mining behavior, anomalous API calls) without you lifting a finger. OpenSearch Security Analytics is built for the investigation and correlation work that starts &lt;em&gt;after&lt;/em&gt; something gets flagged, or for environments where the threats you care about live outside what GuardDuty can even see.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real answer: they're pipeline stages, not competitors
&lt;/h2&gt;

&lt;p&gt;AWS's own guidance is unusually direct about this. From the AWS Security Blog's &lt;a href="https://aws.amazon.com/blogs/security/how-to-use-aws-security-hub-and-amazon-opensearch-service-for-siem/" rel="noopener noreferrer"&gt;SIEM guide&lt;/a&gt;: "Although Security Hub has some similarities to security information and event management (SIEM) tools, it is not designed as a standalone SIEM replacement." The same post adds the mirror-image caveat for OpenSearch: "Although the OpenSearch Service also is not a SIEM out-of-the-box tool, with some customization, you can use it for SIEM tool use cases."&lt;/p&gt;

&lt;p&gt;Read together, those two lines describe the architecture most security teams actually land on. GuardDuty detects. Security Hub aggregates those findings — along with findings from other AWS security services — into one place. Because Security Hub only holds findings for around 90 days and isn't meant for cross-source log correlation, teams export findings out via S3 and a Lambda-based ETL step, or stream them through EventBridge, into an OpenSearch domain. From there, OpenSearch (or Kibana/OpenSearch Dashboards on top of it) handles long-term retention past that 90-day window, correlation against non-AWS log sources, and the dashboards analysts actually live in during an investigation.&lt;/p&gt;

&lt;p&gt;A minimal version of the EventBridge routing rule that kicks this off looks like:&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aws.guardduty"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"detail-type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"GuardDuty Finding"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That rule targets a Lambda function that reshapes the finding and writes it into an OpenSearch index — or, more commonly today, targets Security Hub first, with a second export step moving aggregated findings from Security Hub into OpenSearch on a schedule. The point isn't the exact wiring; it's that GuardDuty findings become one input stream among several feeding a system built for the search and correlation GuardDuty was never designed to do.&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%2F1g1viybaf2s5gyp3zbzp.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%2F1g1viybaf2s5gyp3zbzp.png" alt="guardduty-opensearch-pipeline" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A decision framework, not a coin flip
&lt;/h2&gt;

&lt;p&gt;If your workloads are entirely on AWS, your team is small, and what you need is "tell me when something bad happens so I can go look" — run GuardDuty organization-wide and stop there. It costs nothing to operate beyond the per-GB analysis fee, and it will catch the categories of AWS-native threats it's tuned for without anyone maintaining rules.&lt;/p&gt;

&lt;p&gt;If you're already running GuardDuty but keep hitting the wall where you need to search raw logs, correlate a finding against something GuardDuty doesn't ingest, or retain data longer than 90 days for compliance — that's the signal to add OpenSearch Security Analytics on top, not to replace GuardDuty with it.&lt;/p&gt;

&lt;p&gt;If you have log sources GuardDuty structurally cannot see — on-prem firewalls, custom application audit logs, non-AWS network appliances, Windows domain controllers — you need OpenSearch Security Analytics regardless of what you decide about GuardDuty, because no amount of GuardDuty configuration will ever ingest those.&lt;/p&gt;

&lt;p&gt;And if you're running a mid-size environment — think a fintech spread across 40 AWS accounts with a mix of cloud-native and legacy on-prem systems — you'll likely end up needing both feeding a shared pipeline: GuardDuty as the always-on detection layer for AWS-native threats, Security Hub as the aggregation point, and OpenSearch as the durable, searchable, cross-source system of record underneath it all.&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%2F5113rvm691uc6b9yrtw9.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%2F5113rvm691uc6b9yrtw9.png" alt="Decision framework: use GuardDuty alone for AWS-only workloads with basic alerting needs; add OpenSearch Security Analytics once you need raw log search, retention past 90 days, or non-AWS log sources" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;Turn on GuardDuty across your organization today if it isn't already running — it's the highest-value, lowest-effort step available, and there's no good reason to delay it. Treat OpenSearch Security Analytics as the next investment, not a parallel one: reach for it once you can name the specific gap GuardDuty leaves open, whether that's log sources it can't reach, retention past 90 days, or the ability to search raw events instead of just reading findings. Building the Security Hub-to-OpenSearch pipeline before you have that gap just means paying to run and maintain a cluster you don't yet need.&lt;/p&gt;

</description>
      <category>guardduty</category>
      <category>opensearch</category>
      <category>siem</category>
      <category>aws</category>
    </item>
    <item>
      <title>Send error event of an Lambda function to SNS Topic</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Tue, 19 May 2026 07:16:08 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/send-error-event-of-an-lambda-function-to-sns-topic-1490</link>
      <guid>https://dev.to/nghidanh2005/send-error-event-of-an-lambda-function-to-sns-topic-1490</guid>
      <description>&lt;h1&gt;
  
  
  AWS Lambda Async Failure Destination: Gửi lỗi Lambda sang Amazon SNS ErrorTopic
&lt;/h1&gt;

&lt;p&gt;Khi làm việc với &lt;strong&gt;AWS Lambda asynchronous invocation&lt;/strong&gt;, một vấn đề rất thường gặp là: function xử lý message bị lỗi, nhưng mình cần một nơi tập trung để nhận thông báo lỗi và debug nhanh.&lt;/p&gt;

&lt;p&gt;Trong bài lab này, chúng ta sẽ dựng một flow đơn giản:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Amazon SNS InputTopic
        ↓
AWS Lambda ProcessMessages
        ↓ nếu xử lý thất bại
Amazon SNS ErrorTopic
        ↓
Email notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mục tiêu là cấu hình &lt;strong&gt;failure destination&lt;/strong&gt; cho Lambda function &lt;code&gt;ProcessMessages&lt;/code&gt;, để khi function xử lý message thất bại, Lambda tự động gửi failure record sang SNS topic &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bài toán cần giải quyết
&lt;/h2&gt;

&lt;p&gt;Giả sử bạn có một Lambda function tên là &lt;code&gt;ProcessMessages&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Function này được invoke &lt;strong&gt;asynchronously&lt;/strong&gt; khi có message được publish vào Amazon SNS topic tên là &lt;code&gt;InputTopic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Yêu cầu đặt ra:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Khi Lambda &lt;code&gt;ProcessMessages&lt;/code&gt; xử lý message thất bại, hệ thống phải gửi thông báo lỗi đến SNS topic &lt;code&gt;ErrorTopic&lt;/code&gt;, sau đó SNS gửi email alert cho người quản trị.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Đây là một tình huống rất thực tế trong các hệ thống event-driven trên AWS. Thay vì để lỗi nằm im trong CloudWatch Logs, chúng ta muốn đẩy lỗi ra một kênh alert tập trung.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao dùng Lambda Failure Destination?
&lt;/h2&gt;

&lt;p&gt;Với Lambda asynchronous invocation, caller không chờ Lambda xử lý xong để nhận kết quả ngay lập tức. Lambda nhận event, đưa vào hàng đợi nội bộ, rồi xử lý sau.&lt;/p&gt;

&lt;p&gt;Nếu function lỗi, Lambda có thể retry. Khi event vẫn thất bại sau các lần retry, Lambda có thể gửi failure record đến một destination, ví dụ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon SNS topic&lt;/li&gt;
&lt;li&gt;Amazon SQS queue&lt;/li&gt;
&lt;li&gt;Lambda function khác&lt;/li&gt;
&lt;li&gt;Amazon EventBridge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trong bài lab này, chúng ta dùng &lt;strong&gt;Amazon SNS ErrorTopic&lt;/strong&gt; làm failure destination.&lt;/p&gt;

&lt;p&gt;Điểm quan trọng là:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SNS InputTopic không tự biết Lambda fail.
Lambda mới là nơi biết xử lý thành công hay thất bại.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vì vậy, cách đúng là cấu hình &lt;strong&gt;Destination on failure&lt;/strong&gt; trên Lambda, trỏ đến &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kiến trúc lab
&lt;/h2&gt;

&lt;p&gt;Trong lab này, chúng ta sẽ tạo và cấu hình các thành phần sau:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tạo SNS topic &lt;code&gt;InputTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tạo SNS topic &lt;code&gt;ErrorTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Subscribe email vào &lt;code&gt;ErrorTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tạo Lambda function &lt;code&gt;ProcessMessages&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Gắn &lt;code&gt;InputTopic&lt;/code&gt; làm trigger cho Lambda&lt;/li&gt;
&lt;li&gt;Viết code Lambda cố tình throw error&lt;/li&gt;
&lt;li&gt;Cấu hình Lambda async failure destination trỏ về &lt;code&gt;ErrorTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Publish message vào &lt;code&gt;InputTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Kiểm tra email alert từ &lt;code&gt;ErrorTopic&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Hands-on Lab bằng AWS Console
&lt;/h2&gt;

&lt;p&gt;Phần này dùng AWS Console để thao tác trực tiếp. Bạn có thể làm nhanh trong tài khoản AWS cá nhân.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 1: Tạo SNS topic InputTopic
&lt;/h2&gt;

&lt;p&gt;Vào AWS Console, mở dịch vụ &lt;strong&gt;Amazon SNS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Đi theo đường dẫn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Amazon SNS → Topics → Create topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chọn cấu hình:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type: Standard
Name: InputTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Sau khi tạo xong, lưu lại ARN của topic. Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arn:aws:sns:ap-southeast-1:123456789012:InputTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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




&lt;h2&gt;
  
  
  Bước 2: Tạo SNS topic ErrorTopic
&lt;/h2&gt;

&lt;p&gt;Tiếp tục tạo topic thứ hai để nhận failure notification.&lt;/p&gt;

&lt;p&gt;Vào:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Amazon SNS → Topics → Create topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type: Standard
Name: ErrorTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ErrorTopic&lt;/code&gt; sẽ là nơi nhận failure record từ Lambda khi &lt;code&gt;ProcessMessages&lt;/code&gt; xử lý message thất bại.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 3: Subscribe email vào ErrorTopic
&lt;/h2&gt;

&lt;p&gt;Vào topic &lt;code&gt;ErrorTopic&lt;/code&gt;, chọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subscriptions → Create subscription
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Cấu hình subscription:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Protocol: Email
Endpoint: email của bạn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hieunghiwork123@gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;p&gt;Sau khi tạo subscription, mở hộp thư email và bấm &lt;strong&gt;Confirm subscription&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Lưu ý: email xác nhận có thể nằm trong thư mục Spam hoặc Promotions. Nếu subscription chưa được confirm, SNS sẽ không gửi email alert cho bạn.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 4: Tạo Lambda function ProcessMessages
&lt;/h2&gt;

&lt;p&gt;Vào AWS Lambda:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Lambda → Functions → Create function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Author from scratch
Function name: ProcessMessages
Runtime: Python 3.12
Architecture: x86_64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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




&lt;h2&gt;
  
  
  Bước 5: Viết code Lambda cố tình fail
&lt;/h2&gt;

&lt;p&gt;Để test failure destination, chúng ta sẽ viết Lambda luôn throw exception.&lt;/p&gt;

&lt;p&gt;Trong Lambda code editor, thay code bằng:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Received event:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Giả lập xử lý message thất bại
&lt;/span&gt;    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Simulated processing failure from ProcessMessages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;p&gt;Ý nghĩa của đoạn code này:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda nhận event từ &lt;code&gt;InputTopic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In event ra CloudWatch Logs&lt;/li&gt;
&lt;li&gt;Cố tình throw exception&lt;/li&gt;
&lt;li&gt;Lambda async invocation retry&lt;/li&gt;
&lt;li&gt;Khi retry thất bại hết, Lambda gửi failure record sang &lt;code&gt;ErrorTopic&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Đây là cách test đơn giản để kiểm tra cơ chế &lt;strong&gt;Lambda async failure destination&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 6: Gắn InputTopic làm trigger cho Lambda
&lt;/h2&gt;

&lt;p&gt;Trong Lambda &lt;code&gt;ProcessMessages&lt;/code&gt;, vào tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration → Triggers → Add trigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Chọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source: SNS
SNS topic: InputTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Lúc này flow đầu vào đã có:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;p&gt;Từ giờ, mỗi khi bạn publish message vào &lt;code&gt;InputTopic&lt;/code&gt;, SNS sẽ invoke Lambda &lt;code&gt;ProcessMessages&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 7: Cấu hình Failure Destination cho Lambda
&lt;/h2&gt;

&lt;p&gt;Đây là phần quan trọng nhất của lab.&lt;/p&gt;

&lt;p&gt;Trong Lambda &lt;code&gt;ProcessMessages&lt;/code&gt;, vào:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration → Destinations → Add destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source: Asynchronous invocation
Condition: On failure
Destination type: SNS topic
Destination: ErrorTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hoặc nếu giao diện AWS Console của bạn hiển thị theo cách khác, có thể đi theo đường dẫn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration → Asynchronous invocation → Edit
Destination on failure → SNS topic → ErrorTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

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

&lt;p&gt;Sau bước này, khi Lambda xử lý event thất bại sau các lần retry, Lambda sẽ gửi failure record sang SNS topic &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 8: Kiểm tra IAM permission
&lt;/h2&gt;

&lt;p&gt;Để Lambda gửi được message sang SNS topic &lt;code&gt;ErrorTopic&lt;/code&gt;, execution role của Lambda cần quyền &lt;code&gt;sns:Publish&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Policy tối thiểu có dạng:&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;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sns:Publish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:sns:REGION:ACCOUNT_ID:ErrorTopic"&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;Ví dụ:&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;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sns:Publish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:sns:ap-southeast-1:123456789012:ErrorTopic"&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;Nếu thiếu quyền này, Lambda có thể xử lý fail đúng như mong đợi nhưng không gửi được failure record sang &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Khi debug, bạn có thể kiểm tra metric:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Nếu metric này tăng, thường là do permission, ARN, region hoặc destination config có vấn đề.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 9: Publish message vào InputTopic để test
&lt;/h2&gt;

&lt;p&gt;Vào SNS topic &lt;code&gt;InputTopic&lt;/code&gt;, chọn:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Nhập subject:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Nhập message body:&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;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"process"&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;Sau đó bấm:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Khi đó flow sẽ chạy như sau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InputTopic nhận message
→ SNS invoke Lambda ProcessMessages
→ Lambda throw exception
→ Lambda retry async invocation
→ Sau khi fail hết retry
→ Lambda gửi failure record sang ErrorTopic
→ ErrorTopic gửi email alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Bước 10: Kiểm tra CloudWatch Logs
&lt;/h2&gt;

&lt;p&gt;Vào CloudWatch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CloudWatch → Log groups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tìm log group:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Bạn sẽ thấy log tương tự:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Received event:
...
Exception: Simulated processing failure from ProcessMessages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Điều này chứng minh Lambda đã nhận event từ SNS nhưng xử lý thất bại.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bước 11: Kiểm tra email từ ErrorTopic
&lt;/h2&gt;

&lt;p&gt;Sau một lúc, bạn sẽ nhận được email từ SNS &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Nội dung email thường chứa failure record từ Lambda. Một số field quan trọng gồm:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Ý nghĩa&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requestContext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Thông tin về request Lambda async invocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lý do event được gửi sang failure destination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;approximateInvokeCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Số lần Lambda đã cố invoke event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requestPayload&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Event gốc được gửi vào Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;responseContext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Thông tin response sau khi Lambda xử lý&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;functionError&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Loại lỗi của function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;responsePayload&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Error message và stack trace&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ví dụ khi bạn thấy:&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;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RetriesExhausted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"approximateInvokeCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"functionError"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Unhandled"&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;Điều này nghĩa là Lambda đã xử lý thất bại sau toàn bộ retry attempts. Mặc định, bạn có thể thấy tổng cộng khoảng 3 lần invoke: 1 lần đầu và 2 lần retry.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao email alert có thể đến hơi chậm?
&lt;/h2&gt;

&lt;p&gt;Đây là điểm rất dễ gây nhầm khi mới làm lab.&lt;/p&gt;

&lt;p&gt;Với asynchronous invocation, Lambda không gửi failure record sang destination ngay sau lần fail đầu tiên. Lambda sẽ retry trước. Khi event fail hết các lần retry, lúc đó Lambda mới gửi record sang &lt;code&gt;ErrorTopic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vì vậy nếu bạn thấy Lambda được invoke 2 lần nhưng chưa nhận mail, có thể đơn giản là Lambda chưa retry hết.&lt;/p&gt;

&lt;p&gt;Nếu muốn test nhanh hơn, có thể chỉnh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda → Configuration → Asynchronous invocation → Edit
Retry attempts: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sau đó publish message mới vào &lt;code&gt;InputTopic&lt;/code&gt;. Khi retry attempts là 0, failure destination sẽ được kích hoạt nhanh hơn.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao đây là đáp án đúng trong AWS Exam?
&lt;/h2&gt;

&lt;p&gt;Câu hỏi AWS exam thường đưa ra tình huống:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda được invoke asynchronously&lt;/li&gt;
&lt;li&gt;Lambda xử lý message thất bại&lt;/li&gt;
&lt;li&gt;Cần gửi notification đến SNS topic&lt;/li&gt;
&lt;li&gt;Có sẵn ErrorTopic để nhận lỗi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trong trường hợp này, giải pháp đúng là:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configure a failure destination for the Lambda function.
Specify the ARN of the ErrorTopic SNS topic as the destination ARN.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lý do: failure destination là cơ chế native của Lambda dành cho asynchronous invocation failure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao không dùng SNS filter policy?
&lt;/h2&gt;

&lt;p&gt;Một nhầm lẫn phổ biến là nghĩ rằng có thể dùng SNS filter policy để bắt lỗi Lambda.&lt;/p&gt;

&lt;p&gt;Thực tế, SNS filter policy chỉ lọc message đã được publish vào SNS topic trước khi gửi đến subscriber. Nó không tự biết Lambda function xử lý thành công hay thất bại.&lt;/p&gt;

&lt;p&gt;Flow sai sẽ là:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Trong khi yêu cầu đúng là:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProcessMessages fail → ErrorTopic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vì vậy, không dùng SNS filter policy cho bài toán này.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao không dùng SNS delivery policy?
&lt;/h2&gt;

&lt;p&gt;SNS delivery policy dùng để kiểm soát cách SNS retry khi gửi message đến subscriber. Nó không phải cơ chế để Lambda báo lỗi xử lý message.&lt;/p&gt;

&lt;p&gt;Nói ngắn gọn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SNS delivery policy = SNS gửi message ra subscriber như thế nào
Lambda failure destination = Lambda fail thì gửi failure record đi đâu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bài này cần cơ chế thứ hai.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dọn dẹp tài nguyên sau lab
&lt;/h2&gt;

&lt;p&gt;Sau khi test xong, bạn nên xóa các resource sau để tránh phát sinh chi phí hoặc làm rối tài khoản AWS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda function: ProcessMessages
SNS topic: InputTopic
SNS topic: ErrorTopic
CloudWatch log group: /aws/lambda/ProcessMessages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nếu không cần giữ log, vào CloudWatch và xóa log group tương ứng.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tổng kết
&lt;/h2&gt;

&lt;p&gt;Trong bài lab này, chúng ta đã cấu hình thành công flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SNS InputTopic
        ↓
Lambda ProcessMessages
        ↓ On failure destination
SNS ErrorTopic
        ↓
Email notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Đây là một pattern rất hữu ích khi xây dựng hệ thống event-driven trên AWS. Thay vì chỉ xem lỗi trong CloudWatch Logs, bạn có thể đẩy failure record sang SNS để gửi email, tích hợp với hệ thống alert, hoặc fan-out sang nhiều subscriber khác.&lt;/p&gt;

&lt;p&gt;Keyword cần nhớ cho AWS Exam:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda asynchronous invocation
Failure destination
Destination on failure
SNS ErrorTopic
RetriesExhausted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Khi đề bài nói Lambda async invocation thất bại và cần gửi thông báo sang SNS topic, hãy nghĩ ngay đến:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda async failure destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>sns</category>
      <category>aws</category>
    </item>
    <item>
      <title>Triển Khai nhiều Static Websites trên AWS với nhiều môi trường bằng AWS Amplify</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Mon, 18 May 2026 14:07:32 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/trien-khai-nhieu-static-websites-tren-aws-voi-nhieu-moi-truong-bang-aws-amplify-4ol5</link>
      <guid>https://dev.to/nghidanh2005/trien-khai-nhieu-static-websites-tren-aws-voi-nhieu-moi-truong-bang-aws-amplify-4ol5</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.amazonaws.com%2Fuploads%2Farticles%2Fnob2n7qfrcmtf7nhjhc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnob2n7qfrcmtf7nhjhc6.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi một công ty cần triển khai và duy trì &lt;strong&gt;nhiều static websites&lt;/strong&gt; trên AWS, bài toán thường không chỉ là “host website ở đâu”, mà còn là:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source code nằm ở nhiều hệ thống khác nhau như &lt;strong&gt;AWS CodeCommit, GitHub, Bitbucket&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Có nhiều môi trường release: &lt;strong&gt;Development, Staging, UAT, Production&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Mỗi môi trường phải tự động deploy khi merge code vào branch tương ứng&lt;/li&gt;
&lt;li&gt;Toàn bộ traffic phải dùng &lt;strong&gt;HTTPS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Giải pháp phải &lt;strong&gt;serverless&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Không được yêu cầu server chạy liên tục&lt;/li&gt;
&lt;li&gt;Chi phí vận hành phải thấp nhất&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trong trường hợp này, lựa chọn phù hợp nhất là:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AWS Amplify Hosting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Bài toán kiến trúc
&lt;/h2&gt;

&lt;p&gt;Giả sử công ty có nhiều website tĩnh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Website A
Website B
Website C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source code của các website này có thể nằm ở nhiều nơi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS CodeCommit
GitHub
Bitbucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mỗi repository lại có các branch tương ứng với từng môi trường:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev          → Development
staging      → Staging
uat          → User Acceptance Testing
production   → Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yêu cầu là khi developer merge code vào branch nào, website ở môi trường tương ứng phải được deploy tự động.&lt;/p&gt;

&lt;p&gt;Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merge vào dev branch        → Deploy Development
Merge vào staging branch    → Deploy Staging
Merge vào uat branch        → Deploy UAT
Merge vào production branch → Deploy Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Kiến trúc tổng quan
&lt;/h2&gt;

&lt;p&gt;Flow triển khai có thể hiểu như sau:&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 Repository
        ↓
Git Branch Merge
        ↓
AWS Amplify Hosting
        ↓
Automatic Build &amp;amp; Deploy
        ↓
Environment-specific Static Website
        ↓
HTTPS Access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS Amplify đóng vai trò là dịch vụ managed hosting cho static websites và frontend apps. Nó có thể kết nối trực tiếp với Git repositories, theo dõi branch, tự động build và deploy khi có thay đổi.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vì sao dùng AWS Amplify?
&lt;/h2&gt;

&lt;p&gt;AWS Amplify Hosting phù hợp vì nó giải quyết trực tiếp các yêu cầu chính của bài toán.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Hỗ trợ nhiều Git providers
&lt;/h3&gt;

&lt;p&gt;Amplify có thể kết nối với các hệ thống source control phổ biến như:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS CodeCommit
GitHub
Bitbucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Điều này giúp công ty không cần phải chuẩn hóa toàn bộ source code về một nơi duy nhất. Website nào đang ở GitHub thì vẫn giữ ở GitHub. Website nào đang ở Bitbucket thì vẫn có thể deploy được.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Branch-based deployment
&lt;/h3&gt;

&lt;p&gt;Đây là điểm quan trọng nhất của bài toán.&lt;/p&gt;

&lt;p&gt;Với AWS Amplify, mỗi branch có thể được map với một environment riêng.&lt;/p&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Git Branch&lt;/th&gt;
&lt;th&gt;AWS Environment&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;dev&lt;/td&gt;
&lt;td&gt;Development&lt;/td&gt;
&lt;td&gt;dev.example.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;staging&lt;/td&gt;
&lt;td&gt;Staging&lt;/td&gt;
&lt;td&gt;staging.example.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uat&lt;/td&gt;
&lt;td&gt;User Acceptance Testing&lt;/td&gt;
&lt;td&gt;uat.example.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;production&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Khi code được merge vào branch tương ứng, Amplify sẽ tự động trigger build và deploy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev branch merge
        ↓
Development deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;production branch merge
        ↓
Production deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Không cần tự viết pipeline phức tạp cho từng môi trường.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Serverless static website hosting
&lt;/h2&gt;

&lt;p&gt;Một yêu cầu quan trọng khác là:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Không được có server chạy liên tục.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Amplify Hosting là managed service. Bạn không cần tạo EC2 instance, không cần patch server, không cần quản lý web server như Nginx hay Apache.&lt;/p&gt;

&lt;p&gt;Điều này giúp loại bỏ các thành phần vận hành như:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 instances
Load balancers tự quản lý
Web servers chạy liên tục
Manual deployment scripts
Server patching
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thay vào đó, Amplify quản lý hosting, build, deployment và delivery cho bạn.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. HTTPS được hỗ trợ sẵn
&lt;/h2&gt;

&lt;p&gt;Bài toán yêu cầu:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All data exchange must use HTTPS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AWS Amplify Hosting hỗ trợ HTTPS cho website được deploy. Khi gắn custom domain, Amplify cũng có thể xử lý SSL/TLS certificate để website được truy cập an toàn qua HTTPS.&lt;/p&gt;

&lt;p&gt;Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://dev.example.com
https://staging.example.com
https://uat.example.com
https://www.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Người dùng cuối truy cập website qua browser với HTTPS lock icon, đảm bảo traffic được mã hóa.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Least operational overhead
&lt;/h2&gt;

&lt;p&gt;Nếu nhìn theo góc độ AWS Solutions Architect exam, cụm từ quan trọng nhất trong đề thường là:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LEAST operational overhead&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Điều này nghĩa là giải pháp không chỉ “chạy được”, mà phải là giải pháp cần ít cấu hình, ít vận hành, ít bảo trì nhất.&lt;/p&gt;

&lt;p&gt;AWS Amplify phù hợp vì:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect trực tiếp với Git repository
Tự detect branch merge
Tự build
Tự deploy
Tự host static website
Có HTTPS
Không cần server chạy liên tục
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Đây là một giải pháp managed và serverless, nên operational overhead thấp hơn nhiều so với việc tự lắp ghép nhiều dịch vụ riêng lẻ.&lt;/p&gt;




&lt;h2&gt;
  
  
  So sánh với các lựa chọn khác
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Elastic Beanstalk
&lt;/h3&gt;

&lt;p&gt;Elastic Beanstalk phù hợp hơn cho application backend hoặc web application cần runtime server.&lt;/p&gt;

&lt;p&gt;Với static websites đơn giản, dùng Elastic Beanstalk là không tối ưu vì vẫn có nhiều operational overhead hơn.&lt;/p&gt;

&lt;p&gt;Bạn sẽ phải quan tâm nhiều hơn đến môi trường chạy ứng dụng, scaling, platform, instance, deployment configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Elastic Beanstalk = chạy được, nhưng không lý tưởng cho static sites đơn giản
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  S3 + CodePipeline + CodeBuild
&lt;/h3&gt;

&lt;p&gt;S3 static website hosting kết hợp với CodePipeline và CodeBuild cũng có thể triển khai được.&lt;/p&gt;

&lt;p&gt;Tuy nhiên, bạn sẽ phải tự cấu hình nhiều thứ hơn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;S3 bucket cho từng environment
CodePipeline cho từng branch
CodeBuild project
IAM roles
Artifact flow
CloudFront nếu cần HTTPS với custom domain
Invalidation logic nếu dùng CDN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Giải pháp này có thể đúng về mặt kỹ thuật, nhưng không phải lựa chọn có &lt;strong&gt;least operational overhead&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;S3 + CodePipeline + CodeBuild = works, but more setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  EC2
&lt;/h3&gt;

&lt;p&gt;EC2 là lựa chọn kém nhất cho bài toán này.&lt;/p&gt;

&lt;p&gt;Vì EC2 yêu cầu server chạy liên tục, trái ngược hoàn toàn với yêu cầu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No continuously running servers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ngoài ra, dùng EC2 để host static websites sẽ kéo theo nhiều công việc vận hành:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provision server
Install web server
Patch OS
Configure HTTPS
Monitor instance
Handle scaling
Manage availability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Đây là operational overhead cao nhất.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kiến trúc đề xuất
&lt;/h2&gt;

&lt;p&gt;Một kiến trúc hợp lý sẽ như sau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS CodeCommit / GitHub / Bitbucket
        ↓
Branch merge event
        ↓
AWS Amplify Hosting
        ↓
Automatic build and deployment
        ↓
Development / Staging / UAT / Production
        ↓
HTTPS static websites
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mỗi website có thể có các environment riêng:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Website A
├── dev.example.com
├── staging.example.com
├── uat.example.com
└── www.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Website B
├── dev.website-b.com
├── staging.website-b.com
├── uat.website-b.com
└── www.website-b.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Mapping branch với environment
&lt;/h2&gt;

&lt;p&gt;Một cách triển khai thường gặp:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Branch&lt;/th&gt;
&lt;th&gt;Environment&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;dev&lt;/td&gt;
&lt;td&gt;Development&lt;/td&gt;
&lt;td&gt;Developer testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;staging&lt;/td&gt;
&lt;td&gt;Staging&lt;/td&gt;
&lt;td&gt;Pre-release validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uat&lt;/td&gt;
&lt;td&gt;User Acceptance Testing&lt;/td&gt;
&lt;td&gt;Business/user approval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;production&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;td&gt;Live website&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Khi team merge code vào &lt;code&gt;staging&lt;/code&gt;, Amplify tự động deploy bản staging.&lt;/p&gt;

&lt;p&gt;Khi release đã được approve, team merge vào &lt;code&gt;production&lt;/code&gt;, Amplify tự động deploy bản production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key exam takeaway
&lt;/h2&gt;

&lt;p&gt;Trong AWS exam, khi thấy các keyword sau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Static websites
Multiple Git providers
Branch-based deployment
Development / Staging / UAT / Production
HTTPS
Serverless
No continuously running servers
Least operational overhead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hãy nghĩ ngay đến:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Kết luận
&lt;/h2&gt;

&lt;p&gt;AWS Amplify Hosting là lựa chọn phù hợp nhất cho bài toán deploy nhiều static websites trên AWS với nhiều môi trường release.&lt;/p&gt;

&lt;p&gt;Nó hỗ trợ trực tiếp các yêu cầu quan trọng:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ Static website hosting
✅ Kết nối với CodeCommit, GitHub, Bitbucket
✅ Branch-based deployments
✅ Tự động build và deploy khi merge code
✅ HTTPS enabled
✅ Serverless
✅ Không cần EC2
✅ Không có always-on servers
✅ Least operational overhead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Với bài toán này, giải pháp tốt nhất là:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Host each website by using AWS Amplify Hosting, connect repository branches to the corresponding environments, and trigger deployments automatically when code is merged into each branch.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>amlify</category>
      <category>aws</category>
    </item>
    <item>
      <title>View Quick Chat History with CloudWatch Logs Group</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 06:30:11 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/view-quick-chat-history-with-cloudwatch-logs-group-4g8p</link>
      <guid>https://dev.to/nghidanh2005/view-quick-chat-history-with-cloudwatch-logs-group-4g8p</guid>
      <description>&lt;p&gt;In this blog, we will configure a CloudWatch Log Group to receive chat history from Quick Chat Agents based on Quick User or Agent ID.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS CLI&lt;/li&gt;
&lt;li&gt;Quick Account/User&lt;/li&gt;
&lt;li&gt;Ensure your IAM user/role has the permission:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;quicksight:AllowVendedLogDeliveryForResource&lt;/code&gt;
on resource:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arn:aws:quicksight:us-east-1:account_id:account/account_id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;My Quick resource ARN:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;arn:aws:quicksight:us-east-1:123412341234:account/123412341234&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create Delivery Source&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go to Cloud Watch service and click on Log Management on 'Logs" section and create a log group name "nghi-danh-test-quick-history-chat"&lt;/p&gt;

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

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

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

&lt;p&gt;Next step, open AWS CloudShell to perform "configure delivery sources - delivery destination,.."&lt;/p&gt;

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

&lt;p&gt;Create Delivery Source of QuickSuite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws logs put-delivery-source   &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="nt"&gt;--name&lt;/span&gt; quick-chat-source-nghi-danh  &lt;span class="nt"&gt;--resource-arn&lt;/span&gt; arn:aws:quicksight:us-east-1:account_id:account/account_id &lt;span class="nt"&gt;--log-type&lt;/span&gt; CHAT_LOGS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

&lt;p&gt;Create Delivery Destination:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws logs put-delivery-destination &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; quick-chat-destination-nghi-danh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--delivery-destination-type&lt;/span&gt; CWL &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output-format&lt;/span&gt; json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--delivery-destination-configuration&lt;/span&gt; &lt;span class="nv"&gt;destinationResourceArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:logs:us-east-1:account_id:log-group:nghi-danh-test-quick-history-chat:*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

&lt;p&gt;Connect source and destination:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws logs create-delivery &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--delivery-source-name&lt;/span&gt; quick-chat-source-nghi-danh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--delivery-destination-arn&lt;/span&gt; arn:aws:logs:us-east-1:account_id:delivery-destination:quick-chat-destination-nghi-danh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--record-fields&lt;/span&gt; resource_arn event_timestamp logType accountId user_arn user_type namespace status_code conversation_id system_message_id latency time_to_first_token message_scope user_message_id user_message agent_id flow_id system_text_message surface_type web_search user_selected_resources action_connectors cited_resource file_attachment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

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

&lt;p&gt;After few minutes, it will appear on Log Stream "QUICK_SUITE_CHAT_LOGS"&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ihatesea69" rel="noopener noreferrer"&gt;
        ihatesea69
      &lt;/a&gt; / &lt;a href="https://github.com/ihatesea69/evaluation-amazon-quick-suite" rel="noopener noreferrer"&gt;
        evaluation-amazon-quick-suite
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Amazon Quick chat export CLI
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Amazon Quick Chat Export&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Simple Python script to export Amazon Quick &lt;code&gt;CHAT_LOGS&lt;/code&gt; conversations from CloudWatch Logs Insights to CSV.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS credentials with access to
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;logs:DescribeLogGroups&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logs:StartQuery&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logs:GetQueryResults&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sts:GetCallerIdentity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quicksight:ListUsers&lt;/code&gt; when using &lt;code&gt;--quick-user&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Files&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;download_quick_conversations.py&lt;/code&gt;: main CLI script&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tests/test_download_quick_conversations.py&lt;/code&gt;: unit and stubbed integration tests&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Export chat rows to CSV:&lt;/p&gt;

&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python download_quick_conversations.py &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;region us&lt;span class="pl-k"&gt;-&lt;/span&gt;east&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;1&lt;/span&gt; &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;log&lt;span class="pl-k"&gt;-&lt;/span&gt;group &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;your-log-group&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;start &lt;span class="pl-c1"&gt;2026&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;04&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;01T00:&lt;span class="pl-c1"&gt;00&lt;/span&gt;:00Z &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;end &lt;span class="pl-c1"&gt;2026&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;04&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;02T00:&lt;span class="pl-c1"&gt;00&lt;/span&gt;:00Z &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;quick&lt;span class="pl-k"&gt;-&lt;/span&gt;user &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;user@example.com&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;output quick_chat_logs.csv&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;List distinct &lt;code&gt;agent_id&lt;/code&gt; values only:&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python download_quick_conversations.py &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;region us&lt;span class="pl-k"&gt;-&lt;/span&gt;east&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;1&lt;/span&gt; &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;log&lt;span class="pl-k"&gt;-&lt;/span&gt;group &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;your-log-group&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;start &lt;span class="pl-c1"&gt;2026&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;04&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;01T00:&lt;span class="pl-c1"&gt;00&lt;/span&gt;:00Z &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;end &lt;span class="pl-c1"&gt;2026&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;04&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;02T00:&lt;span class="pl-c1"&gt;00&lt;/span&gt;:00Z &lt;span class="pl-k"&gt;`&lt;/span&gt;
  &lt;span class="pl-k"&gt;--&lt;/span&gt;quick&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ihatesea69/evaluation-amazon-quick-suite" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Use this github repo to download the the content to csv files&lt;/p&gt;

&lt;p&gt;References Link AWS Doc&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://docs.aws.amazon.com/quick/latest/userguide/monitoring-quicksuite-chat-feedback-cloudwatch.html" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;docs.aws.amazon.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
 

</description>
      <category>quick</category>
      <category>amazonquick</category>
      <category>quicksuite</category>
      <category>quicksight</category>
    </item>
    <item>
      <title>I need to learn CNN</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Mon, 23 Mar 2026 13:48:01 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/i-need-to-learn-cnn-6f9</link>
      <guid>https://dev.to/nghidanh2005/i-need-to-learn-cnn-6f9</guid>
      <description>&lt;p&gt;I need to learn CNN for my School Project presentation. &lt;br&gt;
The blogs will split into 3 parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High-level overview (non-coder/non-tech background)&lt;/li&gt;
&lt;li&gt;Detail how CNN work? (with visualization website)&lt;/li&gt;
&lt;li&gt;Python coding example with Pytorch / Tensorflow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. High-level overview
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the most impressive forms of ANN architecture is&lt;br&gt;
that of the Convolutional Neural Network (CNN). CNNs are primarily used to solve difficult image-driven pattern recognition tasks and with their precise yet simple architecture, offers a simplified method of getting started with ANNs.&lt;br&gt;
 &lt;a href="https://arxiv.org/pdf/1511.08458" rel="noopener noreferrer"&gt;Abstraction- An Introduction to Convolutional Neural Networks paper&lt;/a&gt; - For the rest of this blogs, i will try to simplify this paper and summary paragraphs and connect ideas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Simplify this abstraction:&lt;/em&gt; CNN is a "better type" of ANN for &lt;strong&gt;image pattern recognition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keywords:&lt;/strong&gt; Pattern recognition, artificial neural networks, machine learning, image analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Artificial Neural Networks (ANNs) mimic human brain - nervous systems operate. ANNs comprised of interconnected computational nodes (neurons) - Learn from the input in order to optimise its final output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi07r3w2c85l1subnas9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi07r3w2c85l1subnas9.png" alt="A simple three layered feedforward neural network (FNN), comprised&lt;br&gt;
of a input layer, a hidden layer and an output layer. This structure is the basis&lt;br&gt;
of a number of common ANN architectures" width="568" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Load the input (multidimensional vector) fed the data to -&amp;gt; hidden layers. Then hidden layers &lt;strong&gt;make decisions&lt;/strong&gt; from previous layer and weigh up how a stochastic (randomly) change within itself detriments (decrease) or improve the final output This called &lt;strong&gt;learning&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If many of hidden stacked upon each-order -&amp;gt; &lt;strong&gt;deep learning&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>deeplearning</category>
      <category>tensorflow</category>
      <category>python</category>
    </item>
    <item>
      <title>SimpleMem - Lifelong Memory for Agents</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Sun, 08 Mar 2026 16:38:18 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/simplemem-lifelong-memory-for-agents-151l</link>
      <guid>https://dev.to/nghidanh2005/simplemem-lifelong-memory-for-agents-151l</guid>
      <description>&lt;p&gt;I read and summarize research paper so you don't have to. Use the most simple language ever. (Not some IELTS 8.0+ vocabulary words).&lt;/p&gt;

&lt;p&gt;Overview: This framework can use to Store, compress, retrieve long-term memories with semantic lossless compression. &lt;/p&gt;

&lt;p&gt;Works across all MCP Client for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Desktop&lt;/li&gt;
&lt;li&gt;Cursor&lt;/li&gt;
&lt;li&gt;LM Studio&lt;/li&gt;
&lt;li&gt;PyPi Package&lt;/li&gt;
&lt;li&gt;Any MCP Client.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SimpleMem&lt;/strong&gt; is an efficient memory framework based on semantic lossless compression that addresses the fundamental challenge of efficient long-term memory for LLM agents. Unlike existing systems that either passively accumulate redundant context or rely on expensive iterative reasoning loops, &lt;strong&gt;SimpleMem&lt;/strong&gt; maximizes information density and token utilization through a three-stage pipeline:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd2g8x4381q6adt0y7l39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd2g8x4381q6adt0y7l39.png" alt="SimpleMem achieves superior F1 score (43.24%) with minimal token cost (~550), occupying the ideal top-left position." width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of storing un-necessary context, &lt;strong&gt;SimpleMem&lt;/strong&gt; maximize &lt;strong&gt;&lt;em&gt;information density&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;token utilization&lt;/em&gt;&lt;/strong&gt; through a 3-stage pipeline: &lt;/p&gt;

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

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

&lt;p&gt;&lt;strong&gt;Stage 1 Semantic Structured Compression&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Semantic structured compression&lt;/strong&gt;&lt;/em&gt;: Distills unstructured interactions into compact, multi-view indexed memory units. Filters low-utility dialogue and coverts informative windows into compact, context-independent.&lt;/p&gt;

&lt;p&gt;In simple words that this step will filter out "less valuable information" and only keep "important information", and then converts into short - meaningful memory units that can be re-use later context-independent.&lt;/p&gt;

&lt;p&gt;(1) Sliding windows -&amp;gt; (2) Sematic Density Gating -&amp;gt; (3) Memory Units&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(1) Sliding windows&lt;/strong&gt;: Instead of processing the wholes conversation at once, SimpleMem splits it into small overlapping windows of dialogue. Each window contains a short local span of interaction.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;(2): Semantic Density Gating *&lt;/em&gt;(Information Filter): the model checks whether a window contains high-value semantic content or not. If the window is mostly noise, it is discarded, if it contains useful information, the system keeps and extracts it.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Noise = "That's cool bro", "keep it going",..&lt;/li&gt;
&lt;li&gt;Information = "I prefer OOP over Functional programming"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;(3): Convert into memory units&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;SimpleMem rewrites useful content into compact memory units.&lt;br&gt;
This transformation includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coreference resolution&lt;/strong&gt;: Replace value references like "she", "it",.. with explicit entities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal normalization&lt;/strong&gt;: converting relative time phrases like "yesterday" or "last week" into timestamps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fact atomization&lt;/strong&gt;: turning messy dialogue into short, self-contained factual statements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Raw dialogue:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Yesterday I took my kids to the museum.”&lt;/li&gt;
&lt;li&gt;“They loved the dinosaur exhibit.”&lt;/li&gt;
&lt;li&gt;“Yeah, that sounds fun.”&lt;/li&gt;
&lt;li&gt;“My daughter turns 8 next month.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;After Step 1, possible memory units:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[2023-07-12] Sarah took her kids to the Natural History Museum.&lt;/li&gt;
&lt;li&gt;Sarah's kids loved the dinosaur exhibit.&lt;/li&gt;
&lt;li&gt;Sarah's daughter turns 8 in August 2023.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One-line summary: Step 1 breaks dialogue into small windows, filters out low-value parts, and compresses useful content into clean, self-contained memory units.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2 Online Semantic Synthesis&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Intra-session process that instantly integrates related context into unified abstract representations to eliminate redundancy&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After Stage 1 extracts small memory units or facts, Stage 2 looks at related facts within the same session and merges them into unified abstract representations so the system does not store many fragmented pieces that mean nearly the same thing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Online” does not mean internet-based.&lt;/em&gt;&lt;br&gt;
It means the synthesis happens during memory writing, in real time. &lt;strong&gt;SimpleMem&lt;/strong&gt; does not wait for a later background cleanup step; it performs synthesis on-the-fly during the write phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does “semantic synthesis” mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It means the model combines pieces of information based on meaning, not just surface wording.&lt;br&gt;
If several extracted facts refer to the same preference, event, or topic, the system rewrites them into one denser and more coherent memory entry.&lt;/p&gt;

&lt;p&gt;The paper’s example is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“User wants coffee”&lt;/li&gt;
&lt;li&gt;“User prefers oat milk”&lt;/li&gt;
&lt;li&gt;“User likes it hot”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;which gets consolidated into:&lt;/p&gt;

&lt;p&gt;“User prefers hot coffee with oat milk.”&lt;/p&gt;

&lt;p&gt;Without Stage 2, semantically related facts accumulate as fragmented entries. Then, at retrieval time, the system must gather and assemble scattered evidence&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage 1 = clean and extract&lt;/li&gt;
&lt;li&gt;Stage 2 = consolidate and abstract&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3 Intent-Aware Retrieval Planning&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Intent-Aware Retrieval Planning&lt;/strong&gt; decides: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What to retrieve?&lt;/li&gt;
&lt;li&gt;How much to retrieve? &lt;/li&gt;
&lt;li&gt;From which retrieval views? 
When a new query arrives. Instead of always fetching a fixed number of memories, SimpleMem first infers the latent search intent of the query, then adapts the retrieval scope and retrieval depth accordingly. This helps avoid both under-retrieval for complex questions and token waste for simple ones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What does “intent-aware” mean?&lt;/p&gt;

&lt;p&gt;It means the system tries to understand whether the user is asking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a simple factual lookup,&lt;/li&gt;
&lt;li&gt;a multi-hop reasoning query,&lt;/li&gt;
&lt;li&gt;a temporally constrained question,&lt;/li&gt;
&lt;li&gt;or something involving entities, preferences, or metadata.
Based on that, the planner generates a structured retrieval plan:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;qsem for &lt;strong&gt;semantic retrieval&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;qlex for &lt;strong&gt;lexical retrieval&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;qsym for &lt;strong&gt;symbolic retrieval&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;d for adaptive retrieval depth&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once the plan is created, SimpleMem performs parallel multi-view retrieval over three complementary indexes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Semantic layer&lt;/strong&gt; for conceptual similarity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lexical layer&lt;/strong&gt; for exact keywords and rare proper nouns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symbolic layer&lt;/strong&gt; for structured metadata constraints such as time or entity type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it merges the results with a set union and naturally deduplicates overlapping entries, producing a context that is both compact and comprehensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does “determine retrieval scope” mean?&lt;/strong&gt;&lt;br&gt;
It means deciding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How many memory entries to fetch?&lt;/li&gt;
&lt;li&gt;How broad the search should be?&lt;/li&gt;
&lt;li&gt;Which retrieval paths matter most?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the paper, the inferred depth d reflects query complexity, and the system uses a candidate limit n proportional to d. So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simple query → shallow retrieval&lt;/li&gt;
&lt;li&gt;complex query → deeper retrieval. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;What does “construct precise context efficiently” mean?&lt;/em&gt;&lt;br&gt;
It means building a small but highly relevant context for answer generation instead of dumping raw history into the prompt. The paper describes this as querying multiple indexes and combining their outputs through ID-based deduplication, which balances semantic relevance and structural constraints while remaining token-efficient. &lt;/p&gt;

&lt;p&gt;Simple example&lt;br&gt;
If the query is:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“What paintings has Sarah created?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;the system recognizes that it should retrieve memories related to painting/art, then searches across semantic, lexical, and symbolic indexes. In the paper’s example, the final retrieved content includes memories such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sunset with palm trees&lt;/li&gt;
&lt;li&gt;horse portrait(instead of dragging in irrelevant memories like camping)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How is it different from Stage 2?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage 2 consolidates related memories during writing&lt;/li&gt;
&lt;li&gt;Stage 3 selects the right memories during retrieval for answering a query. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;One-line summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stage 3 understands what the user is really looking for, plans the right retrieval strategy, searches across multiple memory views, and builds a compact, accurate context for answering. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Its main idea is: instead of saving the full conversation history, it saves only the most useful information in a cleaner and shorter form. This helps the model remember important things for a long time without wasting too many tokens.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>researchpaper</category>
    </item>
    <item>
      <title>U-Net - CNN for Image Segmentation</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Sat, 07 Mar 2026 12:43:11 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/u-net-cnn-for-image-segmentation-545m</link>
      <guid>https://dev.to/nghidanh2005/u-net-cnn-for-image-segmentation-545m</guid>
      <description>&lt;p&gt;This support for the this post:&lt;a href="https://dev.to/nghidanh2005/i-read-this-paper-for-my-graduation-project-transunet-1d43"&gt;TransUnet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;References Link:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__wikipedia--container"&gt;
  &lt;div class="ltag__wikipedia--header"&gt;
    &lt;img src="https://assets.dev.to/assets/wikipedia-logo-0a3e76624c7b1c3ccdeb9493ea4add6ef5bd82d7e88d102d5ddfd7c981efa2e7.svg" class="ltag__wikipedia--logo" alt="Wikipedia Logo" width="128" height="128"&gt;
    &lt;a href="https://en.wikipedia.org/wiki/U-Net" rel="noopener noreferrer"&gt;U-Net&lt;/a&gt;
  &lt;/div&gt;
  &lt;div class="ltag__wikipedia--extract"&gt;&lt;p&gt;&lt;b&gt;U-Net&lt;/b&gt; is a convolutional neural network that was developed for image segmentation. The network is based on a fully convolutional neural network whose architecture was modified and extended to work with fewer training images and to yield more precise segmentation. Segmentation of a 512&amp;nbsp;×&amp;nbsp;512 image takes less than a second on a modern (2015) GPU using the U-Net architecture.&lt;/p&gt;&lt;/div&gt;
  &lt;div class="ltag__wikipedia--btn--container"&gt;
      &lt;a class="ltag__wikipedia--btn" href="https://en.wikipedia.org/wiki/U-Net" rel="noopener noreferrer"&gt;View on Wikipedia&lt;/a&gt;&amp;gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://aivietnam.edu.vn/blog/intro-to-unet#image-segmentation" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;aivietnam.edu.vn&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://viblo.asia/p/u-net-kien-truc-manh-me-cho-segmentation-1Je5Em905nL" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fviblo.asia%2Fog-facebook-3.png" height="418" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://viblo.asia/p/u-net-kien-truc-manh-me-cho-segmentation-1Je5Em905nL" rel="noopener noreferrer" class="c-link"&gt;
            U-net : Kiến trúc mạnh mẽ cho Segmentation
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            1. Segmentation! Segmentation! Đôi chút về Image Processing trong Deep Learning Với Deep Learning (hay Neural Network), máy tính ngày càng có khả năng quan sát và xử lí những hình ảnh phức tạp ở nhiều...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fviblo.asia%2Ffavicon.ico" width="64" height="64"&gt;
          viblo.asia
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>research</category>
      <category>paper</category>
    </item>
    <item>
      <title>I read this paper for my graduation project (TransUnet)</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Sat, 07 Mar 2026 12:42:23 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/i-read-this-paper-for-my-graduation-project-transunet-1d43</link>
      <guid>https://dev.to/nghidanh2005/i-read-this-paper-for-my-graduation-project-transunet-1d43</guid>
      <description>&lt;p&gt;Link paper: [TransUNet]: Transformers Make Strong&lt;br&gt;
Encoders for Medical Image Segmentation(&lt;a href="https://arxiv.org/pdf/2102.04306" rel="noopener noreferrer"&gt;https://arxiv.org/pdf/2102.04306&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>research</category>
      <category>paper</category>
    </item>
    <item>
      <title>Field-Level Encryption in Amazon CloudFront</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Fri, 13 Feb 2026 07:50:23 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/field-level-encryption-in-amazon-cloudfront-2ejj</link>
      <guid>https://dev.to/nghidanh2005/field-level-encryption-in-amazon-cloudfront-2ejj</guid>
      <description>&lt;h1&gt;
  
  
  Field-Level Encryption in Amazon CloudFront
&lt;/h1&gt;

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

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Field-Level Encryption (FLE)&lt;/strong&gt; is a security feature provided by&lt;br&gt;&lt;br&gt;
Amazon Web Services (AWS)&lt;br&gt;&lt;br&gt;
and implemented in&lt;br&gt;&lt;br&gt;
Amazon CloudFront.&lt;/p&gt;

&lt;p&gt;It allows you to encrypt &lt;strong&gt;specific sensitive fields&lt;/strong&gt; in an HTTP request instead of encrypting only the entire connection via HTTPS.&lt;/p&gt;

&lt;p&gt;This ensures that sensitive data remains encrypted even when it travels through multiple backend components.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Security Problem
&lt;/h2&gt;

&lt;p&gt;HTTPS provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption in transit&lt;/li&gt;
&lt;li&gt;Protection against man-in-the-middle attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the request reaches the backend, data is decrypted.&lt;/li&gt;
&lt;li&gt;In multi-tier architectures (ALB, EC2, Lambda, microservices), sensitive data may be exposed internally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Field-Level Encryption solves this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypting only selected fields (e.g., credit card numbers).&lt;/li&gt;
&lt;li&gt;Keeping those fields encrypted until they reach the trusted backend system with the private key.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 – Client Sends Request
&lt;/h3&gt;

&lt;p&gt;A user submits an HTTPS POST request containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name
&lt;/li&gt;
&lt;li&gt;email
&lt;/li&gt;
&lt;li&gt;credit_card_number (sensitive field)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 2 – Encryption at CloudFront Edge
&lt;/h3&gt;

&lt;p&gt;At the CloudFront Edge Location:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudFront uses an &lt;strong&gt;RSA public key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Only the configured sensitive field (e.g., credit_card_number) is encrypted.&lt;/li&gt;
&lt;li&gt;Other fields remain unchanged.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 3 – Request Sent to Origin
&lt;/h3&gt;

&lt;p&gt;The origin server receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name → readable
&lt;/li&gt;
&lt;li&gt;email → readable
&lt;/li&gt;
&lt;li&gt;credit_card_number → encrypted (ciphertext)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 4 – Decryption at Backend
&lt;/h3&gt;

&lt;p&gt;The backend application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses the corresponding &lt;strong&gt;private key&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Decrypts the encrypted field&lt;/li&gt;
&lt;li&gt;Processes the data securely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Key Components
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Public Key&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uploaded to CloudFront&lt;/li&gt;
&lt;li&gt;Used to encrypt sensitive fields&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Private Key&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stored securely at the backend&lt;/li&gt;
&lt;li&gt;Used to decrypt encrypted fields&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Field-Level Encryption Profile&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines which fields must be encrypted&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Field-Level Encryption Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attached to a CloudFront distribution behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  5. HTTPS vs Field-Level Encryption
&lt;/h2&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;HTTPS&lt;/th&gt;
&lt;th&gt;Field-Level Encryption&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Encrypts data in transit&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypts specific fields&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protects sensitive data across backend layers&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses asymmetric encryption (RSA)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. When to Use It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Online payment systems (PCI DSS compliance)&lt;/li&gt;
&lt;li&gt;Applications collecting personal identifiable information (PII)&lt;/li&gt;
&lt;li&gt;Multi-tier or microservices architectures&lt;/li&gt;
&lt;li&gt;Systems requiring strict decryption access control&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Summary
&lt;/h2&gt;

&lt;p&gt;Field-Level Encryption in Amazon CloudFront:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypts specific fields in HTTP requests.&lt;/li&gt;
&lt;li&gt;Performs encryption at the Edge Location.&lt;/li&gt;
&lt;li&gt;Ensures only trusted systems with the private key can decrypt data.&lt;/li&gt;
&lt;li&gt;Provides stronger protection for sensitive data compared to HTTPS alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is especially useful for financial systems and applications handling highly sensitive user data.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>Designing Serverless Applications at Massive Scale with AWS Lambda and RDS Proxy</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Thu, 12 Feb 2026 06:29:03 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/designing-serverless-applications-at-massive-scale-with-aws-lambda-and-rds-proxy-4k28</link>
      <guid>https://dev.to/nghidanh2005/designing-serverless-applications-at-massive-scale-with-aws-lambda-and-rds-proxy-4k28</guid>
      <description>&lt;p&gt;I love serverless architecture because i can build scalable systems without managing any infra or server, however for scaling some "provisioning" services like RDS is quite difficult.&lt;/p&gt;

&lt;p&gt;This blogs will have you take a look at how to design and scale an serverless architecture with AWS RDS Proxy and AWS Lambda&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Problem: The Hidden Scaling Problem
&lt;/h1&gt;

&lt;p&gt;AWS Lambda can scale horizontally to thousands of concurrent executions within seconds.&lt;/p&gt;

&lt;p&gt;But relational databases (MySQL/PostgreSQL on Amazon RDS or Aurora) have hard limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limited number of concurrent connections
&lt;/li&gt;
&lt;li&gt;Each connection consumes memory and CPU
&lt;/li&gt;
&lt;li&gt;Opening/closing connections is expensive &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If every Lambda invocation creates a new database connection, high concurrency can quickly exhaust the database’s &lt;code&gt;max_connections&lt;/code&gt; limit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connection errors
&lt;/li&gt;
&lt;li&gt;Increased latency
&lt;/li&gt;
&lt;li&gt;Database instability
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the core scaling &lt;u&gt;bottleneck&lt;/u&gt; in serverless architecture&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Solution: Amazon RDS Proxy
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What Is RDS Proxy?
&lt;/h2&gt;

&lt;p&gt;Amazon RDS Proxy is a managed database proxy that sits between your Lambda functions and your RDS database.&lt;/p&gt;

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

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

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

&lt;p&gt;We should use:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Why RDS Proxy?
&lt;/h2&gt;

&lt;p&gt;The main purpose is &lt;strong&gt;connection pooling and connection reuse&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Without proxy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each Lambda instance opens its own DB connection.&lt;/li&gt;
&lt;li&gt;Thousands of Lambdas = thousands of connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With RDS Proxy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proxy maintains a pool of persistent connections to the database.&lt;/li&gt;
&lt;li&gt;Lambda connects to the proxy endpoint.&lt;/li&gt;
&lt;li&gt;Proxy reuses existing DB connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This dramatically reduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database memory usage&lt;/li&gt;
&lt;li&gt;CPU overhead&lt;/li&gt;
&lt;li&gt;Connection storms during traffic spikes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How RDS Proxy Works Internally
&lt;/h2&gt;

&lt;p&gt;There are two authentication layers:&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda → RDS Proxy
&lt;/h3&gt;

&lt;p&gt;Lambda authenticates using either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username/password
&lt;/li&gt;
&lt;li&gt;IAM database authentication (recommended)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With IAM authentication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda generates a temporary auth token.&lt;/li&gt;
&lt;li&gt;Token is valid for ~15 minutes.&lt;/li&gt;
&lt;li&gt;No password is stored in code.&lt;/li&gt;
&lt;li&gt;IAM policies control access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RDS Proxy → Database
&lt;/h3&gt;

&lt;p&gt;RDS Proxy retrieves database credentials from AWS Secrets Manager.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhl8lhwzuo3ln725ltj1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhl8lhwzuo3ln725ltj1.png" alt="RDS retrieves DB credentials from AWS Secrets Manager" width="384" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You store DB credentials in Secrets Manager.&lt;/li&gt;
&lt;li&gt;RDS Proxy is configured to use that secret.&lt;/li&gt;
&lt;li&gt;Proxy establishes and maintains pooled connections to the database.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Lambda never needs the real database password when using IAM auth.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Authentication Flow
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Removes hardcoded credentials&lt;/li&gt;
&lt;li&gt;Enables password rotation&lt;/li&gt;
&lt;li&gt;Improves security posture&lt;/li&gt;
&lt;li&gt;Supports massive concurrency&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  3. Designing Serverless Apps for Massive Scale
&lt;/h1&gt;

&lt;p&gt;Scaling Lambda is automatic.&lt;/p&gt;

&lt;p&gt;Scaling everything else is your responsibility.&lt;/p&gt;

&lt;p&gt;The most common architectural mistake is:&lt;/p&gt;

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

&lt;p&gt;Under heavy load:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda scales&lt;/li&gt;
&lt;li&gt;Database becomes overwhelmed&lt;/li&gt;
&lt;li&gt;System fails&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Pattern: Decoupled and Asynchronous
&lt;/h2&gt;

&lt;p&gt;Instead of tight synchronous chains, use &lt;strong&gt;buffering&lt;/strong&gt; and **event-driven **design:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;SQS absorbs traffic spikes&lt;/li&gt;
&lt;li&gt;Lambda processes messages in controlled batches&lt;/li&gt;
&lt;li&gt;Database load becomes predictable&lt;/li&gt;
&lt;li&gt;System becomes resilient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key design principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decouple services&lt;/li&gt;
&lt;li&gt;Use asynchronous processing&lt;/li&gt;
&lt;li&gt;Avoid direct scaling pressure on databases&lt;/li&gt;
&lt;li&gt;Design for backpressure handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  4. Understanding Lambda Invocation Models
&lt;/h1&gt;

&lt;p&gt;Choosing how Lambda is invoked affects performance and reliability.&lt;/p&gt;

&lt;p&gt;AWS Lambda supports three invocation types.&lt;/p&gt;




&lt;h2&gt;
  
  
  Synchronous Invocation
&lt;/h2&gt;

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

&lt;p&gt;Caller waits for response.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API Gateway&lt;/li&gt;
&lt;li&gt;Application Load Balancer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immediate execution&lt;/li&gt;
&lt;li&gt;Caller handles retry&lt;/li&gt;
&lt;li&gt;Suitable for request/response APIs&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Low latency response is required&lt;/li&gt;
&lt;li&gt;User-facing APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Asynchronous Invocation
&lt;/h2&gt;

&lt;p&gt;Caller sends event and does not wait.&lt;/p&gt;

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

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3&lt;/li&gt;
&lt;li&gt;SNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event is queued internally&lt;/li&gt;
&lt;li&gt;Lambda retries automatically&lt;/li&gt;
&lt;li&gt;Better for background tasks&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Event-driven processing&lt;/li&gt;
&lt;li&gt;Non-blocking workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Poll-Based Invocation (Event Source Mapping)
&lt;/h2&gt;

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

&lt;p&gt;Lambda polls a data source.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQS&lt;/li&gt;
&lt;li&gt;Kinesis&lt;/li&gt;
&lt;li&gt;DynamoDB Streams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Batch processing&lt;/li&gt;
&lt;li&gt;Controlled concurrency&lt;/li&gt;
&lt;li&gt;Ideal for high-throughput workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This model is critical when designing for massive scale.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Putting Everything Together: A Production-Grade Architecture
&lt;/h1&gt;

&lt;p&gt;Here is a scalable, secure serverless design:&lt;/p&gt;

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

&lt;p&gt;Security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database credentials stored in Secrets Manager&lt;/li&gt;
&lt;li&gt;Lambda authenticates via IAM&lt;/li&gt;
&lt;li&gt;RDS Proxy manages pooled connections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQS absorbs spikes&lt;/li&gt;
&lt;li&gt;Lambda scales safely&lt;/li&gt;
&lt;li&gt;RDS Proxy protects database&lt;/li&gt;
&lt;li&gt;Aurora handles transactional workload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reliability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic retries&lt;/li&gt;
&lt;li&gt;Dead-letter queues&lt;/li&gt;
&lt;li&gt;Backpressure handling&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  6. When Should You Use RDS Proxy?
&lt;/h1&gt;

&lt;p&gt;Use RDS Proxy when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You use Lambda with RDS/Aurora&lt;/li&gt;
&lt;li&gt;You expect unpredictable traffic spikes&lt;/li&gt;
&lt;li&gt;You need secure IAM-based DB authentication&lt;/li&gt;
&lt;li&gt;You want connection pooling without managing it manually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not rely on direct Lambda-to-RDS connections in high-scale production systems.&lt;/p&gt;

&lt;h1&gt;
  
  
  7. Final Takeaways
&lt;/h1&gt;

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

&lt;p&gt;Serverless scaling is easy for compute.&lt;/p&gt;

&lt;p&gt;It is difficult for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Stateful systems&lt;/li&gt;
&lt;li&gt;Downstream dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To design correctly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use asynchronous patterns where possible.&lt;/li&gt;
&lt;li&gt;Protect relational databases with RDS Proxy.&lt;/li&gt;
&lt;li&gt;Use IAM authentication instead of hardcoded credentials.&lt;/li&gt;
&lt;li&gt;Understand Lambda invocation types before designing workflows.&lt;/li&gt;
&lt;li&gt;Always design for backpressure and burst traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Serverless is powerful — but only when architecture decisions support massive scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/using-amazon-rds-proxy-with-aws-lambda/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/compute/using-amazon-rds-proxy-with-aws-lambda/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/architecture/how-to-design-your-serverless-apps-for-massive-scale/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/architecture/how-to-design-your-serverless-apps-for-massive-scale/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/architecture/understanding-the-different-ways-to-invoke-lambda-functions/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/architecture/understanding-the-different-ways-to-invoke-lambda-functions/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>lambda</category>
      <category>rds</category>
    </item>
    <item>
      <title>Securing Sensitive S3 Data: The Problem &amp; The Solution</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Wed, 04 Feb 2026 07:56:20 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/securing-sensitive-s3-data-the-problem-the-solution-1ief</link>
      <guid>https://dev.to/nghidanh2005/securing-sensitive-s3-data-the-problem-the-solution-1ief</guid>
      <description>&lt;p&gt;Securing Sensitive S3 Data: The Problem &amp;amp; The Solution&lt;br&gt;
In the world of cloud security, "encryption" is often the default answer. But when dealing with highly sensitive data—like customer call logs—simply scrambling the data isn't enough. You need to control who holds the keys to unscramble it.&lt;/p&gt;

&lt;p&gt;Here is a common real-world scenario and the most efficient AWS architecture to solve it.&lt;/p&gt;

&lt;p&gt;The Problem: Sensitive Data &amp;amp; Granular Access&lt;br&gt;
Imagine your company stores customer call logs in an Amazon S3 bucket. This data contains PII (Personally Identifiable Information), so it must be encrypted at rest.&lt;/p&gt;

&lt;p&gt;However, standard encryption isn't enough. You have a requirement that only specific employees (e.g., the Compliance Team) can decrypt and read these logs. Even if a system administrator has access to the S3 bucket itself, they should not be able to read this specific sensitive data.&lt;/p&gt;

&lt;p&gt;The Challenge: How do you enforce encryption while strictly limiting who can use the decryption keys, with the least amount of operational effort?&lt;/p&gt;

&lt;p&gt;The Solution: SSE-KMS with IAM Policies&lt;br&gt;
The most effective solution is to use Server-Side Encryption with AWS KMS keys (SSE-KMS) combined with restrictive IAM policies.&lt;/p&gt;

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

&lt;p&gt;How it works:&lt;/p&gt;

&lt;p&gt;SSE-KMS: Instead of letting S3 manage the keys transparently (SSE-S3), you use AWS Key Management Service (KMS). This allows you to create a specific Customer Managed Key (CMK) for these call logs.&lt;/p&gt;

&lt;p&gt;Key Policies: You configure the Key Policy (or an IAM policy attached to users) to explicitly allow only the specific employees (e.g., the Compliance Team) to use kms:Decrypt for that key.&lt;/p&gt;

&lt;p&gt;The Result: If a general admin tries to download the object, S3 might let them download the file, but because they lack permission to use the KMS key, the data remains a garbled, encrypted mess.&lt;/p&gt;

&lt;p&gt;Why this wins: It separates "storage access" from "data access." It satisfies the requirement for "Least Privilege" without requiring you to manage your own hardware (CloudHSM) or manage keys manually on your own servers (SSE-C).&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>How to make your 1st Open-source contribution to AWS Repo</title>
      <dc:creator>Danh Hoang Hieu Nghi</dc:creator>
      <pubDate>Sun, 14 Dec 2025 15:37:24 +0000</pubDate>
      <link>https://dev.to/nghidanh2005/how-to-make-your-1st-open-source-contribution-to-aws-repo-2lkk</link>
      <guid>https://dev.to/nghidanh2005/how-to-make-your-1st-open-source-contribution-to-aws-repo-2lkk</guid>
      <description>&lt;p&gt;I think you’ve probably heard about becoming an AWS Community Builder by writing articles, posts, or social media content. Another way is by contributing to AWS open-source projects.&lt;/p&gt;

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

&lt;p&gt;At first, I wondered, “How can I help with anything when I’m just a junior university student?”&lt;/p&gt;

&lt;p&gt;While learning about AWS Bedrock AgentCore, I read the documentation and did some hands-on labs using the AWS AgentCore sample. That’s when I noticed something was wrong. When I clicked on the Memory section, it redirected me to the Identity section instead.&lt;/p&gt;

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

&lt;p&gt;I thought to myself, “What happened? Am I doing something wrong?”&lt;/p&gt;

&lt;p&gt;Later, I realized that while the AWS team was writing the README file, they had simply mistyped these two sections. After that, I searched online for “How to contribute to an open-source project.”&lt;/p&gt;

&lt;p&gt;I then forked the repository to my computer, changed two lines in the README.md file, pushed the changes to my branch, and followed their contribution guidelines. I created an issue using their template and submitted a pull request.&lt;/p&gt;

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

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

&lt;p&gt;A few days later, I received an email saying that my pull request had been accepted. This made me incredibly happy. Such a small change to a large project can benefit the community in a meaningful way.&lt;/p&gt;

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

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

&lt;p&gt;Checkout the Bedrock AgentCore Sample here, help me and everyone by contributing anything to it : &lt;a href="https://github.com/awslabs/amazon-bedrock-agentcore-samples/" rel="noopener noreferrer"&gt;https://github.com/awslabs/amazon-bedrock-agentcore-samples/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>aws</category>
      <category>communitybuilder</category>
    </item>
  </channel>
</rss>
