<?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: Devin</title>
    <description>The latest articles on DEV Community by Devin (@nullreturn).</description>
    <link>https://dev.to/nullreturn</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%2F3292298%2Fe7892538-1d0c-47e8-84b2-c7b57d1d0913.jpeg</url>
      <title>DEV Community: Devin</title>
      <link>https://dev.to/nullreturn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nullreturn"/>
    <language>en</language>
    <item>
      <title>🚀 The Cloud Resume Challenge My Journey to Cloud Mastery</title>
      <dc:creator>Devin</dc:creator>
      <pubDate>Wed, 25 Jun 2025 03:50:44 +0000</pubDate>
      <link>https://dev.to/nullreturn/the-cloud-resume-challenge-my-journey-to-cloud-mastery-18oc</link>
      <guid>https://dev.to/nullreturn/the-cloud-resume-challenge-my-journey-to-cloud-mastery-18oc</guid>
      <description>&lt;p&gt;As a technologist looking to build real world cloud skills, I took on the Cloud Resume Challenge: a project that tests and demonstrates core cloud knowledge through hands-on implementation. This challenge wasn't just about deploying a website; it was a full-spectrum journey through modern cloud infrastructure, tools, development practices, and operational procedures.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌩️ What is the Cloud Resume Challenge
&lt;/h2&gt;

&lt;p&gt;Created by Forrest Brazeal, the Cloud Resume Challenge is a real project that guides you through building and deploying a cloud-native resume website. It covers many core principles of cloud computing and DevOps workflows including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏗 Infrastructure as Code&lt;/li&gt;
&lt;li&gt;⚙️ Serverless architecture&lt;/li&gt;
&lt;li&gt;🎨 Frontend development&lt;/li&gt;
&lt;li&gt;🚀 CI/CD pipelines&lt;/li&gt;
&lt;li&gt;🌐 DNS setup&lt;/li&gt;
&lt;li&gt;🔐 Cloud security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to not just build a site, but to treat your resume like a real-world cloud application where security, automation, and scalability matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 My Stack and Architecture
&lt;/h2&gt;

&lt;p&gt;To complete this challenge I leveraged several AWS services as well as modern development tools. The architecture includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥 &lt;strong&gt;Frontend&lt;/strong&gt;: Static resume website built with HTML, Tailwind CSS, and JavaScript&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Hosting and Delivery&lt;/strong&gt;: Private S3 bucket with content served via CloudFront with HTTPS&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Backend&lt;/strong&gt;: AWS Lambda functions triggered via API Gateway to serve a dynamic visitor counter&lt;/li&gt;
&lt;li&gt;🗃 &lt;strong&gt;Database&lt;/strong&gt;: DynamoDB table to store and increment visitor count&lt;/li&gt;
&lt;li&gt;📜 &lt;strong&gt;Infrastructure&lt;/strong&gt;: Defined and provisioned using Terraform for repeatability and version control&lt;/li&gt;
&lt;li&gt;🤖 &lt;strong&gt;CI/CD Pipeline&lt;/strong&gt;: GitHub Actions to automate builds, testing, deployment, and cache invalidation&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;DNS Management&lt;/strong&gt;: Custom domain from PorkBun managed in Route 53 with alias records to CloudFront&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%2F974y3j568lr6okuun2ce.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%2F974y3j568lr6okuun2ce.png" alt="Cloud Architecture Diagram" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 The Build Step by Step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Resume with HTML and Tailwind
&lt;/h3&gt;

&lt;p&gt;I started with a simple static resume coded in HTML and styled using Tailwind CSS. Tailwind was chosen for its utility-first approach, which let me quickly build responsive layouts without writing much custom CSS. I implemented dark mode media query support and ensured the design worked well on mobile and desktop devices.&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%2F7f03xj16x22l1kvl6cu9.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%2F7f03xj16x22l1kvl6cu9.png" alt="Live Website Screenshot" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Hosting with S3 and CloudFront
&lt;/h3&gt;

&lt;p&gt;To securely host the static site, I created a private S3 bucket and blocked all public access. Using an Origin Access Identity (OAI), I configured CloudFront to act as the only trusted source that could pull content from the bucket. This ensures your content remains secure and only served through the CDN.&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%2Fz9sh69e8vrvugdeg2plz.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%2Fz9sh69e8vrvugdeg2plz.png" alt="S3 Bucket Settings" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ DNS Setup with Route 53 and PorkBun
&lt;/h3&gt;

&lt;p&gt;After registering my domain through PorkBun, I delegated DNS authority to AWS Route 53. I set up a hosted zone, created A records with alias targets pointing to the CloudFront distribution, and updated name servers in PorkBun.&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%2Fqy2cpe20y3hajh5o9jqt.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%2Fqy2cpe20y3hajh5o9jqt.png" alt="Route53 Hosted Zone" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣ Visitor Counter with Lambda and DynamoDB
&lt;/h3&gt;

&lt;p&gt;The visitor counter feature required backend logic. I wrote a Lambda function in Python which incremented a counter in DynamoDB and returned the updated count via API Gateway.&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="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;cloudresume-counter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;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;update_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;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;UpdateExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ADD views :incr&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ExpressionAttributeValues&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;:incr&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;ReturnValues&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;UPDATED_NEW&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;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;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Access-Control-Allow-Methods&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;GET&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;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;views&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Attributes&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;views&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  5️⃣ Lightweight Infrastructure Automation with Terraform
&lt;/h3&gt;

&lt;p&gt;While much of the infrastructure setup was done manually via the AWS Console to gain hands-on familiarity, I used &lt;strong&gt;Terraform selectively&lt;/strong&gt; to automate key backend services and streamline CI/CD integration.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚙️ What I Managed with Terraform:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;DynamoDB Table&lt;/strong&gt; to store the visitor count with on-demand billing&lt;/li&gt;
&lt;li&gt;🧬 &lt;strong&gt;Lambda Function&lt;/strong&gt; deployment, environment variables, and IAM execution role&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;API Gateway&lt;/strong&gt; setup with correct CORS configuration and route integration&lt;/li&gt;
&lt;li&gt;🔐 &lt;strong&gt;IAM Policies&lt;/strong&gt; for secure resource access&lt;/li&gt;
&lt;li&gt;🤖 &lt;strong&gt;CI/CD Support&lt;/strong&gt; via IAM credentials for GitHub Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach let me avoid repetitive manual setups for serverless and security components, while keeping the frontend (S3, CloudFront, Route 53) more visual and hands-on for learning.&lt;/p&gt;

&lt;h4&gt;
  
  
  🧩 Why Partial Terraform?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;I wanted to &lt;strong&gt;focus Terraform on areas where automation made the biggest impact&lt;/strong&gt;, such as API deployment and IAM security.&lt;/li&gt;
&lt;li&gt;This hybrid approach gave me &lt;strong&gt;better control during debugging&lt;/strong&gt; while still benefiting from repeatable deployments for Lambda and CI/CD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;terraform/&lt;br&gt;
├── main.tf              # Root module&lt;br&gt;
├── lambda.tf            # Lambda + IAM&lt;br&gt;
├── dynamodb.tf          # DynamoDB setup&lt;br&gt;
├── apigateway.tf        # API Gateway resources&lt;br&gt;
├── variables.tf         # Inputs&lt;br&gt;
├── outputs.tf           # Useful outputs like API endpoint&lt;br&gt;
├── lambda/&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6️⃣ Deployment Pipeline with GitHub Actions
&lt;/h3&gt;

&lt;p&gt;CI/CD was automated using GitHub Actions. The pipeline triggers on push to the main branch and includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing dependencies&lt;/li&gt;
&lt;li&gt;Building Tailwind CSS output&lt;/li&gt;
&lt;li&gt;Uploading files to S3 with AWS CLI&lt;/li&gt;
&lt;li&gt;Invalidating CloudFront cache&lt;/li&gt;
&lt;li&gt;Basic HTML linting checks&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%2F1ys89zily7tg726o6g0i.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%2F1ys89zily7tg726o6g0i.png" alt="GitHub Actions Run" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔒 Private S3 Access
&lt;/h3&gt;

&lt;p&gt;Configuring the correct permissions for private S3 access was tricky. I used the principle of least privilege and created an Origin Access Identity (OAI), then applied a bucket policy allowing only that OAI to read content.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 CORS Errors
&lt;/h3&gt;

&lt;p&gt;The Lambda API required correct CORS settings to work with the frontend JavaScript. I had to carefully set headers both in the AWS Console and in Terraform.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧼 Cache Invalidation
&lt;/h3&gt;

&lt;p&gt;Updates weren’t showing up due to CloudFront’s cache. I added an invalidation step to my GitHub Actions workflow to automatically purge the cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  📦 Terraform State
&lt;/h3&gt;

&lt;p&gt;I used an S3 backend and DynamoDB table for locking to manage Terraform state securely and avoid corruption.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 What I Learned
&lt;/h2&gt;

&lt;p&gt;This challenge helped me grow in many areas of cloud engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Build clean, fast UIs with Tailwind CSS&lt;/li&gt;
&lt;li&gt;🔐 Secure S3 buckets using OAI&lt;/li&gt;
&lt;li&gt;🌍 Use multiple DNS providers&lt;/li&gt;
&lt;li&gt;🛠 Modularize infrastructure with Terraform&lt;/li&gt;
&lt;li&gt;🤖 Automate deployments with GitHub Actions&lt;/li&gt;
&lt;li&gt;🧠 Build serverless functions&lt;/li&gt;
&lt;li&gt;📈 Debug cloud deployments using logs and state&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔭 Improvements Ahead
&lt;/h2&gt;

&lt;p&gt;Plans for future improvement include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡 Add AWS WAF for security&lt;/li&gt;
&lt;li&gt;📈 Monitor with CloudWatch Alarms&lt;/li&gt;
&lt;li&gt;🌐 Use multi-region CloudFront&lt;/li&gt;
&lt;li&gt;☁️ Use Terraform Cloud for state management&lt;/li&gt;
&lt;li&gt;📊 Add real-time user analytics&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;The Cloud Resume Challenge turned a simple website into a full-scale cloud project. It pushed me to adopt industry standards, automation, and good security practices.&lt;/p&gt;

&lt;p&gt;🔗 Live site: &lt;a href="https://godevtech.cloud" rel="noopener noreferrer"&gt; godevtech.cloud &lt;/a&gt; &lt;br&gt;
📂 GitHub repo: &lt;a href="https://github.com/DevHAXog/CRC-AWS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>awschallenge</category>
      <category>career</category>
      <category>cloudcomputing</category>
    </item>
  </channel>
</rss>
