Azure Policy Baseline: The Guardrails I Would Enable First


Azure Policy Baseline: The Guardrails I Would Enable First
This is the third piece in a series about building an Azure platform. The first looked at landing zones as more than a pile of subscriptions, and the second at management groups and subscription structure. With that hierarchy in place, the obvious next question is: what do you actually enforce inside it?
The honest answer is not “fifty Azure Policies.” A long policy catalogue looks impressive and helps almost no one. What matters is the small set of guardrails you put in place before workloads spread everywhere — while the environment is still small enough to shape.
So this is not a complete policy library. It is the baseline I would turn on first.
Governance should make the safe path easier
The most common way governance goes wrong is that it shows up late and angry. Workloads get deployed, something goes wrong, and policy is bolted on afterwards to punish the team that made the mistake. From then on, governance is the thing that says no.
I would rather governance be the thing that quietly makes the right choice the easy one.
Good governance is not about blocking every mistake. It is about making the intended architecture difficult to accidentally bypass.
Azure Policy is well suited to this if you use it deliberately. It is not a firewall and it is not a code review. It is a way to make the expected behaviour of the platform explicit and continuously checked — so the shape of the environment stays close to what you designed, even as dozens of people deploy into it.
The mindset that keeps this healthy: enforce the few things that are genuinely non-negotiable, audit the things you want to understand before you restrict, and give teams a clear path rather than a wall.
What I would enforce early
These are the controls I am comfortable setting to Deny (or Modify/Append) from day one, because the cost of getting them wrong later is high and the inconvenience of enforcing them now is low.
- Required tags. Owner, environment, and cost-centre at minimum. Tags are the backbone of cost reporting, ownership, and cleanup. Enforcing them later means backfilling thousands of resources by hand, so this is the cheapest possible thing to require on day one. A
Modifyeffect that inherits tags from the resource group makes this nearly invisible to teams. - Allowed regions. Restrict deployments to the regions you actually operate in. This keeps data residency predictable and stops resources quietly appearing in regions nobody monitors or secures.
- Secure transfer / HTTPS only. Require secure transfer on storage accounts and HTTPS-only on app services. There is no good reason to allow the insecure path, and denying it costs teams nothing.
- No public IPs where they are not needed. Deny public IP addresses on resources that should sit behind your network design. Public exposure should be a deliberate, reviewed decision — never the default that happens because someone clicked through a wizard.
- Restrict public network access on data services. Block public access to storage, databases, and key vaults by default. This is the control that most often prevents an accidental data exposure, and it pairs naturally with the private-connectivity model from the landing zone.
The common thread: each of these is something you would have to undo at scale if you allowed it now and regretted it later. Enforcing early is the kind thing to do.
What I would audit before denying
Just as important is knowing what not to deny on day one. Some controls will break existing or in-flight workloads if you switch straight to Deny, and breaking teams is how governance loses trust permanently.
For these, I start with Audit (or DeployIfNotExists), watch what the estate actually looks like, and only tighten to Deny once I understand the impact and have given teams a path.
- Diagnostic settings. Use
DeployIfNotExiststo send logs and metrics to a central Log Analytics workspace, rather than denying resources that lack them. You want the data flowing, not deployments failing. - Defender for Cloud / security baselines. Audit coverage and configuration first. These plans have cost and operational implications, so roll them out knowingly rather than as a hard gate.
- Private endpoint usage. Audit which data services are missing private endpoints. This tells you how close the estate is to your intended network model — useful long before you are ready to enforce it.
- Backup and monitoring. Audit resources that are missing backup or alerting. Whether something needs a backup is a workload decision; surfacing the gap is a platform responsibility.
Audit-first is not weaker governance. It is how you earn the right to enforce later without surprises.
Example baseline categories
A useful way to think about the baseline is by category and intended effect. This is roughly where I would start:
| Category | Example control | Effect | Stage |
|---|---|---|---|
| Tagging | Require owner / environment / cost-centre | Modify / Deny | Enforce |
| Location | Allowed regions only | Deny | Enforce |
| Encryption | Secure transfer / HTTPS only | Deny | Enforce |
| Public exposure | No public IPs unless approved | Deny | Enforce |
| Data access | Restrict public network access on data services | Deny | Enforce |
| Logging | Diagnostic settings to central workspace | DeployIfNotExists | Audit → enforce |
| Security baseline | Defender plans and recommendations | Audit | Audit |
| Connectivity | Private endpoints on data services | Audit | Audit |
| Resilience | Backup and monitoring coverage | Audit | Audit |
Group these into a single initiative (policy set) and assign it at the management-group level so it applies consistently across subscriptions. One assignment at the right scope beats dozens of one-off policies scattered across the estate.
Common mistakes
A few patterns that turn a good baseline into a painful one:
- Turning everything on at
Denyon day one. The fastest way to make teams resent the platform and start looking for ways around it. Enforce the non-negotiables, audit the rest. - No exemption process. There will always be a legitimate exception. If the only way to get one is to disable the policy, people will disable the policy. Use scoped, time-bound exemptions instead.
- Assigning at the wrong scope. Policies pinned to individual subscriptions drift apart over time. Assign initiatives at the management group so new subscriptions inherit the baseline automatically.
- Forgetting remediation.
DeployIfNotExistsandModifypolicies do nothing for existing resources until you run a remediation task. A policy that only governs future deployments leaves the current estate untouched. - Policy sprawl. Fifty narrow policies nobody can reason about is worse than ten you can explain. Keep the baseline small enough to hold in your head.
Closing thoughts
A policy baseline is not about catching every possible mistake. It is about making the platform’s intended shape the path of least resistance — so the secure, supportable, well-tagged deployment is also the easiest one to make.
Start with the few guardrails that are expensive to retrofit, audit the things you want to understand before you restrict them, and grow the baseline as the estate matures and trust builds. Done this way, governance stops being the team that says no and becomes the quiet structure that keeps a fast-moving environment from drifting away from its own design.