OmarMokraniG/azure-estate-exporter

GitHub: OmarMokraniG/azure-estate-exporter

Stars: 0 | Forks: 0

# azure-estate-exporter `azure-estate-exporter` is a PowerShell 7 module that connects to an Azure tenant or subscription you can already read, and produces: 1. **An inventory** of every resource visible to your identity, as JSON and human-readable Markdown. 2. **Architecture diagrams** (Mermaid by default, Excalidraw on demand). 3. **A single-file HTML dashboard** you can email to a customer. 4. **A Terraform HCL baseline** of the existing infrastructure via [`aztfexport`](https://github.com/Azure/aztfexport), Microsoft's official Azure-to-Terraform exporter. 5. **A diff between any two runs** so you can use it as an ongoing audit log. It is designed for Microsoft engineers, architects, partners and customers who need to **document, share, or reverse-engineer** an existing Azure estate quickly and reproducibly. ## Quickstart # 1. Prerequisites — see docs/installation.md for full list # - PowerShell 7+ # - Azure CLI 2.60+ (`az login` already done) # - Terraform 1.5+ # - aztfexport (optional, only needed for Terraform export) # winget install Microsoft.Azure.aztfexport # # or: go install github.com/Azure/aztfexport@latest # 2. Clone and import git clone https://github.com/OmarMokraniG/azure-estate-exporter.git cd azure-estate-exporter Import-Module ./src/AzureEstateExporter # 3. Run against the currently selected subscription Export-AzureEstate -OutputPath ./out # 4. Or target a specific scope Export-AzureEstate -SubscriptionId -ResourceGroup my-rg # 5. Discovery-only (cheap, no Terraform export) Export-AzureEstate -SubscriptionId -InventoryOnly Outputs land in `./out//`: out/2026-05-25T13-00-00/ ├── README.md # index of everything produced ├── index.html # ⭐ self-contained HTML dashboard (Mermaid embedded) ├── inventory.json # full normalized inventory ├── graph.json # nodes + inferred edges (relation + sourceProperty) ├── manifest.json # run metadata, collection confidence, per-resource SHA-256 hashes ├── errors.json # any per-resource failures ├── report/ │ └── report.md # human-friendly Markdown ├── diagrams/ │ ├── estate.mmd # Mermaid (default) │ └── estate.excalidraw # Excalidraw (if -Diagram Excalidraw|Both) ├── terraform/ │ └── // # raw aztfexport output, one HCL folder per resource group │ ├── main.tf │ ├── provider.tf │ └── ... └── terraform-repo/ # ⭐ NEW in v0.3.1 — deployable Terraform baseline repo ├── README.md # how to use; baseline-not-clone warnings ├── .gitignore ├── backend.tf.example # Azure Storage backend stub ├── docs/ │ └── coverage.md # aggregated skipped resources across all RGs └── infra/ └── / # self-contained Terraform working dir ├── main.tf ├── provider.tf # subscription_id = var.subscription_id ├── variables.tf ├── terraform.tfvars.example ├── bootstrap-import.ps1 # imports every resource into state ├── imports.md # raw `terraform import` list (bash users) └── README.md ### Deploy the generated baseline cd out//terraform-repo/infra/ Copy-Item terraform.tfvars.example terraform.tfvars # edit subscription_id terraform init ./bootstrap-import.ps1 -WhatIf # dry run ./bootstrap-import.ps1 # imports every resource into local state terraform plan # should say: No changes. The generated repo is a **baseline, not a perfect clone**. `aztfexport` does not capture secrets, data-plane contents, runtime config, or unsupported resource types — see `docs/coverage.md` inside the generated repo. You can also repackage any existing export without re-running `aztfexport`: New-AzureEstateTerraformRepo -InputPath ./out/ -InitGit -Force ## Diff two runs Compare-AzureEstateRun -Previous out/2026-05-20T10-00-00 -Current out/2026-05-25T13-00-00 # writes out/2026-05-25T13-00-00/diff/changelog.{md,json} Only the **property paths** that changed are emitted — values are never copied across to avoid leaking what redaction was supposed to hide. ## Try without an Azure subscription The [`samples/`](samples/) folder contains anonymized output you can use to test renderers, write downstream tooling or demo the project offline. ## 🌐 Web UI (v0.3, preview) Prefer clicking to scripting? The [`web/`](web/) folder contains a Vite + React SPA that lets you sign in with Entra, browse subscriptions and resource groups, and explore your estate visually: - interactive **resource map** (React Flow + heuristic edges + Azure-style category icons) - sortable, filterable **resource table** with a JSON side panel - one-click **Terraform CLI handoff** that runs the PowerShell module locally # 1. Create your own Entra app registration (one-off, in your tenant) pwsh -File scripts/create-app-reg.ps1 # 2. Configure the web app cd web cp .env.example .env.local # paste the printed appId into VITE_AZURE_CLIENT_ID # 3. Run it npm install npm run dev # open http://localhost:5173 See [`web/README.md`](web/README.md) for deployment to Azure Static Web Apps and notes on Microsoft's Azure architecture icons (we ship generic open-source placeholders; the official icons are an opt-in download). ## Features (v0.4) - ✅ **Customer-grade assessment** — surfaces cost, Defender secure score, policy compliance, public exposure, and RBAC findings out of the box. - ✅ **Deployable Terraform baseline repo** (v0.3.1) — clone the generated `terraform-repo/` folder, run `bootstrap-import.ps1`, and `terraform plan` says _No changes_ against the existing estate. ### What's new in v0.4.0 | New artefact | Source | |---|---| | `cost.json` | Cost Management API (MonthToDate, grouped by RG + service) | | `security.json` | Defender for Cloud secure score + top unhealthy assessments | | `policy.json` | ARG `policyresources` + Policy Insights non-compliant rows | | `exposure.json` | Derived from inventory (NSG 0.0.0.0/0, public storage/Key Vault, App Service without IP restrictions, public IPs) | | `access.json` | Derived from collected role assignments (top privileged principals, broad-scope grants, orphaned assignments) | All five sections are also rendered into the Markdown report and the HTML dashboard, with severity pills and colour-coded headline cards. Opt-out switches: `-SkipCost`, `-SkipSecurity`, `-SkipPolicy`. ## Features (v0.2) - ✅ **Resource Graph–based** discovery across one subscription or all subscriptions visible to your identity. - ✅ **Self-contained HTML dashboard** with embedded Mermaid (works offline). - ✅ **`Compare-AzureEstateRun`** turns the tool into an ongoing audit log. - ✅ **Pluggable collectors**: ARG primary + supplementary ARM collectors for diagnostic settings, role assignments, locks (extension model — easy to add more). - ✅ **Pluggable renderers**: Markdown report, Mermaid diagram, Excalidraw diagram, HTML dashboard, Terraform via `aztfexport`. - ✅ **Rich edges**: every inferred edge carries a `relation` (e.g. `hosted-on`, `in-subnet`, `managed-by`) and the `sourceProperty` path it came from. - ✅ **Collection confidence**: every `manifest.json` includes the tool versions used, the scope queried, and error counts by area. - ✅ **Modes**: `-InventoryOnly`, `-DiagramOnly`, `-TerraformOnly`, plus `-WhatIf` for dry runs. - ✅ **Secret redaction by default** for known-sensitive keys (`password`, `secret`, `connectionString`, `key`, `sas`, `token`, `certificate`). Disable with `-NoRedact` *(not recommended)*. - ✅ **Deterministic output** with a `manifest.json` mapping resource IDs to Terraform addresses + SHA-256 hashes so re-runs produce stable diffs. - ✅ **Failure-tolerant**: a single broken resource group does not abort the run. - ✅ **Devcontainer / Codespaces** ready — see `.devcontainer/devcontainer.json`. ## What is NOT in scope (yet) See [`docs/coverage.md`](docs/coverage.md). High-level: ## Why this exists The classic problem: a customer has an Azure subscription nobody owns the IaC for. To migrate it, document it, or hand it over, you need: - An accurate inventory you can trust. - A picture you can put in a deck. - Terraform you can start iterating on rather than writing from scratch. Doing this by hand for a non-trivial estate takes days. This tool gets you to a solid baseline in minutes, then lets a human review and harden the result. ## Security Read [`SECURITY.md`](SECURITY.md). TL;DR: - The tool needs **Reader** at minimum on the scope you target. - Generated artifacts may include resource metadata that some organisations treat as confidential — **review before sharing or pushing to public repos**. The default `.gitignore` already excludes `out/`. - Never commit `terraform.tfstate*`, `*.tfvars`, or unredacted exports. ## Related work - [`Azure/aztfexport`](https://github.com/Azure/aztfexport) — the official Azure-to-Terraform exporter that powers our Terraform backend. - [Azure Resource Graph](https://learn.microsoft.com/azure/governance/resource-graph/) — primary inventory engine. - [Excalidraw](https://excalidraw.com/) — diagrams. - [Terraformer](https://github.com/GoogleCloudPlatform/terraformer) — alternative exporter; could be plugged in as a future backend. ## License [MIT](LICENSE).
标签:Libemu