<?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: Ravindra Pandya</title>
    <description>The latest articles on DEV Community by Ravindra Pandya (@ravindraptech).</description>
    <link>https://dev.to/ravindraptech</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%2F1580083%2Fc022c85d-596d-4092-9e04-39ada8e24c0d.png</url>
      <title>DEV Community: Ravindra Pandya</title>
      <link>https://dev.to/ravindraptech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ravindraptech"/>
    <language>en</language>
    <item>
      <title>5 Hard-Earned Lessons from Building a Production App on Amazon Bedrock</title>
      <dc:creator>Ravindra Pandya</dc:creator>
      <pubDate>Mon, 19 Jan 2026 19:05:39 +0000</pubDate>
      <link>https://dev.to/ravindraptech/5-hard-earned-lessons-from-building-my-first-production-app-on-amazon-bedrock-27in</link>
      <guid>https://dev.to/ravindraptech/5-hard-earned-lessons-from-building-my-first-production-app-on-amazon-bedrock-27in</guid>
      <description>&lt;p&gt;Recently I got an opportunity to review one of our client's project which was highlighted for sudden increase in cost and some other improvements. The project was an AI-powered document analysis tool for a document processing team using Amazon Bedrock.&lt;/p&gt;

&lt;p&gt;We observed that the document processing team was handling files 10x faster compared to earlier. During review we identified some expensive learning moments after spending some late nights in the AWS console.&lt;/p&gt;

&lt;p&gt;Here are the five lessons that made the biggest difference - things it was considered on day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Model Selection Isn't About Picking the Biggest One
&lt;/h2&gt;

&lt;p&gt;Developer's first instinct was to use Claude Opus. As if you're building something important, you use the most powerful model, right?&lt;/p&gt;

&lt;p&gt;Team was processing various documents - extracting key information, metadata, and structured data. Pretty standard extraction tasks. For two weeks, it was running everything through Opus, getting great results. Then during a review, we thought: "Why don't we try the smaller models?"&lt;/p&gt;

&lt;p&gt;Earlier it seemed risky to go smaller for "serious" work.&lt;/p&gt;

&lt;p&gt;Out of curiosity, we tested the same documents with Claude Haiku. The accuracy? Identical for the use case. The cost difference? &lt;strong&gt;Roughly 15x cheaper&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;That's when it clicked - Bedrock gives you multiple model tiers for a reason. Different tasks need different levels of capability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The current approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured extraction and classification → Start with Haiku&lt;/li&gt;
&lt;li&gt;General analysis or moderate complexity → Test Sonnet
&lt;/li&gt;
&lt;li&gt;Complex reasoning or nuanced interpretation → Upgrade to Opus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now team prototype new features with Haiku first, then move up only when results aren't meeting requirements. The model flexibility in Bedrock has been one of its best features.&lt;/p&gt;

&lt;p&gt;Here's how we can structure the model selection logic:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_model_for_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complexity_score&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Bedrock offers multiple Claude models - pick based on actual need
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;task_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;extraction&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;complexity_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-haiku-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;task_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;analysis&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;complexity_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-sonnet-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-opus-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. CloudWatch Integration Saved the Budget (Once we Set It Up Right)
&lt;/h2&gt;

&lt;p&gt;Here's something many developers don't fully appreciate at first: Bedrock integrates seamlessly with CloudWatch, but you need to actually configure meaningful monitoring.&lt;/p&gt;

&lt;p&gt;When we deployed to production, many end-users started processing documents. The daily AWS bill jumped from $50 to $380 overnight. Found out Friday afternoon when we checked the billing dashboard.&lt;/p&gt;

&lt;p&gt;The problem wasn't Bedrock - it was the implementation. There were logs for every single request with full input/output to CloudWatch Logs. Those logs were costing almost as much as the model invocations. Plus, it had zero rate limiting - if someone uploaded a 100-page document, it just processed it. Multiple times if they clicked impatiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's what I learned about effective monitoring:&lt;/strong&gt;&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;boto3&lt;/span&gt;

&lt;span class="n"&gt;cloudwatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cloudwatch&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke_bedrock_with_tracking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Estimate before calling to catch oversized requests
&lt;/span&gt;    &lt;span class="n"&gt;estimated_input_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.3&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;estimated_input_tokens&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Cap large requests early
&lt;/span&gt;        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Document too large - please split into sections&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-haiku-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Log metrics to CloudWatch, not full content
&lt;/span&gt;    &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&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;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;usage&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;cloudwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_metric_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;BedrockApp/DocumentProcessing&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;MetricData&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;MetricName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;InputTokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;input_tokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Unit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;MetricName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OutputTokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;output_tokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Unit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also set up CloudWatch alarms that actually matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alert if hourly cost exceeds $50&lt;/li&gt;
&lt;li&gt;Alert if any single user makes &amp;gt;100 requests/hour&lt;/li&gt;
&lt;li&gt;Alert if average response size exceeds 2000 tokens (usually indicates something's wrong with my prompts)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These alarms have caught two incidents where users found creative ways to accidentally trigger expensive workflows.&lt;/p&gt;

&lt;p&gt;The beauty of Bedrock being fully integrated with AWS? All my monitoring, alerting, and cost management tools work exactly the same way as the rest of my infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Prompt Engineering Made the Difference Between "Good" and "Great"
&lt;/h2&gt;

&lt;p&gt;If we start with writing prompt which looks very basic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze this document and extract important information.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results were inconsistent. Sometimes we get JSON, sometimes unformatted natural language. Sometimes dates in different formats. Developer spent days debugging and parsing code before realizing the problem wasn't the code.&lt;/p&gt;

&lt;p&gt;The breakthrough came when we started treating prompts like API specifications - detailed, structured, with clear expectations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My current prompt structure:&lt;/strong&gt;&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_document_analysis_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document_text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a document analyzer. Extract specific information from various document types.

Your task:
1. Read the document carefully
2. Extract ONLY the following fields
3. Return results in valid JSON format

Required fields:
- document_type: Type of document (invoice, receipt, form, report, etc.)
- key_entities: List of important names, organizations, or entities (array of strings)
- dates: All dates mentioned (array in YYYY-MM-DD format)
- amounts: Any monetary values with currency (array of objects)
- summary: Brief 1-2 sentence summary (string)
- metadata: Any additional relevant information (object)

Rules:
- If a field is not found, use null (not empty string)
- Convert all dates to YYYY-MM-DD format
- Be specific about amounts and include currency codes
- Do not infer information not explicitly stated

Document text:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document_text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Return ONLY valid JSON with no markdown formatting or preamble.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The improvement was dramatic. Inconsistency dropped from about 30% to under 5%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key insights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be explicit about format - Bedrock's models are capable, but they need clear instructions&lt;/li&gt;
&lt;li&gt;Provide structure with numbered steps&lt;/li&gt;
&lt;li&gt;Define what NOT to do (stopped the model from inventing missing dates)&lt;/li&gt;
&lt;li&gt;Specify output format precisely (I was getting markdown code blocks until I said "no markdown formatting")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I now version my prompts in a &lt;code&gt;prompts/&lt;/code&gt; directory and A/B test changes against a set of 50 sample documents before deploying updates. AWS makes it easy to track these experiments since everything's tagged and logged in CloudWatch.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Building Resilient Error Handling from Day One
&lt;/h2&gt;

&lt;p&gt;In development, everything worked smoothly. In production with many end-users uploading all kinds of documents? That's when we met every possible error condition.&lt;/p&gt;

&lt;p&gt;The wake-up call came when the service went down for 20 minutes because we hit Bedrock's rate limits and the code just... stopped. No retry, no graceful degradation, just dead in the water.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the error handling that's kept us running smoothly since:&lt;/strong&gt;&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;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;botocore.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ClientError&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke_with_resilience&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Bedrock is highly available, but your code should handle edge cases
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-haiku-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;

        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ClientError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;error_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;error_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ThrottlingException&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Bedrock has rate limits - use exponential backoff
&lt;/span&gt;                &lt;span class="n"&gt;wait_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rate limited, waiting &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;wait_time&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;error_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ValidationException&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Input validation failed - don't retry
&lt;/span&gt;                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid request format: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;error_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ModelTimeoutException&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Request took too long
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Timeout on attempt &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, retrying...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;All retries exhausted on timeout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Unexpected error - retry with backoff
&lt;/span&gt;                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unexpected error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;raise&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But here's what really matters for production: &lt;strong&gt;having a fallback strategy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For non-critical requests, if Bedrock is temporarily unavailable, we queue the document for background processing and show the user: "Analysis queued - you'll receive results via email within an hour."&lt;/p&gt;

&lt;p&gt;For time-sensitive requests, we have a simple rule-based extractor as a backup. It's not as good as Bedrock - maybe catches 60% of what the AI does - but it keeps users unblocked.&lt;/p&gt;

&lt;p&gt;The reliability of Bedrock itself has been solid. These error handlers are mostly catching our own mistakes (bad input formatting) or rate limit situations during peak usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Bedrock Guardrails Are a Production Requirement, Not Optional
&lt;/h2&gt;

&lt;p&gt;Week five of production, someone on the document processing team uploaded a file and asked a question that made us realize we had a security problem.&lt;/p&gt;

&lt;p&gt;We were echoing parts of inputs back in error messages. And documents often contain confidential information - personal details, financial data, proprietary information that shouldn't leak into logs or other users' sessions.&lt;/p&gt;

&lt;p&gt;After a friendly but firm conversation with our security team, we implemented Bedrock Guardrails. This is one of those features that seems optional until you need it, then you can't believe you didn't set it up from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we configured:&lt;/strong&gt;&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="c1"&gt;# Apply guardrails to every Bedrock invocation
&lt;/span&gt;&lt;span class="n"&gt;guardrail_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;guardrailIdentifier&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;document-processor-guardrail&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;guardrailVersion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;trace&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;enabled&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;# Shows what triggered blocks - super useful
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-haiku-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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;request_body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;guardrailIdentifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;guardrail_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;guardrailIdentifier&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;guardrailVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;guardrail_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;guardrailVersion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;trace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;guardrail_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;trace&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The guardrails block:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PII (names, addresses, SSNs) from being processed or returned&lt;/li&gt;
&lt;li&gt;Attempts to ask questions about other documents in the system
&lt;/li&gt;
&lt;li&gt;Prompt injection attempts&lt;/li&gt;
&lt;li&gt;Requests that go beyond data extraction capabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;trace&lt;/code&gt; option is invaluable - when something gets blocked, we can see exactly what triggered the guardrail. Helped us tune the policies so legitimate use cases weren't getting caught.&lt;/p&gt;

&lt;p&gt;I also added application-level sanitization as a defense-in-depth measure:&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;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sanitize_before_processing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Pre-process before sending to Bedrock Guardrails
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Redact emails
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[EMAIL_REDACTED]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Redact phone numbers
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\b\d{3}[-.]?\d{3}[-.]?\d{4}\b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[PHONE_REDACTED]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Redact SSNs
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\b\d{3}-\d{2}-\d{4}\b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[SSN_REDACTED]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Between Bedrock Guardrails and application-level checks, I sleep better knowing there are multiple layers protecting sensitive information.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd Tell Someone Starting with Bedrock Today
&lt;/h2&gt;

&lt;p&gt;If you're about to build your first production application on Bedrock, here's what matters:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start with the right model for your task&lt;/strong&gt; - Bedrock's model variety is a feature, not a complication. Test smaller models first - you might be surprised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Set up CloudWatch monitoring from day one&lt;/strong&gt; - Cost alerts, usage metrics, and error tracking. Future you will be grateful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Invest time in your prompts&lt;/strong&gt; - Bedrock's models are incredibly capable, but clear, structured prompts make all the difference between good and great results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Build retry logic and fallbacks&lt;/strong&gt; - Not because Bedrock is unreliable (it's not), but because production systems need resilience at every layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Enable Guardrails before you go live&lt;/strong&gt; - This isn't about trust, it's about defense in depth. Especially if you're handling any sensitive data.&lt;/p&gt;

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

&lt;p&gt;Four months in, our document analyzer processes about 200 files per week across various document types. Monthly Bedrock costs run around $180, and the tool saves our document processing team an estimated 15 hours of manual work every week. That's roughly $45/hour if you value time conservatively - incredible ROI.&lt;/p&gt;

&lt;p&gt;The combination of Bedrock's managed infrastructure, flexible model options, and tight AWS integration meant I could focus on building features instead of managing ML infrastructure. I went from zero to production in three weeks with no ML ops team.&lt;/p&gt;

&lt;p&gt;Would I choose Amazon Bedrock again for my next AI project? Absolutely. The platform gave me everything I needed - I just had to learn how to use it properly.&lt;/p&gt;

&lt;p&gt;And honestly? These "mistakes" weren't really mistakes. They were the learning curve of building production AI applications. Every developer goes through it. The difference is that with Bedrock, the platform itself wasn't the hard part - it was learning to use AI effectively in production.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something with Bedrock? I'd love to hear what you're working on. Drop a comment below or connect with me - always happy to chat about lessons learned.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>bedrock</category>
      <category>ai</category>
      <category>bestpractice</category>
    </item>
    <item>
      <title>Fine-Tuning Open Source Models with Amazon Bedrock: A Complete Guide</title>
      <dc:creator>Ravindra Pandya</dc:creator>
      <pubDate>Mon, 19 Jan 2026 18:48:20 +0000</pubDate>
      <link>https://dev.to/ravindraptech/fine-tuning-open-source-models-with-amazon-bedrock-a-complete-guide-53f2</link>
      <guid>https://dev.to/ravindraptech/fine-tuning-open-source-models-with-amazon-bedrock-a-complete-guide-53f2</guid>
      <description>&lt;p&gt;I've spent the last few months experimenting with fine-tuning foundation models on Amazon Bedrock, and I wanted to share what I've learned. Fine-tuning lets you customize these models for your specific needs, which can make a huge difference for domain-specific tasks. Bedrock handles most of the heavy lifting, so you don't need to worry about managing infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Guide Covers
&lt;/h2&gt;

&lt;p&gt;I'll walk you through the entire process: preparing your dataset, setting up a fine-tuning job, watching it train, and actually using your customized model in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Need
&lt;/h2&gt;

&lt;p&gt;Here's what you should have before diving in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account with Bedrock permissions (you might need to request access if you haven't used Bedrock before)&lt;/li&gt;
&lt;li&gt;AWS CLI installed on your machine&lt;/li&gt;
&lt;li&gt;Some familiarity with machine learning basics&lt;/li&gt;
&lt;li&gt;Python 3.8 or newer&lt;/li&gt;
&lt;li&gt;Comfort navigating the AWS Console&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding What Bedrock Actually Does
&lt;/h2&gt;

&lt;p&gt;Bedrock supports fine-tuning for several open source models, including Meta's Llama family and Cohere's models. The real win here is that AWS manages all the infrastructure complexity. You focus on your data and evaluating results instead of babysitting EC2 instances.&lt;/p&gt;

&lt;p&gt;One thing to note: not every model supports fine-tuning, and availability varies by region. Check the current docs before you get too far into planning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking Your Dataset
&lt;/h2&gt;

&lt;p&gt;For this walkthrough, I'm using publicly available data. Here are some solid options I've worked with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hugging Face Datasets&lt;/strong&gt; - massive collection, easy to access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQuAD&lt;/strong&gt; - great if you're building a Q&amp;amp;A system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Common Crawl&lt;/strong&gt; - useful for general language tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub code datasets&lt;/strong&gt; - perfect for code generation projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's say you want to build a customer support chatbot. I'll use a customer support dataset from Hugging Face as an example:&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;from&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dataset&lt;/span&gt;

&lt;span class="c1"&gt;# Grab a public customer support dataset
&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bitext/Bitext-customer-support-llm-chatbot-training-dataset&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;h2&gt;
  
  
  Getting Your Data Ready
&lt;/h2&gt;

&lt;p&gt;This part is critical. Bedrock wants your data as JSONL (JSON Lines) files. Each line needs to be a complete JSON object with your training example.&lt;/p&gt;

&lt;p&gt;Here's the basic format:&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="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Customer: How do I reset my password?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"completion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"To reset your password, click on 'Forgot Password' on the login page and follow the instructions sent to your email."&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;Converting your dataset looks like this:&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;format_for_bedrock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;instruction&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completion&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Process your data
&lt;/span&gt;&lt;span class="n"&gt;formatted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;formatted_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format_for_bedrock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Write it out as JSONL
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;training_data.jsonl&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;formatted_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&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;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&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;&lt;strong&gt;A few things I learned the hard way:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep your formatting consistent across every single example&lt;/li&gt;
&lt;li&gt;Strip out any PII - seriously, double check this&lt;/li&gt;
&lt;li&gt;You need at least 200-500 good examples, but more is definitely better&lt;/li&gt;
&lt;li&gt;Watch out for imbalanced datasets that lean heavily toward certain types of responses&lt;/li&gt;
&lt;li&gt;Test that your JSONL is valid before uploading (saves time later)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Your Data Into S3
&lt;/h2&gt;

&lt;p&gt;Bedrock pulls training data from S3, so you'll need to upload it there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make a new bucket if needed&lt;/span&gt;
aws s3 mb s3://my-bedrock-finetuning-bucket

&lt;span class="c"&gt;# Push your data up&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;training_data.jsonl s3://my-bedrock-finetuning-bucket/training-data/training_data.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick tip: make sure your bucket is in the same region where you're running the fine-tuning job, or you'll hit weird errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Permissions
&lt;/h2&gt;

&lt;p&gt;You need an IAM role that gives Bedrock access to your S3 bucket. Here's what the permissions should look 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;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bedrock-finetuning-bucket/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bedrock-finetuning-bucket"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the trust policy so Bedrock can actually use this role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"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;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bedrock.amazonaws.com"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"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;"sts:AssumeRole"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Kicking Off a Fine-Tuning Job (Console Method)
&lt;/h2&gt;

&lt;p&gt;Head over to the Bedrock console:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get to the right place&lt;/strong&gt;: Click "Custom models" in the left menu, then "Create fine-tuning job"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pick your base model&lt;/strong&gt;: Choose which foundation model you're starting with. I usually go with Meta Llama 2 or Cohere Command depending on the use case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fill in the details&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give it a name you'll remember&lt;/li&gt;
&lt;li&gt;Name your fine-tuned model something descriptive&lt;/li&gt;
&lt;li&gt;Point it to your S3 training data&lt;/li&gt;
&lt;li&gt;Tell it where to save the results&lt;/li&gt;
&lt;li&gt;Select that IAM role you just created&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tweak the hyperparameters&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Epochs: How many times to go through your data (I start with 3-5)&lt;/li&gt;
&lt;li&gt;Batch size: How many examples to process at once&lt;/li&gt;
&lt;li&gt;Learning rate: Usually best to stick with defaults unless you know what you're doing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Double-check everything and launch it&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Starting a Job via CLI
&lt;/h2&gt;

&lt;p&gt;If you prefer the command line (I usually do):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws bedrock create-model-customization-job &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--job-name&lt;/span&gt; my-customer-support-model &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--custom-model-name&lt;/span&gt; customer-support-assistant-v1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:aws:iam::YOUR_ACCOUNT_ID:role/BedrockFineTuningRole &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--base-model-identifier&lt;/span&gt; arn:aws:bedrock:us-east-1::foundation-model/meta.llama2-13b-chat-v1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--training-data-config&lt;/span&gt; &lt;span class="nv"&gt;s3Uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;s3://my-bedrock-finetuning-bucket/training-data/training_data.jsonl &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output-data-config&lt;/span&gt; &lt;span class="nv"&gt;s3Uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;s3://my-bedrock-finetuning-bucket/output/ &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--hyper-parameters&lt;/span&gt; &lt;span class="nv"&gt;epochCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3,batchSize&lt;span class="o"&gt;=&lt;/span&gt;8,learningRate&lt;span class="o"&gt;=&lt;/span&gt;0.00001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Watching Your Job Run
&lt;/h2&gt;

&lt;p&gt;Fine-tuning takes time. Sometimes a few hours, sometimes longer depending on your dataset size. Here's how to keep tabs on it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the Console&lt;/strong&gt;: Just go to Bedrock &amp;gt; Custom models and you'll see the status. It'll say "InProgress", "Completed", or "Failed"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With CLI&lt;/strong&gt;: Check programmatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws bedrock get-model-customization-job &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--job-identifier&lt;/span&gt; my-customer-support-model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CloudWatch has detailed metrics too if you want to dig into loss curves and validation accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Your Model
&lt;/h2&gt;

&lt;p&gt;Once it's done training, time to see how it performs:&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;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;bedrock_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Give it a test prompt
&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer: What are your business hours?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;arn:aws:bedrock:us-east-1:YOUR_ACCOUNT_ID:custom-model/customer-support-assistant-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&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;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;read&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;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;completion&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;Don't test on your training data. Set aside a separate validation set to get realistic results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually Using Your Model
&lt;/h2&gt;

&lt;p&gt;Now you've got a working fine-tuned model. Here's what you can do with it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plug it into your app&lt;/strong&gt;: Use the AWS SDK to call it from your code&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set up provisioned throughput&lt;/strong&gt;: If you need guaranteed capacity for production, you can purchase dedicated throughput&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build a chatbot&lt;/strong&gt;: Hook it up to your customer-facing systems with Lambda or API Gateway&lt;/p&gt;

&lt;p&gt;Here's a simple production example:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_customer_support_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;arn:aws:bedrock:us-east-1:YOUR_ACCOUNT_ID:custom-model/customer-support-assistant-v1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customer: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;completion&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;h2&gt;
  
  
  What I Wish I'd Known Earlier
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Quality beats quantity every time&lt;/strong&gt;: I've had better results with 300 really good examples than 2000 mediocre ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't mess with hyperparameters right away&lt;/strong&gt;: Start with defaults. You can experiment later once you see baseline performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep track of versions&lt;/strong&gt;: Name your jobs clearly and document which dataset you used. Trust me, you'll forget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch your costs&lt;/strong&gt;: Fine-tuning isn't free. Run small experiments first before going all-in on a massive dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iterate&lt;/strong&gt;: Your first fine-tuned model probably won't be perfect. Look at where it fails, add more examples for those cases, and retrain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always validate properly&lt;/strong&gt;: Keep a holdout set that the model never sees during training. This is how you know if it actually works.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Things Go Wrong
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Job dies immediately&lt;/strong&gt;: Nine times out of ten, it's permissions. Check that your IAM role can actually read from S3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model performs worse than expected&lt;/strong&gt;: Look at your data quality first. Are the prompt-completion pairs actually good examples?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Format errors&lt;/strong&gt;: Validate your JSONL file. Every line must be valid JSON, and field names need to be consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Training loss stays high&lt;/strong&gt;: Try lowering the learning rate or adding more epochs. Also check if you have contradictory examples in your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Fine-tuning with Bedrock has genuinely changed how I approach building AI applications. The managed infrastructure means I can focus on what matters - creating good training data and building useful products - instead of fighting with training infrastructure.&lt;/p&gt;

&lt;p&gt;Start simple. Get something working end-to-end with a small dataset first. Then expand from there as you understand what works for your specific use case.&lt;/p&gt;

&lt;p&gt;The secret sauce is really in the data preparation. Spend time there and the rest tends to fall into place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Go From Here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Try different base models and compare results&lt;/li&gt;
&lt;li&gt;Set up A/B tests to measure improvement over the base model&lt;/li&gt;
&lt;li&gt;Build pipelines to automatically retrain as you collect more data&lt;/li&gt;
&lt;li&gt;Look into fine-tuning for multiple tasks at once&lt;/li&gt;
&lt;li&gt;Keep an eye on AWS docs - they're constantly adding new features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good luck with your fine-tuning projects!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>bedrock</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>Getting Started with Generative AI on AWS: A Practical, Hands-On Guide</title>
      <dc:creator>Ravindra Pandya</dc:creator>
      <pubDate>Mon, 19 Jan 2026 18:34:01 +0000</pubDate>
      <link>https://dev.to/ravindraptech/getting-started-with-generative-ai-on-aws-a-practical-hands-on-guide-1cbn</link>
      <guid>https://dev.to/ravindraptech/getting-started-with-generative-ai-on-aws-a-practical-hands-on-guide-1cbn</guid>
      <description>&lt;p&gt;Over the last year, generative AI has moved from experimentation into production workloads—most commonly for internal assistants, document summarization, and workflow automation. On AWS, this is now feasible without standing up model infrastructure or managing GPU fleets, provided you are willing to work within the constraints of managed services like Amazon Bedrock.&lt;/p&gt;

&lt;p&gt;This guide walks through a minimal but realistic setup that I have seen work repeatedly for early-stage and internal-facing use cases, along with some operational considerations that tend to surface quickly once traffic starts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Use AWS for Generative AI Workloads?
&lt;/h2&gt;

&lt;p&gt;In practice, AWS is not always the fastest platform to prototype on, but it offers predictable advantages once security, access control, and integration with existing systems matter.&lt;/p&gt;

&lt;p&gt;The main reasons teams I’ve worked with choose AWS are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed foundation models via Amazon Bedrock&lt;/strong&gt;, which removes the need to host or patch model infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tight IAM integration&lt;/strong&gt;, making it easier to control which applications and teams can invoke models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native integration with Lambda, S3, API Gateway, and DynamoDB&lt;/strong&gt;, which simplifies deployment when you already operate in AWS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff is less flexibility compared to self-hosted or open platforms, especially around model customization and request-level tuning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reference Architecture (Minimal but Sufficient)
&lt;/h2&gt;

&lt;p&gt;For most starter use cases—internal tools, early pilots, or low-volume APIs—the following flow is sufficient:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A client application sends a request to an HTTP endpoint.&lt;/li&gt;
&lt;li&gt;API Gateway forwards the request to a Lambda function.&lt;/li&gt;
&lt;li&gt;Lambda invokes a Bedrock model.&lt;/li&gt;
&lt;li&gt;(Optional) Requests and responses are logged to S3 or DynamoDB.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern keeps the blast radius small and avoids premature complexity. It also makes it easier to add authentication, throttling, and logging later without reworking the core logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Model Selection in Amazon Bedrock
&lt;/h2&gt;

&lt;p&gt;Bedrock exposes several models with different tradeoffs in latency, cost, and output quality. For text and chat-oriented workloads, the options most teams evaluate first include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic Claude (Sonnet class)&lt;/strong&gt; for balanced reasoning and instruction-following&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Titan or Nova&lt;/strong&gt; when cost predictability is a priority&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta Llama models&lt;/strong&gt; (region-dependent) for teams with open-model familiarity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For general-purpose chat or summarization, Claude Sonnet is often a reasonable starting point, but it is not always the cheapest at scale. Expect to revisit this choice once usage patterns stabilize.&lt;/p&gt;




&lt;h2&gt;
  
  
  IAM Permissions (Minimal but Intentional)
&lt;/h2&gt;

&lt;p&gt;Your Lambda function must be explicitly allowed to invoke Bedrock models. A permissive policy during development might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"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;"bedrock:InvokeModel"&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;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production, this should be restricted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specific model ARNs&lt;/li&gt;
&lt;li&gt;Specific regions&lt;/li&gt;
&lt;li&gt;Dedicated execution roles per service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overly broad permissions tend to surface later during security reviews, not earlier—plan accordingly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Lambda-Based Text Generation API
&lt;/h2&gt;

&lt;p&gt;Below is a deliberately simple Lambda example. It is intended to demonstrate request flow, not production hardening.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python Lambda Function
&lt;/h3&gt;



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

&lt;span class="n"&gt;bedrock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;service_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&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;loads&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-sonnet-4-5-20250929-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-2023-05-31&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&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;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a real deployment, you would likely add structured logging, timeouts, retries, and request validation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exposing the API
&lt;/h2&gt;

&lt;p&gt;To make this accessible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an HTTP API in API Gateway.&lt;/li&gt;
&lt;li&gt;Integrate it with the Lambda function.&lt;/li&gt;
&lt;li&gt;Enable CORS if the client is browser-based.&lt;/li&gt;
&lt;li&gt;Add authentication (IAM, Cognito, or a custom authorizer).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For internal tools, IAM-based access is often sufficient and easier to audit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Operational Considerations That Surface Early
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prompt Management
&lt;/h3&gt;

&lt;p&gt;Hardcoding prompts becomes brittle quickly. Storing prompt templates in S3 or DynamoDB allows versioning and rollback without redeploying code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Logging and Auditing
&lt;/h3&gt;

&lt;p&gt;Persisting requests and responses (with appropriate redaction) is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debugging hallucinations&lt;/li&gt;
&lt;li&gt;Reviewing cost drivers&lt;/li&gt;
&lt;li&gt;Compliance and audit trails&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safety and Guardrails
&lt;/h3&gt;

&lt;p&gt;Bedrock guardrails are worth enabling early, especially for user-facing applications. They are not perfect, but they reduce obvious failure modes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cost Control (Often Underestimated)
&lt;/h2&gt;

&lt;p&gt;Costs typically rise due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excessive token limits&lt;/li&gt;
&lt;li&gt;Repeated calls with similar prompts&lt;/li&gt;
&lt;li&gt;Using large models for trivial tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mitigations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower token ceilings&lt;/li&gt;
&lt;li&gt;Response caching&lt;/li&gt;
&lt;li&gt;Using smaller models for classification or extraction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Monitor usage in CloudWatch and Cost Explorer from day one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding Proprietary Data (RAG Before Fine-Tuning)
&lt;/h2&gt;

&lt;p&gt;For most teams, retrieval-augmented generation is simpler and safer than fine-tuning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store documents in S3&lt;/li&gt;
&lt;li&gt;Index with OpenSearch or a vector store&lt;/li&gt;
&lt;li&gt;Inject only relevant excerpts into prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach avoids retraining cycles and makes updates operationally straightforward.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Building generative AI workloads on AWS does not require an elaborate architecture, but it does require discipline around permissions, costs, and observability. Starting with Bedrock, Lambda, and API Gateway is usually sufficient for early stages. The key is to treat prompts, models, and limits as evolving components—not fixed decisions.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>bedrock</category>
      <category>llm</category>
    </item>
    <item>
      <title>Kickstart Your Cloud Journey with AWS Builder Labs</title>
      <dc:creator>Ravindra Pandya</dc:creator>
      <pubDate>Mon, 11 Aug 2025 06:55:14 +0000</pubDate>
      <link>https://dev.to/ravindraptech/kickstart-your-cloud-journey-with-aws-builder-labs-44fc</link>
      <guid>https://dev.to/ravindraptech/kickstart-your-cloud-journey-with-aws-builder-labs-44fc</guid>
      <description>&lt;p&gt;Hey there, tech enthusiasts! If you’ve been curious about diving into the world of cloud computing, there’s no better place to start than the &lt;strong&gt;Introduction to AWS Cloud: Builder Labs Learning Plan&lt;/strong&gt; on AWS Skill Builder. I recently explored this free learning plan, and let me tell you—it’s a fantastic way to get hands-on with AWS services without feeling overwhelmed. Whether you’re a complete beginner or looking to solidify your cloud basics, this learning plan is a game-changer. Let’s break it down and see why it’s worth your time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the AWS Builder Labs Learning Plan?
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Introduction to AWS Cloud: Builder Labs Learning Plan&lt;/em&gt; is a curated set of &lt;strong&gt;10 free hands-on labs&lt;/strong&gt; designed to give you practical experience with core AWS services. It’s hosted on AWS Skill Builder, Amazon’s go-to platform for cloud training, and it’s perfect for anyone looking to understand the fundamentals of AWS through real-world practice. The labs cover essential areas like compute, networking, storage, databases, serverless computing, content delivery, and security—pretty much the building blocks of cloud infrastructure.&lt;/p&gt;

&lt;p&gt;What I love about this plan is that it’s not just theory. You’re not stuck watching endless videos or reading dense documentation. Instead, you get to roll up your sleeves and work in a real AWS environment, guided step-by-step through each lab. It’s like having a sandbox where you can experiment without worrying about breaking anything (or racking up a surprise AWS bill!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;If you’re new to AWS, the cloud can feel like a massive, intimidating space. With so many services and acronyms—EC2, S3, IAM, VPC—it’s easy to get lost. The Builder Labs Learning Plan cuts through the noise by focusing on &lt;strong&gt;practical skills&lt;/strong&gt; that are highly valued in the industry. Here’s why it’s a must-try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hands-On Learning&lt;/strong&gt;: Each lab lets you build and test solutions in a real AWS environment. You’re not just reading about how to create an S3 bucket—you’re actually doing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible Pace&lt;/strong&gt;: You can complete the labs in any order, at your own speed. Got a busy schedule? No problem. You can pause, retry, or redo labs as many times as you want.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beginner-Friendly&lt;/strong&gt;: The step-by-step guidance makes it approachable, even if you’ve never touched AWS before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certification Prep&lt;/strong&gt;: If you’re eyeing an AWS certification like the Cloud Practitioner or Solutions Architect, these labs are a great way to build confidence and practical knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free!&lt;/strong&gt;: Did I mention it’s completely free? You get access to 10 foundational labs without needing a paid subscription.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Inside the Learning Plan?
&lt;/h2&gt;

&lt;p&gt;The learning plan includes 10 labs, each focusing on a key AWS service or concept. Here’s a quick rundown of what you’ll get to explore:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Virtual Private Cloud (VPC)&lt;/strong&gt;: Set up your own isolated network in AWS, complete with subnets, route tables, and internet connectivity. It’s like building your own private corner of the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Simple Storage Service (S3)&lt;/strong&gt;: Learn the ins and outs of S3 by creating buckets, uploading objects, and managing permissions. If you’ve ever wondered how to store files in the cloud, this is it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Elastic Compute Cloud (EC2)&lt;/strong&gt;: Launch and manage virtual servers in the cloud. You’ll get to configure, secure, and monitor an EC2 instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Identity and Access Management (IAM)&lt;/strong&gt;: Master the basics of AWS security by creating users, groups, roles, and access policies. Security is a big deal, and this lab sets you up for success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Key Management Service (KMS)&lt;/strong&gt;: Dive into encryption by creating and managing keys to secure your cloud resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;: Get hands-on with AWS’s NoSQL database by creating tables, adding items, and running queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon CloudFront&lt;/strong&gt;: Explore AWS’s content delivery network (CDN) to speed up content delivery for users worldwide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Lambda&lt;/strong&gt;: Build your first serverless function and dip your toes into event-driven computing. Serverless is the future, and this lab makes it super approachable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon API Gateway&lt;/strong&gt;: Create and deploy your first API, learning how to manage APIs in the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic Audit of Your AWS Environment&lt;/strong&gt;: Learn how to assess your AWS setup for security and identify areas for improvement using built-in tools.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each lab is designed to take you through a real-world scenario, and the guided instructions make it easy to follow along. By the end, you’ll have a solid grasp of how these services work together to build cloud solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with the Labs
&lt;/h2&gt;

&lt;p&gt;I decided to give the S3 and EC2 labs a try first, as they’re some of the most foundational AWS services. The S3 lab walked me through creating a bucket, uploading a file, and setting permissions. It was super satisfying to see my file stored securely in the cloud—and I didn’t have to guess my way through it. The instructions were clear, and I could experiment without worrying about messing things up.&lt;/p&gt;

&lt;p&gt;The EC2 lab was equally cool. Launching a virtual server felt like a big deal, but the lab broke it down into manageable steps—choosing an instance type, configuring security groups, and connecting to the instance. By the end, I felt like I’d actually &lt;em&gt;built&lt;/em&gt; something tangible in the cloud.&lt;/p&gt;

&lt;p&gt;One thing I appreciated was the flexibility. I could jump between labs based on what I was curious about, and the progress tracker kept me motivated. If I got stuck, I could retry the lab without any hassle. It’s a low-pressure way to learn, which is perfect for beginners or even intermediate folks looking to refresh their skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who’s This For?
&lt;/h2&gt;

&lt;p&gt;This learning plan is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Beginners&lt;/strong&gt;: If you’re new to AWS or cloud computing, this is a perfect starting point. No prior experience is required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers and IT Pros&lt;/strong&gt;: If you’re already in tech and want to add cloud skills to your toolbox, these labs give you practical, hands-on experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certification Hopefuls&lt;/strong&gt;: If you’re prepping for AWS certifications, these labs help you get comfortable with the AWS console and key services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Career Changers&lt;/strong&gt;: Looking to pivot into a cloud career? This plan gives you a taste of what working with AWS is like, without any upfront cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Get Started
&lt;/h2&gt;

&lt;p&gt;Ready to jump in? It’s super easy to get started. Head over to the &lt;a href="https://skillbuilder.aws/learning-plan/JE1AJBF5ZP/introduction-to-aws-cloud-builder-labs-learning-plan/955TYR1UFV" rel="noopener noreferrer"&gt;AWS Skill Builder website&lt;/a&gt; and sign up or sign in to enroll in the &lt;em&gt;Introduction to AWS Cloud: Builder Labs Learning Plan&lt;/em&gt;. You’ll need to enable JavaScript in your browser (most browsers have it enabled by default), and you’re good to go. Once enrolled, you can start any lab, track your progress, and work at your own pace.&lt;/p&gt;

&lt;p&gt;If you want to dive deeper after finishing these 10 labs, AWS Skill Builder offers a full catalog of 200+ Builder Labs, SimuLearns, and Jam Journeys with a paid subscription. But honestly, these free labs are more than enough to get you started and build some serious confidence.&lt;/p&gt;

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

&lt;p&gt;The &lt;em&gt;Introduction to AWS Cloud: Builder Labs Learning Plan&lt;/em&gt; is a fantastic way to get hands-on with AWS and build practical cloud skills. It’s free, flexible, and beginner-friendly, with just the right amount of guidance to make you feel like a pro without overwhelming you. Whether you’re looking to kickstart a cloud career, prep for a certification, or just explore what AWS is all about, this learning plan is a no-brainer.&lt;/p&gt;

&lt;p&gt;So, what are you waiting for? Go fire up those labs and start building in the cloud. And if you’ve already tried them, drop a comment below and let me know which lab was your favorite—I’d love to hear about your experience!&lt;/p&gt;

&lt;p&gt;Happy cloud building! ☁️&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: This blog is based on my personal experience with the AWS Builder Labs Learning Plan, and all opinions are my own. For the most up-to-date details, check out the official AWS Skill Builder website.&lt;/em&gt;&lt;a href="https://skillbuilder.aws/learning-plan/JE1AJBF5ZP/introduction-to-aws-cloud-builder-labs-learning-plan/955TYR1UFV?trk=c85cd1fb-ba1d-42ff-af20-8c9f96cf3b9d&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://aws.amazon.com/blogs/training-and-certification/begin-your-aws-journey-with-new-free-aws-builder-labs-learning-plan-on-aws-skill-builder/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloudcomputing</category>
      <category>aws</category>
      <category>skillbuilder</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AWS AI Conclave Online 2025!</title>
      <dc:creator>Ravindra Pandya</dc:creator>
      <pubDate>Tue, 07 Jan 2025 10:44:56 +0000</pubDate>
      <link>https://dev.to/ravindraptech/aws-ai-conclave-online-2025-19hk</link>
      <guid>https://dev.to/ravindraptech/aws-ai-conclave-online-2025-19hk</guid>
      <description>&lt;p&gt;Registration is now open for the AWS AI Conclave Online 2025!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Join this free online conference to hear from AWS leaders about the latest products, capabilities, and features simplifying the adoption of generative AI at scale for companies of all sizes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't miss the chance to connect 1:1 with AWS experts for valuable insights on building with AWS and cloud computing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Visit the event website for more details: &lt;a href="https://awsaiconclaveonline.virtual.awsevents.com" rel="noopener noreferrer"&gt;https://awsaiconclaveonline.virtual.awsevents.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>awsaiconclave</category>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
