<?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: Walter Fernández</title>
    <description>The latest articles on DEV Community by Walter Fernández (@wfernandezs).</description>
    <link>https://dev.to/wfernandezs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3603652%2F7acc8dae-e124-44ad-a077-bd8fe61aac3d.jpeg</url>
      <title>DEV Community: Walter Fernández</title>
      <link>https://dev.to/wfernandezs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wfernandezs"/>
    <language>en</language>
    <item>
      <title>Building Reliable Distributed Systems with AWS Serverless</title>
      <dc:creator>Walter Fernández</dc:creator>
      <pubDate>Sun, 22 Feb 2026 02:33:13 +0000</pubDate>
      <link>https://dev.to/wfernandezs/building-reliable-distributed-systems-with-aws-serverless-19c4</link>
      <guid>https://dev.to/wfernandezs/building-reliable-distributed-systems-with-aws-serverless-19c4</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%2F1u5uqrv9d239lobm35pd.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%2F1u5uqrv9d239lobm35pd.png" alt="Diagram" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full resolution diagram: &lt;a href="https://pub-2d6402cd5a1e4a988a30b8c9e60104c0.r2.dev/microservice-pattern/caf1078fc1475cbda2c1c24fdba04f8d.svg" rel="noopener noreferrer"&gt;Microservices Diagram&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Most microservices architectures share similar trade-offs. Two of the most common challenges are &lt;strong&gt;transactional consistency&lt;/strong&gt; and keeping services synchronized with data changes. As a result, distributed systems often deal with duplicate events, lost messages, and partial failures.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;idempotency&lt;/strong&gt; becomes essential. In simple terms, idempotency means &lt;em&gt;an operation can be executed multiple times without changing the final result&lt;/em&gt;. That property makes it especially valuable in transactional domains like retail, finance, or travel.&lt;/p&gt;

&lt;p&gt;Another key piece of the puzzle is the &lt;strong&gt;Outbox Pattern&lt;/strong&gt;. Instead of notifying external systems directly—which risks message loss if the network or broker fails—the service persists both the &lt;strong&gt;data change&lt;/strong&gt; and the &lt;strong&gt;event message&lt;/strong&gt; in a single atomic transaction. This guarantees reliable event delivery.&lt;/p&gt;

&lt;p&gt;In this demo, we’ll explore a retail scenario that combines &lt;strong&gt;idempotency&lt;/strong&gt;, the &lt;strong&gt;Outbox Pattern&lt;/strong&gt;, and a simplified saga orchestration using &lt;strong&gt;AWS Step Functions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the high-level flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1. Entry Point:&lt;/strong&gt; An &lt;code&gt;HTTP POST&lt;/code&gt; request hits &lt;strong&gt;API Gateway&lt;/strong&gt;, triggering the &lt;strong&gt;Order Lambda&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2. Data Integrity:&lt;/strong&gt; The Lambda checks an &lt;strong&gt;Idempotency Table&lt;/strong&gt; and performs a &lt;code&gt;TransactWrite&lt;/code&gt; across the &lt;strong&gt;Orders&lt;/strong&gt; and &lt;strong&gt;Outbox&lt;/strong&gt; tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3. Event Trigger:&lt;/strong&gt; A &lt;strong&gt;DynamoDB Stream&lt;/strong&gt; detects the new Outbox record and invokes the &lt;strong&gt;Outbox Processor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4. Workflow Execution:&lt;/strong&gt; The processor starts a &lt;strong&gt;Step Functions&lt;/strong&gt; workflow:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inventory &amp;amp; Payment:&lt;/strong&gt; Attempts to reserve stock and process payment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success Path:&lt;/strong&gt; Sends a notification when everything succeeds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure Path:&lt;/strong&gt; Executes a compensation step to release inventory if payment fails.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This combination provides important benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid duplication:&lt;/strong&gt; Returns the original response for repeated requests with the same identifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance optimization:&lt;/strong&gt; Skips expensive logic for already processed requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic behavior:&lt;/strong&gt; The same input always leads to the same final state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Helps services converge to the same state despite communication failures.
## Idempotency Pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two main ways to implement idempotency in distributed systems: building a custom solution or leveraging a managed library. For this demo, we’ll use &lt;strong&gt;AWS Powertools for TypeScript&lt;/strong&gt;, which provides built-in idempotency utilities for Lambda functions.&lt;/p&gt;

&lt;p&gt;The library stores request state in &lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;, tracking whether a request is &lt;em&gt;in progress&lt;/em&gt; or &lt;em&gt;completed&lt;/em&gt;. This allows safe retries and ensures duplicate invocations return cached responses instead of re-executing business logic.&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%2Fh86g9356bgvc8wq49aqn.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%2Fh86g9356bgvc8wq49aqn.png" alt="image" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outbox Pattern
&lt;/h2&gt;

&lt;p&gt;The Outbox implementation relies on &lt;strong&gt;DynamoDB TransactWrite&lt;/strong&gt; operations across the Orders and Outbox tables, combined with &lt;strong&gt;DynamoDB Streams&lt;/strong&gt;. Whenever a new Outbox record appears, a Lambda function is triggered to start the Step Functions workflow, enabling reliable event propagation without tight coupling.&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%2Fo9d4culwxfkz2cd5wdde.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%2Fo9d4culwxfkz2cd5wdde.png" alt="image" width="800" height="977"&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%2Fhm7onhg1e7bf9ry29hq8.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%2Fhm7onhg1e7bf9ry29hq8.png" alt="image" width="800" height="901"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step function
&lt;/h2&gt;

&lt;p&gt;The Step Functions workflow orchestrates the full order lifecycle. It handles both successful execution and failure scenarios by triggering compensation logic when needed. For demonstration purposes, some steps are mocked or simplified.&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%2F3t7chirhoga3lzbv7rb3.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%2F3t7chirhoga3lzbv7rb3.png" alt="image" width="782" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  End-to-End Test with cURL
&lt;/h3&gt;

&lt;p&gt;To validate the full integration, deploy the stack and submit a sample order. This request triggers the complete execution chain, including idempotency validation, the Outbox event, and the Step Functions workflow.&lt;/p&gt;

&lt;p&gt;The screenshot below shows a successful order request triggered from Postman.&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%2Fx1gqk0lt36xykr0g3oce.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%2Fx1gqk0lt36xykr0g3oce.png" alt="image" width="766" height="986"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Expected Behavior
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First request:&lt;/strong&gt; The workflow executes normally, and the order status is updated upon completion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subsequent requests:&lt;/strong&gt; When the same request is retried with the same idempotency key, the system skips execution and returns the cached response stored in the Idempotency Table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guarantees safe retries without duplicating side effects.&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%2Fae9uz649czkeupsyliru.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%2Fae9uz649czkeupsyliru.png" alt="image" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  X-Ray
&lt;/h3&gt;

&lt;p&gt;Tracing is essential in distributed systems. With AWS X-Ray enabled, we can visualize how a request travels across API Gateway, Lambda, DynamoDB Streams, and Step Functions.&lt;/p&gt;

&lt;p&gt;The following trace illustrates the full request lifecycle.&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%2F4douz1witxgxfork8fay.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%2F4douz1witxgxfork8fay.png" alt="image" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Order Lambda handles idempotency and performs the atomic write.&lt;/li&gt;
&lt;li&gt;The DynamoDB Stream triggers the Outbox Processor.&lt;/li&gt;
&lt;li&gt;The Step Functions workflow orchestrates inventory and payment operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This level of visibility makes debugging faster and helps identify bottlenecks in event-driven architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow Orchestration
&lt;/h3&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%2F3t7chirhoga3lzbv7rb3.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%2F3t7chirhoga3lzbv7rb3.png" alt="image" width="782" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Step Functions graph clearly illustrates the workflow execution. In this demo, all steps completed successfully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ReserveInventory&lt;/strong&gt; – Validates and holds product stock&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ProcessPayment&lt;/strong&gt; – Executes the payment transaction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SendNotification&lt;/strong&gt; – Sends the order confirmation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;CompensateInventory&lt;/strong&gt; branch acts as a safety net. If payment fails, the workflow automatically releases the reserved stock, ensuring system consistency without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;While this demo highlights core patterns, production environments require additional safeguards. A resilient serverless architecture should focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; Enable X-Ray tracing and CloudWatch alarms to detect failures early&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries &amp;amp; DLQs:&lt;/strong&gt; Configure exponential backoff and Dead Letter Queues for exhausted events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; Use Step Functions Express for high-volume, short-lived workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle Management:&lt;/strong&gt; Apply DynamoDB TTL on idempotency records to automatically purge stale data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Distributed systems introduce unavoidable complexity, but patterns like &lt;strong&gt;Idempotency&lt;/strong&gt;, &lt;strong&gt;Outbox&lt;/strong&gt;, and &lt;strong&gt;Step function Orchestration&lt;/strong&gt; help transform fragile event-driven flows into robust architectures.&lt;/p&gt;

&lt;p&gt;Together, they ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safe retries without duplicate side effects&lt;/li&gt;
&lt;li&gt;Reliable event delivery across services
&lt;/li&gt;
&lt;li&gt;Automatic recovery through compensation logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining these patterns with strong observability and operational safeguards, you can build serverless systems that remain consistent—even when individual components fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/wfernandezs/serverless-distributed-patterns" rel="noopener noreferrer"&gt;serverless-distributed-patterns&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Idempotency Powertools:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/powertools/typescript/2.1.1/utilities/idempotency/" rel="noopener noreferrer"&gt;AWS Idempotency Powertools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless Framework:&lt;/strong&gt; &lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;serverless.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connect with Me
&lt;/h2&gt;

&lt;p&gt;If you found this helpful or have questions about implementing Guardrails in your projects, feel free to reach out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/walter-fernandez-sanchez-a3924354" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/walter-fernandez-sanchez-a3924354&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/wfernandezs" rel="noopener noreferrer"&gt;@wfernandezs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>architecture</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Amazon Bedrock Guardrails - Step-by-step implementation with Serverless</title>
      <dc:creator>Walter Fernández</dc:creator>
      <pubDate>Sat, 31 Jan 2026 00:36:08 +0000</pubDate>
      <link>https://dev.to/wfernandezs/amazon-bedrock-guardrails-step-by-step-implementation-with-serverless-3ji2</link>
      <guid>https://dev.to/wfernandezs/amazon-bedrock-guardrails-step-by-step-implementation-with-serverless-3ji2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When defining an AI integration, one of the first concerns that usually comes up is security. More specifically, how to protect applications that rely on large language models once they are exposed to real users.&lt;/p&gt;

&lt;p&gt;Amazon Bedrock makes it easy to work with foundation models without worrying about infrastructure and allows some level of customization to fit business needs. However, that convenience also raises an important question: how do we prevent these models from generating unsafe content or leaking sensitive information?&lt;/p&gt;

&lt;p&gt;This is where Guardrails become especially relevant. Guardrails serve as a safeguard layer, allowing you to filter sensitive data such as PII, restrict specific topics, and define how the model should behave when a rule is violated.&lt;/p&gt;

&lt;p&gt;Given their importance for making AI workloads production-ready, this article focuses on a practical, step-by-step implementation of topic filtering and PII protection using Amazon Bedrock Guardrails, both from the AWS Console and programmatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrail setup on AWS Console
&lt;/h2&gt;

&lt;p&gt;This section covers configuring Guardrails in the AWS Console, followed by a programmatic approach using the Serverless Framework.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Before starting, make sure that Amazon Bedrock is enabled in your AWS account. Once enabled, navigate to Amazon Bedrock, go to the &lt;strong&gt;Build&lt;/strong&gt; section, and select &lt;strong&gt;Guardrails&lt;/strong&gt;. From there, click on &lt;strong&gt;Create guardrail&lt;/strong&gt; to begin the setup process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During the creation process, you will be asked to provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A name to identify the guardrail&lt;/li&gt;
&lt;li&gt;A short description explaining its purpose&lt;/li&gt;
&lt;li&gt;A default message that will be returned whenever a prompt or response is blocked&lt;/li&gt;
&lt;/ul&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%2Fn6j36srdakji9e2cq34v.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%2Fn6j36srdakji9e2cq34v.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once the basic configuration is completed, the next step is defining denied topics. In this example, two topics are restricted: medical and financial queries.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To add a denied topic, select &lt;strong&gt;Add denied topic&lt;/strong&gt; and provide a name, a short definition, and the action to apply for both input and output. For this setup, any prompt related to these topics will be blocked.&lt;/p&gt;

&lt;p&gt;You will also need to add example phrases. These examples help Bedrock identify when a prompt belongs to a restricted topic and improve the accuracy of the filtering.&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%2Fanvx5ui07tile95b4hem.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%2Fanvx5ui07tile95b4hem.png" alt=" " width="800" height="284"&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%2Fif17ggz828d22wm3b30e.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%2Fif17ggz828d22wm3b30e.png" alt=" " width="800" height="1004"&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%2F2eyyk1t6c8bz0z345nlw.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%2F2eyyk1t6c8bz0z345nlw.png" alt=" " width="800" height="1023"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After configuring topic restrictions, continue to the PII filtering section. In &lt;strong&gt;Step 5&lt;/strong&gt;, select &lt;strong&gt;Add new PII&lt;/strong&gt; to configure sensitive information detection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bedrock provides a set of predefined PII types that can be selected individually, along with an action for each one. In this case, the selected PII types will be masked rather than blocked.&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%2Fptsrbyxevr6r45ryvhrc.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%2Fptsrbyxevr6r45ryvhrc.png" alt=" " width="800" height="315"&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%2Fdh42mn12cho3mmnsnnok.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%2Fdh42mn12cho3mmnsnnok.png" alt=" " width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In addition to predefined PII categories, Guardrails allow you to define custom filters using regular expressions. This is useful when dealing with country-specific identifiers that are not covered by default.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this example, a custom regex pattern is added to detect Peruvian national ID numbers (DNI) and mask them when detected.&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%2Falqaauk4sw9ws5musglm.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%2Falqaauk4sw9ws5musglm.png" alt=" " width="663" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This is the final configuration of the sensitive information filters, so let's wrap up the creation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6lo3cmlrdsd5ehlusn0.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%2Fh6lo3cmlrdsd5ehlusn0.png" alt=" " width="663" height="782"&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%2Fpjzfrfggh523nda64zls.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%2Fpjzfrfggh523nda64zls.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once all sensitive information rules are configured, review the final setup and complete the guardrail creation process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After the guardrail is created, Bedrock will display its details, including the guardrail ID. To start using it, a version must be created, as both the guardrail ID and version are required for programmatic usage.&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%2Fj3kwgm3ld1unihie8ybv.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%2Fj3kwgm3ld1unihie8ybv.png" alt=" " width="800" height="347"&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%2F53tu7eomdtme4r1nhcre.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%2F53tu7eomdtme4r1nhcre.png" alt=" " width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Serverless implementation
&lt;/h2&gt;

&lt;p&gt;To demonstrate a programmatic implementation, this project uses TypeScript and the Serverless Framework to expose a simple HTTP POST endpoint.&lt;/p&gt;

&lt;p&gt;The API processes user prompts through an Amazon Bedrock foundation model while enforcing the previously created guardrail. The guardrail ID and version are passed as configuration values and are required for the request to be evaluated against the defined rules.&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%2Femltcp6bc7uwxgdlty81.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%2Femltcp6bc7uwxgdlty81.png" alt=" " width="800" height="897"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing and results
&lt;/h2&gt;

&lt;p&gt;The testing strategy consists of two parts. First, the guardrail is tested directly from the AWS Console using the prompt tool with the Claude 3.5 model. Prompts related to healthcare or financial topics are correctly blocked, which can be verified by enabling the &lt;strong&gt;Trace&lt;/strong&gt; option and inspecting the blocked topic information.&lt;/p&gt;

&lt;p&gt;PII filtering can be tested similarly. When sensitive information is detected, it appears under the &lt;strong&gt;Sensitive information rules&lt;/strong&gt; section with a &lt;strong&gt;Masked&lt;/strong&gt; status, including the custom DNI regex.&lt;/p&gt;

&lt;p&gt;The same behavior is observed when testing the serverless API using Postman. Since the Lambda function targets the same guardrail and model configuration, the results are consistent with those seen in the AWS Console.&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%2Fqmlpl2d8rbyqmaw6m5ns.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%2Fqmlpl2d8rbyqmaw6m5ns.png" alt=" " width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, we will test the PII filtering with the same tool and will appear under "Sensitive information rules" with the "Masked" status. &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%2F9ty5lmvxr8ce6d3bqw9t.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%2F9ty5lmvxr8ce6d3bqw9t.png" alt=" " width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance related to the peruvian ID it will show the result under the same section of PII filtering.&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%2Fo0es3wgbu4nuwpj8jcyj.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%2Fo0es3wgbu4nuwpj8jcyj.png" alt=" " width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By contrast, testing the lambda which is using the previous model and targets the same guardrail, it will work the same. Here's a quick result, for a thorough testing the code repository can be use to test as it will use the same strategy for the AWS Console.&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%2Fnrnbjq6pyeq7zv2jt4sv.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%2Fnrnbjq6pyeq7zv2jt4sv.png" alt=" " width="800" height="243"&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%2Fk26ok1slfn3ayi7k1yhs.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%2Fk26ok1slfn3ayi7k1yhs.png" alt=" " width="800" height="241"&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%2Fdy7emfggobqyxacciyul.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%2Fdy7emfggobqyxacciyul.png" alt=" " width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Guardrails turned out to be an easy and practical way to put clear boundaries around generative AI workloads in Bedrock. Instead of handling every edge case in code, you can rely on a dedicated layer to block unsafe topics and protect sensitive data by default.&lt;/p&gt;

&lt;p&gt;The setup is straightforward, works consistently from the console and from code, and fits naturally into a serverless architecture. While it doesn’t replace application-level validation, it significantly reduces risk and complexity when moving AI features closer to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/wfernandezs/bedrock-guardrails-demo" rel="noopener noreferrer"&gt;bedrock-guardrails-demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Documentation:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html" rel="noopener noreferrer"&gt;Bedrock Guardrails User Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless Framework:&lt;/strong&gt; &lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;serverless.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connect with Me
&lt;/h2&gt;

&lt;p&gt;If you found this helpful or have questions about implementing Guardrails in your projects, feel free to reach out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/walter-fernandez-sanchez-a3924354" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/walter-fernandez-sanchez-a3924354&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/wfernandezs" rel="noopener noreferrer"&gt;@wfernandezs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>bedrock</category>
      <category>serverless</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
