Education

Education

Education

From Terraform to Bicep: A Comparison Deploying Azure Infrastructure

Comparing Terraform vs Bicep for Azure Infrastructure This started out as a technical task, evaluate Bicep vs Terraform but turned into a test of both tools in a hybrid IaC setup. ✅ Virtual WAN, DNS Resolver, Private DNS Zone with Bicep ✅ AKS cluster + app deployment + VPN integration with Terraform 🧠 A few learning curves and one mini CTO crash course along the way 😄 Whether you're already using one or weighing your options, I break down what worked, what didn’t, and where each tool shines.

Aman Karir

Tech Enthusiast

Over the past few months, I’ve been diving deeper into DevOps, focusing on Infrastructure as Code (IaC) and scalable architecture on Azure. (Don’t worry AWS, you’re still on my radar.). In one of my previous articles, I explored how I migrated a Node.js and MongoDB application into Azure Kubernetes Service (AKS) using Terraform and Docker. Terraform quickly became my go to for IaC: mature, multi cloud, and deeply integrated into the DevOps ecosystem.

Recently, I was asked to evaluate Bicep, Azure’s native IaC language, and compare it with Terraform. The goal was to build out a test environment for a secure VPN accessible AKS deployment, with DNS resolution of internal services via Virtual WAN, DNS resolver, and a private DNS zone.

Here’s a breakdown of my experience and the lessons I took from putting Bicep and Terraform head to head.

———————

Project Scope

The infrastructure I deployed in the test environment included:

  • 🔐 Virtual WAN & VPN User Gateway

  • 📛 Private DNS Zone for internal service names

  • 🌐 Azure DNS Resolver

  • 🧪 Private AKS Cluster (deployed with Terraform)

  • 🔗 VPN testing across VNets with internal DNS resolution

🎯 Objective: Simulate a real multi cluster AKS environment, where users access workloads via a single VPN and resolve services through internal DNS. No host file modifications locally, no public IPs, no juggling multiple VPNs.


Bicep: Clean, Native, and Surprisingly Capable

I had never used Bicep before this project, but getting started was straightforward-ish.

Pros:

  • ✅ Clean syntax (much simpler than ARM templates)

  • ✅ No state file management

  • ✅ Native Azure CLI support

  • ✅ IntelliSense in VS Code = faster iteration

Challenges:

  • ⚠️ Resource scope management (e.g. subscription vs resource group) can be unintuitive

  • ⚠️ Loops/conditionals still feel immature

  • ⚠️ Limited examples and community troubleshooting (though Reddit usually saves the day)

Using two Bicep files (main-sub.bicep and main-rg.bicep), I created the resource group, Virtual WAN, VPN gateway, DNS zone, and resolver. It worked well for this kind of Azure native networking setup. Once the foundational networking was in place, I shifted back to Terraform to handle the Kubernetes side of the stack.


Why two Bicep files?

Azure Bicep templates must follow strict scope rules. For example, a resource group can only be created at the subscription level, while most infrastructure (like VNets, DNS zones, and Virtual WANs) must be deployed at the resource group level

To keep things clean and valid:

  • main-sub.bicep handled the subscription-level deployment, where I created the resource group.

  • main-rg.bicep was then scoped to that resource group, where I deployed all infrastructure inside it.

This split is necessary because Bicep doesn’t allow mixing resource scopes in a single file, trying to do so would trigger deployment errors. Once that structure was set, it made iterating on the resource group deployments a lot more modular.


🤖 Terraform: My Default, Still the Heavyweight

(though I wouldn’t trust myself to build production IaC from scratch... yet)

💡 I used Terraform to deploy a nginxdemos/hello container inside AKS, a simple visual way to confirm DNS resolution was working correctly from VPN connected nodes


Why Terraform made sense here:

Although I had already used Bicep to create the underlying networking, when it came to deploying the AKS cluster and its workloads, Terraform was the more practical option, and here's why:

Terraform lets you manage both infrastructure and workloads. With Terraform’s Kubernetes provider, I could provision AKS and immediately deploy the app in one workflow. Bicep can’t directly deploy Kubernetes resources, you'd need to follow up with Helm, kubectl, or GitHub Actions to do that.

Modular structure & community templates. Terraform’s module support made it easier to break down complex deployments and reuse patterns. This helped speed things up, especially when learning how to wire up VNet integration and AKS identity configs.

State management gives better visibility. With a .tfstate file (stored remotely in practice), it’s easier to track exactly what’s deployed and detect config drift.

Stronger ecosystem for day two ops. From secrets integration to scaling out clusters or adding node pools, there are Terraform modules (or community resources) for nearly every AKS use case.


What I used Terraform for:

  • 🛠️ Deployed the AKS cluster into the resource group created by Bicep

  • 🌐 Created a separate VNet + subnet for the cluster

  • 🚀 Deployed a nginxdemos/hello container inside the cluster

  • 🔗 Connected the AKS VNet to the Virtual WAN Hub created via Bicep

TL;DR:Even though I didn’t fully use Bicep for deploying AKS workloads directly, the choice to use Terraform wasn’t just comfort, it was also practicality. Bicep shines for Azure native infrastructure, but once you cross into Kubernetes workloads, Terraform still leads on flexibility and automation.


🧹 Terraform vs. Bicep: What I Learned



🔧 Final Thoughts: Use the Right Tool for the Job

After going through this hands on comparison, here's my take:

  • If you're deep in Azure and want simplicity, Bicep is a great fit. It's fast, clean, and native.

  • If you're managing larger systems, multi-cloud environments, or need advanced tooling, Terraform is still the better choice.

  • We’ll likely keep using Terraform for AKS and app layers, while letting Bicep manage core Azure services like Virtual WAN and DNS zones.


🧠 Brainstorming with My Mini CTO - From Azure to Aww

Apparently, Azure + AKS = bedtime stories now. These little moments remind me why I enjoy learning new things & what I do. It's okay to pause the articles and just enjoy the view. Sure, learning something new can be frustrating. But when it finally clicks, it’s one of the most rewarding feelings! She’s getting a crash course in Kubernetes, and I’m getting a gentle reminder to savour the moments between each push.


👋 Let's Talk IaC

Have you worked with Bicep or Terraform in Azure? Would love to hear your thoughts, lessons learned, or best practices. Whether you're building a single cluster or managing global scale infrastructure, just remember that the right IaC tool depends on your stack, your workflow and your comfort with a bit of YAML therapy.