This is a tenant-neutral template. Every tenant-specific value is a placeholder using Microsoft's documented fictitious identifiers (
contoso,contoso.onmicrosoft.com). It will not deploy against a real tenant until you make it yours. First run the Kickoff agent@operator-kickoffto choose where your copy lives (a local workspace or your own GitHub repo) and sever it from this source template so it can never contribute content back, per ADR 0045. Then run the Tenant Intake agent@operator-tenant, or editinfra/parameters/lab.yamlby hand and follow Getting started. Placeholders to replace: GitHub org/repo, tenant domain, resource group, Purview account name, Key Vault, Log Analytics, OIDC app display names, CODEOWNERS handles, and the content-explorer wrapper-group object ID.
Declarative, version-controlled configuration of a Microsoft Purview environment for a single tenant. Both the Azure resource (control plane) and the catalog contents (data plane) are expressed as code and deployed by GitHub Actions.
Standing up your own environment? Start with the Kickoff guide — the opinionated end-to-end walkthrough from an empty copy to a deployed, tenant-tailored environment.
Template repository. This repo is enabled as a GitHub template — click Use this template to create your own copy. A template-generated repo starts with a clean history and cannot open a pull request back to this source, which is the preferred spin-off path in ADR 0045.
Target account (placeholder):
contoso-labMicrosoft Purview account (tenantcontoso.onmicrosoft.com).
New here? Start with the Kickoff guide — the opinionated end-to-end walkthrough for standing up your own environment. The six steps below are the summary; the Tenant onboarding guide has the exact commands.
From an empty copy to a tailored, deployable repo in six steps.
- Get a copy. Click Use this template on GitHub (a template-generated repo has unrelated history and cannot push back to the source), or
git clone https://github.com/<your-org>/<your-repo>.gitfor a local workspace. - Decouple it. Run the Kickoff agent
@operator-kickoffto choose a local workspace or a spin-off repo and install the no-push-back guard, per ADR 0045. (If you used Use this template, GitHub already decoupled you.) - Tailor it. Run the Tenant Intake agent
@operator-tenant. It interviews you for your tenant values and writes them intoinfra/parameters/lab.yamland the identity-boundary statements. - Review the diff the agent produced, then commit it on a branch.
- Wire up identity. Create the Microsoft Entra app + OIDC federated credential, set the GitHub Environment secrets, and set the
OWNER_APPROVAL_LOGINrepository variable — see Getting started §1–§2. - Validate and deploy. Run
az bicep buildand the Pester suite, then thedeploy-infraworkflow and the per-solutiondeploy-<solution>workflows — see the Tenant onboarding guide and Getting started §4.
Microsoft Purview does not expose a single "Purview-as-Code" product. A complete IaC repo must manage two independent planes, each with its own API surface and auth model:
| Plane | What it manages | API | Auth | This repo |
|---|---|---|---|---|
| Control plane | The Microsoft.Purview/accounts resource, networking, managed identity, SKU |
Azure Resource Manager | Azure RBAC (Contributor on RG) | infra/ — Bicep |
| Data plane | Sensitivity labels, DLP, data lifecycle and records management, insider risk, communication compliance, DSPM, plus Data Map collections, glossary, classifications, data sources, and scans | Microsoft Purview data-plane APIs (REST and Security & Compliance PowerShell) | App-only automation identity (certificate in Key Vault, OIDC from GitHub Actions) with least-privilege Microsoft Purview roles | data-plane/ + scripts/ — YAML rendered by PowerShell |
References:
- Microsoft.Purview/accounts resource (Bicep/ARM/Terraform)
- Authenticate for Purview APIs
- Purview Data Plane REST API reference
- Access control in Microsoft Purview
- Azure Verified Module — Purview Account
.
├── .github/
│ ├── workflows/ # CI (validate) and CD (deploy-infra, per-solution deploy-*)
│ ├── instructions/ # Path-scoped Copilot rules (Bicep, PowerShell, YAML, ...)
│ ├── prompts/ # Reusable /-invoked task templates
│ └── agents/ # Workspace-scoped Squad agents (personas)
├── infra/ # Bicep: Purview account + dependencies (control plane)
│ ├── main.bicep
│ ├── main.bicepparam
│ ├── modules/
│ └── parameters/
├── data-plane/ # Desired-state governance content — one folder per Purview solution
│ ├── information-protection/ # Sensitivity labels + label / auto-label policies
│ ├── classifications/ # Sensitive information type (SIT) catalog
│ ├── audit/
│ ├── dlp/
│ ├── data-lifecycle/
│ ├── records/
│ ├── irm/ # Insider Risk Management
│ ├── communication-compliance/
│ ├── dspm/
│ ├── dspm-ai/
│ ├── adaptive-scopes/
│ ├── collections/ # Data Map collection hierarchy
│ ├── glossary/
│ ├── data-sources/
│ ├── scans/
│ ├── unified-catalog/
│ ├── purview-role-groups/
│ ├── entra-directory-roles/
│ └── administrative-units/
├── scripts/ # PowerShell 7+ reconcilers, smoke tests, provisioning helpers
│ ├── Connect-Purview.ps1
│ ├── Deploy-*.ps1 # Idempotent reconciler per data-plane solution
│ ├── Invoke-*SmokeTest.ps1 # End-to-end lab smoke tests
│ ├── New-*.ps1 # One-time identity / Key Vault / certificate provisioning
│ └── modules/
├── docs/
│ ├── kickoff-guide.md # Opinionated end-to-end kickoff walkthrough (start here)
│ ├── tenant-onboarding.md # Detailed step reference for standing up your environment
│ ├── getting-started.md
│ ├── architecture.md
│ ├── project-plan.md # v2 roadmap + progress checklist
│ ├── adr/ # Architecture decision records
│ ├── governance/
│ ├── runbooks/
│ ├── solutions/
│ └── archive/ # Archived v1 plan
├── tests/ # Pester 5.x unit tests for scripts/ (no live tenant)
├── AGENTS.md
└── README.md
For the full walkthrough from an empty copy to a deployed environment, see the Kickoff guide.
- Prerequisites — see
docs/getting-started.md. - Create the deployment service principal and grant it the required Purview data plane roles (one-time) — see Authenticate for APIs.
- Configure GitHub secrets/variables:
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_SUBSCRIPTION_ID,PURVIEW_ACCOUNT_NAME. - Provision control plane: push to
main, thedeploy-infraworkflow runsaz deployment group createagainstinfra/main.bicep. - Deploy data plane: each surface is applied by its own per-solution workflow —
deploy-labels,deploy-label-policies,deploy-auto-label-policies,deploy-dlp,deploy-irm— which render the YAML underdata-plane/into REST / Security & Compliance PowerShell calls. Every other surface has no automated apply path yet: run itsscripts/Deploy-*.ps1reconciler locally. See ADR 0051 and the backfill tracker #80.
- Idempotent — every apply script GETs current state, diffs, then PUT/PATCHes.
- Declarative YAML — human-reviewable; pull request = change review.
- Least privilege — OIDC federated credentials from GitHub → Entra; no long-lived secrets.
- Separation of concerns — control-plane PRs never change catalog content and vice versa.
Roadmap. This template ships with an empty feature roadmap. New here? The Kickoff guide walks you through standing up your environment end to end. See docs/project-plan.md to plan and track which Microsoft Purview features you adopt into as-code governance, and docs/getting-started.md to set up the tenant connection.
Scheduled watch loops (drift, surface, and the planned code- and feature-currency loops) file their findings as review issues into a discoverable queue — see .github/copilot-automations/README.md.