No-Cost Mode: CI runs terraform fmt/init/validate only. No Azure resources are created by default. Local deployment is optional and disabled by default to avoid charges.
A tiny, portfolio-ready repo that provisions an Azure Storage Account Static Website in two ways:
- Terraform (with a clean GitHub Actions pipeline)
- Bicep (single-file ARM-native template)
It’s designed to demonstrate Azure + IaC fluency safely (no spend) and serve as a template you can extend with OIDC-based deploys later.
Table of Contents
- What’s Included
- Repo Structure
- CI (Validate-Only)
- Optional: Local Deploy (Terraform)
- Optional: Bicep Deploy
- Future: OIDC Deploys from GitHub Actions
- AZ-900 Crash Notes
- Cleanup
- Troubleshooting
- Contributing & Security
- License
- Terraform with the
azurermprovider - Static website enablement via
azurerm_storage_account_static_website - Blob uploads of
index.htmland404.html(Terraform-managed) - GitHub Actions CI:
fmt,init -backend=false,validate - Bicep template enabling static website (no uploads by default)
- AZ-900 crash notes: key services & concepts
. ├─ README.md ├─ docs/ │ └─ az900-crash-notes.md ├─ .github/ │ └─ workflows/ │ └─ tf-ci.yml ├─ terraform/ │ ├─ main.tf │ ├─ variables.tf │ ├─ outputs.tf │ └─ versions.tf └─ bicep/ └─ main.bicep
Workflow: .github/workflows/tf-ci.yml
Runs on push/PR:
terraform fmt -check -recursiveterraform init -backend=falseterraform validate
There is no
planorapplyin CI. This keeps the project cost-free while showing proper IaC hygiene.
Only if you want to see it live. Safe to skip for $0.
# Login + RG
az login
az group create -n rg-azure-staticweb-demo -l eastus
# Deploy
cd terraform
terraform init
terraform plan -var "storage_account_name=<globally-unique-lowercase-3to24>"
terraform apply -auto-approve -var "storage_account_name=<globally-unique-lowercase-3to24>"
# Endpoint
terraform output -raw static_site_url
Optional: Bicep Deploy
Bicep enables the static site on a storage account (no file uploads).
az login
az group create -n rg-azure-staticweb-demo -l eastus
az deployment group create \
--resource-group rg-azure-staticweb-demo \
--template-file ./bicep/main.bicep \
--parameters storageAccountName=<globally-unique-lowercase>
---
Future: OIDC Deploys from GitHub Actions
Create an App Registration in Microsoft Entra ID; add Federated credentials for this repo.
Grant the app Contributor on your subscription or target RG.
Add repo secrets: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID.
Update the workflow to log in with azure/login@v2 and add gated plan/apply jobs.
No long-lived secrets, auditable, and secure.
AZ-900 Crash Notes
Quick refresher on regions vs AZs, RBAC, Policy, Key Vault, storage redundancy (LRS/ZRS/GRS), compute (VM/App Service/Functions/AKS), networking (VNet/NSG/Private Link), monitoring (Monitor/Log Analytics/Defender).
See docs/az900-crash-notes.md
.
Cleanup
If you deployed locally:
terraform destroy -auto-approve -var "storage_account_name=<same-name>"
az group delete -n rg-azure-staticweb-demo -y
Troubleshooting
CI “fmt” fails: run terraform fmt -recursive locally, commit, push.
Missing diff on Windows: omit -diff flag (run terraform fmt -recursive).
az login / no subscription: you can skip local deploy. CI stays green without Azure auth.