Most Azure cost optimisation programmes begin the same way. The bill arrives, it is larger than expected, and someone is asked to produce a report explaining it. Dashboards get built, a rightsizing exercise runs, and six months later the bill is larger again.
The reason is that the report is downstream of the decision. By the time a resource appears in a cost view, someone has already chosen its size, its region, its redundancy and its tier, and nobody was in the room. Microsoft’s Cloud Adoption Framework puts the principle plainly: defining policies is not enough, the organisation must enforce them, and enforcement belongs at the point of deployment.
This piece covers the controls that decide Azure spend before it happens, and one principle that stops governance becoming the thing everyone routes around.
Cost is a governance outcome, not a finance one
The framing that keeps cost programmes stuck is treating spend as something to be analysed after the fact. Four controls decide the bill, and all four operate at provisioning.
| Control | What it prevents | Mechanism |
| Disallowed resource types | Someone deploying a cost-intensive service nobody approved | Azure Policy, Not allowed resource types |
| Allowed locations | Workloads landing in expensive or non-compliant regions | Azure Policy, Allowed locations |
| Tag enforcement and inheritance | Spend that cannot be attributed to anyone | Azure Policy with tag inheritance |
| Budgets with alerts | Drift running for a full billing cycle before anyone notices | Cost Management budgets, which can be cost or usage based, carry multiple thresholds, and trigger automated actions through Action Groups |
None of these is exotic. All four are built in. What makes them effective is that they are inherited rather than requested: applied at the management group, they apply to every subscription beneath, including the ones created next year by people who have never read your governance document.
That inheritance is the same mechanism that makes an Azure landing zone hold together, and it fails for the same reason. A subscription created outside the vending process inherits nothing, and it is not visible as a governance gap. It is visible only as an unexplained line on the invoice.
What we find first
It is rarely the resource everyone assumed was the problem.
In our engagements it is usually a handful of forgotten development and test environments still running at production sizing, or a redundancy setting nobody revisited after go-live. Someone chose zone-redundant or geo-redundant during the build, correctly, and nothing has revisited that decision since.
The pattern underneath is consistent: the team is looking at the big obvious workload, and the money is sitting in the things nobody has looked at since they were deployed.
Tagging is a cost control, not an inventory exercise
Tagging tends to be filed under tidiness. It is the difference between a cost problem you can act on and a cost problem you can only describe.
Untagged spend cannot be allocated, so it cannot be challenged. Nobody defends a number that belongs to nobody. Once resources carry an owner, an environment and a cost centre, the conversation moves from “cloud spend is up 30%” to “this team’s non-production environment is up 30%”, and that is a question with an answer.
Two things make it work in practice. Enforce tags with Azure Policy rather than documenting them, because a documented convention decays within a quarter. And use tag inheritance so resources pick up the tags of their resource group rather than depending on whoever wrote the template.
Allow teams to add their own tags beyond the mandatory set. A tagging strategy that only serves central reporting gets complied with grudgingly; one that also helps a team find its own resources gets maintained.
The principle that stops governance being routed around
This is the one I would argue for hardest, and it is counterintuitive for anyone whose instinct is to lock things down.
Monitor first. Do not block actions until you understand them.
The Cloud Adoption Framework is explicit about this: for lower-priority risk, start by monitoring compliance, then move to more restrictive enforcement once you understand the behaviour. The reasoning is practical rather than philosophical. A policy that blocks something legitimate does not stop the work, it relocates it. The team finds another subscription, another region, or another account, and now you have a governance gap you cannot see rather than a cost you could have discussed.
The corollary is prefer block lists over allow lists. Microsoft’s guidance is direct: it is better to have a short list of services that must not be used than a long list of services that may be. An allow list is a permanent tax on every new service Azure ships, and it guarantees that the platform team is the bottleneck for anything novel.
Both principles point the same way. Governance that is cheap to comply with gets complied with.
Our position: governance at provisioning beats reporting, not alongside it
In our view governance at the point of provisioning beats FinOps tooling and reporting. Not complements, beats. Reporting tells you what already happened. It cannot stop it happening again.
The second half of that position is the one people argue with. A monitor-first approach is not too permissive, even for an estate that is already overspending. The estates that jump straight to blocking are the ones that end up with shadow subscriptions nobody can see, and an invisible overspend is worse than a visible one because you cannot even put it on a chart.
So the sequencing question has a false premise. You do not fix the visible overspend and then enforce going forward. You do both at the same time. One of them recovers money that is already leaking; the other stops the leak reappearing next quarter. Doing them sequentially is how organisations end up running the same rightsizing exercise every eighteen months.
Policy as code, for the reason nobody mentions
Managing policy through the portal works until it does not. The usual argument for policy as code is repeatability. The better argument is that it makes governance reviewable.
When policies live in a repository, a change to what your platform permits arrives as a pull request. It has an author, a reviewer and a date. Six months later, when a resource type everyone assumed was blocked turns out to be deployable, the question “when did this change and who approved it” has an answer.
Enterprise Azure Policy as Code exists for exactly this, and aligns with the landing zone recommended policy set.
There is a maintenance obligation that comes with it, and it is the part most estates skip. Azure landing zone recommended policies change over time. Microsoft publishes guidance on detecting those changes, updating custom policies, and migrating custom policies to built-in equivalents where one now exists. An estate deployed from an accelerator two years ago and never revisited is running a policy set that has since diverged from the recommendation, usually in the direction of more custom policy than it needs.
Start small, and expect to be wrong
The failure mode for governance programmes is scope. A team writes eighty policies, applies them at the root management group, and spends the next two months handling exceptions.
The guidance is to automate a small set of essential policies first, test them, and expand once they hold. That is not timidity. It is that the first set will contain a mistake, and you want to find it against three subscriptions rather than three hundred.
Where to start, in rough order of return:
- Tag enforcement with inheritance, so everything deployed from now on is attributable
- Budget alerts at resource group level, so drift surfaces inside a billing cycle
- Allowed locations, which is usually uncontroversial and prevents a whole class of surprise
- Disallowed resource types, kept deliberately short
- Azure Advisor cost recommendations on a review cadence, because it is free and nobody reads it
The last one is worth a sentence. Advisor generates cost recommendations continuously and they go unread in most tenants. Putting them on a monthly agenda costs nothing and is the least glamorous, highest-yield item on this list.
Note what is absent from that list: rightsizing. It is not that rightsizing is wrong, it is that it is a one-off gain against a recurring problem. An estate that rightsizes without fixing provisioning simply drifts back, and the second exercise is harder than the first because everyone now remembers doing it. Azure cost optimisation that lasts is a change to how resources arrive, not a change to the ones already there.
Two other levers sit outside governance entirely and are worth naming so nobody reads this as the whole picture. Purchase discounts are the largest single reduction available to most estates: Azure savings plans for compute, reservations for one or three year terms, and Azure Hybrid Benefit for existing Windows Server and SQL Server licences. And waste removal, finding resources nobody uses, which Azure Advisor surfaces from the last 30 days of virtual machine usage.
Those are real and you should take them. The reason this piece is about provisioning is that discounts reduce the rate you pay while governance reduces what you deploy, and only one of the two stops the same conversation happening again next year.
There is also a delegation point that decides whether any of this survives contact with delivery teams. The Cloud Adoption Framework is direct that the governance team should set strategy and oversee enforcement, but should not be the team applying the controls. Platform teams apply policies that workloads inherit; workload teams enforce within their own scope. A central group that both writes the rules and operates every control becomes the queue that everything waits behind, which is the same failure that turns a shared CI/CD pipeline into a bottleneck.
Worth being concrete about the scale of the tagging problem, because it is usually underestimated.
Across our estates, untagged spend is rarely a small slice. It is often the largest single category on the bill until someone enforces tagging. Not a rounding error at the bottom of the report, the biggest line on it.
And then something useful happens. Once attribution exists, behaviour shifts faster than any policy change that follows it. The tagging policy is not really the control. It is what makes every subsequent control possible, and it does most of the work before you enforce anything else.
Where to start
Do not begin with a rightsizing exercise. Begin by asking whether a resource deployed tomorrow would arrive tagged, in an approved region, of an approved type, inside a subscription that inherited your policies. If the answer to any of those is no, the reporting will always be describing a problem that has already happened.
Then apply the four controls at the management group rather than the subscription, so they survive the org chart. That ordering is deliberate and it generalises: management group hierarchy is decided before subscription placement, because inheritance is what makes any of these controls survive a reorganisation.
Veratas designs and governs Azure platforms, and does the enterprise architecture work that decides where those boundaries belong in the first place.
If your Azure spend is rising and nobody can attribute it by team, talk to our team. Attribution comes before optimisation, and it is a shorter piece of work than most people expect.
Frequently asked questions
Why does Azure spend drift even with cost reporting in place? Because reporting is downstream of provisioning. Size, region, tier and redundancy are decided at deployment, and a cost view can only describe choices that have already been made.
What is the single highest-return cost control? Enforced tagging with inheritance. Untagged spend cannot be attributed, and unattributed spend is never challenged by anyone.
Should we block services we do not want used? Eventually, but monitor first. The Cloud Adoption Framework recommends understanding behaviour before restricting it, because a policy that blocks legitimate work relocates that work somewhere you cannot see.
Block list or allow list? Block list. Microsoft’s guidance is that a short list of prohibited services is better than a long list of permitted ones, which otherwise needs updating every time Azure ships something new.
Why manage Azure Policy as code? Repeatability, but more usefully reviewability. A change to what your platform permits arrives with an author, a reviewer and a date, which matters when someone asks how a resource type became deployable.
Do landing zone policies need maintaining? Yes. Recommended policy sets change over time, and Microsoft publishes guidance on detecting changes, updating custom policies and migrating to built-in equivalents. An accelerator deployment left untouched for two years has drifted from the recommendation.

Cloud and enterprise architect with 17 years of experience across data platforms, integration and application development. Focus areas include Azure architecture, cloud-native application design, and ERP to data platform integration.






