<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Protect your Azure resources via Tags]]></title><description><![CDATA[Protect your Azure resources via Tags]]></description><link>https://azporro.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 03:08:35 GMT</lastBuildDate><atom:link href="https://azporro.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[What if I told you that Tags can protect critical workloads from being deleted by everyone including Owners?]]></title><description><![CDATA[Yes, you read that right. Not Resource Locks. Not RBAC. Tags.
Here's what we built and why it matters:

The Problem
We were working with a customer with project subscriptions with foundational network]]></description><link>https://azporro.com/Azure-Tags-Protection</link><guid isPermaLink="true">https://azporro.com/Azure-Tags-Protection</guid><category><![CDATA[Azure]]></category><category><![CDATA[Governance]]></category><category><![CDATA[Azure Policy]]></category><category><![CDATA[Landing Zone]]></category><dc:creator><![CDATA[Porat Arzouan]]></dc:creator><pubDate>Wed, 11 Mar 2026 09:58:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6979d0498dfef562e6e8eb29/c3edc0bb-6453-466e-96c7-26d5e217deb4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yes, you read that right. Not Resource Locks. Not RBAC. <strong>Tags.</strong></p>
<p>Here's what we built and why it matters:</p>
<hr />
<p><strong>The Problem</strong></p>
<p>We were working with a customer with project subscriptions with foundational networking resources VNets, Subnets, Route Tables, VPN Gateways, NSGs the underlying infrastructure that connects workloads back to the hub and keeps everything running.</p>
<p>Here's the challenge: the customer needed to grant their engineers <strong>full Owner access</strong> within these project subscriptions to move fast and deliver. But it wasn't just about access, <strong>engineers also needed the autonomy to create their own VNets, VPN Gateways, and other networking resources</strong> for their project needs. You can't just blanket block all networking operations.</p>
<p>But being an owner means having the freedom to do anything within the scope(all, or specific resource), they could also accidentally (or intentionally) delete or modify the <strong>foundational</strong> networking infrastructure that the landing zone depends on. The spoke VNet connecting back to the hub, the Route Tables enforcing traffic flow, the pre-configured peerings all of it was exposed.</p>
<p>Resource Locks? Owners can remove them. RBAC restrictions? that's IT overhead and never-ending race of the correct permissions, also every month new project is launched, and new Custom role is needed.</p>
<p><strong>What about Azure Deployment Stacks?</strong> for those of you who dont know: Deployment Stacks offer built-in deny assignments that can protect managed resources from deletion and modification. It's actually a great fit for this kind of problem. But there was a catch: <strong>Azure Deployment Stacks currently only supports Bicep</strong>. The customer's entire infrastructure is built and managed with <strong>Terraform</strong>. Switching IaC tools wasn't on the table.</p>
<p>So, we needed a solution that works natively with Terraform and still gives us that level of protection. The customer needed a way to say: <strong>"You own everything in your project subscription create whatever you need but you can't touch the networking foundation beneath your feet."</strong></p>
<p><strong>The Idea: Tags as a Protection Mechanism</strong></p>
<p>We designed a multi-layered Azure Policy solution where a simple tag — <code>Environment: networking_protected</code> becomes an <strong>immutability shield</strong> around landing zone networking resources.</p>
<p>Here's how it works:</p>
<p><strong>Layer 1 — Tag Based Immutability (The Game Changer)</strong></p>
<ul>
<li><p>A <strong>Deny</strong> policy prevents <strong>any modification</strong> to resources carrying the protected tag</p>
</li>
<li><p>A <strong>DenyAction</strong> policy prevents <strong>any deletion</strong> of resources carrying the protected tag</p>
</li>
</ul>
<p>The result? Once a networking resource in a project subscription exists that we want to lock, it's locked. No one not Contributors, not even <strong>Owners</strong> — can delete or modify it through the Azure control plane. Engineers keep their full Owner permissions for everything else — including creating their own VNets and VPN Gateways — but the networking foundation remains untouchable. The tag acts as a boolean "this resource is now immutable" flag.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6979d0498dfef562e6e8eb29/d6009eb5-56af-416e-a63f-810c944e5eba.png" alt="" style="display:block;margin:0 auto" />

<p>In this picture you can see multiple policies triggered one for specific DNS config changes block and one for deny creation of any change to Microsoft.Network/* resources</p>
<p>But then you ask yourselves well I can just delete the tag and then I can do whatever I want, that's where Layer 2 come to play with Modify effect</p>
<p><strong>Layer 2 — Self Healing Auto-Tagging</strong><br />We built a <strong>Modify</strong> policy that automatically tags every networking resource (<code>Microsoft.Network/*</code>) with <code>Environment: networking_protected</code> the moment it's created or updated. No human intervention needed. A System-Assigned Managed Identity handles the tagging seamlessly. Every Route Table, every VNet, every VPN Gateway tagged and protected from day one,</p>
<ul>
<li>Modify policies provide corrective remediation and are not a synchronous enforcement boundary.</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/6979d0498dfef562e6e8eb29/194deb44-bdeb-4add-8786-711489a4c398.png" alt="" style="display:block;margin:0 auto" />

<p>And what happens when someone deletes this tag? it automatically within seconds attach back because of the Modify effect</p>
<img src="https://cdn.hashnode.com/uploads/covers/6979d0498dfef562e6e8eb29/b36f69bf-c609-4d50-9640-3acbb2e3a794.png" alt="" style="display:block;margin:0 auto" />

<p><strong>Layer 3 — Compliance Enforcement</strong></p>
<ul>
<li><p><em>That's optional step, not every customer want to deny creation without tag</em></p>
</li>
<li><p>The Deny policy provides the hard enforcement boundary</p>
</li>
</ul>
<p>A <strong>Deny</strong> policy blocks the creation of any networking resource that's missing the required tag. This acts as a safety net if the auto tagging policy is ever disabled, non-compliant resources simply can't be created.</p>
<p><strong>Layer 4 — Granular Action Level Controls</strong><br />We also tried to narrow it down beyond just <code>Microsoft.Network/*</code>. Rather than broad resource-type blocking, we successfully built policies that target <strong>specific actions</strong> for example, blocking only VNet peering creation or deletion, locking DNS server changes on VNets, or preventing VNet deletion specifically. This gave us surgical precision: protect exactly what needs protecting without interfering with engineers everyday work.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6979d0498dfef562e6e8eb29/abfe7fff-1057-4a17-a187-8eedcce36540.png" alt="" style="display:block;margin:0 auto" />

<p><strong>Why We Chose This Solution</strong></p>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p></p></td><td><p><strong>Resource Locks</strong></p></td><td><p><strong>Tag-Based Policy</strong></p></td><td><p><strong>Deployment Stacks</strong></p></td></tr><tr><td><p><strong>Owners bypass?</strong></p></td><td><p><strong>Yes</strong></p></td><td><p><strong>No</strong></p></td><td><p><strong>No</strong></p></td></tr><tr><td><p><strong>Self-healing?</strong></p></td><td><p><strong>No</strong></p></td><td><p><strong>Yes</strong></p></td><td><p><strong>No</strong></p></td></tr><tr><td><p><strong>Scales automatically?</strong></p></td><td><p><strong>No</strong></p></td><td><p><strong>Yes</strong></p></td><td><p><strong>No</strong></p></td></tr><tr><td><p><strong>Audit mode?</strong></p></td><td><p><strong>No</strong></p></td><td><p><strong>Yes</strong></p></td><td><p><strong>No</strong></p></td></tr><tr><td><p><strong>Terraform?</strong></p></td><td><p><strong>Partial</strong></p></td><td><p><strong>Yes</strong></p></td><td><p><strong>No (Bicep only)</strong></p></td></tr></tbody></table>

<p><strong>The Infrastructure as Code Angle</strong></p>
<p>The entire solution is deployed via <strong>Terraform</strong> parameterized, reusable, and scope flexible. You can deploy it at the subscription level, resource group level, or management group level. It supports:</p>
<ul>
<li><p>Definition-only mode (deploy policies without assignments)</p>
</li>
<li><p>Audit-only mode (monitor before enforcing)</p>
</li>
<li><p>Full enforcement mode</p>
</li>
</ul>
<p>One codebase. Any scope. Full governance.</p>
<p><strong>The Takeaway</strong></p>
<p>Governance is not about making every day work harder it's about finding the sweet spot between what the company needs and what engineers need to do their jobs.</p>
<p>Azure Landing Zones give you a solid foundation but protecting the networking within project subscriptions, while giving engineers the freedom to build what they need, is the real-life challenge to many companies. Azure Policy is one of the most underutilized tools in cloud governance. With the right combination of <strong>Modify</strong>, <strong>Deny</strong>, and <strong>DenyAction</strong> effects, you can turn a simple tag into a protection mechanism that even subscription Owners can't bypass, and it works beautifully with Terraform.</p>
<p>Engineers get full Owner access. They create their own resources freely. Landing zone networking stays untouchable. Everyone wins.</p>
<p>Tags aren't just metadata. They can be <strong>guardrails</strong>.</p>
<p><strong>Want the Terraform code?</strong> If this sounds interesting to you, reach out I'd gladly share the Terraform files so you can implement this in your own environment.</p>
]]></content:encoded></item></channel></rss>