Why Azure Architecture Documentation Fails — and What a Documentation Workflow That Actually Works Looks Like

Most Azure architecture documentation is a record of intent, not a record of fact. This post explains why static documentation always drifts from the actual environment — and what an Azure Resource Graph-based documentation workflow looks like in practice.

Marc Dekeyser |

Why Azure Architecture Documentation Fails — and What a Documentation Workflow That Actually Works Looks Like

Azure architecture documentation fails because static tools — Visio, Confluence, PowerPoint — record an architect’s mental model at one moment and have no connection to the Azure control plane, so they drift silently from the live environment. The workflow that holds: query Azure Resource Graph on a schedule and write the output to GitHub or Confluence, so the documentation is a formatted export of what is actually running rather than a separate representation of it.

There’s a Confluence page in your organisation that was accurate about 18 months ago. You know it’s wrong. Everyone on the team knows it’s wrong. And every time someone starts to update it, something else has changed by the time they finish.

At this point you’ve probably made a quiet peace with the situation. The docs are wrong. They’re better than nothing. New engineers get a verbal briefing on the gap between what’s documented and what actually runs. You tell auditors the diagram is “approximately current.” And you keep meaning to fix it properly, which means it never gets fixed at all.

This is not a discipline problem. It’s a structural one. And the structure is what needs to change.

Key takeaways

  • Static documentation drift is structural, not a discipline problem. Confluence and Visio have no link to Azure Resource Manager, so they cannot detect that they are wrong.
  • Most environments carry three or four documentation layers — original design, IaC repo, the Confluence page sent to auditors, and Azure Resource Manager itself. Only Resource Manager cannot be wrong.
  • Stale documentation becomes a governance finding in its own right. An auditor running a landing zone compliance review treats a diagram that no longer matches the tenant as evidence of poor visibility, not just operational confusion.
  • The working alternative is four components: a KQL query library, a scheduled pipeline using a Reader-scoped managed identity, a documentation target, and a 30-minute weekly delta review.

The real reason documentation falls behind

Static documentation tools — Visio, draw.io, Confluence pages, PowerPoint — have no connection to the Azure control plane. They record the architect’s mental model at a specific point in time. The Azure environment keeps changing after that. There’s no mechanism in a Confluence page for detecting that it’s wrong. It just sits there, silently accumulating distance from reality.

Consider what happens in a typical month. A new storage account is provisioned for a feature release. Two NSG rules are modified during an incident. A service principal is created for a new integration and assigned Contributor on a resource group. A Log Analytics workspace is stood up in a second region. An old VM is decommissioned. Three new Conditional Access policies are created by the identity team.

None of these changes, individually, would prompt anyone to update the architecture docs. None of them are significant enough on their own. But their cumulative effect — over six months, over twelve — is that the documented architecture no longer describes the environment that runs. And nobody can tell you exactly when the diagram stopped being accurate, because it happened incrementally.

A Terraform plan will tell you when desired state diverges from actual state. A static document just waits.

The layers of documentation that all have different relationships to truth

Most Azure environments at scale actually have three or four documentation layers, and understanding which one is trustworthy for which purpose matters.

The original architecture design — the document produced during the initial deployment project — is usually the most accurate historical record. It describes what was built. Not what runs now.

The IaC repository (Terraform, Bicep) is a closer approximation of intended state. But IaC state and actual Azure resource state diverge when engineers make changes through the portal or CLI outside the pipeline, when resources are imported into Terraform state without full configuration parity, and when drift accumulates between plan runs. It describes what the pipeline last deployed.

The Confluence or SharePoint page is the document that gets sent to auditors. It reflects the environment as it existed at the last major release or compliance review, with incremental annotations from whoever noticed something changed. Lowest fidelity of the three layers. Highest visibility.

And then there’s Azure Resource Manager — the actual state, queryable through Azure Resource Graph — which is definitively accurate at any given moment. Most organisations treat this as a backend system. But it’s the only documentation that can’t be wrong.

What a real-world failure looks like

A Dutch SaaS company — around 140 employees, Series B, financial services sector — went through a NIS2 readiness audit in early 2025. The auditor asked for current network topology documentation. The team’s Confluence architecture page showed three virtual networks and a hub-spoke topology. The actual environment, when queried through Resource Graph, had six virtual networks, two of which had been created for a regional expansion that had shipped eight months earlier.

The discrepancy wasn’t a security vulnerability. But it was evidence to the auditor that the organisation didn’t have reliable visibility into its own infrastructure. That became a finding in its own right — not a technical finding, a governance finding. The remediation requirement was a documented process for keeping architecture documentation current. Not a one-time fix. A process.

That’s the actual cost of stale documentation in a regulated environment: not just operational confusion, but evidence of control gaps that auditors treat as structural.

Azure Resource Graph is the answer to the maintenance problem

Resource Graph is Microsoft’s control plane query API. Real-time, consistent view of all resources across a tenant — properties, configurations, relationships, policy compliance states — queryable through KQL. The critical property for documentation purposes is that it doesn’t drift. It’s not a cached representation or a periodic snapshot. It reflects the actual state of Azure Resource Manager at query time.

This means you can build documentation that’s always current — not because someone updates it, but because it queries the ground truth instead of representing it.

A basic example. This KQL query returns all virtual networks in a tenant with their address prefixes and subnets:

Resources
| where type == "microsoft.network/virtualnetworks"
| project name, resourceGroup, subscriptionId, location,
    addressSpace = properties.addressSpace.addressPrefixes,
    subnets = properties.subnets
| order by subscriptionId, resourceGroup, name

Run that on a schedule and write the output to Confluence or a GitHub markdown file. The result is a network topology record that’s accurate at the time it runs. No engineer has to remember to update it. It doesn’t reflect anyone’s mental model — it reflects what Azure Resource Manager holds.

Same approach for RBAC documentation. A Resource Graph query against the authorizationresources table returns all role assignments across a tenant: the principal, the role definition, the scope. Written to a documentation target weekly, you have an always-current access model record — exactly the kind of record DORA Article 9 and ISO27001 Annex A.9 require.

A minimal viable implementation

The barrier isn’t technical sophistication. It’s knowing which queries to run, how to structure output for human readability, and how to integrate the process without creating a new maintenance burden.

Four components, in order of what to build first.

A query library. KQL queries covering your documentation surface: network topology, resource inventory by subscription, RBAC assignments, policy compliance state, diagnostic settings coverage, and security configuration of key resource types. Version-control this in the same repository as your IaC.

A scheduled execution mechanism. An Azure DevOps pipeline or GitHub Actions workflow that runs the query library on a defined schedule — weekly is sufficient for most governance purposes — and writes output to the documentation target. Authenticate using a managed identity with Reader access. No secrets. No stored credentials.

A documentation target. Match the output format to where your team actually reads documentation. If engineers live in Confluence, write to Confluence via the API. If the team works in GitHub, write markdown files to a documentation repository. The documentation target should be the same place where architecture reviews happen and where audit evidence is stored.

A change review step. Someone needs to look at the weekly output. Not to validate every resource — that’s what the queries do — but to review the delta from the previous week and confirm that what changed was expected. An NSG rule that appears this week but not last week is either an intended change or it’s drift. The review step makes that visible. Thirty minutes a week for a competent platform engineer.

Initial setup is two to three days: writing the query library, building the pipeline, configuring the documentation target integration. After that, the ongoing cost is the weekly review.

The reorientation this requires is treating Azure Resource Manager as the source of documentation rather than the subject of it. The environment isn’t something documentation describes — it’s the thing that generates the documentation. When you build it that way, accuracy is structural rather than effortful. The docs can’t fall behind, because they’re not a separate representation anymore. They’re a formatted export of what’s actually running.

FAQ

Why does Azure architecture documentation always go stale? Because static tools — Visio, draw.io, Confluence, PowerPoint — have no connection to the Azure control plane. They record the architect’s mental model at one point in time, and the environment keeps changing after that. There is no mechanism in a Confluence page to detect that it has become wrong; it just accumulates distance from reality.

Is the IaC repository an accurate record of the environment? Closer than a Confluence page, but not definitive. Terraform or Bicep state diverges from actual Azure state when engineers change resources outside the pipeline, when resources are imported without full configuration parity, and when drift accumulates between plan runs. It describes what the pipeline last deployed, not what runs now.

How does Azure Resource Graph keep documentation current? Azure Resource Graph is Microsoft’s control plane query API, returning a real-time view of every resource, configuration, and policy compliance state at query time. Run a KQL query library on a weekly schedule, write the output to Confluence or a GitHub markdown file, and the record reflects Azure Resource Manager rather than anyone’s memory — the kind of current asset record DORA’s ICT risk framework expects.

What does it take to set up a Resource Graph documentation workflow? Two to three days of initial setup: a version-controlled KQL query library, a scheduled Azure DevOps or GitHub Actions pipeline authenticated with a Reader-scoped managed identity, and a documentation target your team actually reads. After that, the only ongoing cost is a 30-minute weekly review of the delta from the previous run.

(That assessment layer — querying Resource Graph and writing mapped findings straight to GitHub or Confluence — is the thing I build, PAA, for teams who’d rather not maintain the pipeline themselves. Link in the comments. The four components above work without it, and the discipline matters more than the tool.)

So here’s the question worth answering honestly: if you queried Resource Graph against your own tenant this week, how far from your current architecture diagram would the result be? If you genuinely don’t know, that distance is the finding — and it’s the reason the process, not the diagram, is the thing that needs fixing.