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?
| Feature | Bicep | Terraform |
|---|
| Language Type | Declarative (Azure native) | Declarative (multi-cloud) |
| Best For | Azure-focused deployments | Cross-platform deployments |
| State Management | Uses Azure Resource Manager (ARM) directly | Uses its own state file (.tfstate) |
| Syntax | Simplified over ARM templates | HCL (HashiCorp Configuration Language) |
| Ideal Scenario | Microsoft stack projects | Multi-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
Developer commits IaC changes to Git.
CI pipeline validates syntax and security (e.g., terraform validate).
On approval, the pipeline runs terraform apply or az deployment.
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
| Aspect | Bicep | Terraform |
|---|
| Syntax Simplicity | Easier, Azure-native | Slightly verbose |
| Multi-cloud Support | Azure only | Azure, AWS, GCP, others |
| State Management | Managed by Azure | Manual state (.tfstate) |
| Modularity | Modules and parameters | Modules and variables |
| Ideal Use Case | Azure-specific web apps | Multi-cloud enterprise setups |
Recommendation
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.