Master VMware, Cloud, Backup, Linux & IT Security with Expert Tutorials and Tools

Mastering Azure Infrastructure as Code: Bicep + CI/CD with Azure DevOps and GitHub Actions

1

Cloud deployments have come a long way. Instead of clicking through the Azure Portal every time you need a resource, you can now describe your entire infrastructure in code and let automation do the heavy lifting. This is the essence of Infrastructure as Code (IaC)—and with tools like Bicep, Azure DevOps Pipelines, and GitHub Actions, you can go from manual deployments to fully automated pipelines.

In this blog, we’ll take a deep dive into:

  • What Bicep is and why it’s the future of ARM templates
  • How to write and deploy a simple Bicep template
  • How to plug that template into Azure DevOps and GitHub Actions
  • Best practices for building reliable IaC pipelines

By the end, you’ll have all the knowledge needed to go from beginner IaC deployments to professional-grade CI/CD automation.

What is Bicep?

Bicep is a Domain Specific Language (DSL) for deploying Azure resources. It’s built on top of ARM (Azure Resource Manager) templates but is far more developer-friendly.

  • Readable: No more wrestling with JSON. Bicep is clean and concise.
  • Reversible: You can decompile an existing ARM template back into Bicep.
  • Integrated: Works natively with Azure CLI and PowerShell.
  • Evolving: Microsoft is actively investing in Bicep as the successor of ARM templates.

Think of Bicep as ARM’s smarter, friendlier sibling.

Writing Your First Bicep Template

Let’s start small: deploying an App Service Plan and a Web App.

param appName string = 'my-bicep-webapp'
param location string = resourceGroup().location
param sku string = 'F1'

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
name: '${appName}-plan'
location: location
sku: {
name: sku
tier: 'Free'
}
}

resource webApp 'Microsoft.Web/sites@2022-09-01' = {
name: appName
location: location
properties: {
serverFarmId: appServicePlan.id
}
}

What’s happening here?

  • param – defines inputs so you don’t hardcode values.
  • resource appServicePlan – creates an App Service Plan.
  • resource webApp – creates a Web App that depends on the plan.

Deploying a Bicep Template

Once you save the file as main.bicep, you can deploy it using the Azure CLI:

az group create --name MyResourceGroup --location eastus
az deployment group create \
--resource-group MyResourceGroup \
--template-file main.bicep

oom 💥—your App Service Plan and Web App are live!

But running these commands manually isn’t automation. Let’s take it a step further.

Automating with Azure DevOps

Step 1: Push Your Code to a Repo

Your main.bicep file should live in Azure Repos or GitHub. This gives you version control and team collaboration.

Step 2: Create a Pipeline in Azure DevOps

  1. Go to Pipelines → New Pipeline.
  2. Select your repo.
  3. Configure the pipeline with YAML.

Here’s a sample pipeline:

trigger:
- main

pool:
vmImage: 'ubuntu-latest'

steps:
- task: AzureCLI@2
inputs:
azureSubscription: '<your-service-connection>'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az group create --name MyResourceGroup --location eastus
az deployment group create \
--resource-group MyResourceGroup \
--template-file main.bicep

Step 3: Service Connection Setup

  • Create a Service Principal in Azure.
  • Add it as a Service Connection in DevOps.
  • This is how your pipeline authenticates securely.

Automating with GitHub Actions

If you prefer GitHub, the flow is similar.

Step 1: Create a Workflow File

Inside your repo, create .github/workflows/deploy.yml:

name: Deploy Azure Resources

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2

- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Deploy Bicep template
run: |
az group create --name MyResourceGroup --location eastus
az deployment group create \
--resource-group MyResourceGroup \
--template-file main.bicep

Step 2: Add Secrets

In GitHub:

  • Go to Repo → Settings → Secrets → Actions.
  • Add AZURE_CREDENTIALS (from a service principal JSON).

Hands-On Walkthrough (Step-by-Step)

Azure DevOps Walkthrough

  1. Repo Setup: Commit main.bicep to your repo.
  2. Service Connection: Create a Service Principal in Azure AD → Assign Contributor role → Copy clientId, tenantId, and secret.
  3. Pipeline Creation: In DevOps → Pipelines → New → YAML → paste pipeline YAML.
  4. Run: Push code → Pipeline triggers → Resources created automatically.

GitHub Actions Walkthrough

  1. Repo Setup: Push main.bicep to your GitHub repo.
  2. Service Principal: Run az ad sp create-for-rbac → copy JSON → add as AZURE_CREDENTIALS secret in GitHub.
  3. Workflow File: Add YAML under .github/workflows.
  4. Run: Push → GitHub Actions runs workflow → Resources deployed.

Wrapping Up

With Bicep you define your Azure infrastructure in clean, readable code. With Azure DevOps or GitHub Actions, you automate the entire lifecycle—from commit to deployment.

This is the power of Infrastructure as Code + CI/CD:

  • Faster deployments
  • Fewer mistakes
  • Fully auditable history

🚀 Next step: Take your Bicep template, drop it into a pipeline, and enjoy push-to-deploy infrastructure.

80%
Awesome
  • Design
Leave A Reply

Your email address will not be published.