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

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:

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

9. Best Practices

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.