IaC - Part 2
IaC - Part 2
Part 2: Building and Deploying the Environment (Step‑by‑Step)
This section walks through the exact steps to build and deploy a modular Azure environment using Bicep. The goal is simplicity: follow the steps, run the commands within PowerShell, and watch the environment come to life! I use PowerShell vs the VS Code extension for better reproducibility and management. Copy/Paste vs Point/Click.
1. Create the Project Structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
iac-repo/
├── main.bicep
├── modules/ # Reusable building blocks (no env-specific values)
│ ├── compute/
│ │ ├── vm/
│ │ └── vmss/
│ ├── networking/
│ │ ├── vnet/
│ │ ├── subnet/
│ │ └── nsg/
│ ├── data/
│ │ ├── storage-account/
│ │ └── sql/
│ └── messaging/
│ └── service-bus/
│
├── environments/ # Environment-specific configs
│ ├── dev/
│ ├── test/
│ └── prod/
│
├── pipelines/ # CI/CD automation
│ ├── github-actions/
│ ├── azure-devops/
│ └── templates/
│
├── policies/ # Policy-as-code (OPA, Azure Policy, Sentinel)
│ └── azure-policy/
│
├── docs/ # Architecture diagrams, runbooks, ADRs
│ ├── architecture.md # Diagram in Mermaid
│ └── decisions/
│
└── tools/ # Helper scripts (linting, validation, wrappers)
└── pre-commit-hooks/
Steps:
- Create a folder named iac-repo
- Create a modules subfolder
- Add empty .bicep files for each module
- Add parameter files for each environment
2. Install Required Tools
Verify:
1
2
az version
az bicep version
3. Log In and Select Subscription
1
2
3
az login
az account list --output table
az account set --subscription "<subscription-id>"
4. Create a Resource Group
1
2
3
az group create `
--name rg-iac-lab `
--location centralus
5. Build the Modules
Each module should define one responsibility. Example structure:
network.bicep→ VNet + subnetsnsg.bicep→ NSGs + rulesvm.bicep→ VM + NIC + PIPkeyvault.bicep→ Key Vault + access policiesstorage.bicep→ Storage accountSteps:
- Define parameters.
- Define resources.
- Output values needed by other modules.
- Keep modules small and reusable.
6. Write the Root Template (main.bicep)
main.bicep should:
- Accept environment parameters
- Call each module
- Pass outputs between modules
- Produce final outputs (e.g., VM IP, Key Vault name)
Structure:
- param block
- module calls
- output block
7. Create Parameter Files
Example: dev.bicepparam Store it in iac-repo\environments\dev\
1
2
param environment string = 'dev'
param location string = 'centralus'
Repeat for prod in .\environments\prod\
8. Validate the Deployment
1
2
3
4
az deployment group what-if `
--resource-group rg-iac-lab `
--template-file .\main.bicep `
--parameters .\environments\dev\dev.bicepparam
Did you notice the what-if argument?
Look for:
- Resources to be created
- Resources to be updated
- Unexpected changes
9. Deploy the Environment
1
2
3
4
az deployment group create `
--resource-group rg-iac-lab `
--template-file .\main.bicep `
--parameters .\environments\dev\dev.bicepparam
10. Verify the Deployment
Check:
- Resource Group
- VNet + subnets
- NSGs
- VM + NIC + PIP
- Key Vault
- Storage account
Use:
1
az resource list --resource-group rg-iac-lab --output table
11. Update the Environment
Modify a module → redeploy → ARM handles idempotency.
1
2
3
4
az deployment group create `
--resource-group rg-iac-lab `
--template-file main.bicep `
--parameters dev.bicepparam
12. Deploy to Another Environment
Just swap parameter files:
1
2
3
4
az deployment group create `
--resource-group rg-iac-lab-prod `
--template-file main.bicep `
--parameters prod.bicepparam
13. Commit and Push to GitHub
1
2
3
4
5
git init
git add .
git commit -m "Initial IaC commit"
git remote add origin <repo-url>
git push -u origin main
14. Optional Next Steps (Part 3 - Enhancements?)
- Add Key Vault secrets
- Add CI/CD with GitHub Actions
- Add logging?
- Add hub‑and‑spoke networking?
This post is licensed under CC BY 4.0 by the author.