<?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: PRASANTH M</title>
    <description>The latest articles on DEV Community by PRASANTH M (@prasanth_m_d5eace61d54857).</description>
    <link>https://dev.to/prasanth_m_d5eace61d54857</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4125471%2F94eddb62-9a99-4d88-aa60-200d83b615db.jpg</url>
      <title>DEV Community: PRASANTH M</title>
      <link>https://dev.to/prasanth_m_d5eace61d54857</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prasanth_m_d5eace61d54857"/>
    <language>en</language>
    <item>
      <title>CLOUD WORKSHOP DAY 1 SESSION 1</title>
      <dc:creator>PRASANTH M</dc:creator>
      <pubDate>Tue, 15 Sep 2026 08:49:20 +0000</pubDate>
      <link>https://dev.to/prasanth_m_d5eace61d54857/cloud-workshop-day-1-session-1-3o51</link>
      <guid>https://dev.to/prasanth_m_d5eace61d54857/cloud-workshop-day-1-session-1-3o51</guid>
      <description>&lt;h1&gt;
  
  
  I Built and Deployed My First Portfolio on AWS S3 + CloudFront — And Broke It Along the Way
&lt;/h1&gt;

&lt;p&gt;As an M.Sc Artificial Intelligence and Machine Learning student, I've been trying to move away from just &lt;strong&gt;writing code by following tutorials&lt;/strong&gt; and actually understand how things work by building and deploying projects.&lt;/p&gt;

&lt;p&gt;One of the things I wanted to build was a simple personal portfolio.&lt;/p&gt;

&lt;p&gt;It sounded easy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a portfolio → upload it to AWS → get a public URL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It wasn't quite that simple.&lt;/p&gt;

&lt;p&gt;I ran into permissions issues, S3 configuration problems, CloudFront errors, and eventually discovered that I had accidentally configured CloudFront to look for:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This is the story of how I built it, broke it, debugged it, and finally understood what was actually happening.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Starting With a Simple HTML Portfolio
&lt;/h2&gt;

&lt;p&gt;I initially created my portfolio using a single:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;I kept the design intentionally simple.&lt;/p&gt;

&lt;p&gt;The portfolio contained:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experience&lt;/li&gt;
&lt;li&gt;Selected Work&lt;/li&gt;
&lt;li&gt;Skills&lt;/li&gt;
&lt;li&gt;Education&lt;/li&gt;
&lt;li&gt;Contact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the projects I included were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BloodBridge — intelligent blood donor matching platform&lt;/li&gt;
&lt;li&gt;CITYMIND — a digital twin for city decisions&lt;/li&gt;
&lt;li&gt;IPL Match Winner Prediction&lt;/li&gt;
&lt;li&gt;Rural Water Monitoring and Transparency System&lt;/li&gt;
&lt;li&gt;Textile Hub — a B2B network for the textile trade&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, everything worked locally.&lt;/p&gt;

&lt;p&gt;I could simply open the HTML file in my browser and see the portfolio.&lt;/p&gt;

&lt;p&gt;But then I wanted to actually &lt;strong&gt;deploy it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Moving to AWS S3
&lt;/h2&gt;

&lt;p&gt;I decided to use Amazon S3 for hosting.&lt;/p&gt;

&lt;p&gt;I created an S3 bucket and uploaded my portfolio.&lt;/p&gt;

&lt;p&gt;The object looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s3://portfolio-prasanth/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My first assumption was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The file is uploaded, so anyone should be able to open it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That assumption was wrong.&lt;/p&gt;

&lt;p&gt;When I tried accessing the website, I received:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Error&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Code&amp;gt;&lt;/span&gt;AccessDenied&lt;span class="nt"&gt;&amp;lt;/Code&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Message&amp;gt;&lt;/span&gt;Access Denied&lt;span class="nt"&gt;&amp;lt;/Message&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Error&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. First Struggle — S3 AccessDenied
&lt;/h2&gt;

&lt;p&gt;This was my first real AWS deployment problem.&lt;/p&gt;

&lt;p&gt;The HTML itself wasn't the issue.&lt;/p&gt;

&lt;p&gt;The problem was with &lt;strong&gt;S3 permissions and website access configuration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I had to understand the relationship between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;S3 Bucket
    ↓
Object
    ↓
Permissions
    ↓
Static Website Hosting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I configured static website hosting and worked through the public-access configuration and bucket policy.&lt;/p&gt;

&lt;p&gt;The important part of the bucket policy was allowing public &lt;code&gt;GetObject&lt;/code&gt; access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PublicReadGetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::portfolio-prasanth/*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But then I ran into another issue.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. My Bucket Name Wasn't What I Thought
&lt;/h2&gt;

&lt;p&gt;At one point I was working with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prasanth-portfolio-bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But when I looked at my AWS console, the actual bucket I was configuring was:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;That caused confusion while creating the bucket policy.&lt;/p&gt;

&lt;p&gt;AWS was telling me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Policy has invalid resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason was simple.&lt;/p&gt;

&lt;p&gt;The policy resource has to reference the &lt;strong&gt;actual bucket name&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arn:aws:s3:::portfolio-prasanth/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arn:aws:s3:::prasanth-portfolio-bucket/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was a small mistake, but it taught me something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't blindly copy AWS configuration. Understand what resource you're actually configuring.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Understanding the Static Portfolio Structure
&lt;/h2&gt;

&lt;p&gt;Since my portfolio is a single self-contained &lt;code&gt;index.html&lt;/code&gt; — HTML, CSS, and JavaScript all in one file, with a small canvas animation in the hero section — there was no build step involved. No &lt;code&gt;npm run build&lt;/code&gt;, no &lt;code&gt;dist/&lt;/code&gt; folder, no bundler.&lt;/p&gt;

&lt;p&gt;That turned out to be both a simplification and a lesson in itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index.html
     ↓
AWS S3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser doesn't need a server running to interpret my markup — it just needs a place that can serve the file over HTTP. S3 static website hosting does exactly that.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Adding CloudFront
&lt;/h2&gt;

&lt;p&gt;Then I wanted to put CloudFront in front of S3, mainly to get HTTPS and a CDN in front of the site rather than hitting the S3 website endpoint directly.&lt;/p&gt;

&lt;p&gt;The architecture became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌──────────────┐
                    │    Browser   │
                    └──────┬───────┘
                           │
                           ▼
                    ┌──────────────┐
                    │  CloudFront  │
                    └──────┬───────┘
                           │
                           ▼
                    ┌──────────────┐
                    │      S3      │
                    │   index.html │
                    └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the point where things got interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. The CloudFront 404 Error
&lt;/h2&gt;

&lt;p&gt;Instead of my portfolio, CloudFront returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;404 Not Found

Code: NoSuchKey

Message: The specified key does not exist.

Key: index.html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first I had no idea why AWS was asking for:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;My S3 bucket clearly contained:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;So I started looking at the CloudFront configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Finding the Actual Problem
&lt;/h2&gt;

&lt;p&gt;I checked the CloudFront origin configuration.&lt;/p&gt;

&lt;p&gt;And there it was.&lt;/p&gt;

&lt;p&gt;My origin looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Origin type: S3 static website
Origin path: /index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was the mistake.&lt;/p&gt;

&lt;p&gt;CloudFront already knew that the default root object was:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;And I had also told the origin to use:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;So CloudFront effectively ended up requesting:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;S3 obviously couldn't find that object.&lt;/p&gt;

&lt;p&gt;The error suddenly made sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Fix
&lt;/h2&gt;

&lt;p&gt;I changed the CloudFront origin path from:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(empty)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And kept the CloudFront default root object as:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;So the configuration became conceptually:&lt;br&gt;
&lt;/p&gt;

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

Default root object:
index.html

Origin:
portfolio-prasanth S3 website endpoint

Origin path:
(empty)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the request flow made sense:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
 ↓
CloudFront
 ↓
index.html
 ↓
S3
 ↓
portfolio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
 ↓
CloudFront
 ↓
index.html
 ↓
/index.html
 ↓
index.html/index.html ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. Why I Had to Invalidate CloudFront
&lt;/h2&gt;

&lt;p&gt;Even after fixing the configuration, CloudFront can still have cached responses.&lt;/p&gt;

&lt;p&gt;So I created a CloudFront invalidation:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This tells CloudFront to remove the cached objects so that the next request can fetch the updated content.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;The biggest thing I learned from this wasn't HTML or CSS.&lt;/p&gt;

&lt;p&gt;It wasn't even CloudFront.&lt;/p&gt;

&lt;p&gt;It was &lt;strong&gt;debugging&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before this, when something didn't work, my first instinct was often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The code must be wrong."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But this project showed me that problems can exist at completely different layers.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   ↓
Static files
   ↓
S3
   ↓
Permissions
   ↓
CloudFront
   ↓
Caching
   ↓
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A website can have perfectly valid markup and still return a 404 because the &lt;strong&gt;infrastructure configuration is wrong&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. My Struggles
&lt;/h2&gt;

&lt;p&gt;These were some of the problems I faced:&lt;/p&gt;

&lt;h3&gt;
  
  
  S3
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;I had to understand bucket permissions and public access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bucket policy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Policy has invalid resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was referencing the wrong bucket name.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudFront
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NoSuchKey
Key: index.html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had incorrectly configured the origin path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Account verification
&lt;/h3&gt;

&lt;p&gt;Before I could even create a CloudFront distribution, AWS returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your account must be verified before you can add new CloudFront resources.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New AWS accounts sometimes need manual verification through AWS Support before CloudFront resources can be created — a step I hadn't expected as part of "just hosting a webpage."&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Even after fixing the configuration, CloudFront could still serve an old cached response.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. What I Would Do Differently Next Time
&lt;/h2&gt;

&lt;p&gt;If I were starting this deployment again, my process would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Write and test the portfolio locally
        ↓
2. Upload index.html to S3
        ↓
3. Configure S3 static website hosting + bucket policy
        ↓
4. Verify AWS account (if needed) before touching CloudFront
        ↓
5. Configure CloudFront origin correctly the first time
        ↓
6. Test CloudFront
        ↓
7. Check logs/errors if something fails
        ↓
8. Invalidate cache when required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I would change one configuration at a time and test after each change.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Final Architecture
&lt;/h2&gt;

&lt;p&gt;The final concept I learned is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌───────────────────┐
                 │       User        │
                 └─────────┬─────────┘
                           │
                           ▼
                 ┌───────────────────┐
                 │     CloudFront    │
                 │       CDN         │
                 └─────────┬─────────┘
                           │
                           ▼
                 ┌───────────────────┐
                 │    S3 Bucket      │
                 │                   │
                 │   index.html      │
                 └───────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My portfolio is a single static file, served through AWS infrastructure and a CDN in front of it.&lt;/p&gt;




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

&lt;p&gt;This was a relatively small project, but it gave me something more valuable than just a portfolio.&lt;/p&gt;

&lt;p&gt;It gave me experience with the uncomfortable part of development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;things not working.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had to read errors, inspect configuration, understand what AWS was actually doing, find the mismatch, and fix it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;index.html/index.html&lt;/code&gt; error in particular was frustrating at first.&lt;/p&gt;

&lt;p&gt;But once I understood &lt;strong&gt;why&lt;/strong&gt; it happened, it became one of the most useful lessons from the project.&lt;/p&gt;

&lt;p&gt;I'm still learning AWS, machine learning, and software development, but I'm slowly trying to replace:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Copy the config and hope it works"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Understand what each component is doing, then debug when it doesn't."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I think that's a much better way to learn.&lt;/p&gt;




&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cloud&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon S3&lt;/li&gt;
&lt;li&gt;Amazon CloudFront&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python, PyTorch, TensorFlow, Scikit-learn&lt;/li&gt;
&lt;li&gt;React, TypeScript, Supabase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;Git/GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  aws #cloudfront #s3 #webdevelopment #javascript #beginners #devjourney #learninginpublic
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0m2rofw9mhzrtzdrt29r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0m2rofw9mhzrtzdrt29r.png" alt=" " width="800" height="450"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwr8dqybbaxfqwf6qdycf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwr8dqybbaxfqwf6qdycf.png" alt=" " width="800" height="450"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fatwp2jltfaxweitmklpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fatwp2jltfaxweitmklpa.png" alt=" " width="800" height="450"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft2x716wfbxs34hqcvxpy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft2x716wfbxs34hqcvxpy.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>cloud</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
