<?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: Tapas SInghal</title>
    <description>The latest articles on DEV Community by Tapas SInghal (@its_tapas_ig).</description>
    <link>https://dev.to/its_tapas_ig</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%2F1178687%2F90d7ccf2-1233-49a0-a5a8-884473b23b28.png</url>
      <title>DEV Community: Tapas SInghal</title>
      <link>https://dev.to/its_tapas_ig</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/its_tapas_ig"/>
    <language>en</language>
    <item>
      <title>Building a Secure Enterprise Developer Workspace on AWS</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Thu, 22 Jan 2026 05:39:37 +0000</pubDate>
      <link>https://dev.to/aws-builders/building-a-secure-enterprise-developer-workspace-on-aws-578b</link>
      <guid>https://dev.to/aws-builders/building-a-secure-enterprise-developer-workspace-on-aws-578b</guid>
      <description>&lt;p&gt;I've spent the last few months working with enterprise clients who needed to lock down their developer environments without making life miserable for their engineering teams. The challenge? Give developers powerful workstations while keeping sensitive data and intellectual property locked down tight.&lt;/p&gt;

&lt;p&gt;After trying various approaches, I landed on a solution using AWS WorkSpaces and Directory Services that actually works in the real world. Let me walk you through exactly how I built it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time to complete:&lt;/strong&gt; 45-60 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$25-35/month per WorkSpace (Standard bundle with AutoStop)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; AWS account with admin access&lt;/p&gt;
&lt;h2&gt;
  
  
  What You're Actually Building
&lt;/h2&gt;

&lt;p&gt;Here's the setup we're going for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers get full Windows desktops, but they live in AWS&lt;/li&gt;
&lt;li&gt;Authentication ties into your enterprise identity system&lt;/li&gt;
&lt;li&gt;Access only works from approved networks&lt;/li&gt;
&lt;li&gt;Data stays on the desktop—no copying files out, no USB drives, nothing&lt;/li&gt;
&lt;li&gt;Security policies roll out from a central place, not manually on each machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't theoretical. Companies use this exact pattern when they're serious about data protection.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: Pick Your Region and Stick With It
&lt;/h2&gt;

&lt;p&gt;First things first—log into your AWS Console and pick a region. I usually go with something close to where my team actually sits to minimize latency.&lt;/p&gt;

&lt;p&gt;For this example, let's use &lt;strong&gt;ap-south-1 (Mumbai)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you've selected it in that top-right dropdown, don't change it. I've seen too many people accidentally create resources across multiple regions and wonder why nothing works together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; WorkSpaces can only use directories in the same region. If you create your directory in Mumbai and try to launch WorkSpaces in Singapore, it simply won't work.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Step 2: Set Up Your Identity System
&lt;/h2&gt;

&lt;p&gt;Every enterprise needs a proper identity system. We're going to use AWS Managed Microsoft AD because it integrates cleanly with WorkSpaces.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for &lt;strong&gt;Directory Service&lt;/strong&gt; in the AWS Console&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Set up directory&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;AWS Managed Microsoft AD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Pick &lt;strong&gt;Standard Edition&lt;/strong&gt; (unless you're managing thousands of users)&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Next&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now configure it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Directory DNS name:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Directory NetBIOS name:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Admin password:&lt;/strong&gt; Create something strong (at least 8 characters with uppercase, lowercase, numbers, and symbols). Save it in your password manager.&lt;/p&gt;

&lt;p&gt;For the VPC and subnet selection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use your &lt;strong&gt;default VPC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;two subnets&lt;/strong&gt; in different availability zones (AWS requires this for high availability)&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;subnet-abc123&lt;/code&gt; (us-east-1a) and &lt;code&gt;subnet-def456&lt;/code&gt; (us-east-1b)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click through and &lt;strong&gt;Create directory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Grab a coffee. This takes about 20-30 minutes. You'll know it's ready when the status shows &lt;strong&gt;Active&lt;/strong&gt; in green.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Troubleshooting:&lt;/strong&gt; If directory creation fails, check that your VPC has internet connectivity through an Internet Gateway or NAT Gateway. The directory service needs to reach AWS endpoints.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Create Your First Developer User
&lt;/h2&gt;

&lt;p&gt;Now that we've got our identity system running, let's create an actual user.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go back to &lt;strong&gt;Directory Service&lt;/strong&gt; in the console&lt;/li&gt;
&lt;li&gt;Click on your &lt;strong&gt;enterprise.local&lt;/strong&gt; directory&lt;/li&gt;
&lt;li&gt;In the directory details page, find the &lt;strong&gt;Actions&lt;/strong&gt; dropdown&lt;/li&gt;
&lt;li&gt;You might need to note down the &lt;strong&gt;Directory ID&lt;/strong&gt; (starts with &lt;code&gt;d-&lt;/code&gt;) for later&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Users&lt;/strong&gt; section in the left menu&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create user&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fill in the details:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Username:&lt;/strong&gt; &lt;code&gt;dev.user&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;First name:&lt;/strong&gt; Dev&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Last name:&lt;/strong&gt; User&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Email:&lt;/strong&gt; (optional but recommended for password resets)&lt;/p&gt;

&lt;p&gt;Set a temporary password. Check &lt;strong&gt;User must change password at next sign-in&lt;/strong&gt; if available.&lt;/p&gt;

&lt;p&gt;This user represents one of your developers. In production, you'd probably sync users from your on-premise Active Directory using AWS AD Connector, but for this tutorial, we're keeping it simple.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 4: Launch Your First WorkSpace
&lt;/h2&gt;

&lt;p&gt;Time to create the actual virtual desktop.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for &lt;strong&gt;WorkSpaces&lt;/strong&gt; in the console&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Amazon WorkSpaces&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create WorkSpace&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll see a wizard. Choose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Personal (persistent)&lt;/strong&gt; - each user gets their own desktop that persists&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt; as the OS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt; to move forward.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5: Connect the User to Their Desktop
&lt;/h2&gt;

&lt;p&gt;This part's straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select your directory: &lt;strong&gt;enterprise.local&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Next&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Pick the user: &lt;strong&gt;dev.user&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Next&lt;/strong&gt; again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You're basically saying "this desktop belongs to this user." One-to-one mapping.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 6: Configure the Desktop Hardware
&lt;/h2&gt;

&lt;p&gt;Now we choose what kind of machine this developer gets.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick a &lt;strong&gt;Standard Windows bundle&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;2 vCPU, 4 GB RAM, 80 GB storage&lt;/li&gt;
&lt;li&gt;Costs about $25-35/month with AutoStop&lt;/li&gt;
&lt;li&gt;Perfect for most development work (coding, git, basic IDEs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Running mode&lt;/strong&gt; to &lt;strong&gt;AutoStop&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure &lt;strong&gt;AutoStop timeout&lt;/strong&gt; to &lt;strong&gt;1 hour&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This last bit saves you money. If the developer walks away for lunch and forgets to log out, AWS automatically shuts down the WorkSpace after an hour of inactivity. You only pay for the hours it's actually running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage settings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Root volume: 80 GB (default)&lt;/li&gt;
&lt;li&gt;User volume: 50 GB (default)&lt;/li&gt;
&lt;li&gt;Leave these as-is unless you know developers need more space&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt;, review everything, and hit &lt;strong&gt;Create WorkSpace&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another waiting game—usually 10-15 minutes until the status shows &lt;strong&gt;Available&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's happening:&lt;/strong&gt; AWS is provisioning a Windows Server instance, joining it to your directory, installing the WorkSpaces agent, and configuring all the networking.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Step 7: Lock Down Network Access
&lt;/h2&gt;

&lt;p&gt;Here's where we get serious about security. We only want developers connecting from approved networks—not from random coffee shops or compromised home networks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In WorkSpaces, go to &lt;strong&gt;IP Access Controls&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create IP Access Control Group&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Name it something obvious:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Add a description like:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now add your first rule. If you're testing from your office or home:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find your public IP: Google "what's my IP" or visit &lt;a href="https://whatismyipaddress.com" rel="noopener noreferrer"&gt;https://whatismyipaddress.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Note down the IPv4 address (looks like &lt;code&gt;49.204.123.45&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;In the IP Access Control Group, click &lt;strong&gt;Add Rule&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter your IP with &lt;code&gt;/32&lt;/code&gt; at the end&lt;/li&gt;
&lt;/ol&gt;

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

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add a description like "Home Office" or "Testing Location"&lt;/li&gt;
&lt;li&gt;Save the rule&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That &lt;code&gt;/32&lt;/code&gt; means "only this exact IP address." In production, you'd use your office network's IP range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For office networks:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;203.0.113.0/24  (allows 203.0.113.0 to 203.0.113.255)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; If you have a dynamic IP (changes every few days), you'll need to update this rule whenever your IP changes. Most ISPs offer static IP addresses for business accounts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 8: Attach the Network Rules
&lt;/h2&gt;

&lt;p&gt;Creating the rule isn't enough—we need to attach it to our directory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;WorkSpaces → Directories&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your &lt;strong&gt;enterprise.local&lt;/strong&gt; directory&lt;/li&gt;
&lt;li&gt;Find &lt;strong&gt;IP access control groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Attach &lt;strong&gt;enterprise-trusted-network&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now anyone trying to connect from outside those approved IPs? They're blocked at the door.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: Disable Risky Access Methods
&lt;/h2&gt;

&lt;p&gt;People love convenience, but browsers and mobile devices are security nightmares for enterprise VDI.&lt;/p&gt;

&lt;p&gt;While you're in the directory settings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find &lt;strong&gt;Platform access settings&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Turn OFF:

&lt;ul&gt;
&lt;li&gt;Web access&lt;/li&gt;
&lt;li&gt;Mobile access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Keep only the desktop client enabled&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why? Because the desktop client gives you way more control and security. Browser-based access is a bypass waiting to happen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Start Enforcing Real Security Policies
&lt;/h2&gt;

&lt;p&gt;This is where we stop relying on user behavior and start enforcing rules they can't bypass.&lt;/p&gt;

&lt;p&gt;First, you need to connect to the WorkSpace as an administrator:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the &lt;strong&gt;WorkSpaces client&lt;/strong&gt; from &lt;a href="https://clients.amazonworkspaces.com" rel="noopener noreferrer"&gt;https://clients.amazonworkspaces.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install it on your local machine&lt;/li&gt;
&lt;li&gt;Open the client and enter your &lt;strong&gt;registration code&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Find this in the WorkSpaces console under your directory details&lt;/li&gt;
&lt;li&gt;Looks like &lt;code&gt;WSpdx+ABC123&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Log in with &lt;code&gt;dev.user&lt;/code&gt; and the password you set earlier&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you're in the WorkSpace:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Press &lt;code&gt;Win + R&lt;/code&gt; and type:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Press Enter (you'll need to be logged in as a domain admin—you may need to use "Run as different user" with the directory admin account)&lt;/li&gt;
&lt;li&gt;Expand &lt;strong&gt;Forest: enterprise.local&lt;/strong&gt; → &lt;strong&gt;Domains&lt;/strong&gt; → &lt;strong&gt;enterprise.local&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Right-click on &lt;strong&gt;Group Policy Objects&lt;/strong&gt; and select &lt;strong&gt;New&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Name it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Enterprise-VDI-Data-Restrictions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Right-click your new GPO and select &lt;strong&gt;Edit&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Group Policy is how Windows administrators have been enforcing security for decades. It works, and users can't weasel around it (if you do it right).&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 11: Block All the Data Leaks
&lt;/h2&gt;

&lt;p&gt;Here's the meat of our security model. Inside that Group Policy Editor:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigate to:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Computer Configuration → Policies → Administrative Templates → 
Windows Components → Remote Desktop Services → 
Remote Desktop Session Host → Device and Resource Redirection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Enable these policies:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow Clipboard redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Effect: Can't copy-paste between WorkSpace and local machine&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow drive redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Effect: Can't access local drives from the WorkSpace&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow LPT port redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow COM port redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow client printer redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Effect: Can't print to local printers or "print to PDF"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do not allow supported Plug and Play device redirection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set to: &lt;code&gt;Enabled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Effect: Can't use USB drives or other devices&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Apply the changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close the Group Policy Editor&lt;/li&gt;
&lt;li&gt;In Group Policy Management, right-click the GPO&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Enforced&lt;/strong&gt; to prevent overrides&lt;/li&gt;
&lt;li&gt;Link it to your WorkSpaces OU (usually under Computers)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the WorkSpace, open PowerShell as administrator and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;gpupdate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/force&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see output like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Updating policy...
Computer Policy update has completed successfully.
User Policy update has completed successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the WorkSpace for everything to take effect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Restart-Computer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know this sounds draconian, but this is how enterprises actually protect sensitive code and data. If developers need to move files around, they do it through approved channels like git repositories or internal file shares.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 12: Remove Local Admin Rights
&lt;/h2&gt;

&lt;p&gt;By default, the first user on a WorkSpace gets local admin rights. That's fine for testing, but terrible for production.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the WorkSpace, press &lt;code&gt;Win + R&lt;/code&gt; and type:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Local Users and Groups → Groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Double-click the &lt;strong&gt;Administrators&lt;/strong&gt; group&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;dev.user&lt;/strong&gt; in the list&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Remove&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Log out and log back in for the change to take effect.&lt;/p&gt;

&lt;p&gt;Without admin rights, users can't disable the security policies we just set up. They can still install approved software through Software Center or SCCM if you set those up, but they can't bypass your security baseline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Production tip:&lt;/strong&gt; In real environments, you'd manage this through Group Policy Restricted Groups or use a privileged access management (PAM) solution where users can request temporary admin rights for specific tasks.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 13: Test Everything
&lt;/h2&gt;

&lt;p&gt;Log in as &lt;code&gt;dev.user&lt;/code&gt; and try to break your own security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try copying text from the WorkSpace and pasting it into Notepad on your laptop → Should fail&lt;/li&gt;
&lt;li&gt;Try printing a document or using "Print to PDF" → Blocked&lt;/li&gt;
&lt;li&gt;Plug in a USB drive (if you can access the WorkSpace physically) → Nothing happens&lt;/li&gt;
&lt;li&gt;Try opening Local Group Policy Editor → Access denied&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If all those things fail, congratulations. Your security is actually working.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 14: Mind Your Costs
&lt;/h2&gt;

&lt;p&gt;Before you walk away, remember that WorkSpaces costs money while it's running.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log out when you're done testing&lt;/li&gt;
&lt;li&gt;Let AutoStop shut it down after the timeout&lt;/li&gt;
&lt;li&gt;When you're completely finished with this tutorial, delete the WorkSpace and directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've seen too many people leave test WorkSpaces running for months and get surprised by the bill. Don't be that person.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Missing (On Purpose)
&lt;/h2&gt;

&lt;p&gt;This tutorial covers the foundation, but real enterprise deployments usually add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPN requirements&lt;/strong&gt; - users must connect to corporate VPN first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Device certificates&lt;/strong&gt; - only company-managed devices can connect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MDM integration&lt;/strong&gt; - works with Intune, Jamf, or other MDM platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Trust architecture&lt;/strong&gt; - continuous verification of user and device posture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch monitoring&lt;/strong&gt; - detailed logging of who accessed what and when&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-factor authentication (MFA)&lt;/strong&gt; - requires additional verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session recording&lt;/strong&gt; - records all sessions for compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data loss prevention (DLP)&lt;/strong&gt; - additional scanning for sensitive data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are all important, but they're layers you add once you've got this foundation solid. Walking before running, and all that.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You've Actually Built
&lt;/h2&gt;

&lt;p&gt;Take a step back and look at what you've created:&lt;/p&gt;

&lt;p&gt;✅ Virtual desktops tied to enterprise identities&lt;br&gt;&lt;br&gt;
✅ Network access restricted to approved locations&lt;br&gt;&lt;br&gt;
✅ Data physically can't leave the environment&lt;br&gt;&lt;br&gt;
✅ Security policies that users can't bypass&lt;br&gt;&lt;br&gt;
✅ A design that scales from 10 users to 10,000  &lt;/p&gt;

&lt;p&gt;This isn't a toy project. This is the actual pattern companies use when they're handling sensitive intellectual property, financial data, or regulated information.&lt;/p&gt;




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

&lt;p&gt;Building secure developer environments is always a balancing act. Lock things down too much and developers find workarounds (usually insecure ones). Too loose and you're one leaked credential away from a data breach.&lt;/p&gt;

&lt;p&gt;This WorkSpaces approach isn't perfect, but it's proven. I've deployed variations of this for financial services companies, healthcare organizations, and startups dealing with sensitive customer data.&lt;/p&gt;

&lt;p&gt;The key insight? Security works best when it's invisible to the user. Developers don't think about the directory service or the IP restrictions—they just log in and get work done. Meanwhile, your security team sleeps better at night.&lt;/p&gt;

&lt;p&gt;If you end up implementing this in production, let me know how it goes. I'm always curious to hear what works (and what doesn't) in different environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 My Socials
&lt;/h2&gt;

&lt;p&gt;Feel free to connect with me or collaborate on other serverless &amp;amp; AI projects:&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Portfolio:&lt;/strong&gt; &lt;a href="https://tapasenjinia.me" rel="noopener noreferrer"&gt;https://tapasenjinia.me&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💼 &lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/tapas-singhal/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/tapas-singhal/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🧠 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/its-tapas" rel="noopener noreferrer"&gt;https://github.com/its-tapas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙌 — &lt;strong&gt;Tapas Singhal&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>devops</category>
      <category>workspace</category>
    </item>
    <item>
      <title>SAP on AWS: The $200K Skill Gap While Everyone's Learning AI</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Fri, 19 Dec 2025 19:34:35 +0000</pubDate>
      <link>https://dev.to/aws-builders/sap-on-aws-the-200k-skill-gap-while-everyones-learning-ai-200k</link>
      <guid>https://dev.to/aws-builders/sap-on-aws-the-200k-skill-gap-while-everyones-learning-ai-200k</guid>
      <description>&lt;p&gt;Last week, I watched a senior developer with 8 years of experience get rejected from a cloud migration project. His resume was impressive—Kubernetes expert, certified in three AWS services, even contributed to some open-source projects. The reason? He had zero SAP experience.&lt;/p&gt;

&lt;p&gt;The company was willing to pay $180K for someone who understood both SAP and AWS. They ended up hiring a contractor at $250/hour instead.&lt;/p&gt;

&lt;p&gt;That moment stuck with me. While everyone's panicking about AI replacing developers, there's this massive gap in cloud computing that barely anyone talks about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Uncomfortable Truth About Enterprise IT
&lt;/h2&gt;

&lt;p&gt;During my internship, a senior architect told me something that changed how I see the tech industry: half the world's business runs on SAP. Not the trendy frameworks we obsess over. Not the latest JavaScript library. SAP.&lt;/p&gt;

&lt;p&gt;SAP ERP, S/4HANA, SAP HANA databases—these systems process trillions of dollars in transactions every single day. Your bank uses it. Your favorite retailer uses it. That car you're planning to buy? The entire supply chain runs on SAP.&lt;/p&gt;

&lt;p&gt;And here's the kicker: most of these systems are still running in dusty data centers, burning money on hardware refresh cycles and maintenance contracts that cost more than your house.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  The AI Reality Check
&lt;/h2&gt;

&lt;p&gt;I've seen the LinkedIn posts. "AI will replace cloud engineers!" "Learn to prompt or become obsolete!"&lt;/p&gt;

&lt;p&gt;Here's my honest take: AI absolutely will change this space. I use tools like Claude, ChatGPT, and even newer IDEs like Kiro that help with coding workflows. They're brilliant for explaining SAP concepts, understanding AWS services, or debugging issues. AI will make people in this field more productive, no question.&lt;/p&gt;

&lt;p&gt;But here's what I learned during a recent S/4HANA migration that went sideways at 2AM: AI can suggest solutions, but it can't make the call when you're staring at conflicting recommendations and the CIO is asking if we need to roll back. It can't read the room when the SAP Basis team and AWS architects are blaming each other for performance issues. It can't negotiate with the VP who's terrified of downtime during Q4 holiday sales.&lt;/p&gt;

&lt;p&gt;AI is a tool that makes skilled people more valuable, not a replacement that makes them obsolete. The gap isn't technical knowledge anymore—Google and AI can fill that. The gap is judgment, experience, and the ability to navigate complex situations where there's no clear right answer.&lt;/p&gt;

&lt;p&gt;While everyone's learning prompt engineering, enterprises are bleeding money trying to find people who can actually execute these migrations. That's the opportunity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;SAP on AWS isn't about clicking through the AWS Console and launching EC2 instances. It's a different beast entirely.&lt;/p&gt;

&lt;p&gt;You're dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SAP workloads that need HANA-certified instances (x1, x2, u-instances that cost $50/hour)&lt;/li&gt;
&lt;li&gt;High-performance storage requirements that make regular EBS look like a toy&lt;/li&gt;
&lt;li&gt;Network latency tolerances measured in single-digit milliseconds&lt;/li&gt;
&lt;li&gt;Backup strategies for multi-terabyte databases that can't have "oops" moments&lt;/li&gt;
&lt;li&gt;Disaster recovery plans that CEOs actually care about because downtime means millions lost per hour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS has an entire division dedicated to SAP—SAP on AWS practice, specialized solutions architects, pre-built reference architectures. This isn't some side project. Amazon knows enterprises are spending serious money here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Paths Nobody Mentions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If you're already in the SAP world:&lt;/strong&gt; Learning AWS is your ticket out of being seen as "legacy." SAP consultants who add cloud skills instantly jump tax brackets. You already understand HANA, S/4HANA, and the business side. Add AWS architecture skills, and you're suddenly one of maybe 5,000 people globally who can do both well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're an AWS person:&lt;/strong&gt; SAP is your differentiation. While 50,000 developers are fighting for the same DevOps roles, enterprises are begging for cloud architects who aren't afraid of SAP. You don't need to become an SAP functional consultant. Just understand the infrastructure side—HANA deployments, high availability, backup/recovery, performance tuning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're starting fresh:&lt;/strong&gt; This is where I am right now. It's honestly intimidating—the learning curve is steep on both sides. But that's also the opportunity. In 3-5 years, you'll have skills that take most people 10+ years to acquire, and you'll be working on projects where budgets have commas in them. I spent a month working with SAP HANA and ERP during my internship, and even that brief exposure showed me how massive and complex this ecosystem is.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Where Do I Actually Start?
&lt;/h2&gt;

&lt;p&gt;You need two things: AWS fundamentals and SAP literacy. Not mastery—literacy.&lt;/p&gt;

&lt;p&gt;For AWS: Get hands-on. Actually deploy things, break them, fix them. The certification helps, but building real infrastructure teaches more.&lt;/p&gt;

&lt;p&gt;For SAP: Understand the basics—what HANA is, what S/4HANA does, why BASIS admins matter. SAP has free learning accounts. Use them.&lt;/p&gt;

&lt;p&gt;Then combine both: AWS SAP reference architectures, immersion days, real projects if you can get access.&lt;/p&gt;

&lt;p&gt;The truth? Most people quit because it's not as exciting as the latest trend. That's exactly why the opportunity exists.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I'm working on a detailed learning roadmap with resources, timelines, and hands-on projects. If there's interest, I'll share it—let me know in the comments.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters (At Least to Me)
&lt;/h2&gt;

&lt;p&gt;I'm five months into my career as a developer. I'm still figuring out how to balance learning new technologies with actually getting work done. I'm not making $200K. I'm not leading migration projects.&lt;/p&gt;

&lt;p&gt;But that one-month exposure to SAP HANA and ERP systems during my internship showed me how much of enterprise technology operates differently than what we learn in tutorials. The contractor making $250/hour had skills that bridged both SAP and AWS—that's the gap.&lt;/p&gt;

&lt;p&gt;I'm starting to invest time in understanding SAP alongside my AWS work. It's vast, it's complex, and honestly, it's not always exciting. But the market gap is real, and someone's going to fill it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources That Actually Matter
&lt;/h2&gt;

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




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




&lt;p&gt;&lt;strong&gt;AWS Official:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/sap-lens/sap-lens.html" rel="noopener noreferrer"&gt;AWS SAP Lens (Well-Architected Framework)&lt;/a&gt; - Start here. It's what every SAP on AWS project references.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/sap/" rel="noopener noreferrer"&gt;SAP on AWS Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/certification/certified-sap-on-aws-specialty/" rel="noopener noreferrer"&gt;AWS Partner: SAP on AWS Specialty Certification&lt;/a&gt; (advanced, but the target)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SAP Side:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://learning.sap.com/" rel="noopener noreferrer"&gt;SAP Learning Hub&lt;/a&gt; - Free tier available. Focus on HANA basics and S/4HANA overview.&lt;/li&gt;
&lt;/ul&gt;

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




&lt;p&gt;&lt;strong&gt;Hands-On:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://explore.skillbuilder.aws/learn/course/external/view/elearning/57/sap-on-aws-technical-foundations" rel="noopener noreferrer"&gt;AWS Skill Builder: SAP on AWS&lt;/a&gt; - Free courses and learning paths&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://workshops.aws/categories/SAP" rel="noopener noreferrer"&gt;AWS Workshops: SAP on AWS&lt;/a&gt; - Hands-on labs you can actually do&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://repost.aws/community/TAujMzs1_ZR3SIaMwia7ln7A/sap-on-aws" rel="noopener noreferrer"&gt;AWS SAP Community on re:Post&lt;/a&gt; - Actual engineers solving actual problems&lt;/li&gt;
&lt;/ul&gt;

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




&lt;p&gt;&lt;strong&gt;Reality Check:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look at SAP BASIS job descriptions—see what skills they value&lt;/li&gt;
&lt;li&gt;Compare with AWS Solutions Architect roles focused on enterprise&lt;/li&gt;
&lt;li&gt;The overlap is your opportunity
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lf24o6u7s616t8xjcaf.png" alt="Cert" width="800" height="580"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  My Plan Moving Forward
&lt;/h2&gt;

&lt;p&gt;Committing to this learning path while maintaining current role and continuing to develop technical skills is going to be difficult especially when there is a race against Ai. It requires discipline—early mornings, focused weekends, and saying no to distractions—but the market demand and career trajectory make it worth the investment.&lt;/p&gt;

&lt;p&gt;The challenge is not only about technical. It's staying consistent when progress feels slow, when the concepts are dense, and when friends are learning flashier technologies. But that's also what creates the opportunity. Most people won't put in this work, which is exactly why those who do become valuable.&lt;/p&gt;

&lt;p&gt;I'm documenting this journey not as an expert, but as someone in the trenches. If you're considering this path or already working in SAP or AWS, or have insights or thought to share, I would love to connect.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 My Socials
&lt;/h2&gt;

&lt;p&gt;Feel free to connect with me or collaborate on other serverless &amp;amp; AI projects:&lt;/p&gt;

&lt;p&gt;🔗 Portfolio: &lt;a href="https://tapasenjinia.me" rel="noopener noreferrer"&gt;https://tapasenjinia.me&lt;/a&gt;&lt;br&gt;
💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/tapas-singhal/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/tapas-singhal/&lt;/a&gt;&lt;br&gt;
🧠 GitHub: &lt;a href="https://github.com/its-tapas" rel="noopener noreferrer"&gt;https://github.com/its-tapas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙌 — Tapas Singhal&lt;/p&gt;

</description>
      <category>aws</category>
      <category>sap</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>End to End Generative AI mini Project On AWS Using AWS Bedrock, AWS Lambda, API Gateway and S3</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Thu, 01 May 2025 19:37:31 +0000</pubDate>
      <link>https://dev.to/aws-builders/end-to-end-generative-ai-mini-project-on-aws-using-aws-bedrock-aws-lambda-api-gateway-and-s3-4fp4</link>
      <guid>https://dev.to/aws-builders/end-to-end-generative-ai-mini-project-on-aws-using-aws-bedrock-aws-lambda-api-gateway-and-s3-4fp4</guid>
      <description>&lt;p&gt;In this blog, I’ll walk you through &lt;strong&gt;exactly how I created an AI-powered blog generator bot&lt;/strong&gt; using &lt;strong&gt;Amazon Bedrock&lt;/strong&gt;, &lt;strong&gt;Lambda&lt;/strong&gt;, &lt;strong&gt;S3&lt;/strong&gt;, and &lt;strong&gt;API Gateway&lt;/strong&gt;. This was a mini project to practice serverless architecture using AWS services and AI text generation models to get introduce to Amazon Bedrock.&lt;/p&gt;

&lt;p&gt;🔧 I used a non-chat LLaMA model from &lt;strong&gt;Amazon Bedrock&lt;/strong&gt;, because that was available in my region (&lt;code&gt;ap-south-1&lt;/code&gt;) and suited my use case well for blog generation, dont hesitate to use anyother model.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What You’ll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to access and use Amazon Bedrock models&lt;/li&gt;
&lt;li&gt;How to prepare a Lambda function with external libraries like &lt;code&gt;boto3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to integrate Lambda with API Gateway for POST requests&lt;/li&gt;
&lt;li&gt;How to store generated blog content into S3 buckets&lt;/li&gt;
&lt;li&gt;How to test the endpoint using free tools like ReqBin&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Step 1: Enable Amazon Bedrock and Choose Model
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 Accessing Bedrock
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to AWS Console → Services → &lt;strong&gt;Amazon Bedrock&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Request model access (you may need to request access for models like &lt;strong&gt;LLaMA3&lt;/strong&gt;, &lt;strong&gt;Titan&lt;/strong&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Wait for approval (this can take from minutes to a few hours).&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 I used &lt;strong&gt;&lt;code&gt;meta.llama3-8b-instruct-v1:0&lt;/code&gt;&lt;/strong&gt;, which was available in my region. I didn’t choose a chat model specifically — I used what was available for experimentation. If available you should choose a chat based model or any other good text based model.&lt;/p&gt;
&lt;/blockquote&gt;

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




&lt;h2&gt;
  
  
  🧠 Step 2: Write and Prepare the Lambda Function
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 Writing the Function
&lt;/h3&gt;

&lt;p&gt;The Lambda function handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receiving the blog topic from API Gateway&lt;/li&gt;
&lt;li&gt;Sending the prompt to the Bedrock model&lt;/li&gt;
&lt;li&gt;Receiving and parsing the response&lt;/li&gt;
&lt;li&gt;Saving the blog to S3
&lt;/li&gt;
&lt;/ul&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;botocore.config&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;blog_generate_using_bedrock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blogtopic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;str&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;Write a blog minimum 300 to 500 words(no need to strictly follow) in a professional mammer with only 5 subtopics and a conclusion &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;blogtopic&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;body&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;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_gen_len&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;600&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_p&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.9&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;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="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;ap-south-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;botocore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;retries&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;max_attempts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&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;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;body&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;&amp;lt;Your_Model_ID&amp;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;response_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;response&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="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;response_data&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_content&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;response_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;blog_details&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;response_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;generation&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="n"&gt;blog_details&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="nf"&gt;print&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;Error generating the blog:&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="sh"&gt;""&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_blog_details_s3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s3_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;generate_blog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;s3&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;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_key&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;generate_blog&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Code saved to s3&lt;/span&gt;&lt;span class="sh"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error when saving the code to s3&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="c1"&gt;# TODO implement
&lt;/span&gt;
    &lt;span class="n"&gt;event&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="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;blogtopic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;blog_topic&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;generate_blog&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;blog_generate_using_bedrock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blogtopic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;blogtopic&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;generate_blog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;curr_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%H%M%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;s3_key&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;blog-output/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;curr_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;Your_s3_bucket&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="nf"&gt;save_blog_details_s3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s3_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;generate_blog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No blog was generated &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="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;Blog Generation is Completed&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;NOTE: - Replace 'Your_Model_ID' with your bedrock model's ModelID and 'Your_s3_bucket' with your AWS bucket&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Important: Add boto3 Dependency
&lt;/h3&gt;

&lt;p&gt;Amazon Bedrock needs &lt;strong&gt;latest boto3 version&lt;/strong&gt;, which is &lt;strong&gt;not included&lt;/strong&gt; in Lambda by default. You have &lt;strong&gt;two options&lt;/strong&gt;:&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ Option 1: Create a Lambda Layer with boto3
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;On your local system, run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;mkdir &lt;/span&gt;python
   pip &lt;span class="nb"&gt;install &lt;/span&gt;boto3 &lt;span class="nt"&gt;-t&lt;/span&gt; python/
   zip &lt;span class="nt"&gt;-r&lt;/span&gt; boto3_layer.zip python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Go to AWS Console → Lambda → Layers → Create Layer&lt;/li&gt;
&lt;li&gt;Upload &lt;code&gt;boto3_layer.zip&lt;/code&gt; and choose compatible runtimes (Python 3.12, 3.11, or 3.10)&lt;/li&gt;
&lt;li&gt;Attach the layer to your Lambda function&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your Result should look like this&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydgc9c83hqvjb844zw6k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydgc9c83hqvjb844zw6k.png" alt="layer" width="800" height="167"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  🧠 Option 2: Include boto3 manually in deployment zip
&lt;/h4&gt;

&lt;p&gt;(Same as above, but upload the entire zipped folder as your Lambda deployment package.)&lt;/p&gt;


&lt;h2&gt;
  
  
  🔗 Step 3: Setup API Gateway for Integration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🔹 Create an HTTP API
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to AWS Console → API Gateway&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;HTTP API&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click “Build” and name it (e.g., &lt;code&gt;BlogGenAPI&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  🔹 Configure Routing
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;strong&gt;route&lt;/strong&gt;: &lt;code&gt;POST /blog-generation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;integration target&lt;/strong&gt;: Your Lambda function&lt;/li&gt;
&lt;li&gt;Deploy the API and create a &lt;strong&gt;Stage&lt;/strong&gt; (in my case: &lt;code&gt;dev&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;You’ll get
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Invoke URL
   https://your-api-id.execute-api.region.amazonaws.com/dev/

   AND 

   Route details
   POST /blog-generation   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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



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


&lt;h2&gt;
  
  
  🪣 Step 4: Create and Connect S3 Bucket
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to AWS Console → S3 → Create a bucket

&lt;ul&gt;
&lt;li&gt;Bucket name: &lt;code&gt;awsbedrocktapas&lt;/code&gt; (you can name it anything but should be unique)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;No need to make it public&lt;/li&gt;
&lt;li&gt;Go to IAM role of the Lambda and allow:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;s3:PutObject&lt;/code&gt; on your bucket&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;In your Lambda code, the S3 upload part 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="n"&gt;s3_key&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;blog-output/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;curr_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;s3_bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR Bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s3_key&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;generated_blog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Raplace 'YOUR Bucket' with your bucket name you just created&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Step 5: Test the API using any tool, I am using ReqBin (Free Online Tool)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://reqbin.com" rel="noopener noreferrer"&gt;reqbin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Choose method: &lt;code&gt;POST&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: Your deployed API Gateway endpoint
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-api-id.execute-api.region.amazonaws.com/dev/blog-generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Choose Content-Type: &lt;code&gt;json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add body:
&lt;/li&gt;
&lt;/ol&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;"blog_topic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Benefits of Remote Work in 2025"&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;ol&gt;
&lt;li&gt;Hit “Send” and check the response&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;You should see:&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;"blog_topic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Benefits of Remote Work in 2025"&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;Now check your S3 bucket — you’ll find a &lt;code&gt;.txt&lt;/code&gt; file with your freshly AI-generated blog!&lt;/p&gt;

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




&lt;h2&gt;
  
  
  🧾 Example Output Blog
&lt;/h2&gt;

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




&lt;h2&gt;
  
  
  ✅ Final Flow Diagram (Optional)
&lt;/h2&gt;

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




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;Using just four core AWS services — &lt;strong&gt;Bedrock, Lambda, API Gateway, and S3&lt;/strong&gt; — we’ve built a complete, serverless AI-powered blog generator.&lt;/p&gt;

&lt;p&gt;This project taught me how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with LLMs via Bedrock&lt;/li&gt;
&lt;li&gt;Integrate custom code into Lambda&lt;/li&gt;
&lt;li&gt;Manage external Python libraries via Lambda Layers&lt;/li&gt;
&lt;li&gt;Expose a POST API endpoint for external use&lt;/li&gt;
&lt;li&gt;Save data persistently using S3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💬 You can build on top of this by adding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A frontend (React/Next.js)&lt;/li&gt;
&lt;li&gt;An email sender to notify when blog is ready&lt;/li&gt;
&lt;li&gt;An admin dashboard for blog management&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌐 My Socials
&lt;/h2&gt;

&lt;p&gt;Feel free to connect with me or collaborate on other serverless &amp;amp; AI projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;Portfolio&lt;/strong&gt;: &lt;a href="https://tapasenjinia.me" rel="noopener noreferrer"&gt;https://tapasenjinia.me&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 &lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/tapas-singhal/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/tapas-singhal/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/its-tapas" rel="noopener noreferrer"&gt;https://github.com/its-tapas&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📂 Project Repository
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/its-tapas/blogGen" rel="noopener noreferrer"&gt;https://github.com/its-tapas/blogGen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;🤝 &lt;em&gt;Open to improvements, ideas, and suggestions. Don't hesitate to fork, star, or contribute to this project!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Thanks for reading 🙌 — Tapas Singhal&lt;/p&gt;

</description>
      <category>aws</category>
      <category>bedrock</category>
      <category>ai</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Building a Scalable Web Application on AWS Using Core Services [Perfect for Beginners]</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Sun, 02 Feb 2025 22:25:13 +0000</pubDate>
      <link>https://dev.to/aws-builders/building-a-scalable-web-application-on-aws-using-core-services-perfect-for-beginners-22h8</link>
      <guid>https://dev.to/aws-builders/building-a-scalable-web-application-on-aws-using-core-services-perfect-for-beginners-22h8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog, I’ll walk you through a &lt;strong&gt;Level 2 AWS project&lt;/strong&gt; where we build a scalable web application using AWS core services. Whether you're new to AWS or looking to solidify your understanding, this guide will help you get hands-on with services like &lt;strong&gt;VPC, EC2, IAM, S3, and ALB&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://catalog.workshops.aws/aws101/en-US" rel="noopener noreferrer"&gt;AWS Workshop Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/zyOFJRvC2o0" rel="noopener noreferrer"&gt;Watch the YouTube Tutorial&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you prefer a &lt;strong&gt;detailed, step-by-step practical implementation&lt;/strong&gt;, check out my &lt;strong&gt;&lt;a href="https://youtu.be/zyOFJRvC2o0" rel="noopener noreferrer"&gt;YouTube tutorial here&lt;/a&gt;&lt;/strong&gt;. The video covers every step of the process, from setting up the VPC to deploying the web server and configuring the load balancer. You can also follow along with the &lt;strong&gt;&lt;a href="https://catalog.workshops.aws/aws101/en-US" rel="noopener noreferrer"&gt;AWS Workshop Link&lt;/a&gt;&lt;/strong&gt; for a self-paced learning experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

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

&lt;p&gt;Here’s an overview of what we’ll build:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC&lt;/strong&gt;: A virtual network to host our resources securely.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2&lt;/strong&gt;: A web server to host our application.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM&lt;/strong&gt;: Role-based access control for secure resource management.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALB&lt;/strong&gt;: An Application Load Balancer to distribute traffic.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3&lt;/strong&gt;: Cloud storage for static assets.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step-by-Step Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setting Up Networking (VPC)
&lt;/h3&gt;

&lt;p&gt;We started by creating a &lt;strong&gt;Virtual Private Cloud (VPC)&lt;/strong&gt; with public and private subnets across two Availability Zones. This ensures our resources are isolated and secure.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Resource Security (Security Groups)
&lt;/h3&gt;

&lt;p&gt;Next, we created &lt;strong&gt;Security Groups&lt;/strong&gt; to control inbound and outbound traffic. One group allows HTTP traffic from the internet, while the other restricts access to the web server.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Access Management (IAM)
&lt;/h3&gt;

&lt;p&gt;We configured an &lt;strong&gt;IAM Role&lt;/strong&gt; with the necessary permissions for our EC2 instance to interact with other AWS services securely.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deploying Compute (EC2)
&lt;/h3&gt;

&lt;p&gt;Using &lt;strong&gt;Amazon EC2&lt;/strong&gt;, we launched a web server in the private subnet. We also used &lt;strong&gt;User Data&lt;/strong&gt; to automate the installation of a PHP web server.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Administering the Web Server (SSM)
&lt;/h3&gt;

&lt;p&gt;We connected to the EC2 instance securely using &lt;strong&gt;AWS Systems Manager (SSM)&lt;/strong&gt;, eliminating the need for SSH keys or public IPs.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Load Balancing (ALB)
&lt;/h3&gt;

&lt;p&gt;To distribute traffic, we set up an &lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt; that routes incoming HTTP requests to our web server.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Testing and Scaling
&lt;/h3&gt;

&lt;p&gt;Finally, we tested the web application and explored scaling options using &lt;strong&gt;Auto Scaling Groups&lt;/strong&gt; (optional challenge).&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Up
&lt;/h2&gt;

&lt;p&gt;Don’t forget to clean up your resources to avoid unnecessary charges! Terminate the EC2 instance, delete the ALB, and remove any unused resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following this guide, you’ve built a scalable and secure web application on AWS. This project is a great way to get hands-on experience with core AWS services and understand how they work together.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/tapas-singhal-b1380521a/" rel="noopener noreferrer"&gt;My LinkedIn Profile&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you face any issues, feel free to reach out to me directly on LinkedIn. &lt;br&gt;
The &lt;strong&gt;YouTube video&lt;/strong&gt; provides a &lt;strong&gt;detailed, step-by-step practical implementation&lt;/strong&gt; of this workshop, making it easier to follow along and implement the project yourself. &lt;/p&gt;

&lt;p&gt;Let me know if you have any questions or suggestions in the comments below! Happy building! 🚀&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscommunitybuiler</category>
      <category>vpc</category>
      <category>alb</category>
    </item>
    <item>
      <title>[Mini Project] Serverless URL Shortener Using AWS Lambda, Api Gateway and DynamoDB</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Sat, 01 Feb 2025 18:04:18 +0000</pubDate>
      <link>https://dev.to/aws-builders/mini-project-serverless-url-shortener-using-aws-lambda-api-gateway-and-dynamodb-233o</link>
      <guid>https://dev.to/aws-builders/mini-project-serverless-url-shortener-using-aws-lambda-api-gateway-and-dynamodb-233o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd6vv7ghj8c2r760r2fl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd6vv7ghj8c2r760r2fl.png" alt="Serverless URL Shortener" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before Starting Consider these options too- &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For direct steps Go to &lt;a href="https://github.com/its-tapas/KloudBuilder/tree/main/Level-2/*%5BMini%20Project%5D%20Serverless%20URL%20Shortener" rel="noopener noreferrer"&gt;GitHub - [Mini Project] Serverless URL Shortener&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You can Find the &lt;strong&gt;Amazon Blog&lt;/strong&gt; for Build a Serverless, Private URL Shortener - &lt;a href="https://aws.amazon.com/blogs/compute/build-a-serverless-private-url-shortener" rel="noopener noreferrer"&gt;Here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;If You Like to &lt;strong&gt;Build a serverless URL shortener app without AWS Lambda&lt;/strong&gt; Go to - &lt;a href="https://aws.amazon.com/blogs/compute/building-a-serverless-url-shortener-app-without-lambda-part-1" rel="noopener noreferrer"&gt;Amazon Blog Link&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this tutorial, we will walk through building a &lt;strong&gt;Serverless URL Shortener&lt;/strong&gt; using AWS services like &lt;strong&gt;Lambda&lt;/strong&gt;, &lt;strong&gt;API Gateway&lt;/strong&gt;, and &lt;strong&gt;DynamoDB&lt;/strong&gt;. The goal of this project is to create a highly scalable and serverless system where long URLs are shortened, and users can be redirected to the original URLs using the short codes.&lt;/p&gt;

&lt;p&gt;The project is designed to be beginner-friendly and will guide you step-by-step. You’ll also learn about AWS services like Lambda, API Gateway, and DynamoDB, which are commonly used in serverless architectures.&lt;/p&gt;

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

&lt;p&gt;Before we start, ensure that you have the following prerequisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS Account&lt;/strong&gt;: If you don’t already have an AWS account, you can sign up &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;(below if working with CLI)&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS CLI&lt;/strong&gt;: The AWS Command Line Interface (CLI) will help you interact with AWS services directly from your terminal. Follow the &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;installation instructions&lt;/a&gt; for Windows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.x&lt;/strong&gt;: Our Lambda function will be written in Python. Make sure Python 3.x is installed on your system from &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;python.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postman&lt;/strong&gt;: For testing our API, we’ll be using Postman. You can download and install it from &lt;a href="https://www.postman.com/downloads/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Set Up DynamoDB Table
&lt;/h2&gt;

&lt;p&gt;The first step in building our serverless URL shortener is to create a DynamoDB table where the shortened URLs and their corresponding long URLs will be stored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DynamoDB&lt;/strong&gt; is a fully managed NoSQL database provided by AWS. It allows you to store data in a key-value format, and it scales automatically based on your application's needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;strong&gt;AWS Management Console&lt;/strong&gt; and navigate to &lt;strong&gt;DynamoDB&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Table&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Table name&lt;/strong&gt; as &lt;code&gt;URLShortener&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Partition key&lt;/strong&gt; to &lt;code&gt;short_code&lt;/code&gt; (Type: String).

&lt;ul&gt;
&lt;li&gt;This will uniquely identify each shortened URL by its short code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2: Create the Lambda Function
&lt;/h2&gt;

&lt;p&gt;Next, we need to create an &lt;strong&gt;AWS Lambda&lt;/strong&gt; function that will generate short codes and handle the URL redirection.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is AWS Lambda?
&lt;/h3&gt;

&lt;p&gt;AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. You upload your code, set a trigger, and Lambda takes care of the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;AWS Lambda&lt;/strong&gt; in the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Function&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Author from Scratch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Function name&lt;/strong&gt; as &lt;code&gt;URLShortenerFunction&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Runtime&lt;/strong&gt; to Python 3.x.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Permissions&lt;/strong&gt; section, create a new role with basic Lambda permissions (AWS will automatically create the role).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Function&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 3: Add Code to the Lambda Function
&lt;/h2&gt;

&lt;p&gt;After creating the Lambda function, we need to add the Python code that will perform the main logic of the URL shortener. This includes generating a short code for a given long URL and redirecting users when they visit the short code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lambda function&lt;/strong&gt; acts as the business logic handler in this project. It will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receive the original long URL.&lt;/li&gt;
&lt;li&gt;Generate a short code.&lt;/li&gt;
&lt;li&gt;Store the mapping in DynamoDB.&lt;/li&gt;
&lt;li&gt;Redirect the user to the original URL when they use the short code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code for Lambda function:
&lt;/h3&gt;

&lt;p&gt;Here’s the Python code that will handle the URL shortening and redirection:&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="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;string&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;

&lt;span class="n"&gt;dynamodb&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;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dynamodb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Table&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_short_code&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ascii_letters&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digits&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&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;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&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;_&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="mi"&gt;6&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="n"&gt;http_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;httpMethod&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;http_method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Create a short URL
&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="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;long_url&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;long_url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;short_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_short_code&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Item&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;short_code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;short_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;long_url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;long_url&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;short_code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;short_code&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;http_method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Redirect to the long URL
&lt;/span&gt;        &lt;span class="n"&gt;short_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;queryStringParameters&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;short_code&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;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Key&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;short_code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;short_code&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Item&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&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;404&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;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;Short URL not found&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="n"&gt;long_url&lt;/span&gt; &lt;span class="o"&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;Item&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;long_url&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="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;301&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;headers&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;Location&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;long_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&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="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="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;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;Invalid HTTP method&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;ul&gt;
&lt;li&gt;Click Deploy to save the changes. ( You can modify the code as per required including DynamoDB Table Name and test it as well) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4: Set Up API Gateway
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is API Gateway?
&lt;/h3&gt;

&lt;p&gt;API Gateway is a service from AWS that allows developers to create, publish, maintain, monitor, and secure APIs. With API Gateway, you can expose HTTP endpoints that can interact with backend services such as AWS Lambda functions.&lt;/p&gt;

&lt;p&gt;Follow these steps to set up API Gateway:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to API Gateway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the &lt;strong&gt;AWS Management Console&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the search bar, type &lt;strong&gt;API Gateway&lt;/strong&gt;, and select it from the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a new API:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;strong&gt;Create API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;HTTP API&lt;/strong&gt;, and then click &lt;strong&gt;Build&lt;/strong&gt; to begin creating a new API.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Define the API Routes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;POST /shorten&lt;/strong&gt;: This route will handle the creation of short URLs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GET /redirect&lt;/strong&gt;: This route will redirect users to the original URL based on the short code provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integrate Routes with Lambda:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For each route, select the &lt;code&gt;URLShortenerFunction&lt;/code&gt; Lambda function that we created in Step 2.&lt;/li&gt;
&lt;li&gt;API Gateway will automatically link the function to the routes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy the API:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After setting up the routes, you need to deploy the API. &lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Deploy&lt;/strong&gt; to create a new stage. A stage is an environment for your API (e.g., &lt;code&gt;prod&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Name the stage, such as &lt;code&gt;prod&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;AWS will provide a URL for the deployed API. This is the URL you will use to interact with your API.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example API endpoint URL format:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;https://.execute-api..amazonaws.com/prod&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Explanation of API Gateway's Role:
&lt;/h3&gt;

&lt;p&gt;API Gateway serves as a bridge between the frontend (users) and the backend (Lambda). When a user requests a short URL or tries to access the original URL using the short code, API Gateway routes the requests to the Lambda function, which processes the logic (e.g., generating a short code or retrieving the original URL).&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Test the URL Shortener
&lt;/h2&gt;

&lt;p&gt;Once you have set up the Lambda function and API Gateway, it’s time to test the URL shortener functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Using Postman (Recommended for Windows)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Postman&lt;/strong&gt; is a tool that allows you to send HTTP requests and view responses, making it perfect for testing APIs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Short URL:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Postman&lt;/strong&gt; and create a new request.&lt;/li&gt;
&lt;li&gt;Set the request type to &lt;strong&gt;POST&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the URL for the &lt;code&gt;shorten&lt;/code&gt; route:
&amp;gt; https://.execute-api..amazonaws.com/prod/shorten&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Body&lt;/strong&gt; tab, select &lt;strong&gt;raw&lt;/strong&gt; and choose &lt;strong&gt;JSON&lt;/strong&gt; as the format.&lt;/li&gt;
&lt;li&gt;Add the following JSON payload to the body:
&lt;/li&gt;
&lt;/ol&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;"long_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.example.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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Click Send&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;If everything works correctly, you should receive a response with a short_code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Redirect to the Original URL:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new request in Postman, set it to GET, and enter the following URL: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;https://.execute-api..amazonaws.com/prod/redirect?short_code=&lt;br&gt;
Replace  with the code you received from the previous step.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Send&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;You should be redirected to the original URL &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing Using Command Prompt or PowerShell
&lt;/h3&gt;

&lt;p&gt;If you prefer using the &lt;strong&gt;Command Prompt&lt;/strong&gt; or &lt;strong&gt;PowerShell&lt;/strong&gt;, you can test the API using &lt;code&gt;Invoked&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Short URL:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Command Prompt&lt;/strong&gt; or &lt;strong&gt;PowerShell&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use the following command to send a &lt;code&gt;POST&lt;/code&gt; request:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   Invoke-RestMethod &lt;span class="nt"&gt;-Uri&lt;/span&gt; &lt;span class="s2"&gt;"https://&amp;lt;api-id&amp;gt;.execute-api.&amp;lt;region&amp;gt;.amazonaws.com/prod/shorten"&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nt"&gt;-Method&lt;/span&gt; Post &lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nt"&gt;-ContentType&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nt"&gt;-Body&lt;/span&gt; &lt;span class="s1"&gt;'{"long_url": "https://www.example.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You should receive a &lt;code&gt;short_code&lt;/code&gt; in the response.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Redirect to the Original URL:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Use the following command to send a &lt;code&gt;GET&lt;/code&gt; request:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   Invoke-RestMethod &lt;span class="nt"&gt;-Uri&lt;/span&gt; &lt;span class="s2"&gt;"https://&amp;lt;api-id&amp;gt;.execute-api.&amp;lt;region&amp;gt;.amazonaws.com/prod/redirect?short_code=&amp;lt;short_code&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;short_code&amp;gt;&lt;/code&gt; with the code you received earlier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should be redirected to the original URL.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 6: Clean Up
&lt;/h2&gt;

&lt;p&gt;After you’ve finished testing and exploring your serverless URL shortener, you should clean up your AWS resources to avoid ongoing charges.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Clean Up:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Delete the DynamoDB Table:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;DynamoDB&lt;/strong&gt; in the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;URLShortener&lt;/code&gt; table, and click &lt;strong&gt;Delete&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Delete the Lambda Function:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Lambda&lt;/strong&gt; in the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;URLShortenerFunction&lt;/code&gt; function, and click &lt;strong&gt;Delete&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Delete the API Gateway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;API Gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select the API you created, and click &lt;strong&gt;Delete&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we’ve built a simple yet scalable serverless URL shortener using AWS Lambda, API Gateway, and DynamoDB. This solution is lightweight and fully serverless, which means you only pay for the compute power you use and the resources you consume.&lt;/p&gt;

&lt;p&gt;We covered the following key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt; for storing short codes and URLs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Lambda&lt;/strong&gt; for handling the logic of generating short codes and redirecting users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt; to expose HTTP routes and connect the Lambda functions to the web.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this knowledge, you can build other serverless applications using AWS services. Feel free to explore further and enhance this project by adding features like analytics, user authentication, or custom domains.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;Feel free to contribute to this project by opening issues or submitting pull requests. Here’s how you can help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new features or improve existing ones.&lt;/li&gt;
&lt;li&gt;Write documentation or tutorials.&lt;/li&gt;
&lt;li&gt;Fix bugs or optimize the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out the repository: &lt;a href="https://github.com/its-tapas/KloudBuilder/tree/main/Level-2/*%5BMini%20Project%5D%20Serverless%20URL%20Shortener" rel="noopener noreferrer"&gt;GitHub - [Mini Project] Serverless URL Shortener&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>dynamodb</category>
      <category>awscommunitybuilder</category>
    </item>
    <item>
      <title>Embracing the AWS Community: Unpacking My AWS Community Builder Welcome Swag Kit 🚀</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Tue, 26 Dec 2023 14:19:58 +0000</pubDate>
      <link>https://dev.to/aws-builders/embracing-the-aws-community-unpacking-my-aws-community-builder-welcome-swag-kit-5d1l</link>
      <guid>https://dev.to/aws-builders/embracing-the-aws-community-unpacking-my-aws-community-builder-welcome-swag-kit-5d1l</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdb1ubocds14vnbboqbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdb1ubocds14vnbboqbt.png" alt="Swag Setup" width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Hello fellow developers and AWS enthusiasts! I am beyond excited to share my recent experience as a proud recipient of the AWS Community Builder 1st Welcome Swag Kit! 🙌 The joy was doubled as I had the incredible honor of not only receiving the standard welcome kit but also winning two extra premium swags - the "T-shirt of Building" and the "Builder Hoodie of Protection" in a thrilling trivia and movie guessing contest hosted by the amazing Jason Dunn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the AWS Community Builder Program?
&lt;/h2&gt;

&lt;p&gt;For those unfamiliar with the AWS Community Builder Program and its offerings, you can find more details &lt;a href="https://lnkd.in/dJ6CgNpW" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This vibrant community is designed for developers and enthusiasts to learn, connect, and collaborate on all things AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Swag Unveiling
&lt;/h2&gt;

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

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

&lt;p&gt;Let me take you through the contents of the welcome swag kit, which included a diary and pen for note-taking, a sleek tumbler for those long coding sessions, a collection of vibrant stickers to personalize my workspace, AWS badges that symbolize my commitment to the community, and handy sticky notes for quick reminders. Each item is not just a swag but a thoughtful addition to my developer's toolkit.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Premium Bonus Swags
&lt;/h2&gt;

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

&lt;p&gt;As if the welcome kit wasn't exciting enough, the first welcome call meeting challenges brought an extra layer of fun and rewards. I am proud to say that I emerged victorious, earning not one but two premium bonus swags. The "Builder Hoodie of Protection" is a comfy, ultra-soft, and incredibly stylish addition to my wardrobe, while the "T-shirt of Building" is another badge of honor that I wear with pride.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fun and Learning with Jason Dunn
&lt;/h2&gt;

&lt;p&gt;A significant highlight of this journey was the engaging trivia and movie guessing contest hosted by Jason Dunn. It was not only a blast but also a fantastic opportunity to showcase our knowledge, connect with fellow community members, and, of course, win those coveted premium swags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Showcase
&lt;/h2&gt;

&lt;p&gt;For a closer look at these fantastic swags, I've put together a video. Check it out &lt;a href="https://lnkd.in/dyQJyrsH" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expressing Gratitude
&lt;/h2&gt;

&lt;p&gt;A heartfelt thank you to Amazon Web Services (AWS), Jason Dunn, Shafraz Rahim, and all other community managers for orchestrating this wonderful experience and providing these amazing goodies! 🎉 Your efforts are truly appreciated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Being part of the AWS Community Builder Program has been an enriching experience, and the welcome swag kit, along with the bonus premium swags, serves as a tangible symbol of the warmth and camaraderie within the AWS community. I eagerly anticipate continued learning, connecting, and collaborating with fellow developers.&lt;/p&gt;

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

</description>
      <category>swags</category>
      <category>aws</category>
      <category>developers</category>
      <category>awscommunitybuilders</category>
    </item>
    <item>
      <title>Project - Implement Blue/Green deployment of Python (Django) Application on AWS Elastic Beanstalk</title>
      <dc:creator>Tapas SInghal</dc:creator>
      <pubDate>Fri, 06 Oct 2023 13:47:30 +0000</pubDate>
      <link>https://dev.to/aws-builders/project-implement-bluegreen-deployment-of-python-django-application-on-aws-elastic-beanstalk-4k9f</link>
      <guid>https://dev.to/aws-builders/project-implement-bluegreen-deployment-of-python-django-application-on-aws-elastic-beanstalk-4k9f</guid>
      <description>&lt;h1&gt;
  
  
  buddydome
&lt;/h1&gt;

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

&lt;p&gt;Result:- &lt;a href="www.buddydome.cloud"&gt; &lt;/a&gt;&lt;a href="http://www.buddydome.cloud" rel="noopener noreferrer"&gt;www.buddydome.cloud&lt;/a&gt; &lt;br&gt;
Github Repo:-&lt;a href="https://github.com/its-tapas/buddydome" rel="noopener noreferrer"&gt; &lt;/a&gt;&lt;a href="https://github.com/its-tapas/buddydome" rel="noopener noreferrer"&gt;https://github.com/its-tapas/buddydome&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt; Major AWS Services used :- &lt;/p&gt;
&lt;ul&gt;

&lt;li&gt;RDS&lt;/li&gt;

&lt;li&gt;S3&lt;/li&gt;

&lt;li&gt;ELASTICBEANSTALK&lt;/li&gt;

&lt;li&gt;ROUTE53&lt;/li&gt;




&lt;/ul&gt;

&lt;h1&gt;
  
  
  Step-1: Create an AWS database instance of postgreSql database  ( Compulsory in both )
&lt;/h1&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    -Login to AWS console and head toward for RDS Service
    -Launch an Postgresql Database instance and note down the username,master username and password of the instance ( it will be shown one time only so make sure to note them down very carefully)
    -Wait for the database instance to be in running state ( Takes approximately 10 min)
    -After Launched, click on the instance and it will show the details of your database
    -Open Django project's Settings.py file, there you will see a section "DATABASE" IN LINE 85 
          &amp;gt;&amp;gt;&amp;gt; Change name to the username to saved earlier
          &amp;gt;&amp;gt;&amp;gt; Change Username to master username
          &amp;gt;&amp;gt;&amp;gt; Change Password to new Password
          &amp;gt;&amp;gt;&amp;gt; Change Host to new host which is shown exactly on aws console database instance page
    -SAVE CHANGES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Step-2: (Follow only if you are working with BuddyDome with s3 only otherwise ignore this step) Setting up S3 bucket
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Create an s3 bucket ( with unchecking the box of " Block all public access" ) &lt;br&gt;&lt;br&gt;
Change the bucket policy as follows &lt;br&gt;&lt;br&gt;
   //S3 Policy//&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3-bucket/*"
        }
    ]
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Create an IAM user&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;gt;&amp;gt;&amp;gt;In AWS Look for IAM service 
        &amp;gt;&amp;gt;&amp;gt;Create an IAM user with S3 Policy
        &amp;gt;&amp;gt;&amp;gt;Generate Access key and secret key and note them down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Go to your Django project and first install two libraries using following command &lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         pip install boto3 django-storages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Add Following in settings.py file&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          import boto3
          from storages.backends.s3boto3 import S3Boto3Storage


          INSTALLED_APPS = [ 
                  'storages'
                  ]

          //Write Corresponding Values//
          AWS_ACCESS_KEY_ID =
          AWS_SECRET_ACCESS_KEY = 
          AWS_STORAGE_BUCKET_NAME = 
          AWS_S3_REGION_NAME='ap-south-1'

          AWS_QUERYSTRING_AUTH = False


          # Set the static files storage backend to S3
          STATICFILES_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"

          # Set the URL for static files
          STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/"

          AWS_LOCATION = 'media'

          DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

          # Set the URL for media files
          MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{AWS_LOCATION}/"

          STATIC_ROOT = "https://s3.amazonaws.com/my-static-bucket/"
          MEDIA_ROOT = "https://s3.amazonaws.com/my-media-bucket/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Some Changes in all urls.py file &lt;br&gt;&lt;br&gt;
    //urls.py//&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          from Buddy import settings
          from django.conf.urls.static import static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;//In URL_patterns ending Square bracket Add below code as it is//&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;           +static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Step-3: Deployment Using AWS Elastic Beanstalk( Compulsory in Both)
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Install Elastic Beanstalk CLI using following:-&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     pip install awsebcli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Create a Config file to speicify settings file and .conf file to specify upload limit for your elasticbeasntalk environment in following format&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ~/BuddyDome/
    |-- .ebextensions
    |   `-- django.config
    |-- .platform
    |   --nginx
    |        --conf.d
    |                `--proxy.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Write the following in django.config file&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    container_commands:
      01_collectstatic:
        command: "source $PYTHONPATH/activate &amp;amp;&amp;amp; python manage.py collectstatic --noinput"
    option_settings:
      aws:elasticbeanstalk:container:python:
        WSGIPath: Buddy.wsgi:application
      aws:elasticbeanstalk:environment:proxy:staticfiles:
        static: "static"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Write the Following in proxy.conf&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In terminal initialize the application for elasticbeanstalk using awsebcli &lt;br&gt;&lt;br&gt;
Make sure you are in main directory where you can access manage.py file ( Use dir or ls command to verify)&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

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

    Select a default region 
    (Default is 3): 6  

    application name: Buddydome

    Enter Application Name
    (default is "BuddyDome "): BuddyDome

    Select a platform
    (make a selection): 9       //Python

    Select a platform branch. 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In Terminal Create Elastic beanstalk environment:- &lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    eb create Buddydome-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;use the following to get the status and to open the deployed application:-&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Use the following only in case you make some changes after environment creation&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    eb deploy&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Step-4 : Setting Up DNS (Route53 and Hostinger)&lt;br&gt;
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Go to Route53 and create a "Hosted Zone" with corresponding Hostinger domain name ( e.g. buddydome.cloud) &lt;/li&gt;
&lt;li&gt;Change Hostinger Nameservers to Route53 Generated Nameservers (changes might take upto 24hr)&lt;/li&gt;
&lt;li&gt;In Hosted Zone, create a "A" type Record 
        &lt;ul&gt;
&lt;li&gt;Leave Subdomain as blank&lt;/li&gt;
&lt;li&gt;Toggle "Alias"&lt;/li&gt;
&lt;li&gt;In Endpoint, choose Alias to "Elastic Beanstalk environment"&lt;/li&gt;
&lt;li&gt;CHoose Corresponding Region, ap-south-1 "Asia Pacific (Mumbai)" &lt;/li&gt;   
&lt;li&gt;Choose Environment, select the corresponding elasticbeanstalk environment that directs to Buddydome Project&lt;/li&gt;
 
Click "Add another record" 
       &lt;li&gt; &amp;gt; &amp;gt; Write "www" in subdomain&lt;/li&gt;
       &lt;li&gt; &amp;gt; &amp;gt; Choose Type as "CNAME"&lt;/li&gt;
       &lt;li&gt; &amp;gt; &amp;gt; In Value write original domain i.e. buddydome.cloud&lt;/li&gt;

&lt;li&gt; Click "Create Records" &lt;/li&gt;
        &lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note:- You can add more subdomains similarly by adding another record &lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
With this your application has been successfully deployed and hosted with a Domain&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>django</category>
      <category>elasticbeanstalk</category>
    </item>
  </channel>
</rss>
