Azure  

Infrastructure as Code (IaC) for Web Projects Using Bicep and Terraform

Introduction

Modern web projects rely on complex infrastructures — virtual networks, databases, load balancers, web apps, and security configurations. Managing this infrastructure manually is not only time-consuming but error-prone.

That’s where Infrastructure as Code (IaC) comes in. IaC allows developers and DevOps engineers to define, provision, and manage infrastructure using declarative code — ensuring repeatability, version control, and automation.

In this article, we’ll focus on implementing IaC using Bicep (Microsoft’s declarative ARM template language) and Terraform (a cross-platform IaC tool), specifically for ASP.NET Core + Angular web applications hosted in Azure.

1. What is Infrastructure as Code (IaC)?

Infrastructure as Code is a DevOps practice where infrastructure setup (servers, storage, networking, etc.) is automated through code rather than manual configuration.

Benefits include

  • Consistency across environments (Dev, QA, Prod)

  • Easy rollback and change tracking via Git

  • Faster provisioning for CI/CD

  • Reduced human error

  • Reusability of environment definitions

2. Why Use Bicep and Terraform?

FeatureBicepTerraform
Language TypeDeclarative (Azure native)Declarative (multi-cloud)
Best ForAzure-focused deploymentsCross-platform deployments
State ManagementUses Azure Resource Manager (ARM) directlyUses its own state file (.tfstate)
SyntaxSimplified over ARM templatesHCL (HashiCorp Configuration Language)
Ideal ScenarioMicrosoft stack projectsMulti-cloud or hybrid environments

If your web project is fully Azure-based, Bicep is a natural fit. For hybrid or multi-cloud web projects, Terraform provides greater flexibility.

3. Typical Web Project Infrastructure

Let’s assume you’re deploying an ASP.NET Core Web API with an Angular frontend, hosted in Azure App Service, with an Azure SQL Database and Application Insights for monitoring.

Infrastructure Components:

  • Azure Resource Group

  • Azure App Service Plan

  • Azure Web App (for API and Angular app)

  • Azure SQL Database + Server

  • Azure Storage Account (for static files/logs)

  • Application Insights

4. Technical Workflow (Flowchart)

┌────────────────────────┐
│   Infrastructure Code  │
│  (Bicep / Terraform)   │
└────────────┬───────────┘
             │
             ▼
     ┌──────────────┐
     │ Azure CLI /  │
     │ Terraform CLI│
     └──────┬───────┘
             │
             ▼
     ┌──────────────┐
     │ Azure Resource│
     │ Manager (ARM) │
     └──────┬────────┘
             │
             ▼
     ┌────────────────────────┐
     │ Provisioned Resources  │
     │ (Web App, SQL, Storage)│
     └────────────────────────┘

5. Implementing IaC with Bicep

Step 1: Install Bicep CLI

az bicep install

Step 2: Create a Bicep File (main.bicep)

param location string = resourceGroup().location
param appServicePlanName string = 'webapp-plan'
param webAppName string = 'enterprise-webapp'
param sqlServerName string = 'enterprisesqlserver'
param sqlAdminUser string = 'sqladmin'
param sqlAdminPassword string

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: 'S1'
    tier: 'Standard'
    size: 'S1'
    capacity: 1
  }
}

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

resource sqlServer 'Microsoft.Sql/servers@2022-02-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: sqlAdminUser
    administratorLoginPassword: sqlAdminPassword
  }
}

resource sqlDB 'Microsoft.Sql/servers/databases@2022-02-01-preview' = {
  name: 'enterprise_db'
  parent: sqlServer
  location: location
  sku: {
    name: 'S0'
    tier: 'Standard'
  }
}

Step 3: Deploy to Azure

az deployment group create --resource-group EnterpriseRG --template-file main.bicep

6. Implementing IaC with Terraform

Step 1: Install Terraform

choco install terraform

Step 2: Define Infrastructure in main.tf

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "EnterpriseRG"
  location = "East US"
}

resource "azurerm_app_service_plan" "plan" {
  name                = "webapp-plan"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  sku {
    tier = "Standard"
    size = "S1"
  }
}

resource "azurerm_app_service" "app" {
  name                = "enterprise-webapp"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  app_service_plan_id = azurerm_app_service_plan.plan.id
}

Step 3: Run Terraform Commands

terraform init
terraform plan
terraform apply

Terraform automatically creates the Azure resources defined in your configuration.

7. Integrating IaC with CI/CD Pipeline

Example: Jenkins or GitHub Actions pipeline

Workflow

  1. Developer commits IaC changes to Git.

  2. CI pipeline validates syntax and security (e.g., terraform validate).

  3. On approval, the pipeline runs terraform apply or az deployment.

  4. Resources are deployed automatically before the app build step.

Jenkinsfile Example

pipeline {
  agent any
  stages {
    stage('Init Terraform') {
      steps {
        sh 'terraform init'
      }
    }
    stage('Validate') {
      steps {
        sh 'terraform validate'
      }
    }
    stage('Plan & Apply') {
      steps {
        withCredentials([azureServicePrincipal(...)]) {
          sh 'terraform plan -out=tfplan'
          sh 'terraform apply -auto-approve tfplan'
        }
      }
    }
  }
}

This automates your entire environment setup before the application deployment, ensuring zero manual provisioning.

8. Comparing Bicep vs Terraform in Real Projects

AspectBicepTerraform
Syntax SimplicityEasier, Azure-nativeSlightly verbose
Multi-cloud SupportAzure onlyAzure, AWS, GCP, others
State ManagementManaged by AzureManual state (.tfstate)
ModularityModules and parametersModules and variables
Ideal Use CaseAzure-specific web appsMulti-cloud enterprise setups

Recommendation

  • Use Bicep for pure Azure projects (like ASP.NET Core + Angular hosted in Azure App Service).

  • Use Terraform when infrastructure spans Azure + AWS + On-premises.

9. Best Practices

  • Keep IaC templates in version control (Git)

  • Use naming conventions for resources

  • Store secrets in Azure Key Vault instead of hardcoding

  • Use modules for reusability (e.g., network.bicep, sql.bicep)

  • Validate infrastructure using terraform validate or bicep build

  • Apply RBAC (Role-Based Access Control) for deployment pipelines

Conclusion

Implementing Infrastructure as Code (IaC) using Bicep and Terraform transforms the way developers and DevOps teams manage cloud infrastructure.

For Azure-only web projects, Bicep offers simplicity, deep integration, and maintainability.
For cross-platform or hybrid environments, Terraform remains the go-to solution for scalability and cloud independence.

By combining IaC with CI/CD pipelines, you achieve fully automated, version-controlled, and reproducible deployments — essential for modern web projects built with ASP.NET Core and Angular.