Loading...

That's not my name! How to use Azure Policy to enforce resource naming conventions in your DevOps pipelines

That's not my name! How to use Azure Policy to enforce resource naming conventions in your DevOps pipelines

Let’s talk about Azure naming conventions

I know, I know, you’re probably thinking, “Seriously? We’re gonna talk about names?” But trust me, this stuff matters.

naming conventions

Why Should You Care About Names?

Think about it like this: imagine you’ve got a massive garage full of tools, but nothing’s labeled. Nightmare, right? That’s kinda what it’s like when you’ve got a ton of Azure resources with random names. It’s a mess, and nobody wants to deal with that.

Good names make life easier. You can tell at a glance what something is, where it belongs, and what it’s for. Plus, when it comes to tracking costs or making sure you’re following the rules, good names are a lifesaver.

What Microsoft Says About It

Microsoft’s got some ideas about how to name stuff in Azure. They suggest something like this:

<org>-<proj>-<env>-<region>-<resource-type>-<instance>

So, if you’re working on a web app for Contoso, it might look like:

contoso-webapp-prod-eastus-app-01

Not too shabby, right? You can tell it’s for Contoso, it’s a web app, it’s in production, sitting in East US, and it’s an app service. The ‘01’ at the end is just in case you need more than one.

The problem with doing this manually

Trying to make sure everyone follows these rules manually is a pain in the butt. People forget, they get lazy, or they just don’t care. And then you’ve got a mess on your hands.

Plus, going through and checking all the names by hand? Boring. And fixing mistakes after the fact? Even worse.

How to make it suck less

This is where the cool part comes in. We can use Azure CLI and Azure Policy to do the heavy lifting for us. Basically, we set up a system that checks the names before anything gets created. If the name’s wrong, it doesn’t let it through.

Here’s the general idea:

  1. Figure out what pattern you want your names to follow - welcome to Regex hell!
  2. Write a little script that checks if a name matches that pattern
  3. Hook that script in your Azure DevOps pipeline

Now, every time someone tries to create something, it has to pass the name check first. Pretty slick, huh? But if we just wrote the script in DevOps, then it would only apply if someone tries to deploy resources via DevOps. It wouldn’t catch non compliant resources that are created for example in the Azure Portal. Our hero? It’s once again Azure Policy! Azure Policy makes sure that regardless how a resource is being created, it needs to comply to the policy that you set.

Use Azure Policy

We have several options now… either create the policy with Azure CLI or deploy the policy definition and policy assignment with Bicep.

I’ll cover how to use Bicep for this:

targetScope = 'subscription'
resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
name: 'enforce-resource-naming'
properties: {
displayName: 'Enforce resource naming pattern'
mode: 'All'
policyRule: {
if: {
field: 'name'
notMatch: '^[a-zA-Z0-9]{1,}-[a-zA-Z0-9]{1,}-[a-zA-Z0-9]{1,}-[a-zA-Z0-9]{1,}-[a-zA-Z0-9]{1,}-[a-zA-Z0-9]{1,}$'
}
then: {
effect: 'deny'
}
}
parameters: {}
metadata: {
category: 'Naming'
}
}
}
resource policyAssignment 'Microsoft.Authorization/policyAssignments@2021-06-01' = {
name: 'enforce-resource-naming-assignment'
properties: {
displayName: 'Enforce resource naming pattern assignment'
policyDefinitionId: policyDefinition.id
scope: subscription().id
}
}

If we now deploy a resource:

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
name: 'contoso-webapp-prod-weu-stg-01' // This name must comply with the policy
location: 'westeurope'
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
}
}

Azure policy will check if the name complies. If not, it will block the deployment due to the deny in the policy.

You can also check your previously created resources with

az policy state list --query "[?complianceState=='NonCompliant']"

Make it work in your DevOps pipeline

And the best part? You can hook it right into your DevOps pipeline. So before you deploy anything, you can double-check that it’s all the way you wanted it in the first place. It runs the az policy state list command to check whether any resources are non-compliant. If violations are detected, the pipeline exits with a non zero status which causes the pipeline to fail.

trigger:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
azureSubscription: '<Your-Service-Connection>'
resourceGroupName: '<Your resource group name>'
location: 'westeurope'
steps:
# Install Azure CLI and Bicep
- task: AzureCLI@2
inputs:
azureSubscription: $(azureSubscription)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
 # Install Azure CLI Bicep extension
 az bicep install
displayName: 'Install Bicep CLI'
# Deploy Bicep File to Azure
- task: AzureCLI@2
inputs:
azureSubscription: $(azureSubscription)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
 echo "Deploying Bicep template..."
 az group create --name $(resourceGroupName) --location $(location)

 # Deploy Bicep file
 az deployment group create \
 --resource-group $(resourceGroupName) \
 --template-file main.bicep
displayName: 'Deploy Bicep Template'
# Check Azure Policy Compliance
- task: AzureCLI@2
inputs:
azureSubscription: $(azureSubscription)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
 echo "Checking Azure Policy compliance..."

 # Check for any non-compliant resources in the resource group
 compliance_results=$(az policy state list --resource-group $(resourceGroupName) --query "[?complianceState=='NonCompliant'].{resourceId:resourceId, policyAssignmentName:policyAssignment}" --output table)

 if [ -n "$compliance_results" ]; then
 echo "Non-compliant resources detected:"
 echo "$compliance_results"
 exit 1 # Fail the pipeline if there are non-compliant resources
 else
 echo "All resources are compliant with Azure Policy."
 fi
displayName: 'Check Policy Compliance'

Conclusion

Naming conventions aren’t exactly the most thrilling topic. But trust me, getting this stuff right can save you a ton of headaches down the road. It’s like organizing your garage – it’s a pain to do, but once it’s done, life gets so much easier. Azure Policy does the heavy lifting here for us and hooking that approach into your Azure DevOps pipeline will just make sure that you’ll never ever have to think about naming again. You are welcome!

Published on:

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

Recent content on Luise Freese: Consultant & MVP

Share post:

Related posts

Introducing Azure HorizonDB - PostgreSQL

Run enterprise Postgres workloads on Azure HorizonDB with around 3x the throughput of self-managed deployments — zone-resilient by default, no...

6 hours ago

Azure DevOps and GitHub: Journeying into the AI Era

AI is changing how software gets planned, built, and reviewed. As teams adopt agentic development, the platform underneath those workflows mat...

1 day ago

Introducing azure-functions-skills: An AI-Era Workspace for Azure Functions (Preview)

azure-functions-skills gives GitHub Copilot CLI, Claude Code, Codex CLI, and VS Code the skills, MCP configuration, hooks, and instructions ne...

1 day ago

Announcing the Public Preview of Integrated Embeddings in Azure Cosmos DB: Build AI Apps With Embeddings That Stay in Sync

AI applications built on Azure Cosmos DB depend on embeddings for grounded results. Keeping them in sync with your data is the hard part: it m...

1 day ago

Introducing OmniVec: An Open-Source Embedding Platform for AI Apps on Azure

Today we are open-sourcing OmniVec, a platform for building and operating the embedding pipelines that keep the vector representation of your ...

1 day ago

Azure Cosmos DB All Versions and Deletes Change Feed Mode is Now Generally Available

Modern applications don’t just write data and move on. They react to it. A new order triggers an inventory update. A profile change sync...

1 day ago

Change Partition Keys in Azure Cosmos DB is Now Generally Available

We’re excited to announce the general availability of Change Partition Key in Azure Cosmos DB for NoSQL, now with online copy support. Y...

1 day ago

Announcing the General Availability of Per Partition Automatic Failover for Azure Cosmos DB NoSQL

Today, we are excited to announce the General Availability of Per Partition Automatic Failover (PPAF) for Azure Cosmos DB NoSQL API. PPAF is a...

1 day ago

Public Preview: AI-powered Azure Cosmos DB Migration Assistant for RDBMS to NoSQL

Today, we are excited to announce the public preview of the Azure Cosmos DB Migration Assistant for RDBMS to NoSQL, now available in the Azure...

1 day ago

Azure Cosmos DB MCP Toolkit Is Now Generally Available — Bringing Your Database to AI Agents at Scale

Since we introduced the Azure Cosmos DB MCP Toolkit at Ignite 2025 in preview, the response has been clear: developers want a straightforward ...

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