Azure / azure-policy

Repository for Azure Resource Policy built-in definitions and samples
MIT License
1.51k stars 1.09k forks source link

Alias request: "Microsoft.Web/sites/eligibleLogCategories" #1395

Open mortenlerudjordet opened 1 month ago

mortenlerudjordet commented 1 month ago

Scenario Dynamically find supported log category for all types of web apps as these are different depending on windows,linux and container. Code tries to show a concept of how to activate only supported logs on a given web app type.

"resources": [
  {
    "type": "Microsoft.Web/sites/providers/diagnosticSettings",
    "apiVersion": "2021-05-01-preview",
    "name": "[concat(parameters('resourceName'), '/', 'Microsoft.Insights/', parameters('profileName'))]",
    "location": "[parameters('location')]",
    "dependsOn": [],
    "properties": {
      "workspaceId": "[parameters('logAnalytics')]",
      "metrics": [
        {
          "category": "AllMetrics",
          "timeGrain": null,
          "enabled": "[parameters('metricsEnabled')]",
          "retentionPolicy": {
            "days": 0,
            "enabled": false
          }
        }
      ],
      "copy": [
        {
            "name": "logs",
            "count": "[length(parameters('resourceLogCategories'))]",
            "input": {
                "category": "[parameters('resourceLogCategories')[copyIndex('logs')]]",
                "enabled": "[or(contains(parameters('logsEnabled'),parameters('resourceLogCategories')[copyIndex('logs')]),contains(parameters('logsEnabled'), 'AllLogs'))]"
            }
        }
      ]
    }
  }
],
"outputs": {
  "policy": {
    "type": "string",
    "value": "[concat('Diagnostic setting name: ', parameters('profileName'), ', resourceName: ', parameters('resourceName'), ' to Log Analytics: ', parameters('logAnalytics'), ' configured')]"
  }
}
},
"parameters": {
"resourceLogCategories": {
  "value": "[split(field('Microsoft.Web/sites/eligibleLogCategories'),',')]"
}

Compliance logic:

{
    "details": {
        "type": "Microsoft.Insights/diagnosticSettings",
        "evaluationDelay": "[parameters('evaluationDelay')]",
        "roleDefinitionIds": [
            "/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa",
            "/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293"
        ],
        "existenceCondition": {
            "allOf": [
                {
                    "field": "name",
                    "equals": "[parameters('profileName')]"
                },
                {
                    "count": {
                        "field": "Microsoft.Insights/diagnosticSettings/logs[*]",
                        "where": {
                            "allOf": [
                                {
                                    "value": "[current('Microsoft.Insights/diagnosticSettings/logs[*].enabled')]",
                                    "equals": "True"
                                },
                                {
                                    "value": "[current('Microsoft.Insights/diagnosticSettings/logs[*].category')]",
                                    "in": "[if(contains(parameters('logsEnabled'), 'AllLogs'),split(field('Microsoft.Web/sites/eligibleLogCategories),',')), intersection(parameters('logsEnabled'),split(field('Microsoft.Web/sites/eligibleLogCategories),',')))]"
                                }
                            ]
                        }
                    },
                    "equals": "[if(contains(array(parameters('logsEnabled')), 'AllLogs'), length(split(field('Microsoft.Web/sites/eligibleLogCategories),','))), length(intersection(array(array(parameters('logsEnabled'))),split(field('Microsoft.Web/sites/eligibleLogCategories),','))))]"
                },
                {
                    "field": "Microsoft.Insights/diagnosticSettings/metrics.enabled",
                    "equals": "[parameters('metricsEnabled')]"
                },
                {
                    "field": "Microsoft.Insights/diagnosticSettings/workspaceId",
                    "matchInsensitively": "[parameters('logAnalytics')]"
                }
            ]
        }
    }
}

Log parameter:

    "logsEnabled": {
      "type": "array",
      "metadata": {
        "displayName": "Logs to enable",
        "description": "Name of logs to enable for web app, supports multiple selections. Use syntax: AppServiceHTTPLogs;AppServiceAppLogs or just AllLogs"
      },
      "allowedValues": [
        "AllLogs",
        "AppServiceConsoleLogs",
        "AppServiceHTTPLogs",
        "AppServiceEnvironmentPlatformLogs",
        "AppServiceAuditLogs",
        "AppServiceFileAuditLogs",
        "AppServiceAppLogs",
        "AppServiceIPSecAuditLogs",
        "AppServicePlatformLogs",
        "AppServiceAntivirusScanAuditLogs"
      ],
      "defaultValue": ["AllLogs"]
    }
mortenlerudjordet commented 1 month ago

The requested value can be retireved inside the template, though for compliancy to report correctly for the different kinds of web apps one needs to have the field('Microsoft.Web/sites/eligibleLogCategories) available in existenceCondition to have a robust way of making sure the correct chosen logs are active.

The following code works for dynamically activating the suported log categories on a given web app. One note, for some web apps eligibleLogCategories contains invalid categories, before using the content of the parameter one needs to strip these out. Example is the value ScanLogs, as from the code below can be seen stripped out before using.

Code:

"resources": [
{
  "type": "Microsoft.Resources/deployments",
  "apiVersion": "2024-03-01",
  "name": "diag_web_app_parent",
  "properties": {
    "mode": "Incremental",
    "expressionEvaluationOptions": {
      "scope": "inner"
    },
    "parameters": {
      "resourceLogCategories": {
        "value": "[split(replace(reference(resourceId('Microsoft.Web/sites', parameters('resourceName')),'2022-09-01').eligibleLogCategories, ',ScanLogs', ''),',')]"
      },
      "profileName": {
        "value": "[parameters('profileName')]"
      },
      "logAnalytics": {
        "value": "[parameters('logAnalytics')]"
      },
      "metricsEnabled": {
        "value": "[parameters('metricsEnabled')]"
      },
      "logsEnabled": {
        "value": "[parameters('logsEnabled')]"
      },
      "location": {
        "value": "[parameters('location')]"
      },
      "resourceName": {
        "value": "[parameters('resourceName')]"
      }
    },
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "resourceLogCategories": {
          "type": "array"
        },
        "profileName": {
          "type": "string"
        },
        "resourceName": {
          "type": "string"
        },
        "logAnalytics": {
          "type": "string"
        },
        "metricsEnabled": {
          "type": "string"
        },
        "logsEnabled": {
          "type": "array"
        },
        "location": {
          "type": "string"
        }
      },
      "resources": [
        {
          "type": "Microsoft.Web/sites/providers/diagnosticSettings",
          "apiVersion": "2021-05-01-preview",
          "name": "[concat(parameters('resourceName'), '/', 'Microsoft.Insights/', parameters('profileName'))]",
          "location": "[parameters('location')]",
          "dependsOn": [],
          "properties": {
            "workspaceId": "[parameters('logAnalytics')]",
            "metrics": [
              {
                "category": "AllMetrics",
                "timeGrain": null,
                "enabled": "[parameters('metricsEnabled')]",
                "retentionPolicy": {
                  "days": 0,
                  "enabled": false
                }
              }
            ],
            "copy": [
              {
                "name": "logs",
                "count": "[length(parameters('resourceLogCategories'))]",
                "input": {
                  "category": "[parameters('resourceLogCategories')[copyIndex('logs')]]",
                  "enabled": "[or(contains(parameters('logsEnabled'),parameters('resourceLogCategories')[copyIndex('logs')]),contains(parameters('logsEnabled'),'AllLogs'))]"
                }
              }
            ]
          }
        }
      ]
    }
  }
}
]