{"id":91261,"date":"2021-06-08T17:00:30","date_gmt":"2021-06-08T17:00:30","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=91261"},"modified":"2021-06-07T22:02:53","modified_gmt":"2021-06-07T22:02:53","slug":"how-essential-are-azure-policies","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/how-essential-are-azure-policies\/","title":{"rendered":"How Essential Are Azure Policies"},"content":{"rendered":"<p><strong>Policies<\/strong> in <strong>Azure<\/strong> are like Wally. They are there, but not obvious to find, hidden in the middle of many services, waiting for someone recognize their importance.<\/p>\n<h2>Why do we need Policies<\/h2>\n<h3>Billing<\/h3>\n<p>The billing control in <strong>Azure<\/strong> has by itself many different reasons to enforce policies. You, with your single <strong>Azure<\/strong> subscription, may think it\u2019s simple to control billing. Imagine how it is for a worldwide corporation with a single tenant and branches in all continents to control the billing of each cloud project.<\/p>\n<h4>Avoid Unnecessary Expenses<\/h4>\n<h5>Auto-Turnoff<\/h5>\n<p><strong>Virtual Machines<\/strong> have an auto-turnoff setting. Should virtual machines that are classified as not being 24\/7 be using the auto-turnoff?<\/p>\n<p>The company could create different subscriptions, one for the non-24\/7 VMs and another for the 24\/7 VMs and apply policies to ensure these configurations.<\/p>\n<h5>Serverless SQL<\/h5>\n<p>If we configure a Serverless <strong>SQL<\/strong>, which could turn itself off, to use <strong>Azure Defender for SQL<\/strong>, the requests from <strong>Azure Defender<\/strong> can prevent the database to ever go offline and provide no cost benefit.<\/p>\n<p>The policies could ensure this is turned off for serverless SQL and keep the\u00a0<strong>Azure Serverless SQL DB<\/strong>\u00a0provisioned in safe internal virtual networks that doesn&#8217;t require\u00a0<strong>Azure Defender for SQL<\/strong>.<\/p>\n<h5>BYOL<\/h5>\n<p>In order to better manage the licensing of the software, the policies could ensure the use of different subscriptions for services with <strong>BYOL<\/strong> enabled and for services without <strong>BYOL<\/strong> enabled. The procedure and permissions to make a deployment to each of these subscriptions could be different, exactly to ensure the correct allocation of financial resources<\/p>\n<h5>Dev\/Test Subscription<\/h5>\n<p>The Dev\/Test subscription is a great feature provided by <strong>Azure<\/strong> to save our money with our development and test environments. The policies can ensure everything related to development and test is only created in Dev\/Test Subscriptions.<\/p>\n<p>You can learn more about <a href=\"https:\/\/azure.microsoft.com\/en-us\/pricing\/dev-test\/?WT.mc_id=DP-MVP-4014132\">Dev\/Test Subscriptions here<\/a><\/p>\n<h4>Keep Billing Control<\/h4>\n<p>In a big corporation, keep the control about who is spending money in the cloud and if the money is being worth may be difficult. That&#8217;s why Cost centres and project isolation and analysis may be a good idea.<\/p>\n<p>Each <strong>Azure<\/strong> object allow many <strong>Tags<\/strong>, additional information attached to the object.<\/p>\n<p>Using <strong>Tags<\/strong> and the policies we can ensure:<\/p>\n<ul>\n<li>All resources are \u201cTagged\u201d for billing purposes<\/li>\n<li>All resources are allocated on the correct place according the billing tags<\/li>\n<\/ul>\n<h3>Security<\/h3>\n<p>It\u2019s surprising how often we make implementations in the cloud we would never make in an on premise environment.<\/p>\n<p>When we provision a service, such as an <strong>Azure<\/strong> storage account or an <strong>Azure SQL Database<\/strong>, most people end up leaving the service with a public internet endpoint.<\/p>\n<p>Would you implement a <strong>SQL Server<\/strong> in your on-premise environment and leave it open to the internet? Why would you do this in the cloud?<\/p>\n<p>The policies can ensure that these situations don\u2019t happen or, if they do, they are isolated on a subscription\/region intended for test purposes and never in a production environment.<\/p>\n<h3>Monitoring and Compliance<\/h3>\n<p>Almost all services on <strong>Azure<\/strong> implement a diagnostic feature that can enable the service to capture logging information and send to a centralized log analytics. Using policies, we can ensure these options will be correctly configured on all services.<\/p>\n<p>We can also control the region of deployment of our services. In a corporation with many branches all around the world, the subscriptions can be broken down in management groups. This can be done according to the region of the branch and each branch may be restricted to implement solutions on specific locations.<\/p>\n<h2>Creating a Policy in JSON<\/h2>\n<p>The policies are created using JSON. The more we parameterize the policies, more reusable they will be.<\/p>\n<p>This is an example of a policy to control the naming convention of azure resources<\/p>\n<pre><code>\r\n{\r\n\r\n\"parameters\": {\r\n\"ResourceType\": {\r\n\"type\": \"String\",\r\n\"metadata\": {\r\n\"displayName\": \"Resource type\",\r\n\"description\": \"Resource type to enforce naming pattern.\",\r\n\"strongType\": \"resourceTypes\"   }\r\n},\r\n\r\n\"NamePattern\": {\r\n\"type\": \"String\",\r\n\"metadata\": {\r\n\"displayName\": \"Resource Name Pattern\",\r\n\"description\": \"The pattern to be applied to the resource\"\r\n}\r\n}\r\n},\r\n\r\n\"policyRule\": {\r\n\r\n\"if\": {\r\n\r\n\"allOf\": [\r\n\r\n{\r\n\"field\": \"type\",\r\n\"equals\": \"[parameters('ResourceType')]\"\r\n},\r\n\r\n{\r\n\"field\": \"name\",\r\n\"notLike\": \"[parameters('NamePattern')]\"\r\n}\r\n]\r\n},\r\n\r\n\"then\": {\r\n\"effect\": \"deny\"\r\n} } }\r\n<\/code><\/pre>\n<p>You may notice the policy <strong>JSON<\/strong> code has two distinct areas: <strong>Parameters<\/strong> and <strong>PolicyRule<\/strong>. We could build this policy without parameters, for sure, but in this case, it would be a specific policy for one type of object and one naming convention.<\/p>\n<p>Using the policy with parameters allow us to save the policy definition and re-use it for any object type and naming convention.<\/p>\n<h2>Effect<\/h2>\n<p>Another important option to check on the <strong>JSON<\/strong> is the <strong>effect .<\/strong> Our example uses only the deny effect.<\/p>\n<p>Each <strong>Policy<\/strong> can have multiple effects and <strong>Azure<\/strong> uses an order of evaluation of the effects. Some of the effects when on the beginning of the evaluation can cancel the later effects.<\/p>\n<p>These are the available effects for the policies:<\/p>\n<ul>\n<li><strong>Deny:<\/strong> Refuses the object creation if not compliant with the policy.<\/li>\n<li><strong>Audit:<\/strong> Record auditing messages about the policy result<\/li>\n<li><strong>AuditIfNotExists:<\/strong> After the successful creation of the resource, checks of another resource existence. If the resource doesn\u2019t exist, it records an auditing message and mark the deployed resource as non-compliant.<\/li>\n<li><strong>DeployIfNotExists:<\/strong> This effect will deploy a template in case of the objects of the template don\u2019t exist.<\/li>\n<li><strong>Append:<\/strong> Creates additional fields on the object being deployed<\/li>\n<li><strong>Disabled:<\/strong> This effect disables the policy evaluation.<\/li>\n<li><strong>Modify:<\/strong> The modify effect is used to change objects, adding, or modifying field values. A single modify effect can have many actions<\/li>\n<\/ul>\n<p>These effects use the following evaluation order:<\/p>\n<ul>\n<li>Disabled<\/li>\n<li>Append and Modify<\/li>\n<li>Deny<\/li>\n<li>Audit<\/li>\n<\/ul>\n<p>You can take a look on <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/governance\/policy\/concepts\/effects?WT.mc_id=DP-MVP-4014132\">more details about the effects here<\/a><\/p>\n<h2>Applying the policies<\/h2>\n<p>We organize the cloud of a big corporation using <strong>Management Groups<\/strong> and <strong>Subscriptions<\/strong>, creating a hierarchy of management groups and subscriptions using the criteria we think it will fit better.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1107\" height=\"677\" class=\"wp-image-91262\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image.png\" \/><\/p>\n<p>We can apply the policy on any management group, and the policy will be valid to all subscriptions and managed groups below it. Another option is to apply the policy to a subscription, in this case the policy will be valid only to that subscription.<\/p>\n<p>In any of these choices, the process for the policy application is the same.<\/p>\n<p>After selecting <strong>Policy<\/strong> option in the menu on any of these objects, on the following screen we will find the authoring menu options on the left side, like the image below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"307\" height=\"163\" class=\"wp-image-91263\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-1.png\" \/><\/p>\n<p>We will use these three options to create and apply the policy:<\/p>\n<p><strong>Definitions:<\/strong> We use this option to create the policy. Usually we store the policy on the object we first used to create its definition and it can be used on this object and below. If the object is a management group, you will be able to apply the policy on any subscription or management group below this one. However, if the object is a subscription, you will only be able to apply the policy to that subscription and resource groups under that subscription.<\/p>\n<p><strong>Assignments:<\/strong> These are the assignments of the policy to the current object. The object can have assignments of policies stored in itself or in any object above, but not in objects below it.<\/p>\n<p><strong>Exemptions:<\/strong> These are objects to define exceptions to the policies. When applying the policies to the subscription\/management group we can define a set of exceptions that should not be checked by the policy.<\/p>\n<h2>Creating the Policy Definition<\/h2>\n<ol>\n<li>Once you are already on the object selected for the policy (<strong>Management Group<\/strong> or <strong>Subscription<\/strong>, doesn\u2019t matter) click on <strong>Definitions<\/strong><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1038\" height=\"642\" class=\"wp-image-91264\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-2.png\" \/><\/p>\n<ol>\n<li>In <strong>Definition Location<\/strong>, click the <em>\u201c\u2026\u201d<\/em> button<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"366\" class=\"wp-image-91265\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-3.png\" \/><\/p>\n<ol>\n<li>Choose the location to store the policy. Usually, you should choose the object you are managing at the moment. Mind the subscription is optional, you can choose a management group to store your policy<\/li>\n<li>Click <strong>Select<\/strong> button<\/li>\n<li>In the <strong>Name<\/strong> textbox, type <em>\u201cNaming Convention\u201d, <\/em>it will be the name of our policy definition<\/li>\n<li>In the <strong>Description<\/strong> textbox, type a description, such as <em>\u201cCreate a Naming convention for objects\u201d<\/em><\/li>\n<li>On the <strong>Category<\/strong> radio buttons, you can choose between use an existing policy category or create a new category. Leave as <strong>Create New<\/strong><\/li>\n<li>On the <strong>Category<\/strong> textbox, type <em>\u201cNaming Convention\u201d<\/em><\/li>\n<li>On the <strong>Policy Rule<\/strong> textbox, past our policy <strong>JSON<\/strong>, as you can see above on this blog<\/li>\n<li>Click <strong>Save<\/strong> button<\/li>\n<\/ol>\n<h2>Assigning the Policy<\/h2>\n<ol>\n<li>Under <strong>Authoring<\/strong>, click <strong>Assignments<\/strong>.<\/li>\n<li>Click the <strong>Assign Policy<\/strong> button<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"440\" height=\"48\" class=\"wp-image-91266\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-4.png\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"967\" height=\"790\" class=\"wp-image-91267\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-5.png\" \/><\/p>\n<ol>\n<li>Click the <em>\u201c\u2026\u201d<\/em> button besides the <strong>Policy definition<\/strong> box<\/li>\n<li>Click the policy we just created<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1034\" height=\"413\" class=\"wp-image-91268\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-6.png\" \/><\/p>\n<ol>\n<li>Click the<strong> Select<\/strong> button<\/li>\n<li>On the box <strong>Assignment Name<\/strong>, type <em>\u201cResource Group Name Convention\u201d<\/em><\/li>\n<\/ol>\n<p>The parameterized policy is generic and can have many applications. Each assignment will have one specific application, we will define it by setting the parameters.<\/p>\n<ol>\n<li>Click <strong>Next<\/strong> button<\/li>\n<li>The <strong>Resource Type<\/strong> box became a combo where we can choose what resource type we will apply this policy to. In our example, <em>subscriptions\/resourcegroups<\/em><\/li>\n<li>On the Resource Name Pattern text box,\u00a0 type <em>&#8220;rg-*&#8221;<\/em> as an example. We can use wildcards, creating the name pattern for resource groups.\u00a0<\/li>\n<li>Click <strong>Next<\/strong> button<\/li>\n<li>The remediation allows us to configure the policy to execute actions when needed, but we will not use this option, so click <strong>Next<\/strong> button<\/li>\n<li>On the <strong>Non-Compliance Message<\/strong> textbox, you can customize the message for non-compliant resource groups<\/li>\n<li>Click <strong>Next<\/strong> button<\/li>\n<li>Click <strong>Create<\/strong> button<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1361\" height=\"227\" class=\"wp-image-91269\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-7.png\" \/><\/p>\n<h2>Applied Policy<\/h2>\n<p>It may take 1 or 2 minutes until the created assignment makes effect. Once it does, you will not be able to create resource groups anymore unless they use the naming convention <em>rg-*<\/em><\/p>\n<p>The customized error message is a bit more hidden. Once you receive the error when creating the resource group, you click the message <em>\u201cView error details\u201d<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"523\" height=\"410\" class=\"wp-image-91270\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-8.png\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"689\" height=\"296\" class=\"wp-image-91271\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-9.png\" \/><\/p>\n<p>Click the <strong>Raw Error<\/strong> tab and you will see a <strong>JSON<\/strong> document. This document has the custom message you configured in the policy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"491\" class=\"wp-image-91272\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-10.png\" \/><\/p>\n<p>We can use the left menu to check the compliance of the policy on each object that have policy assignments.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"314\" height=\"325\" class=\"wp-image-91273\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-11.png\" \/><\/p>\n<p>Once you click on the <strong>Compliance<\/strong> option, you will see the overall compliance of all policies assigned to this object. On this example we have a single policy assigned, so the overall numbers are the same as the single policy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1270\" height=\"275\" class=\"wp-image-91274\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-12.png\" \/><\/p>\n<p>If you click on one policy you will be able to check all the objects by <strong>Policy Compliance State<\/strong>. For example, you can see all non-compliant objects.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1085\" height=\"525\" class=\"wp-image-91275\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-13.png\" \/><\/p>\n<p>This is the <strong>Policy State<\/strong> filter available on the 2<sup>nd<\/sup> dropdown:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"461\" height=\"389\" class=\"wp-image-91276\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-14.png\" \/><\/p>\n<h2>Useful Policies<\/h2>\n<p><strong>Azure<\/strong> has many useful pre-defined policies. For example, we mentioned on this blog how the tags on each resource can be useful. Many of these policies are planned to manage tags in different ways.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"966\" height=\"267\" class=\"wp-image-91277\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-15.png\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"963\" height=\"603\" class=\"wp-image-91278\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-16.png\" \/><\/p>\n<p>Useful policies will be subject of many other blogs because there are many of them to talk about.<\/p>\n<h2>Conclusion<\/h2>\n<p>The policies are not very well-known on azure environment, but we require them to keep our cloud environment in order.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Policies in Azure are like Wally. They are there, but not obvious to find, hidden in the middle of many services, waiting for someone recognize their importance. Why do we need Policies Billing The billing control in Azure has by itself many different reasons to enforce policies. You, with your single Azure subscription, may think&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5364,5548],"coauthors":[6810],"class_list":["post-91261","post","type-post","status-publish","format-standard","hentry","category-blogs","tag-azure","tag-policy-management"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=91261"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91261\/revisions"}],"predecessor-version":[{"id":91281,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91261\/revisions\/91281"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=91261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=91261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=91261"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=91261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}