<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Learn with Jyothish]]></title><description><![CDATA[Learn with Jyothish]]></description><link>https://blog.meetjyothish.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 02:21:53 GMT</lastBuildDate><atom:link href="https://blog.meetjyothish.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building and Deploying a Portfolio Website on Azure Static Web Apps with Terraform and GitHub Actions]]></title><description><![CDATA[I wanted to find a way to practice my Azure and Terraform skills. What better way than to build a production-ready website and finally put my theoretical knowledge into action?
My main goal was to learn how to use Terraform to deploy resources to Azu...]]></description><link>https://blog.meetjyothish.com/building-and-deploying-a-portfolio-website-on-azure-static-web-apps-with-terraform-and-github-actions</link><guid isPermaLink="true">https://blog.meetjyothish.com/building-and-deploying-a-portfolio-website-on-azure-static-web-apps-with-terraform-and-github-actions</guid><category><![CDATA[Azure]]></category><category><![CDATA[github-actions]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[Azure Static Web Apps]]></category><dc:creator><![CDATA[Jyothish]]></dc:creator><pubDate>Sat, 12 Jul 2025 22:52:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752362364582/8d07e1d2-24a2-401c-8075-379f8435f119.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I wanted to find a way to practice my Azure and Terraform skills. What better way than to build a production-ready website and finally put my theoretical knowledge into action?</p>
<p>My main goal was to learn how to use Terraform to deploy resources to Azure. However, along the way, I picked up more useful tools and skills than I expected, from generating frontends with AI to setting up a basic CI/CD pipeline using GitHub Actions.</p>
<p>By the end of this blog, you'll learn how I:</p>
<ul>
<li><p>Deployed my portfolio website <a target="_blank" href="https://meetjyothish.com/">meetjyothish.com</a> to <strong>Azure Static Web Apps</strong> using <strong>Terraform</strong>.</p>
</li>
<li><p>Integrated my Static Web App with GitHub repository and set up a streamlined CI/CD pipeline using GitHub Actions and the Azure CLI.</p>
</li>
<li><p>Created a clean and modern frontend with <a target="_blank" href="https://lovable.dev/?via=jyothish"><strong>lovable.dev</strong>.</a></p>
</li>
<li><p>Utilized <strong>VS Code</strong> and <strong>GitHub Copilot</strong> to build the website to be a production ready portfolio.</p>
</li>
</ul>
<p>In my next blog post, I’ll walk through how I integrated Azure Functions into my site to track visitor counts. I’ll also show how I used an Azure Function to handle a contact form, which sends the submitted details to my email via the Mailersend API whenever someone requests an interview. Lastly, I’ll explain how I set up real-time notifications for new visitor IPs and locations using Azure Functions in combination with the ipinfo API.</p>
<p>If you want to try this, check out this link to sign up for Lovable AI and start building your portfolio.</p>
<p>Affiliate link - <a target="_blank" href="https://lovable.dev/?via=jyothish">https://lovable.dev/?via=jyothish</a></p>
<hr />
<h2 id="heading-generating-a-frontend-with-lovabledev">Generating a Frontend with Lovable.dev</h2>
<p>I wanted to make sure my portfolio website was running locally before deploying anything to Azure. I had heard about a few AI-based website generators, and after trying a couple, I found that <a target="_blank" href="http://lovable.ai/">lovable.</a>dev gave me the cleanest UI out of the box.</p>
<p>I signed up for the free version (since I wasn't planning to scale the website or make anything super complex) and started working on my first prompt.</p>
<p><strong>Pro Tip:</strong> <a target="_blank" href="https://lovable.dev/?via=jyothish">Lovable.dev</a> only gives you <strong>5 prompts per day</strong> — so make them count. I didn’t realize this at first and burned through them quickly. I had to work with the result I got, which meant I spent quite a bit of time later tweaking the frontend to fit my needs 😅.</p>
<p>Instead of deep diving into prompt engineering guides, I just opened Notepad and wrote down what I wanted my website to look like. Then, I asked ChatGPT to turn that into a proper prompt for <a target="_blank" href="http://Lovable.AI">Lovable.AI</a>.</p>
<p>Here’s an example of the prompt it helped me create:</p>
<blockquote>
<p>“Help me create a professional and sleek portfolio web app. I will attach my resume for reference to build the content around my experience and skills. The overall design should reflect a modern vibe, but still remain clean, simple, and visually attractive.”</p>
</blockquote>
<h3 id="heading-sections-amp-features-i-asked-for">Sections &amp; Features I Asked For:</h3>
<ul>
<li><p><strong>Hero section</strong>: My name, a headline, and a short summary</p>
</li>
<li><p><strong>About Me</strong> section</p>
</li>
<li><p><strong>Projects</strong>: With GitHub links and project descriptions</p>
</li>
<li><p><strong>Contact</strong>: A simple form or mailto link</p>
</li>
<li><p><strong>Dark/Light mode toggle</strong></p>
</li>
<li><p><strong>Responsive design</strong> (mobile + desktop)</p>
</li>
<li><p><strong>Modern fonts</strong> like Inter or Roboto</p>
</li>
<li><p><strong>Clean code structure</strong> so I could edit it later</p>
</li>
</ul>
<p>Once you’re happy with the results on <a target="_blank" href="https://lovable.dev/?via=jyothish">Lovable</a>, you still have 4 prompts left per day, so feel free to use them to tweak layout, copy, or fix issues. Once satisfied, click the <strong>GitHub icon</strong> at the top right, choose <strong>“Connect GitHub,”</strong> and follow the steps. This will create a new GitHub repo and push the full codebase there.</p>
<p>After that, clone the repo to your local machine using VS Code and start fine-tuning the website to fit your exact needs. If you prefer to continue working with Lovable website, you can do so with further prompts. But i decided to do the rest of dev on my own locally.</p>
<hr />
<h2 id="heading-setting-up-the-local-dev-environment-in-vs-code">Setting Up the Local Dev Environment in VS Code</h2>
<p>The code generated by Lovable was written in React, so before making any changes, I had to:</p>
<ul>
<li><p>Install <strong>Node.js</strong> and <strong>npm</strong></p>
</li>
<li><p>Set up the local development environment using <strong>Vite</strong> (as the build tool and dev server)</p>
</li>
<li><p>Run the project locally using <code>npm run dev</code></p>
</li>
</ul>
<p>Once I had the site running locally, I started cleaning up unnecessary Lovable artifacts. For example:</p>
<ul>
<li><p>The <strong>favicon</strong> and branding used the default Lovable logo ,I replaced this with a simple logo I created for my site.</p>
</li>
<li><p>I rewrote <code>index.html</code> to include custom <strong>meta tags</strong> for social previews, so when I shared my website link, it would show my own branding.</p>
</li>
<li><p>I used <strong>GitHub Copilot</strong> to help me identify and clean up parts of the code, though at one point it broke the layout , so I rolled back the changes using Git revert.</p>
</li>
</ul>
<h3 id="heading-pro-tip">Pro Tip:</h3>
<p>Track all your changes with Git! It saved me more than once when Copilot made suggestions that seemed right but didn’t work as expected.</p>
<p>Once I finished cleaning things up, I asked Copilot to do a quick pass through the code and flag any <strong>potential security issues</strong>. I'm not a full-time web dev, so I wanted to make sure I wasn't exposing anything critical . especially since I might integrate APIs or backend services later.</p>
<p>After I was satisfied with my website locally, I proceeded to work on my Terraform code to deploy it to Azure Static Web Apps using GitHub Actions. I ensured that I had the following installed:</p>
<ul>
<li><p>Azure CLI</p>
</li>
<li><p>Terraform</p>
</li>
<li><p>Active subscription ID and tenant ID</p>
</li>
</ul>
<p>To log in to your Azure subscription, use the following command:</p>
<pre><code class="lang-bash">az login
</code></pre>
<p>Once logged in, I developed the following code. Refer to the Terraform registry if you plan to deploy something else.</p>
<p><a target="_blank" href="http://main.tf"><strong>main.tf</strong></a></p>
<pre><code class="lang-plaintext">resource "azurerm_resource_group" "rg" {
  name     = "rg-${var.application_name}-${var.environment_name}"
  location = var.primary_location
}

resource "azurerm_static_web_app" "webapp" {
  name                = "WebApp-${var.application_name}-${var.environment_name}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  repository_url      = "your github url"
  repository_branch   = "main"
  repository_token    = var.github_token
}
</code></pre>
<p><strong>Note:</strong> It is recommended to use environment variables for tokens and tenant ID/subscription ID if you plan to do this in production.</p>
<p><strong>terraform.tfvars</strong></p>
<pre><code class="lang-plaintext">application_name = "portfolio"
environment_name = "Prod"
primary_location = "centralus"
github_token     = "github_yourtoken"
subscription_id  = "yoursubid"
tenant_id        = "yoursubtenantid"
</code></pre>
<p><a target="_blank" href="http://versions.tf"><strong>versions.tf</strong></a></p>
<pre><code class="lang-plaintext">terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~&gt; 4.30.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~&gt; 3.5.1"
    }
  }
}

provider "azurerm" {
  features {}
  subscription_id = var.subscription_id
}
</code></pre>
<p><a target="_blank" href="http://variables.tf"><strong>variables.tf</strong></a></p>
<pre><code class="lang-javascript">variable <span class="hljs-string">"application_name"</span> {
  type = string
}

variable <span class="hljs-string">"environment_name"</span> {
  type = string
}

variable <span class="hljs-string">"primary_location"</span> {
  type = string
}

variable <span class="hljs-string">"github_token"</span> {
  type        = string
  description = <span class="hljs-string">"GitHub Personal Access Token for repository access"</span>
}

variable <span class="hljs-string">"subscription_id"</span> {
  type = string
}

variable <span class="hljs-string">"tenant_id"</span> {
  type        = string
  description = <span class="hljs-string">"Azure Tenant ID"</span>
}

# NOTE: Ensure sensitive information like your Azure Subscription ID, Tenant ID, and GitHub Tokens 
# are NOT hardcoded <span class="hljs-keyword">in</span> your Terraform files or checked into version control. Instead, use 
# environment variables or a secure vault (e.g., Azure Key Vault, HashiCorp Vault) to store these values
</code></pre>
<p>After installing Terraform, run the following commands:</p>
<pre><code class="lang-bash">terraform init
terraform plan
terraform apply
</code></pre>
<p>This will create your Azure Static Web App. You can log in to the Azure portal at <a target="_blank" href="http://portal.azure.com">portal.azure.com</a> to verify that your web app is live. You will receive a fully qualified domain name (FQDN) that you can use to view the site online.</p>
<p><strong>Note:</strong> After deploying with Terraform, my Static Web App didn’t automatically create a GitHub Actions workflow, likely due to a missing or invalid <code>repository_token</code>. To fix this, I manually ran the following command to link the GitHub repo and generate the workflow file:</p>
<pre><code class="lang-bash">az staticwebapp update --name WebApp-portfolio-Prod --branch main --<span class="hljs-built_in">source</span> https://github.com/yourpath-to/repo --token ghh-yorutoken --output jsonc
</code></pre>
<p>This created a YAML file in GitHub repository under <code>.github/workflows</code>. This file is used by GitHub Actions to define CI/CD pipeline.</p>
<p>At this point, if the YAML file automatically created by Azure is correct, it should automatically build and deploy your website to Azure Static Web Apps. I encountered an issue where it couldn't find the location of my code because I was using Vite, and my <code>app_artifact_location</code> was <code>dist</code>.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">app_artifact_location:</span> <span class="hljs-string">dist</span>
</code></pre>
<p>After adding this to the YAML file, it proceeded to run my actions, and my website was live. after this i could make changes, and every changes were reflected on my Production site, after i commit changes to my remote repo, since Github Actions will automatically deploy the changed code for me.</p>
]]></content:encoded></item></channel></rss>