From Zero to Live: Building My Blog with Infrastructure as Code

How I went from "what's a pipeline?" to deploying a live website - and why you should try it too
What you'll learn: A real-world journey from IaC beginner to deployed blog, including the mistakes, victories, and practical steps that got me there.

Three weeks ago, if you had told me I'd be writing a blog post about Infrastructure as Code (IaC), I would have laughed. Not because I didn't want to learn it, but because it seemed like this mysterious, complex thing that only seasoned DevOps engineers could master.

I was wrong. Very wrong.

This blog you're reading right now? It's deployed using Azure Static Web Apps, managed with Bicep templates, and automatically deployed through GitHub Actions. And honestly, if I can build this, anyone can.

Why I Decided to Take the Plunge

I've been working on various development projects using my Azure free credits, but I was getting tired of clicking through the Azure portal every time I wanted to deploy something. More importantly, I kept hearing about Infrastructure as Code from our DevOps team at work, and I wanted to understand what they were talking about when they mentioned "pipelines" and "deployment automation."

The final push came when one of our DevOps engineers (shoutout to you if you're reading this!) explained how IaC could save me hours of manual work while making my deployments more reliable. He was right, but the learning curve felt intimidating.

I decided to start with a personal blog project - something visible and rewarding that would force me to learn the fundamentals without the pressure of a work deadline.

The Stack: Keeping It Simple but Powerful

After some research, I settled on a stack that seemed approachable for a beginner:

The beauty of this setup? Everything integrates naturally, and most of it is free for personal projects.

Setting Up the Foundation

The Service Principal Dance

Before diving into code, I needed to set up authentication between GitHub and Azure. This involves creating a "service principal" - essentially a robot user that GitHub can use to deploy resources on your behalf.

az ad sp create-for-rbac \
  --name "github-actions-personal-blog" \
  --role contributor \
  --scopes /subscriptions/{your-subscription-id} \
  --sdk-auth

The output is a JSON blob that goes into your GitHub repository secrets as AZURE_CREDENTIALS. Simple enough, though it took me a few tries to get the permissions right.

Repository Structure

I organized my project like this:

my-blog/
├── .github/workflows/deploy.yml    # The automation magic
├── infrastructure/main.bicep       # Infrastructure definition
├── src/index.html                  # The actual blog content
└── README.md                       # Documentation

Clean and straightforward - exactly what you want when learning something new.

The Real Learning: When Things Go Wrong

Challenge #1: Decoding GitHub Actions Logs

My first deployment failed spectacularly. The GitHub Actions log showed this cryptic error:

ERROR: "RepositoryUrl is invalid. The repository url must use HTTPS."

At first, I panicked. Then I realized this was exactly the kind of problem-solving that makes you a better developer. I started reading the logs more carefully and discovered that GitHub's github.repositoryUrl variable returns an SSH URL (git@github.com:user/repo.git), but Azure Static Web Apps expects HTTPS (https://github.com/user/repo.git).

The fix was simple:

# Convert SSH URL to HTTPS format
REPO_URL="https://github.com/${{ github.repository }}.git"

The lesson was valuable: Error messages aren't scary - they're clues. Learning to read deployment logs is a superpower.

Challenge #2: Security Warnings

My Bicep template initially had these outputs:

output repositoryToken string = staticWebApp.listSecrets().properties.repositoryToken
output deploymentToken string = staticWebApp.listSecrets().properties.apiKey

The deployment warned me that outputs shouldn't contain secrets. Fair point! I learned to retrieve secrets during the deployment process instead of exposing them in template outputs.

These weren't roadblocks - they were learning opportunities that made me understand the security considerations behind IaC.

The Bicep Template: Infrastructure as Code in Action

Here's the core of my infrastructure definition:

resource staticWebApp 'Microsoft.Web/staticSites@2022-09-01' = {
  name: staticWebAppName
  location: location
  sku: {
    name: 'Free'
    tier: 'Free'
  }
  properties: {
    repositoryUrl: repositoryUrl
    branch: branch
    buildProperties: {
      appLocation: appLocation
      apiLocation: apiLocation
      outputLocation: outputLocation
    }
    stagingEnvironmentPolicy: 'Enabled'
  }
}

What I love about this: it's declarative. I'm describing what I want, not how to create it. Azure figures out the implementation details.

The GitHub Actions Pipeline: Automation Magic

My deployment workflow does three main things:

  1. Validates the infrastructure before deploying
  2. Deploys the Azure resources
  3. Publishes the website content

The validation step was a game-changer for me:

- name: What-If Analysis
  run: |
    az deployment group what-if \
      --resource-group ${{ env.AZURE_RESOURCE_GROUP }} \
      --template-file infrastructure/main.bicep \
      --parameters repositoryUrl="$REPO_URL"

This shows exactly what changes will be made before making them. It's like having a safety net for your infrastructure changes.

The Moment of Truth

After fixing those initial hiccups, I pushed my code to the main branch and watched the GitHub Actions tab like a hawk.

Green checkmarks across the board.

Then I clicked the deployment URL and saw my blog live on the internet with an SSL certificate and everything. That feeling of seeing your code running in the cloud? Absolutely incredible.

What I Actually Learned

Technical Skills

Mindset Shifts

Resources That Made This Possible

I couldn't have done this without some excellent learning materials:

Microsoft Learn's Bicep modules - Comprehensive but approachable
GitHub Actions documentation - Better than I expected for getting started
Azure Static Web Apps quickstarts - Perfect for understanding the basics
PetterTech on YouTube - Excellent, easy-to-understand content around DevOps and development concepts with a specific focus on Azure
Our DevOps team at work - Patient mentoring makes all the difference

Special thanks to my own personal Brent who introduced me to these concepts and encouraged me to dive in. Having someone to ask "probably dumb" questions made this journey so much smoother.

What's Next: Phase 2 and Beyond

This blog is just the beginning. I'm already planning to add:

The foundation is solid, and adding features will be an opportunity to learn more advanced IaC patterns.

Why You Should Try This Too

If you're a developer who's been curious about DevOps but felt intimidated, I want to tell you something: you already have most of the skills you need.

You understand code structure, debugging, and problem-solving. IaC is just applying those same skills to infrastructure management. The concepts that seemed foreign three weeks ago now feel like natural extensions of development practices I already knew.

And if you're not a developer - if you're a sysadmin like me who's transitioned into security engineering, spending your days wrangling PowerShell scripts and Python automation - you're actually closer than you think. Every time you've automated a repetitive task, standardized a deployment process, or written a script to configure multiple servers consistently, you've been thinking in Infrastructure as Code principles. You just didn't call it that.

The jump from "I automate my daily tasks" to "I define my infrastructure in code" is smaller than it appears. You already understand the pain points IaC solves because you've lived them.

Start small. Pick a simple project like a static website. Use the free tiers. Break things. Fix them. Learn from the error messages.

Most importantly, don't let perfect be the enemy of good. My first deployment failed. My Bicep template had security warnings. My workflow needed multiple iterations. That's not failure - that's learning.

The Real Victory

The best part about this project isn't the working blog (though I'm pretty proud of it). It's the confidence that comes from demystifying something that seemed impossibly complex just a few weeks ago.

Now when our DevOps team talks about deployment pipelines and infrastructure automation, I don't just nod along - I actually understand what they're discussing. Better yet, I can contribute to those conversations.

That's the real power of hands-on learning.