Azure policy with "Modify" effect not working

117 Views Asked by At

I have an Azure policy with a "Modify" effect:

{
  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.Web/sites"
        },
        {
          "field": "Microsoft.Web/sites/publicNetworkAccess",
          "exists": "false"
        }
      ]
    },
    "then": {
      "effect": "[parameters('effect')]",
      "details": {
        "roleDefinitionIds": [
          "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
        ],
        "operations": [
          {
            "condition": "[greaterOrEquals(requestContext().apiVersion, '2022-09-01')]",
            "operation": "addOrReplace",
            "field": "Microsoft.Web/sites/publicNetworkAccess",
            "value": "Disabled"
          }
        ]
      }
    }
  },
  "parameters": {
    "effect": {
      "type": "String",
      "metadata": {
        "displayName": "Effect",
        "description": "Enable or disable the execution of the policy"
      },
      "allowedValues": [
        "Modify",
        "Disabled"
      ],
      "defaultValue": "Modify"
    }
  }
}

As I understand, this policy will set the attribute "publicNetworkAccess" of resource "Microsoft.Web/sites" to false if the attribute does not exist

After assigning the policy to my only subscription, I used ARM template to deploy the "Microsoft.Web/sites" resources:

{
            "type": "Microsoft.Web/sites",
            "apiVersion": "2021-02-01",
            "name": "[parameters('webAppName')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]"
            ],
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "httpsOnly": true,
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
                "siteConfig": {
                    "linuxFxVersion": "[parameters('linuxFxVersion')]",
                    "minTlsVersion": "1.2",
                    "ftpsState": "FtpsOnly"
                }
            }
        }

However, after the deployment is completed, I check the app service and see that the "publicNetworkAccess" is set to "Enabled": enter image description here

It means that the policy does not take effect. What's wrong with my policy ?

2

There are 2 best solutions below

0
Niclas On

Change your policyRule to include anyOf like this (this is best practice):

"policyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Web/sites"
          },
          {
            "anyOf": [
              {
                "field": "Microsoft.Web/sites/publicNetworkAccess",
                "exists": "false"
              },
              {
                "field": "Microsoft.Web/sites/publicNetworkAccess",
                "notEquals": "Disabled"
              }
            ]
          }
        ]
      },
      "then": {

For sake of learning, then use PS this to check if the property is modifiable:

Set-AzContext -SubscriptionId <subid>
Get-AzPolicyAlias -NamespaceMatch Microsoft.Web | where ResourceType -like 'sites*' | Select-Object -ExpandProperty Aliases | Where-Object { $_.DefaultMetadata.Attributes -eq 'Modifiable' } | where name -like '*public*' | Select Name,DefaultPath

Remember that the policyRule only proceed if the condition is evaluated as 'true'.

            "anyOf": [
              {
                "field": "Microsoft.Web/sites/publicNetworkAccess",
                "exists": "false"
              },
              {
                "field": "Microsoft.Web/sites/publicNetworkAccess",
                "notEquals": "Disabled"
              }
            ]

By default, the web app will have this value "publicNetworkAccess": null, which means that the above if-statement is true.

Reason for non-compliance: Current value must exist. Now the policy is ready for remediation.

You are using Contributor as permissions for the (system assigned) managed identity, this is overprivileged, but will of course worked.

To follow the process, you can run this to get all the properties of your web app BEFORE the remediation:

$webapp = Get-AzResource -Name <WEBAPPNAME> -ResourceGroupName <RG-NAME> -ResourceType Microsoft.Web/sites

$webapp it is empty. You can also confirm by running this:

$webapp.Properties.publicNetworkAccess

Now run your policy remediation, once completed, repeat the $webapp = Get-AzResource-command steps to refresh the variable.

0
Venkat V On

However, after the deployment is completed, I check the app service and see that the "publicNetworkAccess" is set to "Enabled":

Here is the updated Azure Policy to disable the publicNetworkAccess property for Azure Web Apps (Microsoft.Web/sites) only if it is already enabled.

Note: Make sure you have role assignment access, such as the Owner role, and also wait for some time for the process to update.

    {
      "mode": "All",
      "policyRule": {
        "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.Web/sites"
            },
            {
              "field": "Microsoft.Web/sites/publicNetworkAccess",
              "equals": "Enabled"
            }
          ]
        },
        "then": {
          "effect": "[parameters('effect')]",
          "details": {
            "roleDefinitionIds": [
              "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
            ],
            "operations": [
              {
                "operation": "addOrReplace",
                "field": "Microsoft.Web/sites/publicNetworkAccess",
                "value": "Disabled"
              }
            ]
          }
        }
      },
      "parameters": {
        "effect": {
          "type": "String",
          "metadata": {
            "displayName": "Effect",
            "description": "Enable or disable the execution of the policy"
          },
          "allowedValues": [
            "Modify",
            "Disabled"
          ],
          "defaultValue": "Modify"
        }
      }
    }

While assigning the policy, make sure to enable the remediation task to implement changes as follows.

enter image description here

The policy has been updated to disable public access for web apps.

enter image description here

enter image description here

The public access for the web app has been set to disabled.

enter image description here