Policy as Code for Azure – Is It Worth Your Time?

Elliott Leighton-Woodruff, Principle Architecture at Synextra
Article by:
Elliott Leighton-Woodruff
Principal Architect

Let’s be honest, nobody gets into cloud because they love governance, but at some point you realise that clicking around the portal isn’t cutting it especially when the auditors start poking about. Hunting through Azure’s portal for half-remembered settings just doesn’t scale, especially if you’ve got more than a single environment. This is where policy as code steps in: visible, reviewed, and predictable enforcement, right there alongside your infrastructure.

Why PaC (Policy-as-Code)?

A manual governance approach is slow, error-prone and rarely matches between dev, test and prod. Moving to code means:

  • No more drift between subscriptions or environments
  • Every change is tracked and reviewable (so you know what broke and why)
  • Easy audit compliance “Yes, it’s in Git”
  • Undo or fix mistakes by rolling back, rather than click-hunting

Terraform

If your team already uses Terraform (and let’s face it, most mature Azure teams do), rolling policies into your workflow just makes sense. Terraform’s support for Azure Policy lets you deal with both infrastructure and governance using the same language and pipelines.

Prerequisites

  • Terraform installed (grab it from HashiCorp’s site)
  • Azure subscription and appropriate permissions (Contributor or above for most things; Policy Contributor for policy work)
  • A Git repository to store your code and track changes
  • Either Azure CLI or Azure PowerShell set up locally

Define the policy you want to use

Let’s say you want every resource to prevent storage account from being made public (because someone on your team will definitely forget). There’s an inbuilt policy for this we just need to call it with a data resource:

You can view the actual policy here: Block public access to SA – Azure Policy | Azure

And the list of all built in policies here: List of built-in policy definitions – Azure Policy | Microsoft Learn

Additionally, defining custom policies can be achieved using: azurerm_policy_definition | Terraform Registry

Assign the policy

Here you decided, should this be assigned to a management group, a subscription or even lower still? Generally I’d always recommend management group level policies and at the highest level you can afford too, though development and production environments have different needs so keep that in mind.

Worth noting the above denies the creation of the resource, though you could set this to audit if you just wanted to report.

Apply an exemption, if needed

Theres various reasons why you might want an exemption, ensuring these are in code keeps the whole process well audited and can provide key insights when that pesky auditor starts asking you questions!

CI/CD

It’s not policy as code if you’re pushing from local every time. Hook Terraform into your CI/CD pipeline, Azure DevOps, GitHub Actions, whatever fits. Pipelines should:

  • Run terraform plan on PRs to preview changes
  • Require review before terraform apply
  • Store the state securely (prefer backends like Azure Storage for tfstate)

No more “who made this change?” dramas.

What about Bicep or EPAC?

Not every team wants to learn HCL (the Terraform language), or maybe your estate is 100% Azure and you want the shortest path.

Bicep

  • Azure-native: Bicep is purpose-built for Azure not cloud-agnostic, but tight integration and easy syntax.
  • No external state file: State is always what’s live in Azure. Good and bad no risk of state file loss, but rollbacks need extra care.
  • Policy Support: Can define and assign policies, though less mature for governance workflows than Terraform.
  • When to Use: You want native Azure support, a gentle learning curve, and direct integration with ARM templates.

EPAC (Enterprise Policy as Code)

  • Azure Policy Focused: EPAC is all about policy, not infra it’s Microsoft’s automation and governance toolkit built for environments with serious audit needs.
  • Source of Truth: Your repo defines the desired state. If it’s not in Git, it gets deleted that’s powerful, but be careful in brownfield setups.
  • CI/CD-Friendly: Designed for pipelines; integrates with Azure DevOps and GitHub Actions for controlled, reviewed deployments.
  • Advanced Extras: Supports documentation automation, policy exemptions and is the best fit if you want to wrangle lots of management groups or need built-in compliance reports.

Let’s go!

There you have a solid way to stop governance being “someone else’s problem”. Start in code, start simple, and make sure policy gets as much love as your app code, because trust me the auditors look just as hard at both.

 

Subscribe to our newsletter

Stay ahead of the curve with the latest trends, tips, and insights in cloud computing

thank you for contacting us image
Thanks, we'll be in touch.
Go back
By sending this message you agree to our terms and conditions.