Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 74 additions & 194 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,258 +1,138 @@
\[!\[tf-ci](https://github.com/Simar-DevOps/azure-static-website-mini/actions/workflows/tf-ci.yml/badge.svg)](https://github.com/Simar-DevOps/azure-static-website-mini/actions/workflows/tf-ci.yml)
[![tf-ci](https://github.com/Simar-DevOps/azure-static-website-mini/actions/workflows/tf-ci.yml/badge.svg)](https://github.com/Simar-DevOps/azure-static-website-mini/actions/workflows/tf-ci.yml)

# Azure Static Website — Terraform & Bicep (Mini)

> **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.

\# Azure Static Website — Terraform \& Bicep (Mini)
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.

---

> \*\*No-Cost Mode:\*\* CI runs \*\*fmt/init/validate only\*\*. No Azure resources are created by default. Local deployment is optional and disabled by default to avoid charges.



This mini repo demonstrates how to provision an \*\*Azure Storage Account Static Website\*\* using \*\*two IaC approaches\*\*:

\- \*\*Terraform\*\* (with a GitHub Actions workflow that formats, inits, and validates)

\- \*\*Bicep\*\* (single-file ARM-native template)



It’s designed to showcase \*\*Azure fluency with zero spend\*\*. You can enable real deploys later using \*\*OIDC\*\* from GitHub Actions without long-lived secrets.


## Table of Contents
- [What’s Included](#whats-included)
- [Repo Structure](#repo-structure)
- [CI (Validate-Only)](#ci-validate-only)
- [Optional: Local Deploy (Terraform)](#optional-local-deploy-terraform)
- [Optional: Bicep Deploy](#optional-bicep-deploy)
- [Future: OIDC Deploys from GitHub Actions](#future-oidc-deploys-from-github-actions)
- [AZ-900 Crash Notes](#az-900-crash-notes)
- [Clean Up](#clean-up)
- [Troubleshooting](#troubleshooting)
- [Contributing & Security](#contributing--security)
- [License](#license)

---

## What’s Included
- **Terraform** with the `azurerm` provider
- **Static website** enablement via `azurerm_storage_account_static_website`
- **Blob uploads** of `index.html` and `404.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

---

\## 📂 Repository Structure
## Repo Structure
.

├─ README.md

├─ docs/

│ └─ az900-crash-notes.md

├─ .github/

│ └─ workflows/

│ └─ tf-ci.yml

├─ terraform/

│ ├─ main.tf

│ ├─ variables.tf

│ ├─ outputs.tf

│ └─ versions.tf

└─ bicep/

└─ main.bicep


---



\## ✅ What This Repo Shows



\- \*\*Terraform\*\* for Azure (`azurerm` provider)

\- \*\*Static Website\*\* enablement via `azurerm\_storage\_account\_static\_website`

\- \*\*Blob uploads\*\* of `index.html` and `404.html` (Terraform-managed)

\- \*\*GitHub Actions CI\*\*: `terraform fmt`, `init -backend=false`, `validate`

\- \*\*Bicep\*\* template that enables the same static website (no uploads by default)

\- \*\*AZ-900 crash notes\*\* with key concepts and services: `docs/az900-crash-notes.md`



---



\## 🔧 Prerequisites (for optional local deploy)



\- \*\*Azure CLI\*\* (`az login`)

\- \*\*Terraform\*\* >= 1.6

\- An \*\*Azure subscription\*\* (only needed if you choose to deploy locally)



> If you don’t have/want a subscription right now, skip local deploy — CI stays green and costs remain $0.



---

## CI (Validate-Only)
Workflow: `.github/workflows/tf-ci.yml`
Runs on push/PR:
- `terraform fmt -check -recursive`
- `terraform init -backend=false`
- `terraform validate`


\## 🚦 CI: Validate-Only (No Deploys)



The GitHub Actions workflow at `.github/workflows/tf-ci.yml` runs on push/PR:

\- `terraform fmt -check -recursive`

\- `terraform init -backend=false`

\- `terraform validate`



There is \*\*no `plan` or `apply`\*\* in CI. This keeps the project \*\*cost-free\*\* and still demonstrates proper IaC hygiene.


> There is **no** `plan` or `apply` in CI. This keeps the project **cost-free** while showing proper IaC hygiene.

---



\## ▶️ Optional: Local Deploy (Terraform)



> \*\*Only if you want to see it live\*\*. You can safely skip this to keep costs at $0.


## Optional: Local Deploy (Terraform)
> Only if you want to see it live. Safe to skip for $0.

```bash

\# 1) Login and create a resource group

# Login + RG
az login

az group create -n rg-azure-staticweb-demo -l eastus



\# 2) Terraform deploy

# 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>"

terraform plan -var "storage\_account\_name=<globally-unique-lowercase-3to24>"

terraform apply -auto-approve -var "storage\_account\_name=<globally-unique-lowercase-3to24>"



\# 3) Grab the site URL

terraform output -raw static\_site\_url

Open the printed URL (e.g., https://<sa>.z13.web.core.windows.net/) — you should see the Terraform-managed Hello page.



Clean up (to avoid charges):
terraform destroy -auto-approve -var "storage\_account\_name=<same-name-used-above>"

az group delete -n rg-azure-staticweb-demo -y




🧱 Optional: Bicep Deploy (Enable Static Site)



The Bicep file enables the static website on a storage account (it does not upload files by default).
# 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>

az deployment group create \\

&nbsp; --resource-group rg-azure-staticweb-demo \\

&nbsp; --template-file ./bicep/main.bicep \\

&nbsp; --parameters storageAccountName=<globally-unique-lowercase>





Deployment outputs the static site endpoint. You can upload files to the $web container manually if desired.

🔐 Future: GitHub Actions OIDC (Deploys Without Secrets)



When you want CI/CD to create resources:



Create an App Registration in Microsoft Entra ID with federated credentials for your GitHub repo.



Grant the app Contributor on your subscription or target resource group.



Add repo secrets: AZURE\_CLIENT\_ID, AZURE\_TENANT\_ID, AZURE\_SUBSCRIPTION\_ID.



Update the workflow to include azure/login@v2 and add a gated plan/apply job.



This keeps things secure (no long-lived keys) and auditable.

🧭 AZ-900 Crash Notes



Quick notes to refresh core concepts: regions vs AZs, RBAC, Policy, Key Vault, storage redundancy (LRS/ZRS/GRS), compute options (VM/App Service/Functions/AKS), networking (VNet, NSG, Private Link), and monitoring (Monitor, Log Analytics, Defender).



See: docs/az900-crash-notes.md

---

Future: OIDC Deploys from GitHub Actions

🏁 Status
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.

✅ Terraform + Bicep templates
Update the workflow to log in with azure/login@v2 and add gated plan/apply jobs.

No long-lived secrets, auditable, and secure.

---

✅ Validate-only CI (no deploys by default)
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
.

---

✅ AZ-900 crash notes
Clean Up

If you deployed locally:

terraform destroy -auto-approve -var "storage_account_name=<same-name>"
az group delete -n rg-azure-staticweb-demo -y

💤 Optional local deploy instructions (disabled by default)
---

Troubleshooting

CI “fmt” fails: run terraform fmt -recursive locally, commit, push.

Goal: Demonstrate Azure + IaC proficiency with zero default cost.
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.