Loading...

Go Go governance! Enforcing Azure Policies with Azure CLI

Go Go governance! Enforcing Azure Policies with Azure CLI

This post is part of a series about Deployments, Role Assignments and more!


In my last post about ABAC I showed that we can assign a role to resources that are tagged with for example with Department == Finance or Project == DeathStar? Well that only makes sense if noone forgets to tag resources correctly, right?

If you’ve worked with Azure for any amount of time, you know how easy it is for things to get out of control. Different teams deploying resources, some in the wrong regions, others without proper tags—before you know it, your cloud setup looks like a mess. That’s where Azure Policies come in to save the day.

Think of Azure Policies as guardrails that help you keep everything in line. They make sure that everyone follows the rules you set. No more resources popping up in unapproved regions or missing critical information like cost tags.

The Workaround (and Why It Doesn’t Work)

Manually enforcing these rules by trusting teams to follow best practices or having endless spreadsheets and documents for tracking resource usage, doesn’t work (Ask me how I know 😇). Without policies, you’d rely on documentation, hope (🤞🤞), and good intentions. Maybe you’d have a workaround where people manually check if resources are in the right region or tag everything properly. Sorry to break it to you, but that ain’t a proper process. Azure Policies automate all of that, so you don’t have to chase people down. Once you set a policy, it just works. If someone tries to break the rules, the policy will stop them. No manual enforcement needed. The policy stops non-compliant resources from being created in the first place.

It’s not a trick, it’s an Azure policy

What We’ll Do Here

Today, we’re going to enforce two simple, but super effective policies:

  1. Everything in your subscription has to be deployed in West Europe
  2. All resources in a specific resource group need a CostCenter tag (because tracking cloud costs is important, right?).

Let’s Enforce a Location Policy for the Entire Subscription

First up, we’ll make sure everything in your Azure subscription is deployed in westeurope.

Create the Location Policy

The Azure CLI makes this process easy. First, we’ll create a policy that only allows resources to be deployed in westeurope.

# Create the policy definition in Azure
az policy definition create `
--name "AllowedLocations" `
--display-name "Enforce West Europe Location" `
--description "Ensures that resources are only deployed in West Europe." `
--rules '{
 "if": {
 "field": "location",
 "notEquals": "westeurope"
 },
 "then": {
 "effect": "Deny"
 }
}' `
--mode All

This policy checks the location of any new resource, and if it’s not set to westeurope, the creation gets blocked.

Assign the Policy to Your Subscription

Now that we’ve created the policy, we need to assign it to the whole subscription to make sure it applies everywhere.

# Get your subscription ID
$SUBSCRIPTION_ID=$(az account show --query "id" -o tsv)
# Assign the policy to the subscription
az policy assignment create `
--name "RequireWestEurope" `
--policy "AllowedLocations" `
--scope "/subscriptions/$SUBSCRIPTION_ID" `
--display-name "Enforce West Europe Location"

With this in place, no matter how someone tries to create a resource (CLI, portal, etc.), if it’s not in West Europe, it won’t happen. 🎤💧⬇️

Enforcing a Tagging Policy for a Specific Resource Group

Now let’s focus on enforcing tags for a particular resource group. Let’s say you have a resource group where every resource needs a CostCenter tag, so you can track cloud spending effectively.

Create the Tagging Policy

Here’s the policy that checks if the CostCenter tag is present. If it’s not, the policy blocks the creation of that resource.


# Create the policy definition in Azure
az policy definition create --name "EnforceCostcenterTag" `
--rules '{
 "if":{
 "field":"tags.Costcenter",
 "exists":"false"
 },
 "then": {
 "effect":"Deny"
 }
 }' `
--mode All `
--display-name "Enforce Costcenter Tag on All Resources"

This policy checks each resource, and if it’s missing the CostCenter tag, the policy kicks in and denies its creation.

Assign the Tagging Policy to a Resource Group

Now, assign this policy to a specific resource group where you need to enforce tagging.

# Define the resource group name
RESOURCE_GROUP_NAME="YourResourceGroup"
SUBSCRIPTION_ID=$(az account show --query "id" -o tsv)
SCOPE="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME"
# Assign the policy to the resource group
az policy assignment create `
--name "RequireCostCenterTag" `
--policy "EnforceCostCenterTag" `
--scope "$SCOPE" `
--display-name "Require CostCenter Tag on Resources"

From now on, if someone tries to create a resource in this group without a CostCenter tag, they’ll get stopped right away.

Why This Works for Every Deployment Method

What makes Azure Policies powerful is that they work no matter how you deploy resources

  • If someone uses the Azure Portal, they’ll be blocked if they try to create a non-compliant resource
  • Using Azure CLI? The policy still applies!
  • Even if you’re using Infrastructure as Code (like Bicep or Terraform), the policies will ensure that every resource meets your standards.

Sneak Peek into Azure DevOps pipelines

In a future post, I’ll explain how these policies play an important role when integrating Azure DevOps pipelines into your deployment workflows. Imagine automating your entire deployment process, and still having these policies enforce compliance on every resource that gets created. No more manual checks, just smooth, policy-driven deployments.

Stay tuned 🤖

Published on:

Learn more
Luise Freese: Consultant & MVP
Luise Freese: Consultant & MVP

Recent content on Luise Freese: Consultant & MVP

Share post:

Related posts

Give your Foundry Agent Custom Tools with MCP Servers on Azure Functions

Learn how to connect your MCP server hosted on Azure Functions to Microsoft Foundry agents. This post covers authentication options and setup ...

4 hours ago

Scalable AI with Azure Cosmos DB: Tredence Intelligent Document Processing (IDP) | March 2026

Azure Cosmos DB enables scalable AI-driven document processing, addressing one of the biggest barriers to operational scale in today’s enterpr...

1 day ago

Announcing the end of support for Node.js 20.x in the Azure SDK for JavaScript

After July 9, 2026, the Azure SDK for JavaScript will no longer support Node.js 20.x. Upgrade to an Active Node.js Long Term Support (LTS) ver...

1 day ago

MCP Apps on Azure Functions: Quickstart with TypeScript

Learn how to build and deploy MCP (Model Context Protocol) apps on Azure Functions using TypeScript. This guide covers MCP tools, resources, l...

2 days ago

Setting up Power BI Version Control with Azure Dev Ops

In this blog post is a way set up version control for Power BI semantic models (and reports) using the PBIP (Power BI Project) format, Azure D...

7 days ago

Azure Developer CLI (azd) – March 2026: Run and Debug AI Agents Locally, GitHub Copilot Integration, & Container App Jobs

Run, invoke, and monitor AI agents locally or in Microsoft Foundry with the new azd AI agent extension commands. Plus GitHub Copilot-powered p...

8 days ago

Writing Azure service-related unit tests with Docker using Spring Cloud Azure

This post shows how to write Azure service-related unit tests with Docker using Spring Cloud Azure. The post Writing Azure service-related uni...

9 days ago

Azure SDK Release (March 2026)

Azure SDK releases every month. In this post, you find this month's highlights and release notes. The post Azure SDK Release (March 2026) appe...

12 days ago

Specifying client ID and secret when creating an Azure ACS principal via AppRegNew.aspx will be removed

The option to specify client ID and secret when creating Azure ACS principals will be removed. Users must adopt the system-generated client ID...

13 days ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy