From 2f99e76d3832f602b4381ff3c966922030ef218f Mon Sep 17 00:00:00 2001 From: Heinrich Gantenbein Date: Mon, 1 Aug 2022 20:07:15 -0500 Subject: [PATCH] Exemptions managed with EPAC - Added Exemptions: - Get-AzExemptions.ps1. - Define Exemptions in Definitions/Exemptions. - Define as Json or CSV. - Optional XLSX though a third-party PowerShell gallery module. - Fix bug with suppressDeletes switch. - Renamed Definitions/DocumentationSpec to Definitions/Documentation. Script will check old path if new path doesn't exist to avoid breaking changes. - Improved documentation generation. --- Definitions/Assignments/README.md | 10 +- .../README.md | 4 +- Definitions/Exemptions/README.md | 63 ++ Definitions/Initiatives/README.md | 4 +- Definitions/Policies/README.md | 4 +- Definitions/README.md | 7 +- Pipeline/README.md | 11 +- README.md | 12 +- ...d-AzPoliciesInitiativesAssignmentsPlan.ps1 | 154 +-- Scripts/Deploy/Convert-XlsToCsv.ps1 | 40 + ...PoliciesInitiativesAssignmentsFromPlan.ps1 | 61 +- .../Build-AzInitiativeDefinitionsPlan.ps1 | 14 +- .../Helpers/Build-AzPolicyAssignmentsPlan.ps1 | 14 +- .../Helpers/Build-AzPolicyExemptionsPlan.ps1 | 306 ++++++ .../Helpers/Confirm-ActiveAzExemptions.ps1 | 88 ++ Scripts/Helpers/Confirm-MetadataMatches.ps1 | 36 +- Scripts/Helpers/Convert-EffectToString.ps1 | 2 +- .../Helpers/Convert-ParametersToString.ps1 | 2 +- .../Get-AzAssignmentsAtScopeRecursive.ps1 | 195 ++-- Scripts/Helpers/Get-DeepClone.ps1 | 4 +- Scripts/Helpers/Get-FilteredHashTable.ps1 | 109 ++- Scripts/Helpers/Get-GlobalSettings.ps1 | 32 +- Scripts/Helpers/Invoke-AzCli.ps1 | 2 +- .../Out-InitiativeDocumentationToFile.ps1 | 14 +- Scripts/Helpers/Select-PacEnvironment.ps1 | 41 +- .../Build-PolicyAssignmentDocumentation.ps1 | 17 +- .../Operations/Create-AzRemediationTasks.ps1 | 1 + Scripts/Operations/Get-AzExemptions.ps1 | 122 +++ Scripts/Operations/README.md | 6 +- .../security-baseline-assignments.jsonc | 886 +++++++++--------- .../Assignments/tag-assignments.jsonc | 77 -- .../contoso.jsonc | 0 StarterKit/Definitions/global-settings.jsonc | 12 - StarterKit/Pipelines/AzureDevOps/pipeline.yml | 40 + Sync-Repo.ps1 | 2 +- 35 files changed, 1611 insertions(+), 781 deletions(-) rename Definitions/{DocumentationSpecs => Documentation}/README.md (99%) create mode 100644 Definitions/Exemptions/README.md create mode 100644 Scripts/Deploy/Convert-XlsToCsv.ps1 create mode 100644 Scripts/Helpers/Build-AzPolicyExemptionsPlan.ps1 create mode 100644 Scripts/Helpers/Confirm-ActiveAzExemptions.ps1 create mode 100644 Scripts/Operations/Get-AzExemptions.ps1 rename StarterKit/Definitions/{DocumentationSpecs => Documentation}/contoso.jsonc (100%) diff --git a/Definitions/Assignments/README.md b/Definitions/Assignments/README.md index f87bfc05..8e8ea5b7 100644 --- a/Definitions/Assignments/README.md +++ b/Definitions/Assignments/README.md @@ -99,10 +99,10 @@ Assignment files are hierarchical for efficient Json definitions, avoiding dupli "Lowest Level Local Parameter": "Value" } } - + ] }, - + ] }, { @@ -155,7 +155,7 @@ Assignment files are hierarchical for efficient Json definitions, avoiding dupli ] } ] -} +} ```
@@ -209,7 +209,9 @@ The assignment selector determines the array being selected for this run of the 1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../../Scripts/Operations/README.md)** diff --git a/Definitions/DocumentationSpecs/README.md b/Definitions/Documentation/README.md similarity index 99% rename from Definitions/DocumentationSpecs/README.md rename to Definitions/Documentation/README.md index d496f5c2..11bb6d75 100644 --- a/Definitions/DocumentationSpecs/README.md +++ b/Definitions/Documentation/README.md @@ -203,7 +203,9 @@ Each array entry defines three (3) files to be generated: Markdown, csv, and Jso 1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../../Scripts/Operations/README.md)** diff --git a/Definitions/Exemptions/README.md b/Definitions/Exemptions/README.md new file mode 100644 index 00000000..72fbb771 --- /dev/null +++ b/Definitions/Exemptions/README.md @@ -0,0 +1,63 @@ +# Exemptions + +## Table of Contents + +- [Exemption Files](#exemption-files) +- [Example](#example) +- [Reading List](#reading-list) + +## Exemption Files + +Exemptions can be defined as Json or CSV files. The names of the definition files don't matter. Additionally, through the use of a third-party PowerShell module from the PowerShell Gallery `ImportExcel` (https://www.powershellgallery.com/packages/ImportExcel, https://github.com/dfinke/ImportExcel/tree/master/Public). The contributors to this project are not responsible for any issues with that module. To mitigate the risk, the StarterKit has commented out the use of the conversion to protect your system from any vulnerabilities and executes the script without an Azure login. + +The pacEnvironment (see global-settings.jsonc) is represented with a folder, such as dev, test, tenant1, ... A missing folder indicates that the pacEnvironment's Exemptions are managed by this solution. To extract existing extension, the operations script Get-AzExemptions.ps1 can be used to generate Json and CSV files. The output should be used to start the Exemption definitions. + +### Format + +`name`, `exemptioncategory`, `scope` and `assignmentId` are required fields. The others are optional. + +```jsonc +{ + "exemptions": [ + { + "name": "Unique name", + "displayName": "Descriptive name displayed on portal", + "description": "More details", + "exemptionCategory": "waiver", + "scope": "/subscriptions/11111111-2222-3333-4444-555555555555", + "policyAssignmentId": "/providers/microsoft.management/managementgroups/contoso-prod/providers/microsoft.authorization/policyassignments/prod-asb", + "policyDefinitionReferenceIds": [ + "webApplicationFirewallShouldBeEnabledForApplicationGatewayMonitoringEffect" + ], + "metadata": { + "custom": "value" + } + } + ] +} +``` + +If you use spreadsheets (.csv or .xlsx): +- Column headers must be exactly as the Json labels above. +- `policyDefinitionReferenceIds` use comma separated list within each cell. +- `metadata` cells must conatin valid Json. + + +## Reading List + +1. **[Pipeline](../../Pipeline/README.md)** + +1. **[Update Global Settings](../../Definitions/README.md)** + +1. **[Create Policy Definitions](../../Definitions/Policies/README.md)** + +1. **[Create Initiative Definitions](#initiative-definitions)** + +1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** + +1. **[Operational Scripts](../../Scripts/Operations/README.md)** + +**[Return to the main page](../../README.md)** +
diff --git a/Definitions/Initiatives/README.md b/Definitions/Initiatives/README.md index 2621cf7c..4666d406 100644 --- a/Definitions/Initiatives/README.md +++ b/Definitions/Initiatives/README.md @@ -101,7 +101,9 @@ The Initiative definition files are structured based on the official [Azure Init 1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../../Scripts/Operations/README.md)** diff --git a/Definitions/Policies/README.md b/Definitions/Policies/README.md index 4cd61c98..2551735a 100644 --- a/Definitions/Policies/README.md +++ b/Definitions/Policies/README.md @@ -82,7 +82,9 @@ The Policy definition files are structured based on the official [Azure Policy d 1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../../Scripts/Operations/README.md)** diff --git a/Definitions/README.md b/Definitions/README.md index 58a358a1..bfe54b47 100644 --- a/Definitions/README.md +++ b/Definitions/README.md @@ -26,7 +26,8 @@ This folder and subfolders contain the definitions to deploy. Tasks: 1. Create custom Policy definitions (optional) in folder **[Policies](Policies/README.md)** 1. Create custom Initiative definitions (optional) in folder **[Initiatives](Initiatives/README.md)** 1. Define the Policy Assignments in folder **[Assignments](Assignments/README.md)** -1. Define Documentation in folder **[DocumentationSpecs](../Definitions/DocumentationSpecs/README.md)** +1. Define the Policy Exemptions in folder **[Define Policy Exemptions](../Definitions/Exemptions/README.md)** +1. Define Documentation in folder **[Documentation](../Definitions/Documentation/README.md)** ## Global Settings @@ -139,7 +140,9 @@ Each entry in the array defines one of the environments: 1. **[Define Policy Assignments](../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../Scripts/Operations/README.md)** diff --git a/Pipeline/README.md b/Pipeline/README.md index f8ee7014..6e931442 100644 --- a/Pipeline/README.md +++ b/Pipeline/README.md @@ -15,6 +15,7 @@ This repository contains starter pipeline definitions for Azure DevOps. **The au - [Build-AzPoliciesInitiativesAssignmentsPlan.ps1](#build-azpoliciesinitiativesassignmentsplanps1) - [Deploy-AzPoliciesInitiativesAssignmentsFromPlan.ps1](#deploy-azpoliciesinitiativesassignmentsfromplanps1) - [Set-AzPolicyRolesFromPlan.ps1](#set-azpolicyrolesfromplanps1) +- [Consuming Excel Files](#consuming-excel-files) - [Pipeline Execution](#pipeline-execution) - [Reading List](#reading-list) @@ -143,6 +144,12 @@ Creates the role assignments for the Managed Identities required for `DeployIfNo
+## Consuming Excel Files + +Exemptions and assignments can use Json, CSV and Excel (.xlsx) files. Support for Excel files uses a third-party PowerShell module from the PowerShell Gallery. However, the StarterKit pipeline disables the use of .xslx files module (`Convert-XlsToCSV.ps1`) to mitigate potential vulnerability risks in a third-party utility (this does not imply any such vulnerabilities exist). You can enable it at your own risk by uncommenting the sections in each planning stage. The pipeline further mitigates the risk by executing this step without Azure credentials. + +
+ ## Pipeline Execution Upon `commit to a feature branch or a manual pipeline run`, the pipeline runs stage devAllStage to deploy Policies, Initiatives and Assignments to the PAC DEV environment. Second, it calculates the plan for PROD environment deployment based on the Feature branch. This plan is never executed. Instead the logs and if desired the artifact generated are used by the developer to verify the definition files and to determine if the code is ready for a Pull Request. The PR approver(s) will use the same input plus the source code changes to decide the PR approval or rejection. @@ -181,7 +188,9 @@ If there are no changes, empty stage(s) are executed to explicitly show that no 1. **[Define Policy Assignments](../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../Definitions/Documentation/README.md)** 1. **[Operational Scripts](../Scripts/Operations/README.md)** diff --git a/README.md b/README.md index f0b60910..d0312ec8 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,10 @@ More details: - [Create Policy Definitions](Definitions/Policies/README.md) - [Create Initiative Definitions](Definitions/Initiatives/README.md) - [Define Policy Assignments](Definitions/Assignments/README.md) -- [Documenting Assignments and Initiatives](Definitions/DocumentationSpecs/README.md) +- [Define Policy Exemptions](Definitions/Exemptions/README.md) + + +- [Documenting Assignments and Initiatives](Definitions/Documentation/README.md) - [Operational Scripts](Scripts/Operations/README.md)

@@ -207,13 +210,13 @@ Pipelines can customized to fit your needs: ### Edit and create Policies, Initiatives and Assignments -Using the starter kit edit the directories in the `Definitions` folder. To simplify entering parameters, you can use the [Initiative documenting feature](Definitions/DocumentationSpecs/README.md#documenting-assignments-and-initiatives) which creates Markdown, CSV and a Json parameter file. You need to specify your initiatives to be documented (folder [`Definitions\DocumentationSpecs`](Definitions/DocumentationSpecs/README.md#specifying-initiative-documentation)) and execute script [`./Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1`](Scripts/Operations/README.md#build-policyassignmentdocumentationps1) +Using the starter kit edit the directories in the `Definitions` folder. To simplify entering parameters, you can use the [Initiative documenting feature](Definitions/Documentation/README.md#documenting-assignments-and-initiatives) which creates Markdown, CSV and a Json parameter file. You need to specify your initiatives to be documented (folder [`Definitions\Documentation`](Definitions/Documentation/README.md#specifying-initiative-documentation)) and execute script [`./Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1`](Scripts/Operations/README.md#build-policyassignmentdocumentationps1)
### Document your Assignments -This solution can generate [documentation in markdown and csv formats](Definitions/DocumentationSpecs/README.md). +This solution can generate [documentation in markdown and csv formats](Definitions/Documentation/README.md). ## GitHub Folder Structure @@ -261,7 +264,8 @@ The repo contains a script to synchronize directories in both directions: `Sync- 1. **[Create Policy Definitions](Definitions/Policies/README.md)** 1. **[Create Initiative Definitions](Definitions/Initiatives/README.md)** 1. **[Define Policy Assignments](Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](Definitions/Exemptions/README.md)** +1. **[Documenting Assignments and Initiatives](Definitions/Documentation/README.md)** 1. **[Operational Scripts](Scripts/Operations/README.md)**
diff --git a/Scripts/Deploy/Build-AzPoliciesInitiativesAssignmentsPlan.ps1 b/Scripts/Deploy/Build-AzPoliciesInitiativesAssignmentsPlan.ps1 index 34b28545..69d68081 100644 --- a/Scripts/Deploy/Build-AzPoliciesInitiativesAssignmentsPlan.ps1 +++ b/Scripts/Deploy/Build-AzPoliciesInitiativesAssignmentsPlan.ps1 @@ -54,6 +54,7 @@ function Write-AssignmentDetails { . "$PSScriptRoot/../Helpers/Build-AzInitiativeDefinitionsPlan.ps1" . "$PSScriptRoot/../Helpers/Build-AzPolicyAssignmentIdentityAndRoleChanges.ps1" . "$PSScriptRoot/../Helpers/Build-AzPolicyAssignmentsPlan.ps1" +. "$PSScriptRoot/../Helpers/Build-AzPolicyExemptionsPlan.ps1" . "$PSScriptRoot/../Helpers/Build-AzPolicyDefinitionsForInitiative.ps1" . "$PSScriptRoot/../Helpers/Build-AzPolicyDefinitionsPlan.ps1" . "$PSScriptRoot/../Helpers/Confirm-AssignmentParametersMatch.ps1" @@ -94,7 +95,7 @@ $scopeTreeInfo = Get-AzScopeTree ` -scopeParam $rootScope ` -defaultSubscriptionId $pacEnvironment.defaultSubscriptionId -$existingAssignments, $null = Get-AzAssignmentsAtScopeRecursive ` +$existingAssignments, $null, $existingExemptions = Get-AzAssignmentsAtScopeRecursive ` -scopeTreeInfo $scopeTreeInfo ` -notScopeIn $pacEnvironment.globalNotScopeList ` -includeResourceGroups $IncludeResourceGroupsForAssignments.IsPresent @@ -156,6 +157,7 @@ Build-AzInitiativeDefinitionsPlan ` -initiativeNeededRoleDefinitionIds $initiativeNeededRoleDefinitionIds # Process Assignment Json files +$allAssignments = @{} $newAssignments = @{} $updatedAssignments = @{} $replacedAssignments = @{} @@ -163,33 +165,55 @@ $deletedAssignments = @{} $unchangedAssignments = @{} $removedRoleAssignments = @{} $addedRoleAssignments = @{} -if (!$TestInitiativeMerge.IsPresent) { - Build-AzPolicyAssignmentsPlan ` - -pacEnvironmentSelector $pacEnvironment.pacEnvironmentSelector ` - -assignmentsRootFolder $pacEnvironment.assignmentsFolder ` - -noDelete $SuppressDeletes.IsPresent ` - -rootScope $rootScope ` - -rootScopeId $rootScopeId ` - -scopeTreeInfo $scopeTreeInfo ` - -globalNotScopeList $pacEnvironment.globalNotScopeList ` - -managedIdentityLocation $pacEnvironment.managedIdentityLocation ` - -allPolicyDefinitions $allPolicyDefinitions ` - -customPolicyDefinitions $customPolicyDefinitions ` - -replacedPolicyDefinitions $replacedPolicyDefinitions ` - -allInitiativeDefinitions $allInitiativeDefinitions ` - -customInitiativeDefinitions $customInitiativeDefinitions ` - -replacedInitiativeDefinitions $replacedInitiativeDefinitions ` - -policyNeededRoleDefinitionIds $policyNeededRoleDefinitionIds ` - -initiativeNeededRoleDefinitionIds $initiativeNeededRoleDefinitionIds ` - -existingAssignments $existingAssignments ` - -newAssignments $newAssignments ` - -updatedAssignments $updatedAssignments ` - -replacedAssignments $replacedAssignments ` - -deletedAssignments $deletedAssignments ` - -unchangedAssignments $unchangedAssignments ` - -removedRoleAssignments $removedRoleAssignments ` - -addedRoleAssignments $addedRoleAssignments -} +Build-AzPolicyAssignmentsPlan ` + -pacEnvironmentSelector $pacEnvironment.pacEnvironmentSelector ` + -assignmentsRootFolder $pacEnvironment.assignmentsFolder ` + -noDelete $SuppressDeletes.IsPresent ` + -rootScope $rootScope ` + -rootScopeId $rootScopeId ` + -scopeTreeInfo $scopeTreeInfo ` + -globalNotScopeList $pacEnvironment.globalNotScopeList ` + -managedIdentityLocation $pacEnvironment.managedIdentityLocation ` + -allPolicyDefinitions $allPolicyDefinitions ` + -customPolicyDefinitions $customPolicyDefinitions ` + -replacedPolicyDefinitions $replacedPolicyDefinitions ` + -allInitiativeDefinitions $allInitiativeDefinitions ` + -customInitiativeDefinitions $customInitiativeDefinitions ` + -replacedInitiativeDefinitions $replacedInitiativeDefinitions ` + -policyNeededRoleDefinitionIds $policyNeededRoleDefinitionIds ` + -initiativeNeededRoleDefinitionIds $initiativeNeededRoleDefinitionIds ` + -allAssignments $allAssignments ` + -existingAssignments $existingAssignments ` + -newAssignments $newAssignments ` + -updatedAssignments $updatedAssignments ` + -replacedAssignments $replacedAssignments ` + -deletedAssignments $deletedAssignments ` + -unchangedAssignments $unchangedAssignments ` + -removedRoleAssignments $removedRoleAssignments ` + -addedRoleAssignments $addedRoleAssignments + +# Process exemption JSON files +[hashtable] $newExemptions = @{} +[hashtable] $updatedExemptions = @{} +[hashtable] $replacedExemptions = @{} +[hashtable] $deletedExemptions = @{} +[hashtable] $unchangedExemptions = @{} +[hashtable] $orphanedExemptions = @{} +[hashtable] $expiredExemptions = @{} +Build-AzPolicyExemptionsPlan ` + -pacEnvironmentSelector $pacEnvironment.pacEnvironmentSelector ` + -exemptionsRootFolder $pacEnvironment.exemptionsFolder ` + -noDelete $SuppressDeletes.IsPresent ` + -allAssignments $allAssignments ` + -replacedAssignments $replacedAssignments ` + -existingExemptions $existingExemptions ` + -newExemptions $newExemptions ` + -updatedExemptions $updatedExemptions ` + -replacedExemptions $replacedExemptions ` + -deletedExemptions $deletedExemptions ` + -unchangedExemptions $unchangedExemptions ` + -orphanedExemptions $orphanedExemptions ` + -expiredExemptions $expiredExemptions # Publish plan to be consumed by next stage $numberOfPolicyChanges = ` @@ -204,7 +228,11 @@ $numberOfPolicyChanges = ` $deletedAssignments.Count + ` $replacedAssignments.Count + ` $updatedAssignments.Count + ` - $newAssignments.Count + $newAssignments.Count + ` + $newExemptions.Count + ` + $updatedExemptions.Count + ` + $replacedExemptions.Count + ` + $deletedExemptions.Count $numberOfRoleChanges = ` $removedRoleAssignments.Count + ` $addedRoleAssignments.Count @@ -232,6 +260,13 @@ $plan = @{ updatedAssignments = $updatedAssignments newAssignments = $newAssignments + deletedExemptions = $deletedExemptions + replacedExemptions = $replacedExemptions + updatedExemptions = $updatedExemptions + newExemptions = $newExemptions + orphanedExemptions = $orphanedExemptions + expiredExemptions = $expiredExemptions + removedRoleAssignments = $removedRoleAssignments addedRoleAssignments = $addedRoleAssignments } @@ -265,33 +300,38 @@ Write-Information "Initiative definitions - updated : $($updatedInitiativeDefi Write-Information "Initiative definitions - replaced : $($replacedInitiativeDefinitions.Count)" Write-Information "Initiative definitions - deleted : $($deletedInitiativeDefinitions.Count)" Write-Information "---------------------------------------------------------------------------------------------------" -if (!$TestInitiativeMerge.IsPresent) { - Write-Information "Assignments - unchanged : $($unchangedAssignments.Count)" - Write-Information "Assignments - new : $($newAssignments.Count)" - Write-Information "Assignments - updated : $($updatedAssignments.Count)" - Write-Information "Assignments - replaced : $($replacedAssignments.Count)" - Write-Information "Assignments - deleted : $($deletedAssignments.Count)" - Write-Information "---------------------------------------------------------------------------------------------------" - Write-Information "Assignments - Removed Role Assignment(s) : $($removedRoleAssignments.Count)" - Write-Information "Assignments - New Role Assignment(s) : $($addedRoleAssignments.Count)" +Write-Information "Assignments - unchanged : $($unchangedAssignments.Count)" +Write-Information "Assignments - new : $($newAssignments.Count)" +Write-Information "Assignments - updated : $($updatedAssignments.Count)" +Write-Information "Assignments - replaced : $($replacedAssignments.Count)" +Write-Information "Assignments - deleted : $($deletedAssignments.Count)" +Write-Information "Assignments - Removed Role Assignment(s) : $($removedRoleAssignments.Count)" +Write-Information "Assignments - New Role Assignment(s) : $($addedRoleAssignments.Count)" +Write-Information "---------------------------------------------------------------------------------------------------" +Write-Information "Exemptions - unchanged : $($unchangedExemptions.Count)" +Write-Information "Exemptions - new : $($newExemptions.Count)" +Write-Information "Exemptions - updated : $($updatedExemptions.Count)" +Write-Information "Exemptions - replaced : $($replacedExemptions.Count)" +Write-Information "Exemptions - deleted : $($deletedExemptions.Count)" +Write-Information "Exemptions - orphaned in definition file : $($orphanedExemptions.Count)" +Write-Information "Exemptions - expired in definition file : $($expiredExemptions.Count)" - Write-Information "***************************************************************************************************" - if ($numberOfRoleChanges -gt 0) { - Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]yes" - Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]yes" - Write-Information "Executing Policy deployment stage/step" - Write-Information "Executing Role Assignment stage/step" - } - elseif ($numberOfPolicyChanges -gt 0) { - Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]yes" - Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]no" - Write-Information "Executing Policy deployment stage/step" - Write-Information "Skipping Role Assignment stage/step - no changes" - } - else { - Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]no" - Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]no" - Write-Information "Skipping Policy deployment stage/step - no changes" - Write-Information "Skipping Role Assignment stage/step - no changes" - } +Write-Information "***************************************************************************************************" +if ($numberOfRoleChanges -gt 0) { + Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]yes" + Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]yes" + Write-Information "Executing Policy deployment stage/step" + Write-Information "Executing Role Assignment stage/step" +} +elseif ($numberOfPolicyChanges -gt 0) { + Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]yes" + Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]no" + Write-Information "Executing Policy deployment stage/step" + Write-Information "Skipping Role Assignment stage/step - no changes" +} +else { + Write-Host "##vso[task.setvariable variable=deployPolicyChanges;isOutput=true]no" + Write-Host "##vso[task.setvariable variable=deployRoleChanges;isOutput=true]no" + Write-Information "Skipping Policy deployment stage/step - no changes" + Write-Information "Skipping Role Assignment stage/step - no changes" } diff --git a/Scripts/Deploy/Convert-XlsToCsv.ps1 b/Scripts/Deploy/Convert-XlsToCsv.ps1 new file mode 100644 index 00000000..ab59d295 --- /dev/null +++ b/Scripts/Deploy/Convert-XlsToCsv.ps1 @@ -0,0 +1,40 @@ +#Requires -PSEdition Core + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false, HelpMessage = "Definitions folder path. Defaults to environment variable `$env:PAC_DEFINITIONS_FOLDER or './Definitions'.")] + [string]$definitionsRootFolder +) + +. "$PSScriptRoot/../Helpers/Get-PacFolders.ps1" + +$folders = Get-PacFolders -definitionsRootFolder $definitionsRootFolder +$InformationPreference = "Continue" + +[bool] $importExcelModuleNotInstalled = $null -eq (Get-InstalledModule ImportExcel -ErrorAction SilentlyContinue) +if ($importExcelModuleNotInstalled) { + Write-Information "===================================================================================================" + Write-Information "Installing ImportExcel from PowerShell Gallery: https://www.powershellgallery.com/packages/ImportExcel" + Write-Information "===================================================================================================" + $result = Install-Module -Name ImportExcel -Force -PassThru -ErrorAction Continue + if ($null -eq $result) { + Write-Error "Install-Module for ImportExcel failed. You cannot use .xlsx files in your environment. Use csv files instead" -ErrorAction Stop + } +} + +Write-Information "===================================================================================================" +Write-Information "Converting definition Excel files (.xlsx) in folder '$definitionsRootFolder' too CSV" +Write-Information "===================================================================================================" + +$definitionsRootFolder = $folders.definitionsRootFolder +$excelFiles = @() + (Get-ChildItem -Path $definitionsRootFolder -Recurse -File -Filter "*.xlsx") + +foreach ($excelFile in $excelFiles) { + $excelFileFullName = $excelFile.fullName + Write-Information $excelFileFullName + $excelArray += (Import-Excel $excelFileFullName -ErrorAction Stop) + + $csvFileFullName = $excelFileFullName -replace '\.xlsx$', '.csv' + $excelArray | ConvertTo-Csv -UseQuotes AsNeeded | Out-File $csvFileFullName -Force +} +Write-Information "" diff --git a/Scripts/Deploy/Deploy-AzPoliciesInitiativesAssignmentsFromPlan.ps1 b/Scripts/Deploy/Deploy-AzPoliciesInitiativesAssignmentsFromPlan.ps1 index 0e233522..21d929bd 100644 --- a/Scripts/Deploy/Deploy-AzPoliciesInitiativesAssignmentsFromPlan.ps1 +++ b/Scripts/Deploy/Deploy-AzPoliciesInitiativesAssignmentsFromPlan.ps1 @@ -46,7 +46,7 @@ function New-AzPolicyAssignmentHelper { ) $splatTransform = "Name Description DisplayName Metadata EnforcementMode Scope" - [hashtable] $splat = $assignmentDefinition | Get-FilteredHashTable -Filter $splatTransform + [hashtable] $splat = $assignmentDefinition | Get-FilteredHashTable -splatTransform $splatTransform $splat.Add("PolicyParameterObject", ($assignmentDefinition.PolicyParameterObject | ConvertTo-HashTable)) $notScope = $assignmentDefinition.NotScope if ($null -ne $notScope -and $notScope.Length -gt 0) { @@ -99,7 +99,7 @@ function Set-AzPolicyAssignmentHelper { ) $splatTransform = "Id Description DisplayName EnforcementMode Metadata" - [hashtable] $splat = $assignmentDefinition | Get-FilteredHashTable -Filter $splatTransform + [hashtable] $splat = $assignmentDefinition | Get-FilteredHashTable -splatTransform $splatTransform $parameterObject = $assignmentDefinition.PolicyParameterObject | ConvertTo-HashTable $splat.Add("PolicyParameterObject", $parameterObject) $splat.Add("WarningAction", "SilentlyContinue") @@ -190,14 +190,14 @@ if (!$noChanges) { Write-Information "Create new and replaced (create) Policy definitions ($($policyDefinitions.Count))" $splatTransform = "Name DisplayName Description Metadata Mode Parameter Policy ManagementGroupName SubscriptionId" foreach ($policyDefinitionName in $policyDefinitions.Keys) { - $policyDefinition = $policyDefinitions[$policyDefinitionName] | Get-FilteredHashTable -Filter $splatTransform + $policyDefinition = $policyDefinitions[$policyDefinitionName] | Get-FilteredHashTable -splatTransform $splatTransform Write-Information " ""$($policyDefinition.Name)"" - ""$($policyDefinition.DisplayName)""" $null = New-AzPolicyDefinition @policyDefinition } $policyDefinitions = $plan.updatedPolicyDefinitions | ConvertTo-HashTable Write-Information "Update Policy definitions ($($policyDefinitions.Count))" foreach ($policyDefinitionName in $policyDefinitions.Keys) { - $policyDefinition = $policyDefinitions[$policyDefinitionName] | Get-FilteredHashTable -Filter $splatTransform + $policyDefinition = $policyDefinitions[$policyDefinitionName] | Get-FilteredHashTable -splatTransform $splatTransform Write-Information " ""$($policyDefinition.Name)"" - ""$($policyDefinition.DisplayName)""" $null = Set-AzPolicyDefinition @policyDefinition } @@ -209,7 +209,7 @@ if (!$noChanges) { Write-Information "Create new and replaced Initiative definitions ($($initiativeDefinitions.Count))" $splatTransform = "Name DisplayName Description Metadata Parameter PolicyDefinition GroupDefinition ManagementGroupName SubscriptionId" foreach ($initiativeDefinitionName in $initiativeDefinitions.Keys) { - $initiativeDefinition = $initiativeDefinitions[$initiativeDefinitionName] | Get-FilteredHashTable -Filter $splatTransform + $initiativeDefinition = $initiativeDefinitions[$initiativeDefinitionName] | Get-FilteredHashTable -splatTransform $splatTransform $initiativeDefinition.Add("ApiVersion", "2020-08-01") Write-Information " ""$($initiativeDefinition.Name)"" - ""$($initiativeDefinition.DisplayName)""" $null = New-AzPolicySetDefinition @initiativeDefinition @@ -217,7 +217,7 @@ if (!$noChanges) { $initiativeDefinitions = $plan.updatedInitiativeDefinitions | ConvertTo-HashTable Write-Information "Updated Initiative definitions ($($initiativeDefinitions.Count))" foreach ($initiativeDefinitionName in $initiativeDefinitions.Keys) { - $initiativeDefinition = $initiativeDefinitions[$initiativeDefinitionName] | Get-FilteredHashTable -Filter $splatTransform + $initiativeDefinition = $initiativeDefinitions[$initiativeDefinitionName] | Get-FilteredHashTable -splatTransform $splatTransform $initiativeDefinition.Add("ApiVersion", "2020-08-01") Write-Information " ""$($initiativeDefinition.Name)"" - ""$($initiativeDefinition.DisplayName)""" $null = Set-AzPolicySetDefinition @initiativeDefinition @@ -295,6 +295,7 @@ if (!$noChanges) { #endregion #region Delete obsolete Policy definitions + Write-Information "---------------------------------------------------------------------------------------------------" $policyDefinitions = $plan.deletedPolicyDefinitions | ConvertTo-HashTable Write-Information "Deleted Policy definitions ($($policyDefinitions.Count))" @@ -303,6 +304,54 @@ if (!$noChanges) { Write-Information " ""$($policyDefinition.name)"" - ""$($policyDefinition.displayName)""" $null = Remove-AzPolicyDefinition -Id $policyDefinition.id -Force } + + #endregion + + #region Exemptions + + Write-Information "---------------------------------------------------------------------------------------------------" + $exemptions = (ConvertTo-HashTable $plan.deletedExemptions) + (ConvertTo-HashTable $plan.replacedExemptions) + Write-Information "Delete obsolete and replaced Exemptions ($($exemptions.Count))" + foreach ($exemptionId in $exemptions.Keys) { + $exemption = $exemptions[$exemptionId] + Write-Information " ""$($exemptionId)"" - ""$($exemption.DisplayName)""" + Remove-AzPolicyExemption -Id $exemptionId -Force + } + + Write-Information "---------------------------------------------------------------------------------------------------" + $exemptions = (ConvertTo-HashTable $plan.newExemptions) + (ConvertTo-HashTable $plan.replacedExemptions) + Write-Information "Create new and replaced Exemptions ($($exemptions.Count))" + $splatTransform = "Name Scope DisplayName Description Metadata ExemptionCategory ExpiresOn PolicyDefinitionReferenceIds/PolicyDefinitionReferenceId" + $assignmentsCache = @{} + foreach ($exemptionId in $exemptions.Keys) { + $exemption = $exemptions[$exemptionId] + $policyAssignmentId = $exemption.policyAssignmentId + $filteredExemption = $exemptions[$exemptionId] | Get-FilteredHashTable -splatTransform $splatTransform + Write-Information " ""$($exemptionId)"" - ""$($exemption.DisplayName)""" + # Need assignment + $assignment = $null + if ($assignmentsCache.ContainsKey($policyAssignmentId)) { + $assignment = $assignmentsCache.$policyAssignmentId + } + else { + # Retrieve Policy Assignment + $assignment = Get-AzPolicyAssignment -Id $policyAssignmentId + $null = $assignmentsCache.Add($policyAssignmentId, $assignment) + } + $null = New-AzPolicyExemption @filteredExemption -PolicyAssignment $assignment + } + + Write-Information "---------------------------------------------------------------------------------------------------" + $exemptions = (ConvertTo-HashTable $plan.updatedExemptions) + Write-Information "Update Exemptions ($($exemptions.Count))" + $splatTransform = "Id DisplayName Description Metadata ExemptionCategory ExpiresOn ClearExpiration PolicyDefinitionReferenceIds/PolicyDefinitionReferenceId" + foreach ($exemptionId in $exemptions.Keys) { + $exemption = $exemptions[$exemptionId] + $filteredExemption = $exemptions[$exemptionId] | Get-FilteredHashTable -splatTransform $splatTransform + Write-Information " ""$($exemptionId)""" + $null = Set-AzPolicyExemption @filteredExemption + } + #endregion #region Role Assignment Plan diff --git a/Scripts/Helpers/Build-AzInitiativeDefinitionsPlan.ps1 b/Scripts/Helpers/Build-AzInitiativeDefinitionsPlan.ps1 index 1d79696f..17d98776 100644 --- a/Scripts/Helpers/Build-AzInitiativeDefinitionsPlan.ps1 +++ b/Scripts/Helpers/Build-AzInitiativeDefinitionsPlan.ps1 @@ -64,7 +64,7 @@ function Build-AzInitiativeDefinitionsPlan { Write-Error "Initiative Json file '$($initiativeFile.Name)' is not valid = $Json" -ErrorAction Stop } $initiativeObject = $Json | ConvertFrom-Json -Depth 100 - + $name = $initiativeObject.name $displayName = $initiativeObject.properties.displayName if ($null -eq $name) { @@ -98,7 +98,7 @@ function Build-AzInitiativeDefinitionsPlan { [hashtable] $groupDefinitions = @{} if ($null -ne $initiativeObject.properties.policyDefinitionGroups) { - $null = ($initiativeObject.properties.policyDefinitionGroups) | ForEach-Object { + $null = ($initiativeObject.properties.policyDefinitionGroups) | ForEach-Object { $groupDefinitions.Add($_.name, $_) } } @@ -127,10 +127,11 @@ function Build-AzInitiativeDefinitionsPlan { break } $null = $groupDefinitions.Add($policyDefinitionGroupName, $policyDefinitionGroup) - Write-Information " $policyDefinitionGroupName" + # Write-Information " $policyDefinitionGroupName" } } } + Write-Information " Imported $($groupDefinitions.Count) PolicyDefinitionGroups from '$($importedInitiative.displayName)'" } else { Write-Error " Initiative $($importedInitiative.displayName) does not contain PolicyDefinitionGroups to import" -ErrorAction Stop @@ -164,7 +165,9 @@ function Build-AzInitiativeDefinitionsPlan { Description = $description Parameter = $parameterTable PolicyDefinition = $policyDefinitions - GroupDefinition = $groupDefinitions.Values + } + if ($groupDefinitions.Count -gt 0) { + $initiativeDefinitionConfig.Add("GroupDefinition", $groupDefinitions.Values) } # Adding SubscriptionId or ManagementGroupName value and optional fields to the splat $initiativeDefinitionConfig += $rootScope @@ -225,7 +228,6 @@ function Build-AzInitiativeDefinitionsPlan { Write-Information "Update($changesString) '$($name)' - '$($displayName)'" $updatedInitiativeDefinitions.Add($name, $initiativeDefinitionConfig) } - } } } @@ -237,7 +239,7 @@ function Build-AzInitiativeDefinitionsPlan { } foreach ($deletedName in $obsoleteInitiativeDefinitions.Keys) { $deleted = $obsoleteInitiativeDefinitions[$deletedName] - if ($SuppressDeletes.IsPresent) { + if ($noDelete) { Write-Information "Suppressing Delete '$($deletedName)' - '$($deleted.displayName)'" } else { diff --git a/Scripts/Helpers/Build-AzPolicyAssignmentsPlan.ps1 b/Scripts/Helpers/Build-AzPolicyAssignmentsPlan.ps1 index a5593e57..b028325b 100644 --- a/Scripts/Helpers/Build-AzPolicyAssignmentsPlan.ps1 +++ b/Scripts/Helpers/Build-AzPolicyAssignmentsPlan.ps1 @@ -19,6 +19,7 @@ function Build-AzPolicyAssignmentsPlan { [hashtable] $replacedInitiativeDefinitions, [hashtable] $policyNeededRoleDefinitionIds, [hashtable] $initiativeNeededRoleDefinitionIds, + [hashtable] $allAssignments, [hashtable] $existingAssignments, [hashtable] $newAssignments, [hashtable] $updatedAssignments, @@ -150,7 +151,7 @@ function Build-AzPolicyAssignmentsPlan { } else { $policySpecText = "Policy '$($name)'" - } + } $result = Confirm-PolicyDefinitionUsedExists -allPolicyDefinitions $allPolicyDefinitions -replacedPolicyDefinitions $replacedPolicyDefinitions -policyNameRequired $name if ($result.usingUndefinedReference) { continue @@ -286,7 +287,7 @@ function Build-AzPolicyAssignmentsPlan { $assignmentConfig += @{ existingAssignment = $value } - + $policyDefinitionMatches = $policyDefinitionId -eq $assignmentInAzure.policyDefinitionId $replaceIn = (-not $policyDefinitionMatches) -or $result.usingReplacedReference $replace, $changingRoleAssignments = Build-AzPolicyAssignmentIdentityAndRoleChanges ` @@ -295,7 +296,7 @@ function Build-AzPolicyAssignmentsPlan { -assignmentConfig $assignmentConfig ` -removedRoleAssignments $removedRoleAssignments ` -addedRoleAssignments $addedRoleAssignments - + if ($replace) { $replacedAssignments.Add($id, $assignmentConfig) $changesString = ($policyDefinitionMatches ? "-" : "P") ` @@ -330,7 +331,7 @@ function Build-AzPolicyAssignmentsPlan { # Write-Information " *** NOTSCOPE UPDATE at $($scopeInfo.scope)" $numberOfNotScopeChanges += 1 $updatedAssignments.Add($Id, $assignmentConfig) - } + } elseif ($match) { if ($changingRoleAssignments) { Write-AssignmentDetails ` @@ -354,7 +355,7 @@ function Build-AzPolicyAssignmentsPlan { + ($parametersMatch ? "-": "p") ` + ($notScopeMatches ? "-": "N") ` + ($changingRoleAssignments ? "R": "-") - + Write-AssignmentDetails ` -printHeader $noChangedAssignments ` -def $def ` @@ -386,6 +387,7 @@ function Build-AzPolicyAssignmentsPlan { -prefix "+++ NEW" $noChangedAssignments = $false } + $allAssignments.Add($id, $assignmentConfig) } } } @@ -398,7 +400,7 @@ function Build-AzPolicyAssignmentsPlan { } if ($obsoleteAssignments.Count -gt 0) { - if ($SuppressDeletes.IsPresent) { + if ($noDelete) { Write-Information "Suppressing Delete Assignments ($($obsoleteAssignments.Count))" foreach ($id in $obsoleteAssignments.Keys) { Write-Information " '$id'" diff --git a/Scripts/Helpers/Build-AzPolicyExemptionsPlan.ps1 b/Scripts/Helpers/Build-AzPolicyExemptionsPlan.ps1 new file mode 100644 index 00000000..70ee6f99 --- /dev/null +++ b/Scripts/Helpers/Build-AzPolicyExemptionsPlan.ps1 @@ -0,0 +1,306 @@ +#Requires -PSEdition Core + +function Build-AzPolicyExemptionsPlan { + [CmdletBinding()] + param ( + [string] $pacEnvironmentSelector, + [string] $exemptionsRootFolder, + [bool] $noDelete, + [hashtable] $allAssignments, + [hashtable] $replacedAssignments, + [hashtable] $existingExemptions, + [hashtable] $newExemptions, + [hashtable] $updatedExemptions, + [hashtable] $replacedExemptions, + [hashtable] $deletedExemptions, + [hashtable] $unchangedExemptions, + [hashtable] $orphanedExemptions, + [hashtable] $expiredExemptions + ) + + $path = "$($exemptionsRootFolder)/$pacEnvironmentSelector" + Write-Information "===================================================================================================" + Write-Information "Processing Policy Exemption files in folder '$path'" + Write-Information "===================================================================================================" + [array] $exemptionFiles = @() + if (Test-Path $path) { + # Do not manage exemptions if directory does not exist + $exemptionFiles += Get-ChildItem -Path $path -Recurse -File -Filter "*.json" + $exemptionFiles += Get-ChildItem -Path $path -Recurse -File -Filter "*.jsonc" + $exemptionFiles += Get-ChildItem -Path $path -Recurse -File -Filter "*.csv" + + [hashtable] $allExemptions = @{} + [hashtable] $obsoleteExemptions = $existingExemptions.Clone() + if ($exemptionFiles.Length -gt 0) { + Write-Information "Number of Policy Exemption files = $($exemptionFiles.Length)" + $now = Get-Date + foreach ($file in $exemptionFiles) { + $exemptionArray = @() + $extension = $file.Extension + $fullName = $file.FullName + $fileName = $file.Name + $content = Get-Content -Path $fullName -Raw -ErrorAction Stop + Write-Information $fileName + if ($extension -eq ".json" -or $extension -eq ".jsonc") { + if (!(Test-Json $content)) { + Write-Error " Invalid JSON" -ErrorAction Stop + } + $jsonObj = ConvertFrom-Json $content -AsHashtable -Depth 100 + if ($null -ne $jsonObj) { + $jsonExemptions = $jsonObj.exemptions + if ($null -ne $jsonExemptions -and $jsonExemptions.Count -gt 0) { + $exemptionArray += $jsonExemptions + } + } + } + elseif ($extension -eq ".csv") { + $xlsExemptionArray = @() + ($content | ConvertFrom-Csv -ErrorAction Stop) + # Adjust flat structure from spreadsheets to the almost flat structure in JSON + [System.Collections.ArrayList] $exemptionArrayList = [System.Collections.ArrayList]::new() + foreach ($row in $xlsExemptionArray) { + $policyDefinitionReferenceIds = @() + $step1 = $row.policyDefinitionReferenceIds + if ($null -ne $step1 -and $step1 -ne "") { + $step2 = $step1.Trim() + $step3 = $step2 -split "," + foreach ($item in $step3) { + $step4 = $item.Trim() + if ($step4.Length -gt 0) { + $policyDefinitionReferenceIds += $step4 + } + } + } + $metadata = $null + $step1 = $row.metadata + if ($null -ne $step1 -and $step1 -ne "") { + $step2 = $step1.Trim() + if ($step2.StartsWith("{") -and (Test-Json $step2)) { + $step3 = ConvertFrom-Json $step2 -AsHashtable -Depth 100 + if ($step3 -ne @{}) { + $metadata = $step3 + } + } + else { + Write-Error " Invalid metadata format, must be empty or legal JSON: '$step2'" + } + } + $exemption = [ordered]@{ + name = $row.name + displayName = $row.displayName + description = $row.description + exemptionCategory = $row.exemptionCategory + expiresOn = $row.expiresOn + scope = $row.scope + policyAssignmentId = $row.policyAssignmentId + policyDefinitionReferenceIds = $policyDefinitionReferenceIds + metadata = $metadata + } + $null = $exemptionArrayList.Add($exemption) + } + $exemptionArray = $exemptionArrayList.ToArray() + } + else { + Write-Information "Unknown file extension $fileName" + continue + } + + foreach ($exemptionRaw in $exemptionArray) { + + # Validate the content, remove extraneous columns + $name = $exemptionRaw.name + $displayName = $exemptionRaw.displayName + $description = $exemptionRaw.description + $exemptionCategory = $exemptionRaw.exemptionCategory + $scope = $exemptionRaw.scope + $policyAssignmentId = $exemptionRaw.policyAssignmentId + $policyDefinitionReferenceIds = $exemptionRaw.policyDefinitionReferenceIds + $metadata = $exemptionRaw.metadata + if (($null -eq $name -or $name -eq '') -or ($null -eq $exemptionCategory -or $exemptionCategory -eq '') -or ($null -eq $scope -or $scope -eq '') -or ($null -eq $policyAssignmentId -or $policyAssignmentId -eq '')) { + if (-not (($null -eq $name -or $name -eq '') -and ($null -eq $exemptionCategory -or $exemptionCategory -eq '') ` + -and ($null -eq $scope -or $scope -eq '') -and ($null -eq $policyAssignmentId -or $policyAssignmentId -eq '') ` + -and ($null -eq $displayName -or $displayName -eq "") -and ($null -eq $description -or $description -eq "") ` + -and ($null -eq $expiresOnRaw -or $expiresOnRaw -eq "") -and ($null -eq $metadata) ` + -and ($null -eq $policyDefinitionReferenceIds -or $policyDefinitionReferenceIds.Count -eq 0))) { + #ignore empty lines from Excel or CSV + Write-Error " Exemption is missing one or more of required fields name($name), scope($scope) and policyAssignmentId($policyAssignmentId)" -ErrorAction Stop + } + } + $exemption = @{ + Name = $name + Scope = $scope + policyAssignmentId = $policyAssignmentId + ExemptionCategory = $exemptionCategory + } + if ($displayName -and $displayName -ne "") { + $null = $exemption.Add("DisplayName", $displayName) + } + else { + $displayName = $null + } + if ($description -and $description -ne "") { + $null = $exemption.Add("Description", $description) + } + else { + $description = $null + } + + $expiresOn = $null + $expired = $false + $expiresOnRaw = $exemptionRaw.expiresOn + if ($null -ne $expiresOnRaw) { + if ($expiresOnRaw -is [datetime]) { + $expiresOn = $expiresOnRaw + } + elseif ($expiresOnRaw -is [string]) { + if ($expiresOnRaw -ne "") { + try { + $expiresOn = [datetime]::Parse($expiresOnRaw) + } + catch { + Write-Error "$_" -ErrorAction Stop + } + } + } + else { + Write-Error "expiresOn field '$($expiresOnRaw)' is not a recognized type $($expiresOnRaw.GetType().Name)" -ErrorAction Stop + } + } + if ($null -ne $expiresOn) { + $expired = $expiresOn -lt $now + $null = $exemption.Add("ExpiresOn", $expiresOn) + } + + if ($policyDefinitionReferenceIds -and $policyDefinitionReferenceIds.Count -gt 0) { + $null = $exemption.Add("PolicyDefinitionReferenceIds", $policyDefinitionReferenceIds) + } + else { + $policyDefinitionReferenceIds = $null + } + if ($metadata -and $metadata -ne @{} -and $metadata -ne "") { + $null = $exemption.Add("Metadata", $metadata) + } + else { + $metadata = $null + } + $id = "$scope/providers/Microsoft.Authorization/policyExemptions/$name" + + # Check for duplicates + if ($allExemptions.ContainsKey($id) -or $orphanedExemptions.ContainsKey($id) -or $expiredExemptions.ContainsKey($id)) { + Write-Error " Duplicate exemption id (name=$name, scope=$scope)" -ErrorAction Stop + } + + # Filter orhaned and expired Exemptions + if ($expired) { + $null = $expiredExemptions.Add($id, $exemption) + continue + } + if (-not $allAssignments.ContainsKey($policyAssignmentId)) { + $null = $orphanedExemptions.Add($id, $exemption) + continue + } + + # Calculate desired state mandated changes + $null = $allExemptions.Add($id, $exemption) + if ($existingExemptions.ContainsKey($id)) { + $obsoleteExemptions.Remove($id) + $existingExemption = $existingExemptions.$id + if ($existingExemption.policyAssignmentId -ne $policyAssignmentId) { + # Replaced Assignment + Write-Information "Replace(assignment) '$($name)', '$($scope)'" + $null = $replacedExemptions.Add($id, $exemption) + } + elseif ($replacedAssignments.ContainsKey($policyAssignmentId)) { + # Replaced Assignment + Write-Information "Replace(reference) '$($name)', '$($scope)'" + $null = $replacedExemptions.Add($id, $exemption) + } + else { + # Maybe update existing Exemption + $displayNameMatches = $existingExemption.displayName -eq $displayName + $descriptionMatches = $existingExemption.description -eq $description + $exemptionCategoryMatches = $existingExemption.exemptionCategory -eq $exemptionCategory + $expiresOnMatches = $existingExemption.expiresOn -eq $expiresOn + $clearExpiration = $false + if (-not $expiresOnMatches) { + if ($null -eq $expiresOn) { + $null = $exemption.Add("ClearExpiration", $true) + $clearExpiration = $true + } + } + $policyDefinitionReferenceIdsMatches = Confirm-ObjectValueEqualityDeep -existingObj $existingExemption.policyDefinitionReferenceIds -definedObj $policyDefinitionReferenceIds + $metadataMatches = Confirm-MetadataMatches ` + -existingMetadataObj $existingExemption.metadata ` + -definedMetadataObj $metadata + # Update policy definition in Azure if necessary + if ($displayNameMatches -and $descriptionMatches -and $exemptionCategoryMatches -and $expiresOnMatches -and $policyDefinitionReferenceIdsMatches -and $metadataMatches) { + # Write-Information "Unchanged '$($name)' - '$($displayName)'" + $null = $unchangedExemptions.Add($id, $displayName) + } + else { + $changesString = ($displayNameMatches ? "-" : "n") ` + + ($descriptionMatches ? "-" : "d") ` + + ($metadataMatches ? "-": "m") ` + + ($exemptionCategoryMatches ? "-": "c") ` + + ($expiresOnMatches ? "-": "x") ` + + ($clearExpiration ? "c": "-") ` + + ($policyDefinitionReferenceIdsMatches ? "-": "r") + + Write-Information "Update($changesString) '$($name)', '$($scope)'" + $null = $exemption.Add("Id", $id) + $null = $updatedExemptions.Add($id, $exemption) + } + } + } + else { + # Create Exemption + Write-Information "New '$($name)', '$($scope)'" + $null = $newExemptions.Add($id, $exemption) + } + } + } + + if ($unchangedExemptions.Count -gt 0) { + Write-Information "$($unchangedExemptions.Count) unchanged Exemptions" + } + if ($orphanedExemptions.Count -gt 0) { + Write-Information "$($orphanedExemptions.Count) orphaned Exemptions in definition files" + foreach ($id in $orphanedExemptions.Keys) { + $exemption = $orphanedExemptions[$id] + Write-Information " $($exemption.name), $($exemption.scope), $($exemption.policyAssignmentId)" + } + } + if ($expiredExemptions.Count -gt 0) { + Write-Information "$($expiredExemptions.Count) expired Exemptions in definition files" + foreach ($id in $expiredExemptions.Keys) { + $exemption = $expiredExemptions[$id] + Write-Information " $($exemption.name), $($exemption.scope), $($exemption.policyAssignmentId)" + } + } + if ($obsoleteExemptions.Count -gt 0) { + if ($noDelete) { + Write-Information "Suppressing delete Exemptions ($($obsoleteExemptions.Count))" + foreach ($id in $obsoleteExemptions.Keys) { + $exemption = $existingExemptions[$id] + Write-Information " $($exemption.displayName), $($exemption.name), $($exemption.scope)" + } + } + else { + Write-Information "Delete Exemptions ($($obsoleteExemptions.Count))" + foreach ($id in $obsoleteExemptions.Keys) { + $exemption = $existingExemptions[$id] + Write-Information " $($exemption.name), $($exemption.displayName), $($exemption.scope)" + $deletedExemptions.Add($id, $exemption) + } + } + } + Write-Information "" + Write-Information "" + } + else { + Write-Information "Warning: no Exemptions files for EPAC environment $pacEnvironmentSelector in directory '$path'!" + } + } + else { + Write-Information "Exemptions for EPAC environment $pacEnvironmentSelector are not managed by EPAC. To manage them craete a folder named '$path'." + } +} diff --git a/Scripts/Helpers/Confirm-ActiveAzExemptions.ps1 b/Scripts/Helpers/Confirm-ActiveAzExemptions.ps1 new file mode 100644 index 00000000..dca7ca99 --- /dev/null +++ b/Scripts/Helpers/Confirm-ActiveAzExemptions.ps1 @@ -0,0 +1,88 @@ +function Confirm-ActiveAzExemptions { + [CmdletBinding()] + param ( + [hashtable] $exemptions, + [hashtable] $assignments + ) + + # Process Exemptions + [hashtable] $allExemptions = @{} + [hashtable] $activeExemptions = @{} + [hashtable] $expiringExemptions = @{} + [hashtable] $expiredExemptions = @{} + [hashtable] $orphanedExemptions = @{} + + $now = Get-Date + foreach ($exemptionId in $exemptions.Keys) { + $exemption = $exemptions.$exemptionId + $policyAssignmentId = $exemption.policyAssignmentId + $isValid = $assignments.ContainsKey($policyAssignmentId) + $expiresOnString = $exemption.expiresOn + $expired = $false + $expiresInDays = [Int32]::MaxValue + if ($exemption.expiresOn) { + $expiresOn = [datetime]::Parse($expiresOnString) + $expired = $expiresOn -lt $now + $expiresIn = New-TimeSpan -Start $now -End $expiresOn + $expiresInDays = $expiresIn.Days + } + $status = "orphaned" + if ($isValid) { + if ($expired) { + $status = "expired" + } + else { + $status = "active" + } + } + + $name = $exemption.name + $displayName = $exemption.displayName + if ($null -eq $displayName) { + $displayName = $name + } + + $metadata = $exemption.metadata + if ($metadata -eq @{}) { + $metadata = $null + } + + $exemptionObj = [pscustomobject][ordered]@{ + name = $name + displayName = $exemption.displayName + description = $exemption.description + exemptionCategory = $exemption.exemptionCategory + expiresOn = $expiresOnString + status = $status + expiresInDays = $expiresInDays + scope = $exemption.scope + policyAssignmentId = $policyAssignmentId + policyDefinitionReferenceIds = $exemption.policyDefinitionReferenceIds + metadata = $metadata + id = $exemptionId + } + + $null = $allExemptions.Add($exemptionId, $exemptionObj) + switch ($status) { + active { + $null = $activeExemptions.Add($exemptionId, $exemptionObj) + } + orphaned { + $null = $orphanedExemptions.Add($exemptionId, $exemptionObj) + } + expired { + $null = $expiredExemptions.Add($exemptionId, $exemptionObj) + } + } + } + + $exemptionsResult = @{ + all = $allExemptions + active = $activeExemptions + expiresInDays = $expiringExemptions # Subset of active + orphaned = $orphanedExemptions # Orpahned trumps expired + expired = $expiredExemptions + } + + return $exemptionsResult +} \ No newline at end of file diff --git a/Scripts/Helpers/Confirm-MetadataMatches.ps1 b/Scripts/Helpers/Confirm-MetadataMatches.ps1 index aee82ea6..5d0bae64 100644 --- a/Scripts/Helpers/Confirm-MetadataMatches.ps1 +++ b/Scripts/Helpers/Confirm-MetadataMatches.ps1 @@ -3,23 +3,39 @@ function Confirm-MetadataMatches { [CmdletBinding()] param( - [PSCustomObject] $existingMetadataObj, - [PSCustomObject] $definedMetadataObj + $existingMetadataObj, + $definedMetadataObj ) $match = $false - if ($null -eq $existingMetadataObj) { - Write-Error "Existing metadata object cannot be `$null; this is likely a programming error" + if ($null -eq $existingMetadataObj -or $existingMetadataObj -eq @{}) { + if ($null -eq $definedMetadataObj -or $definedMetadataObj -eq @{}) { + $match = $true + } } else { # remove system generated metadata from consideration - [hashtable] $existingMetadata = ConvertTo-HashTable $existingMetadataObj - $existingMetadata.Remove("createdBy") - $existingMetadata.Remove("createdOn") - $existingMetadata.Remove("updatedBy") - $existingMetadata.Remove("updatedOn") - if ($null -eq $definedMetadataObj) { + $existingMetadata = @{} + if ($existingMetadataObj -isnot [hashtable]) { + $existingMetadata = ConvertTo-HashTable $existingMetadataObj + } + else { + $existingMetadata = Get-DeepClone -InputObject $existingMetadataObj + } + if ($existingMetadata.ContainsKey("createdBy")) { + $existingMetadata.Remove("createdBy") + } + if ($existingMetadata.ContainsKey("createdOn")) { + $existingMetadata.Remove("createdOn") + } + if ($existingMetadata.ContainsKey("updatedBy")) { + $existingMetadata.Remove("updatedBy") + } + if ($existingMetadata.ContainsKey("updatedOn")) { + $existingMetadata.Remove("updatedOn") + } + if ($null -eq $definedMetadataObj -or $definedMetadataObj -eq @{}) { if ($existingMetadata.Count -eq 0) { $match = $true } diff --git a/Scripts/Helpers/Convert-EffectToString.ps1 b/Scripts/Helpers/Convert-EffectToString.ps1 index b601cd61..7188f170 100644 --- a/Scripts/Helpers/Convert-EffectToString.ps1 +++ b/Scripts/Helpers/Convert-EffectToString.ps1 @@ -28,7 +28,7 @@ function Convert-EffectToString { foreach ($allowed in $allowedValues) { if ($allowed -cne $effect) { $effectShort = Convert-EffectToShortForm -effect $allowed - $text += "\n$effectShort" + $text += ", $effectShort" } } } diff --git a/Scripts/Helpers/Convert-ParametersToString.ps1 b/Scripts/Helpers/Convert-ParametersToString.ps1 index a006cb95..0d65c6d1 100644 --- a/Scripts/Helpers/Convert-ParametersToString.ps1 +++ b/Scripts/Helpers/Convert-ParametersToString.ps1 @@ -32,7 +32,7 @@ function Convert-ParametersToString { $newLine = "" foreach ($parameterText in $parameterList) { $text += "$newLine$parameterText" - $newLine = "\n" + $newLine = "; " } } } diff --git a/Scripts/Helpers/Get-AzAssignmentsAtScopeRecursive.ps1 b/Scripts/Helpers/Get-AzAssignmentsAtScopeRecursive.ps1 index 657e8fec..899c787a 100644 --- a/Scripts/Helpers/Get-AzAssignmentsAtScopeRecursive.ps1 +++ b/Scripts/Helpers/Get-AzAssignmentsAtScopeRecursive.ps1 @@ -11,7 +11,8 @@ function Add-Assignments { [bool] $getAssignments, [bool] $getRemediations, [hashtable] $assignments, - [hashtable] $remediations + [hashtable] $remediations, + [bool] $supressRoleAssignments ) #region $maybeRemediations @@ -55,14 +56,11 @@ function Add-Assignments { $headerDisplayed = $true } $existingRoleAssignments = @() - if ($null -ne $assignment.identity -and $null -ne $assignment.identity.principalId) { + if (-not $supressRoleAssignments -and $null -ne $assignment.identity -and $null -ne $assignment.identity.principalId) { + # Collate existing role assignments at Policy assignment scope and at additionalRoleAssignments scope(s) $existingRoleAssignments = @() + (Invoke-AzCli role assignment list --scope $scope --assignee $assignment.identity.principalId --only-show-errors) - } - - # Collate existing role assignments at Policy assignment scope and at additionalRoleAssignments scope(s) - if ($null -ne $assignment.identity -and $null -ne $assignment.identity.principalId) { $principalId = $assignment.identity.principalId - $scopesChecked = @{ + $scopesChecked = @{ $assignment.scope = $true } if ($assignment.metadata -and $assignment.metadata.roles) { @@ -74,18 +72,19 @@ function Add-Assignments { } } } - Write-Information " `'$($assignment.displayName)`': $($existingRoleAssignments.Length) Role Assignments" + Write-Information " `'$($assignment.displayName)`': $($existingRoleAssignments.Length) Role Assignments" } else { Write-Information " `'$($assignment.displayName)`'" } - $value = @{ + $value = @{ assignment = $assignment roleAssignments = $existingRoleAssignments } $assignments.Add($assignment.id, $value) } + #endregion #region Remediations @@ -181,6 +180,7 @@ function Add-Assignments { } #endregion } + } function Get-AzAssignmentsAtSpecificScope { @@ -188,12 +188,14 @@ function Get-AzAssignmentsAtSpecificScope { param ( [string] $scope, [bool] $getAssignments, + [bool] $getExemptions, [bool] $getRemediations, [hashtable] $allPolicyDefinitions, [hashtable] $allInitiativeDefinitions, [hashtable] $assignments, - [hashtable] $remediations - + [hashtable] $exemptions, + [hashtable] $remediations, + [bool] $supressRoleAssignments ) $splits = $scope.Split('/') @@ -203,34 +205,109 @@ function Get-AzAssignmentsAtSpecificScope { $null = Invoke-AzCli account set --subscription $subscriptionId if ($splits.Length -ge 5) { # Resource Group scope - $assignmentList = @() + (Invoke-AzCli policy assignment list --resource-group $scope) - if ($assignmentList.Length -gt 0) { - $header = "Resource Group $scope with $($assignmentList.Length) Policy Assignments" - $rg = $splits[-1] - [hashtable] $scopeSplat = @{ - subscription = $subscriptionId - "resource-group" = $rg + if ($getAssignments -or $getRemediations) { + $assignmentList = @() + (Invoke-AzCli policy assignment list --resource-group $scope) + if ($assignmentList.Length -gt 0) { + $header = "Resource Group $scope with $($assignmentList.Length) Policy Assignments" + $rg = $splits[-1] + [hashtable] $scopeSplat = @{ + subscription = $subscriptionId + "resource-group" = $rg + } + Add-Assignments ` + -assignmentList $assignmentList ` + -header $header ` + -scope $scope ` + -scopeSplat $scopeSplat ` + -allPolicyDefinitions $allPolicyDefinitions ` + -allInitiativeDefinitions $allInitiativeDefinitions ` + -getAssignments $getAssignments ` + -getRemediations $getRemediations ` + -assignments $assignments ` + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments } - Add-Assignments ` - -assignmentList $assignmentList ` - -header $header ` - -scope $scope ` - -scopeSplat $scopeSplat ` - -allPolicyDefinitions $allPolicyDefinitions ` - -allInitiativeDefinitions $allInitiativeDefinitions ` - -getAssignments $getAssignments ` - -getRemediations $getRemediations ` - -assignments $assignments ` - -remediations $remediations } } else { # Subscription scope + if ($getAssignments -or $getRemediations) { + $assignmentList = @() + (Invoke-AzCli policy assignment list --scope $scope) + if ($assignmentList.Length -gt 0) { + $header = "Subscription $subscriptionId with $($assignmentList.Length) Policy Assignments" + [hashtable] $scopeSplat = @{ + subscription = $subscriptionId + } + Add-Assignments ` + -assignmentList $assignmentList ` + -header $header ` + -scope $scope ` + -scopeSplat $scopeSplat ` + -allPolicyDefinitions $allPolicyDefinitions ` + -allInitiativeDefinitions $allInitiativeDefinitions ` + -getAssignments $getAssignments ` + -getRemediations $getRemediations ` + -assignments $assignments ` + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments + } + } + if ($getExemptions) { + $exemptionList = (Invoke-AzCli policy exemption list --disable-scope-strict-match --scope $scope) + foreach ($exemptionRaw in $exemptionList) { + $exemptionId = $exemptionRaw.id + if (-not $exemptions.ContainsKey($exemptionId)) { + $name = $exemptionRaw.name + + [array] $splits = $exemptionId -split "/" + $numberOfSplits = $splits.Count + $scopeLastIndex = $numberOfSplits - 5 + $scopeSplits = $splits[0..$scopeLastIndex] + $scope = $scopeSplits -join "/" + + $displayName = $exemptionRaw.displayName + $description = $exemptionRaw.description + $exemptionCategory = $exemptionRaw.exemptionCategory + $expiresOn = $exemptionRaw.expiresOn + $policyAssignmentId = $exemptionRaw.policyAssignmentId + $policyDefinitionReferenceIds = $exemptionRaw.policyDefinitionReferenceIds + $metadata = $exemptionRaw.metadata + $exemption = @{ + name = $name + scope = $scope + policyAssignmentId = $policyAssignmentId + exemptionCategory = $exemptionCategory + } + if ($displayName -and $displayName -ne "") { + $exemption.Add("displayName", $displayName) + } + if ($description -and $description -ne "") { + $exemption.Add("description", $description) + } + if ($expiresOn -and $expiresOn -ne "") { + $exemption.Add("expiresOn", $expiresOn) + } + if ($policyDefinitionReferenceIds -and $policyDefinitionReferenceIds.Count -gt 0) { + $exemption.Add("policyDefinitionReferenceIds", $policyDefinitionReferenceIds) + } + if ($metadata -and $metadata -ne @{} ) { + $exemption.Add("metadata", $metadata) + } + $null = $exemptions.Add($exemptionId, $exemption) + } + } + } + } + } + else { + # Management Groups scope + if ($getAssignments -or $getRemediations) { $assignmentList = @() + (Invoke-AzCli policy assignment list --scope $scope) + $mg = $splits[-1] if ($assignmentList.Length -gt 0) { - $header = "Subscription $subscriptionId with $($assignmentList.Length) Policy Assignments" + $header = "Management Group $mg with $($assignmentList.Length) Policy Assignments" [hashtable] $scopeSplat = @{ - subscription = $subscriptionId + "management-group" = $mg } Add-Assignments ` -assignmentList $assignmentList ` @@ -242,30 +319,9 @@ function Get-AzAssignmentsAtSpecificScope { -getAssignments $getAssignments ` -getRemediations $getRemediations ` -assignments $assignments ` - -remediations $remediations - } - } - } - else { - # Management Groups scope - $assignmentList = @() + (Invoke-AzCli policy assignment list --scope $scope) - $mg = $splits[-1] - if ($assignmentList.Length -gt 0) { - $header = "Management Group $mg with $($assignmentList.Length) Policy Assignments" - [hashtable] $scopeSplat = @{ - "management-group" = $mg + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments } - Add-Assignments ` - -assignmentList $assignmentList ` - -header $header ` - -scope $scope ` - -scopeSplat $scopeSplat ` - -allPolicyDefinitions $allPolicyDefinitions ` - -allInitiativeDefinitions $allInitiativeDefinitions ` - -getAssignments $getAssignments ` - -getRemediations $getRemediations ` - -assignments $assignments ` - -remediations $remediations } } } @@ -277,13 +333,17 @@ function Get-AzAssignmentsAtScopeRecursive { [parameter(Mandatory = $True)] [string[]] $notScopeIn, [parameter(Mandatory = $false)] [bool] $includeResourceGroups = $false, [parameter(Mandatory = $false)] [bool] $getAssignments = $true, + [parameter(Mandatory = $false)] [bool] $getExemptions = $true, + [Parameter(Mandatory = $false)] [int] $expiringInDays = 7, [parameter(Mandatory = $false)] [bool] $getRemediations = $false, [parameter(Mandatory = $false)] [hashtable] $allPolicyDefinitions = $null, - [parameter(Mandatory = $false)] [hashtable] $allInitiativeDefinitions = $null + [parameter(Mandatory = $false)] [hashtable] $allInitiativeDefinitions = $null, + [switch] $supressRoleAssignments ) [array] $subscriptionIds = @() - [hashtable] $assignmentsInAzure = @{} + [hashtable] $assignmentsInAzure = @{} + [hashtable] $exemptions = @{} [hashtable] $remediations = @{} # Check parameters @@ -297,7 +357,7 @@ function Get-AzAssignmentsAtScopeRecursive { if (-not ($getAssignments -or $getRemediations)) { } - + Write-Information "===================================================================================================" Write-Information "Get Policy and Role Assignments recursively" Write-Information "===================================================================================================" @@ -306,11 +366,14 @@ function Get-AzAssignmentsAtScopeRecursive { $subscriptionIds += $scopeTreeInfo.SingleSubscription Get-AzAssignmentsAtSpecificScope -scope "$($scopeTreeInfo.SingleSubscription)" ` -getAssignments $getAssignments ` + -getExemptions $getExemptions ` -getRemediations $getRemediations ` -allPolicyDefinitions $allPolicyDefinitions ` -allInitiativeDefinitions $allInitiativeDefinitions ` -assignments $assignmentsInAzure ` - -remediations $remediations + -exemptions $exemptions ` + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments.IsPresent } elseif ($null -ne $scopeTreeInfo.ScopeTree) { # Management Group -> Process Management Groups and Subscriptions @@ -327,7 +390,8 @@ function Get-AzAssignmentsAtScopeRecursive { -allPolicyDefinitions $allPolicyDefinitions ` -allInitiativeDefinitions $allInitiativeDefinitions ` -assignments $assignmentsInAzure ` - -remediations $remediations + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments.IsPresent foreach ($child in $currentMg.children) { if ($notScopeIn.Contains($child.id)) { Write-Information "Skipping notScope $($child.name) ($($child.id))" @@ -344,11 +408,14 @@ function Get-AzAssignmentsAtScopeRecursive { Write-Debug " Subscription testing list += subscription $($child.id)" Get-AzAssignmentsAtSpecificScope -scope $child.id ` -getAssignments $getAssignments ` + -getExemptions $getExemptions ` -getRemediations $getRemediations ` -allPolicyDefinitions $allPolicyDefinitions ` -allInitiativeDefinitions $allInitiativeDefinitions ` -assignments $assignmentsInAzure ` - -remediations $remediations + -exemptions $exemptions ` + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments.IsPresent $subscriptionIds += $child.id } } @@ -356,7 +423,7 @@ function Get-AzAssignmentsAtScopeRecursive { } } } - + Write-Debug "Testing subscriptionIds($($subscriptionIds.Count)), notScopeResourceGroupIds($($notScopeResourceGroupIds.Count)), notScopePatterns($($notScopePatterns.Count))" # Find Resource Groups in all subscriptions in notScope if ($subscriptionIds.Length -gt 0 -and $includeResourceGroups) { @@ -412,7 +479,8 @@ function Get-AzAssignmentsAtScopeRecursive { -allPolicyDefinitions $allPolicyDefinitions ` -allInitiativeDefinitions $allInitiativeDefinitions ` -assignments $assignmentsInAzure ` - -remediations $remediations + -remediations $remediations ` + -supressRoleAssignments $supressRoleAssignments.IsPresent } } } @@ -420,6 +488,7 @@ function Get-AzAssignmentsAtScopeRecursive { Write-Information "" Write-Information "" - return $assignmentsInAzure, $remediations + + return $assignmentsInAzure, $remediations, $exemptions } \ No newline at end of file diff --git a/Scripts/Helpers/Get-DeepClone.ps1 b/Scripts/Helpers/Get-DeepClone.ps1 index 26355973..4c2ebe75 100644 --- a/Scripts/Helpers/Get-DeepClone.ps1 +++ b/Scripts/Helpers/Get-DeepClone.ps1 @@ -2,9 +2,9 @@ function Get-DeepClone { [cmdletbinding()] param( - [PSObject] $InputObject + $InputObject ) - + if ($InputObject -is [hashtable]) { $clone = @{} foreach ($key in $InputObject.Keys) { diff --git a/Scripts/Helpers/Get-FilteredHashTable.ps1 b/Scripts/Helpers/Get-FilteredHashTable.ps1 index 1860e5e0..8bffb86d 100644 --- a/Scripts/Helpers/Get-FilteredHashTable.ps1 +++ b/Scripts/Helpers/Get-FilteredHashTable.ps1 @@ -5,46 +5,95 @@ function Get-FilteredHashTable { param ( [parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] - [pscustomobject] $Object, + [pscustomobject] $splat, [Parameter()] - [string] $Filter = $null + [string] $splatTransform = $null ) - [hashtable] $result = @{} - [hashtable] $inHt = @{} - if ($null -ne $Object) { - if ($Object -is [hashtable]) { - $inHt = $Object + [hashtable] $filteredSplat = @{} + if ($null -ne $splat) { + # ignore an empty splat + if (-not ($splat -is [hashtable])) { + $ht = $splat | ConvertTo-HashTable + $splat = $ht } - else { - $inHt = $Object | ConvertTo-HashTable - } - if ($null -eq $Filter -or $Filter -eq "") { - $result = $inHt + + $transforms = $splat.Keys + if ($splatTransform) { + $transforms = $splatTransform.Split() } - else { - $transforms = $Filter.Split() - # ignore an empty splat - foreach ($transform in $transforms) { - $splits = $transform.Split("/") - $selector = $splits[0] - if ($inHt.ContainsKey($selector)) { - $entry = $inHt[$selector] - $value = $entry - if ($entry -is [array] -or $entry -is [PSCustomObject] -or $entry -is [hashtable]) { - $json = ConvertTo-Json $entry -Depth 100 -Compress - $value = $json - } - switch ($splits.Length) { - 1 { $result.Add($selector, $value); break } # - 2 { $result.Add($splits[1], $value); break } - Default { throw "inHtTransform has too menay parts ""$transform""" } + foreach ($transform in $transforms) { + $splits = $transform.Split("/") + $splatSelector = $splits[0] + if ($splat.ContainsKey($splatSelector)) { + $argName = $splatSelector + $argValue = $splat.$splatSelector + $splatValue = $argValue + + # Infer format from data type + $type = "value" + if ($null -eq $splatValue -or $splatValue -eq "") { + $type = "key" + } + elseif ($splatValue -is [array]) { + $type = "array" + foreach ($value in $splatValue) { + if (-not($value -is [string] -or $value -is [System.ValueType])) { + $type = "json" + break + } + } + } + elseif ($splatValue -is [string] -or $splatValue -is [System.ValueType]) { + $type = "value" + } + else { + $type = "json" + } + + # Check overrides + if ($splits.Length -in @(2, 3)) { + if ($splits[1] -in @("json", "array", "key", "value")) { + # Infered type is explicitly overriden + $type = $splits[1] + if ($splits.Length -eq 3) { + $argName = $splits[2] + } + } + elseif ($splits.Length -eq 2) { + # Inferred type used and the second part is the newArgName + $argName = $splits[1] + } + else { + # Unknown type specified + Write-Error "Invalid `splatTransform = '$transform', second part must be one of the following json, array, keyvalues, key, string, value." -ErrorAction Stop + } + } + switch ($type) { + "json" { + $argValue = ConvertTo-Json $splatValue -Depth 100 + $null = $filteredSplat.Add($argName, $argValue) + } + "key" { + # Just the key (no value) + $null = $filteredSplat.Add($argName, $true) + } + "value" { + $null = $filteredSplat.Add($argName, $argValue) + } + "array" { + $null = $filteredSplat.Add($argName, $argValue) + } + Default { + Write-Error "Unknown format '$_' for -splatTransform specified '$transform'" -ErrorAction Stop + break } } } } } - return $result + + return $filteredSplat } \ No newline at end of file diff --git a/Scripts/Helpers/Get-GlobalSettings.ps1 b/Scripts/Helpers/Get-GlobalSettings.ps1 index 61b59d54..a44a43ba 100644 --- a/Scripts/Helpers/Get-GlobalSettings.ps1 +++ b/Scripts/Helpers/Get-GlobalSettings.ps1 @@ -113,20 +113,26 @@ function Get-GlobalSettings { Write-Information "Output folder: $outputFolder" Write-Information "" + $documentationDefinitionsFolder = "$definitionsRootFolder/Documentation" + if (!(Test-Path $documentationDefinitionsFolder -PathType Container)) { + $documentationDefinitionsFolder = "$definitionsRootFolder/DocumentationSpecs" # Legacy location + } + [hashtable] $globalSettings = @{ - definitionsRootFolder = $definitionsRootFolder - globalSettingsFile = $globalSettingsFile - outputFolder = $outputFolder - inputFolder = $inputFolder - policyDefinitionsFolder = "$definitionsRootFolder/Policies" - initiativeDefinitionsFolder = "$definitionsRootFolder/Initiatives" - assignmentsFolder = "$definitionsRootFolder/Assignments" - documentationSpecsFolder = "$definitionsRootFolder/DocumentationSpecs" - pacEnvironmentSelectors = $pacEnvironmentSelectors - pacEnvironmentPrompt = $prompt - pacEnvironments = $pacEnvironmentDefinitions - globalNotScopes = $globalNotScopes - managedIdentityLocations = $managedIdentityLocations + definitionsRootFolder = $definitionsRootFolder + globalSettingsFile = $globalSettingsFile + outputFolder = $outputFolder + inputFolder = $inputFolder + policyDefinitionsFolder = "$definitionsRootFolder/Policies" + initiativeDefinitionsFolder = "$definitionsRootFolder/Initiatives" + assignmentsFolder = "$definitionsRootFolder/Assignments" + exemptionsFolder = "$definitionsRootFolder/Exemptions" + documentationDefinitionsFolder = "$documentationDefinitionsFolder" + pacEnvironmentSelectors = $pacEnvironmentSelectors + pacEnvironmentPrompt = $prompt + pacEnvironments = $pacEnvironmentDefinitions + globalNotScopes = $globalNotScopes + managedIdentityLocations = $managedIdentityLocations } return $globalSettings } diff --git a/Scripts/Helpers/Invoke-AzCli.ps1 b/Scripts/Helpers/Invoke-AzCli.ps1 index ae937541..7ea4bc69 100644 --- a/Scripts/Helpers/Invoke-AzCli.ps1 +++ b/Scripts/Helpers/Invoke-AzCli.ps1 @@ -193,7 +193,7 @@ function Invoke-AzCli { $result = "" try { - $result = az @Arguments @splatArguments @additionalArguments + $result = az @Arguments @splatArguments @additionalArguments --only-show-errors if (!$?) { throw "Command 'az $Arguments $splatArguments' command exited with error" } diff --git a/Scripts/Helpers/Out-InitiativeDocumentationToFile.ps1 b/Scripts/Helpers/Out-InitiativeDocumentationToFile.ps1 index 17303403..e7b52ef6 100644 --- a/Scripts/Helpers/Out-InitiativeDocumentationToFile.ps1 +++ b/Scripts/Helpers/Out-InitiativeDocumentationToFile.ps1 @@ -216,7 +216,7 @@ function Out-InitiativeDocumentationToFile { $groupNames = $perInitiative.groupNames $groupNamesFragment = "n/a" if ($groupNames.Count -gt 0) { - $groupNamesFragment = $groupNames -join "\n" + $groupNamesFragment = $groupNames -join ", " } $null = $cells.Add($groupNamesFragment) } @@ -247,7 +247,7 @@ function Out-InitiativeDocumentationToFile { [void] $sb.Append("`n // ") [void] $sb.Append("`n // -----------------------------------------------------------------------------------------------------------------------------") - [void] $sb.Append("`n // '$($_.category)' Policy: '$($_.displayName)'") + [void] $sb.Append("`n // $($_.category): $($_.displayName)") [void] $sb.Append("`n // -----------------------------------------------------------------------------------------------------------------------------") $parametersForThisPolicy = @{} @@ -264,10 +264,10 @@ function Out-InitiativeDocumentationToFile { $initiativesForThisParameter = $parameterForThisPolicy.initiativesForThisParameter $initiativeText = "" if ($perInitiative.isEffectParameterized) { - $initiativeText = "'$($initiativeDisplayName)': effect default) = $($perInitiative.effectDefault)" + $initiativeText = "$($initiativeDisplayName): $($perInitiative.effectDefault) (default)" } else { - $initiativeText = "'$($initiativeDisplayName)': effect fixed = $($perInitiative.effectValue)" + $initiativeText = "$($initiativeDisplayName): $($perInitiative.effectValue) (fixed)" } $null = $initiativesForThisParameter.Add("$initiativeText") } @@ -294,10 +294,10 @@ function Out-InitiativeDocumentationToFile { $initiativesForThisParameter = [System.Collections.ArrayList]::new() $initiativeText = "" if ($perInitiative.isEffectParameterized) { - $initiativeText = "'$($initiativeDisplayName)': effect default = $($perInitiative.effectDefault)" + $initiativeText = "$($initiativeDisplayName): $($perInitiative.effectDefault) (default)" } else { - $initiativeText = "'$($initiativeDisplayName)': effect fixed = $($perInitiative.effectValue)" + $initiativeText = "$($initiativeDisplayName): $($perInitiative.effectValue) (fixed)" } $null = $initiativesForThisParameter.Add("$initiativeText") $parameterForThisPolicy = @{ @@ -325,7 +325,7 @@ function Out-InitiativeDocumentationToFile { [void] $sb.Append("`n $($parameterForThisPolicy.parameterString),") $null = $parametersAlreadyCovered.Add($parameterName, "covered") } - [void] $sb.Append("`n // Alowed Values = $($parameterForThisPolicy.allowedValuesString)") + [void] $sb.Append("`n // Allowed Values = $($parameterForThisPolicy.allowedValuesString)") $initiativesForThisParameter = $parameterForThisPolicy.initiativesForThisParameter foreach ($initiativeForThisParameter in $initiativesForThisParameter) { [void] $sb.Append("`n // $($initiativeForThisParameter)") diff --git a/Scripts/Helpers/Select-PacEnvironment.ps1 b/Scripts/Helpers/Select-PacEnvironment.ps1 index cd3565dd..3e44f2d3 100644 --- a/Scripts/Helpers/Select-PacEnvironment.ps1 +++ b/Scripts/Helpers/Select-PacEnvironment.ps1 @@ -88,26 +88,27 @@ function Select-PacEnvironment { } } $pacEnvironmentDefinition = @{ - pacEnvironmentSelector = $pacEnvironmentSelector - interactive = $interactive - cloud = $pacEnvironment.cloud - tenantId = $pacEnvironment.tenantId - defaultSubscriptionId = $pacEnvironment.defaultSubscriptionId - rootScope = $pacEnvironment.rootScope - rootScopeId = $pacEnvironment.rootScopeId - globalNotScopeList = $globalNotScopeList - managedIdentityLocation = $managedIdentityLocation - definitionsRootFolder = $globalSettings.definitionsRootFolder - policyDefinitionsFolder = $globalSettings.policyDefinitionsFolder - initiativeDefinitionsFolder = $globalSettings.initiativeDefinitionsFolder - assignmentsFolder = $globalSettings.assignmentsFolder - documentationSpecsFolder = $globalSettings.documentationSpecsFolder - outputFolder = $globalSettings.outputFolder - inputFolder = $globalSettings.inputFolder - policyPlanOutputFile = "$($globalSettings.outputFolder)/policy-plan-$pacEnvironmentSelector/policy-plan.json" - rolesPlanOutputFile = "$($globalSettings.outputFolder)/roles-plan-$pacEnvironmentSelector/roles-plan.json" - policyPlanInputFile = "$($globalSettings.inputFolder)/policy-plan-$pacEnvironmentSelector/policy-plan.json" - rolesPlanInputFile = "$($globalSettings.inputFolder)/roles-plan-$pacEnvironmentSelector/roles-plan.json" + pacEnvironmentSelector = $pacEnvironmentSelector + interactive = $interactive + cloud = $pacEnvironment.cloud + tenantId = $pacEnvironment.tenantId + defaultSubscriptionId = $pacEnvironment.defaultSubscriptionId + rootScope = $pacEnvironment.rootScope + rootScopeId = $pacEnvironment.rootScopeId + globalNotScopeList = $globalNotScopeList + managedIdentityLocation = $managedIdentityLocation + definitionsRootFolder = $globalSettings.definitionsRootFolder + policyDefinitionsFolder = $globalSettings.policyDefinitionsFolder + initiativeDefinitionsFolder = $globalSettings.initiativeDefinitionsFolder + assignmentsFolder = $globalSettings.assignmentsFolder + exemptionsFolder = $globalSettings.exemptionsFolder + documentationDefinitionsFolder = $globalSettings.documentationDefinitionsFolder + outputFolder = $globalSettings.outputFolder + inputFolder = $globalSettings.inputFolder + policyPlanOutputFile = "$($globalSettings.outputFolder)/policy-plan-$pacEnvironmentSelector/policy-plan.json" + rolesPlanOutputFile = "$($globalSettings.outputFolder)/roles-plan-$pacEnvironmentSelector/roles-plan.json" + policyPlanInputFile = "$($globalSettings.inputFolder)/policy-plan-$pacEnvironmentSelector/policy-plan.json" + rolesPlanInputFile = "$($globalSettings.inputFolder)/roles-plan-$pacEnvironmentSelector/roles-plan.json" } return $pacEnvironmentDefinition diff --git a/Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1 b/Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1 index af72cc80..41274256 100644 --- a/Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1 +++ b/Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1 @@ -49,7 +49,7 @@ param ( $InformationPreference = 'Continue' $globalSettings = Get-GlobalSettings -definitionsRootFolder $definitionsRootFolder -outputFolder $outputFolder -$definitionsFolder = $globalSettings.documentationSpecsFolder +$definitionsFolder = $globalSettings.documentationDefinitionsFolder $pacEnvironments = $globalSettings.pacEnvironments $outputPath = "$($globalSettings.outputFolder)/AzPolicyDocumentation" if (-not (Test-Path $outputPath)) { @@ -145,12 +145,12 @@ foreach ($file in $files) { Write-Error "Json document does not contain the required 'pacEnvironment' element." -ErrorAction Stop } # Load pacEnvironment - $pacEnvironmenSelector = $environmentCategoryEntry.pacEnvironment + $pacEnvironmentSelector = $environmentCategoryEntry.pacEnvironment Write-Information "" - if ($currentPacEnvironmentSelector -ne $pacEnvironmenSelector) { - $currentPacEnvironmentSelector = $pacEnvironmenSelector + if ($currentPacEnvironmentSelector -ne $pacEnvironmentSelector) { + $currentPacEnvironmentSelector = $pacEnvironmentSelector Write-Information "===================================================================================================" - Write-Information "Policy as Code environment (pacEnvironment) '$($pacEnvironmenSelector)'" + Write-Information "Policy as Code environment (pacEnvironment) '$($pacEnvironmentSelector)'" Write-Information "===================================================================================================" Write-Information "" $pacEnvironment = Switch-PacEnvironment ` @@ -246,11 +246,10 @@ foreach ($file in $files) { } if (-not $cachedPolicyInitiativeInfos.ContainsKey($pacEnvironmentSelector)) { - if ($currentPacEnvironmentSelector -ne $pacEnvironmenSelector) { - # Should always be true + if ($currentPacEnvironmentSelector -ne $pacEnvironmentSelector) { $currentPacEnvironmentSelector = $pacEnvironmentSelector Write-Information "===================================================================================================" - Write-Information "Policy as Code environment (pacEnvironment) '$($pacEnvironmenSelector)'" + Write-Information "Policy as Code environment (pacEnvironment) '$($pacEnvironmentSelector)'" Write-Information "===================================================================================================" Write-Information "" $pacEnvironment = Switch-PacEnvironment ` @@ -263,7 +262,7 @@ foreach ($file in $files) { # Retrieve Policies and Initiatives for current pacEnvironment from cache or from Azure $policyInitiativeInfo = Get-PolicyInitiativeInfos ` - -pacEnvironmentSelector $currentPacEnvironmentSelector ` + -pacEnvironmentSelector $pacEnvironmentSelector ` -pacEnvironment $pacEnvironment ` -cachedPolicyInitiativeInfos $cachedPolicyInitiativeInfos diff --git a/Scripts/Operations/Create-AzRemediationTasks.ps1 b/Scripts/Operations/Create-AzRemediationTasks.ps1 index c84daf1d..718b0af0 100644 --- a/Scripts/Operations/Create-AzRemediationTasks.ps1 +++ b/Scripts/Operations/Create-AzRemediationTasks.ps1 @@ -44,6 +44,7 @@ $null, $remediations = Get-AzAssignmentsAtScopeRecursive ` -notScopeIn $pacEnvironment.globalNotScopeList ` -includeResourceGroups $false ` -getAssignments $false ` + -getExemptions $false ` -getRemediations $true ` -allPolicyDefinitions $allPolicyDefinitions ` -allInitiativeDefinitions $allInitiativeDefinitions diff --git a/Scripts/Operations/Get-AzExemptions.ps1 b/Scripts/Operations/Get-AzExemptions.ps1 new file mode 100644 index 00000000..903d7a40 --- /dev/null +++ b/Scripts/Operations/Get-AzExemptions.ps1 @@ -0,0 +1,122 @@ +#Requires -PSEdition Core + +[CmdletBinding()] +param( + [parameter(Mandatory = $false, HelpMessage = "Defines which Policy as Code (PAC) environment we are using, if omitted, the script prompts for a value. The values are read from `$DefinitionsRootFolder/global-settings.jsonc.", Position = 0)] + [string] $PacEnvironmentSelector, + + [Parameter(Mandatory = $false, HelpMessage = "Definitions folder path. Defaults to environment variable `$env:PAC_DEFINITIONS_FOLDER or './Definitions'.")] + [string]$DefinitionsRootFolder, + + [Parameter(Mandatory = $false, HelpMessage = "Output Folder. Defaults to environment variable `$env:PAC_OUTPUT_FOLDER or './Outputs'.")] + [string] $OutputFolder, + + [Parameter(Mandatory = $false, HelpMessage = "Set to false if used non-interactive")] + [bool] $interactive = $true +) + +. "$PSScriptRoot/../Helpers/Get-PacFolders.ps1" +. "$PSScriptRoot/../Helpers/Get-GlobalSettings.ps1" +. "$PSScriptRoot/../Helpers/Select-PacEnvironment.ps1" +. "$PSScriptRoot/../Helpers/Get-AzPolicyInitiativeDefinitions.ps1" +. "$PSScriptRoot/../Helpers/Get-AzAssignmentsAtScopeRecursive.ps1" +. "$PSScriptRoot/../Helpers/Get-AzScopeTree.ps1" +. "$PSScriptRoot/../Helpers/ConvertTo-HashTable.ps1" +. "$PSScriptRoot/../Helpers/Invoke-AzCli.ps1" +. "$PSScriptRoot/../Helpers/Split-AssignmentIdForAzCli.ps1" +. "$PSScriptRoot/../Helpers/Set-AzCloudTenantSubscription.ps1" +. "$PSScriptRoot/../Helpers/Confirm-ActiveAzExemptions.ps1" + +$InformationPreference = "Continue" +Invoke-AzCli config set extension.use_dynamic_install=yes_without_prompt -SuppressOutput +$pacEnvironment = Select-PacEnvironment $PacEnvironmentSelector -definitionsRootFolder $DefinitionsRootFolder -outputFolder $OutputFolder -interactive $interactive +Set-AzCloudTenantSubscription -cloud $pacEnvironment.cloud -tenantId $pacEnvironment.tenantId -subscriptionId $pacEnvironment.defaultSubscriptionId -interactive $pacEnvironment.interactive + +$rootScopeId = $pacEnvironment.rootScopeId +$rootScope = $pacEnvironment.rootScope +$outputPath = "$($pacEnvironment.outputFolder)/Exemptions/$($pacEnvironment.pacEnvironmentSelector)" +if (-not (Test-Path $outputPath)) { + New-Item $outputPath -Force -ItemType directory +} + + +$allAzPolicyInitiativeDefinitions = Get-AzPolicyInitiativeDefinitions -rootScope $rootScope -rootScopeId $rootScopeId +$allPolicyDefinitions = $allAzPolicyInitiativeDefinitions.builtInPolicyDefinitions + $allAzPolicyInitiativeDefinitions.existingCustomPolicyDefinitions +$allInitiativeDefinitions = $allAzPolicyInitiativeDefinitions.builtInInitiativeDefinitions + $allAzPolicyInitiativeDefinitions.existingCustomInitiativeDefinitions + +$scopeTreeInfo = Get-AzScopeTree ` + -tenantId $pacEnvironment.tenantId ` + -scopeParam $rootScope ` + -defaultSubscriptionId $pacEnvironment.defaultSubscriptionId + +$assignments, $null, $exemptions = Get-AzAssignmentsAtScopeRecursive ` + -scopeTreeInfo $scopeTreeInfo ` + -notScopeIn $pacEnvironment.globalNotScopeList ` + -includeResourceGroups $false ` + -getAssignments $true ` + -getExemptions $true ` + -expiringInDays $expiringInDays ` + -getRemediations $false ` + -allPolicyDefinitions $allPolicyDefinitions ` + -allInitiativeDefinitions $allInitiativeDefinitions ` + -supressRoleAssignments + +$numberOfExemptions = $exemptions.Count +Write-Information "===================================================================================================" +Write-Information "Output Exemption list ($numberOfExemptions)" +Write-Information "===================================================================================================" + +$exemptionsResult = Confirm-ActiveAzExemptions -exemptions $exemptions -assignments $assignments +$policyDefinitionReferenceIdsTransform = @{label = "policyDefinitionReferenceIds"; expression = { ($_.policyDefinitionReferenceIds -join ",").ToString() } } +$metadataTransform = @{label = "metadata"; expression = { IF ($_.metadata) { (ConvertTo-Json $_.metadata -Depth 100 -Compress).ToString() } Else { '' } } } +$expiresInDaysTransform = @{label = "expiresInDays"; expression = { IF ($_.expiresInDays -eq [Int32]::MaxValue) { 'n/a' } Else { $_.expiresInDays } } } +foreach ($key in $exemptionsResult.Keys) { + [hashtable] $exemptions = $exemptionsResult.$key + Write-Information "Output $key Exemption list ($($exemptions.Count))" + + $valueArray = @() + $exemptions.Values + + if ($valueArray.Count -gt 0) { + + $stem = "$outputPath/$($key)-exemptions" + + # JSON Output + $jsonArray = @() + $valueArray | Select-Object -Property ` + name, ` + displayName, ` + description, ` + exemptionCategory, ` + expiresOn, ` + status, ` + $expiresInDaysTransform, ` + scope, ` + policyAssignmentId, ` + policyDefinitionReferenceIds, ` + metadata + $jsonFile = "$($stem).json" + if (Test-Path $jsonFile) { + Remove-Item $jsonFile + } + ConvertTo-Json $jsonArray -Depth 100 | Out-File $jsonFile -Force + + # Spreadsheet outputs (csv and xlsx) + $excelArray = @() + $valueArray | Select-Object -Property ` + name, ` + displayName, ` + description, ` + exemptionCategory, ` + expiresOn, ` + status, ` + $expiresInDaysTransform, ` + scope, ` + policyAssignmentId, ` + $policyDefinitionReferenceIdsTransform, ` + $metadataTransform + + $csvFile = "$($stem).csv" + if (Test-Path $csvFile) { + Remove-Item $csvFile + } + $excelArray | ConvertTo-Csv -UseQuotes AsNeeded | Out-File $csvFile -Force + } +} diff --git a/Scripts/Operations/README.md b/Scripts/Operations/README.md index 6e6b18e7..aac3c8cf 100644 --- a/Scripts/Operations/README.md +++ b/Scripts/Operations/README.md @@ -51,7 +51,7 @@ This script executes all remediation tasks in a Policy as Code environment speci ## Build-PolicyAssignmentDocumentation.ps1 -Generates documentation for assignments and initiatives based on Json files in `$definitionsFolder/DocumentationSpecs`. [See Define Documentation for details](../../Definitions/DocumentationSpecs/README.md). +Generates documentation for assignments and initiatives based on Json files in `$definitionsFolder/Documentation`. [See Define Documentation for details](../../Definitions/Documentation/README.md). |Parameter | Required | Explanation | |----------|----------|-------------| @@ -126,7 +126,9 @@ Lists Role assignments per user. 1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)** -1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)** +1. **[Define Policy Exemptions](../../Definitions/Exemptions/README.md)** + +1. **[Documenting Assignments and Initiatives](../../Definitions/Documentation/README.md)** 1. **[Operational Scripts](#Scripts)** diff --git a/StarterKit/Definitions/Assignments/security-baseline-assignments.jsonc b/StarterKit/Definitions/Assignments/security-baseline-assignments.jsonc index dbb9b6d0..ec8c5e2a 100644 --- a/StarterKit/Definitions/Assignments/security-baseline-assignments.jsonc +++ b/StarterKit/Definitions/Assignments/security-baseline-assignments.jsonc @@ -110,45 +110,45 @@ "Developer", "Premium" ], - // Alowed Values = ["Developer","Basic","Standard","Premium","Consumption"] + // Allowed Values = ["Developer","Basic","Standard","Premium","Consumption"] // 'Azure Security Benchmark': effect default = Audit "aPIManagementServicesShouldUseAVirtualNetworkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit "evaluatedSkuNames-ef619a2c-cc4d-4d03-b2ba-8c94a834d85b": [ "Developer", "Premium" ], - // Alowed Values = ["Developer","Basic","Standard","Premium","Consumption"] + // Allowed Values = ["Developer","Basic","Standard","Premium","Consumption"] // 'NIST SP 800-53 Rev. 5': effect fixed = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Configuration' Policy: 'App Configuration should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "appConfigurationShouldUsePrivateLinkMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Platform' Policy: 'Azure Spring Cloud should use network injection' // ----------------------------------------------------------------------------------------------------------------------------- "effect-af35e2a4-ef96-44e7-a9ae-853dd97032c4": "Audit", - // Alowed Values = ["Audit","Disabled","Deny"] + // Allowed Values = ["Audit","Disabled","Deny"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "azureSpringCloudShouldUseNetworkInjectionMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "evaluatedSkuNames-af35e2a4-ef96-44e7-a9ae-853dd97032c4": [ "Standard" ], - // Alowed Values = "Standard" + // Allowed Values = "Standard" // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'App Service apps should only be accessible over HTTPS' // ----------------------------------------------------------------------------------------------------------------------------- "webAppEnforceHttpsMonitoringEffectV2": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -160,28 +160,28 @@ // 'App Service' Policy: 'CORS should not allow every resource to access your API App' // ----------------------------------------------------------------------------------------------------------------------------- "apiAppRestrictCORSAccessMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'CORS should not allow every resource to access your Function Apps' // ----------------------------------------------------------------------------------------------------------------------------- "functionAppRestrictCORSAccessMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'CORS should not allow every resource to access your Web Applications' // ----------------------------------------------------------------------------------------------------------------------------- "webAppRestrictCORSAccessMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure API app has 'Client Certificates (Incoming client certificates)' set to 'On'' // ----------------------------------------------------------------------------------------------------------------------------- "ensureAPIAppHasClientCertificatesIncomingClientCertificatesSetToOnMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -203,314 +203,314 @@ // 'App Service' Policy: 'Ensure that 'Java version' is the latest, if used as a part of the API app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatJavaVersionIsTheLatestIfUsedAsAPartOfTheApiAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'Java version' is the latest, if used as a part of the Function app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatJavaVersionIsTheLatestIfUsedAsAPartOfTheFunctionAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'Java version' is the latest, if used as a part of the Web app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatJavaVersionIsTheLatestIfUsedAsAPartOfTheWebAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'PHP version' is the latest, if used as a part of the API app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatPHPVersionIsTheLatestIfUsedAsAPartOfTheApiAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'PHP version' is the latest, if used as a part of the WEB app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatPHPVersionIsTheLatestIfUsedAsAPartOfTheWEBAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'Python version' is the latest, if used as a part of the API app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatPythonVersionIsTheLatestIfUsedAsAPartOfTheApiAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'Python version' is the latest, if used as a part of the Function app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatPythonVersionIsTheLatestIfUsedAsAPartOfTheFunctionAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure that 'Python version' is the latest, if used as a part of the Web app' // ----------------------------------------------------------------------------------------------------------------------------- "ensureThatPythonVersionIsTheLatestIfUsedAsAPartOfTheWebAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Ensure WEB app has 'Client Certificates (Incoming client certificates)' set to 'On'' // ----------------------------------------------------------------------------------------------------------------------------- "ensureWEBAppHasClientCertificatesIncomingClientCertificatesSetToOnMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'FTPS only should be required in your API App' // ----------------------------------------------------------------------------------------------------------------------------- "fTPSOnlyShouldBeRequiredInYourAPIAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'FTPS only should be required in your Function App' // ----------------------------------------------------------------------------------------------------------------------------- "fTPSOnlyShouldBeRequiredInYourFunctionAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'FTPS should be required in your Web App' // ----------------------------------------------------------------------------------------------------------------------------- "fTPSShouldBeRequiredInYourWebAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Function apps should have 'Client Certificates (Incoming client certificates)' enabled' // ----------------------------------------------------------------------------------------------------------------------------- "functionAppsShouldHaveClientCertificatesEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Function apps should only be accessible over HTTPS' // ----------------------------------------------------------------------------------------------------------------------------- "functionAppEnforceHttpsMonitoringEffectV2": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Latest TLS version should be used in your API App' // ----------------------------------------------------------------------------------------------------------------------------- "latestTLSVersionShouldBeUsedInYourAPIAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Latest TLS version should be used in your Function App' // ----------------------------------------------------------------------------------------------------------------------------- "latestTLSVersionShouldBeUsedInYourFunctionAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Latest TLS version should be used in your Web App' // ----------------------------------------------------------------------------------------------------------------------------- "latestTLSVersionShouldBeUsedInYourWebAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Managed identity should be used in your API App' // ----------------------------------------------------------------------------------------------------------------------------- "managedIdentityShouldBeUsedInYourAPIAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Managed identity should be used in your Function App' // ----------------------------------------------------------------------------------------------------------------------------- "managedIdentityShouldBeUsedInYourFunctionAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Managed identity should be used in your Web App' // ----------------------------------------------------------------------------------------------------------------------------- "managedIdentityShouldBeUsedInYourWebAppMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Remote debugging should be turned off for API Apps' // ----------------------------------------------------------------------------------------------------------------------------- "apiAppDisableRemoteDebuggingMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Remote debugging should be turned off for Function Apps' // ----------------------------------------------------------------------------------------------------------------------------- "functionAppDisableRemoteDebuggingMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Remote debugging should be turned off for Web Applications' // ----------------------------------------------------------------------------------------------------------------------------- "webAppDisableRemoteDebuggingMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'App Service' Policy: 'Resource logs in App Services should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "diagnosticLogsInAppServicesShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Automation' Policy: 'Automation account variables should be encrypted' // ----------------------------------------------------------------------------------------------------------------------------- "effect-3657f5a0-770e-44a3-b44e-9431ba1e9735": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "encryptionOfAutomationAccountMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Automation' Policy: 'Azure Automation accounts should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-56a5ee18-2ae6-4810-86f7-18e39ce5629b": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Azure Data Explorer' Policy: 'Azure Data Explorer encryption at rest should use a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-81e74cea-30fd-40d5-802f-d72103c2aaaa": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Azure Data Explorer' Policy: 'Disk encryption should be enabled on Azure Data Explorer' // ----------------------------------------------------------------------------------------------------------------------------- "effect-f4b53539-8df9-40e4-86c6-6b607703bd4e": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Azure Data Explorer' Policy: 'Double encryption should be enabled on Azure Data Explorer' // ----------------------------------------------------------------------------------------------------------------------------- "effect-ec068d99-e9c7-401f-8cef-5bdde4e6ccf1": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Azure Stack Edge' Policy: 'Azure Stack Edge devices should use double-encryption' // ----------------------------------------------------------------------------------------------------------------------------- "effect-b4ac1030-89c5-4697-8e00-28b5ba6a8811": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Backup' Policy: '[Preview]: Azure Recovery Services vaults should use customer-managed keys for encrypting backup data' // ----------------------------------------------------------------------------------------------------------------------------- "enableDoubleEncryption-2e94d99a-8a36-4563-bc77-810d8893b671": true, - // Alowed Values = [true,false] + // Allowed Values = [true,false] // 'NIST SP 800-53 Rev. 5': effect default = Audit "effect-2e94d99a-8a36-4563-bc77-810d8893b671": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Backup' Policy: 'Azure Backup should be enabled for Virtual Machines' // ----------------------------------------------------------------------------------------------------------------------------- "azureBackupShouldBeEnabledForVirtualMachinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Batch' Policy: 'Azure Batch account should use customer-managed keys to encrypt data' // ----------------------------------------------------------------------------------------------------------------------------- "effect-99e9ccd8-3db9-4592-b0d1-14b1715a4d8a": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Batch' Policy: 'Resource logs in Batch accounts should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInBatchAccountRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInBatchAccountMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Bot Service' Policy: 'Bot Service should be encrypted with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-51522a96-0869-4791-82f3-981000c2c67f": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cache' Policy: 'Azure Cache for Redis should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "azureCacheForRedisShouldUsePrivateEndpointMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cache' Policy: 'Only secure connections to your Azure Cache for Redis should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-22bee202-a82f-4305-9a2a-6d7f44d4dedb": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "diagnosticsLogsInRedisCacheMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cognitive Services' Policy: 'Cognitive Services accounts should disable public network access' // ----------------------------------------------------------------------------------------------------------------------------- "effect-0725b4dd-7e76-479c-a735-68e7ee23d5ca": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "publicNetworkAccessShouldBeDisabledForCognitiveServicesAccountsMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cognitive Services' Policy: 'Cognitive Services accounts should enable data encryption with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-67121cc7-ff39-4ab8-b7e3-95b84dab487d": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "cognitiveServicesAccountsShouldEnableDataEncryptionWithACustomerManagedKeyMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cognitive Services' Policy: 'Cognitive Services accounts should have local authentication methods disabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-71ef260a-8f18-47b7-abcb-62d0673d94dc": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cognitive Services' Policy: 'Cognitive Services accounts should restrict network access' // ----------------------------------------------------------------------------------------------------------------------------- "cognitiveServicesAccountsShouldRestrictNetworkAccessMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-037eea7a-bd0a-46c5-9a66-03aea78705d3": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -532,102 +532,102 @@ // 'Compute' Policy: 'Managed disks should be double encrypted with both platform-managed and customer-managed keys' // ----------------------------------------------------------------------------------------------------------------------------- "effect-ca91455f-eace-4f96-be59-e6e2c35b4816": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Compute' Policy: 'OS and data disks should be encrypted with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-702dd420-7fcc-42c5-afe8-4026edd20fe0": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Compute' Policy: 'Resource logs in Virtual Machine Scale Sets should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "includeAKSClusters-7c1b1214-f927-48bf-8882-84f0af6588b1": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInServiceFabricMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Compute' Policy: 'Virtual machines and virtual machine scale sets should have encryption at host enabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-fc4d8e41-e223-45ea-9bf5-eada37891d87": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Compute' Policy: 'Virtual machines should be migrated to new Azure Resource Manager resources' // ----------------------------------------------------------------------------------------------------------------------------- "classicComputeVMsMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-1d84d5fb-01f6-4d12-ba4f-4a26081d403d": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Container Instance' Policy: 'Azure Container Instance container group should use customer-managed key for encryption' // ----------------------------------------------------------------------------------------------------------------------------- "effect-0aa61e00-0a01-4a3c-9945-e93cffedf0e6": "Audit", - // Alowed Values = ["Audit","Disabled","Deny"] + // Allowed Values = ["Audit","Disabled","Deny"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Container Registry' Policy: 'Container registries should be encrypted with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-5b9159ae-1701-4a6f-9a7a-aa9c8ddd0580": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "containerRegistriesShouldBeEncryptedWithACustomerManagedKeyMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Container Registry' Policy: 'Container registries should not allow unrestricted network access' // ----------------------------------------------------------------------------------------------------------------------------- "effect-d0793b48-0edc-4296-a390-4c75d1bdfd71": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "containerRegistriesShouldNotAllowUnrestrictedNetworkAccessMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Container Registry' Policy: 'Container registries should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "containerRegistriesShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cosmos DB' Policy: 'Azure Cosmos DB accounts should have firewall rules' // ----------------------------------------------------------------------------------------------------------------------------- "azureCosmosDBAccountsShouldHaveFirewallRulesMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-862e97cf-49fc-4a5c-9de4-40d4e2e7c8eb": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cosmos DB' Policy: 'Azure Cosmos DB accounts should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-1f905d99-2ab7-462c-a6b0-f709acca6c8f": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "azureCosmosDbAccountsShouldUseCustomerManagedKeysToEncryptDataAtRestMonitoringEffect": "disabled", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Cosmos DB' Policy: 'Cosmos DB database accounts should have local authentication methods disabled' // ----------------------------------------------------------------------------------------------------------------------------- "azureCosmosDbAccountsShouldHaveLocalAuthenticationMethodsDisabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -642,30 +642,30 @@ "DataBox", "DataBoxHeavy" ], - // Alowed Values = ["DataBox","DataBoxHeavy"] + // Allowed Values = ["DataBox","DataBoxHeavy"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "effect-c349d81b-9985-44ae-a8da-ff98d108ede8": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Data Box' Policy: 'Azure Data Box jobs should use a customer-managed key to encrypt the device unlock password' // ----------------------------------------------------------------------------------------------------------------------------- "effect-86efb160-8de7-451d-bc08-5d475b0aadae": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "supportedSKUs-86efb160-8de7-451d-bc08-5d475b0aadae": [ "DataBox", "DataBoxHeavy" ], - // Alowed Values = ["DataBox","DataBoxHeavy"] + // Allowed Values = ["DataBox","DataBoxHeavy"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Data Factory' Policy: 'Azure data factories should be encrypted with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-4ec52d6d-beb7-40c4-9a9e-fe753254690e": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -677,40 +677,40 @@ // 'Data Lake' Policy: 'Resource logs in Azure Data Lake Store should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "diagnosticsLogsInDataLakeStoreRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInDataLakeStoreMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Data Lake' Policy: 'Resource logs in Data Lake Analytics should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInDataLakeAnalyticsRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInDataLakeAnalyticsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Event Grid' Policy: 'Azure Event Grid domains should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "azureEventGridDomainsShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Event Grid' Policy: 'Azure Event Grid topics should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "azureEventGridTopicsShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -727,20 +727,20 @@ // 'Event Hub' Policy: 'Resource logs in Event Hub should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInEventHubRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInEventHubMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'General' Policy: 'Audit usage of custom RBAC rules' // ----------------------------------------------------------------------------------------------------------------------------- "useRbacRulesMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -757,76 +757,76 @@ // 'Guest Configuration' Policy: 'Audit Linux machines that allow remote connections from accounts without passwords' // ----------------------------------------------------------------------------------------------------------------------------- "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Linux machines that do not have the passwd file permissions set to 0644' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Linux machines that have accounts without passwords' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that allow re-use of the previous 24 passwords' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that do not have a maximum password age of 70 days' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that do not have a minimum password age of 1 day' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that do not have the password complexity setting enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that do not restrict the minimum password length to 14 characters' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Audit Windows machines that do not store passwords using reversible encryption' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Authentication to Linux machines should require SSH keys' // ----------------------------------------------------------------------------------------------------------------------------- "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "authenticationToLinuxMachinesShouldRequireSSHKeysMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- @@ -843,109 +843,109 @@ // 'Guest Configuration' Policy: 'Linux machines should have Log Analytics agent installed on Azure Arc' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "ArcLinuxMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Linux machines should meet requirements for the Azure compute security baseline' // ----------------------------------------------------------------------------------------------------------------------------- "linuxGuestConfigBaselinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Windows Defender Exploit Guard should be enabled on your machines' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "windowsDefenderExploitGuardMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40": "Compliant", - // Alowed Values = ["Compliant","Non-Compliant"] + // Allowed Values = ["Compliant","Non-Compliant"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Windows machines should have Log Analytics agent installed on Azure Arc' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "ArcWindowsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Windows machines should meet requirements of the Azure compute security baseline' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "windowsGuestConfigBaselinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Guest Configuration' Policy: 'Windows web servers should be configured to use secure communication protocols' // ----------------------------------------------------------------------------------------------------------------------------- "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // Duplicate: "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsIncludeArcMachines": "true", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "windowsWebServersShouldBeConfiguredToUseSecureCommunicationProtocolsMinimumTLSVersion": "1.2", - // Alowed Values = ["1.1","1.2"] + // Allowed Values = ["1.1","1.2"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112": "1.2", - // Alowed Values = ["1.1","1.2"] + // Allowed Values = ["1.1","1.2"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // Duplicate: "IncludeArcMachines": "false", - // Alowed Values = ["true","false"] + // Allowed Values = ["true","false"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'HDInsight' Policy: 'Azure HDInsight clusters should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-64d314f6-6062-4780-a861-c23e8951bee5": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'HDInsight' Policy: 'Azure HDInsight clusters should use encryption at host to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-1fd32ebd-e4c3-4e13-a54a-d7422d4d95f6": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'HDInsight' Policy: 'Azure HDInsight clusters should use encryption in transit to encrypt communication between Azure HDInsight cluster nodes' // ----------------------------------------------------------------------------------------------------------------------------- "effect-d9da03a1-f3c3-412a-9709-947156872263": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Internet of Things' Policy: '[Preview]: IoT Hub device provisioning service data should be encrypted using customer-managed keys (CMK)' // ----------------------------------------------------------------------------------------------------------------------------- "effect-47031206-ce96-41f8-861b-6a915f3de284": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -957,174 +957,174 @@ // 'Internet of Things' Policy: 'Resource logs in IoT Hub should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInIoTHubRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInIoTHubMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: '[Preview]: Certificates should have the specified maximum validity period' // ----------------------------------------------------------------------------------------------------------------------------- "maximumValidityInMonths-0a075868-4c26-42ef-914c-5bc007359560": 12, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-0a075868-4c26-42ef-914c-5bc007359560": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "certificatesValidityPeriodInMonths": 12, - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = disabled "certificatesValidityPeriodMonitoringEffect": "disabled", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: '[Preview]: Private endpoint should be configured for Key Vault' // ----------------------------------------------------------------------------------------------------------------------------- "privateEndpointShouldBeConfiguredForKeyVaultMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-5f0bc445-3935-4915-9981-011aa2b46147": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Azure Key Vault should disable public network access' // ----------------------------------------------------------------------------------------------------------------------------- "effect-55615ac9-af46-4a59-874e-391cc3dfb490": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "firewallShouldBeEnabledOnKeyVaultMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Key Vault keys should have an expiration date' // ----------------------------------------------------------------------------------------------------------------------------- "effect-152b15f7-8e1f-4c1f-ab71-8c010ba5dbc0": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "keysExpirationSetEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Key Vault secrets should have an expiration date' // ----------------------------------------------------------------------------------------------------------------------------- "effect-98728c90-32c7-4049-8429-847dc0f4fe37": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "secretsExpirationSetEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Key vaults should have purge protection enabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-0b60c0b2-2dc2-4e1c-b5c9-abbed971de53": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "keyVaultsShouldHavePurgeProtectionEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Key vaults should have soft delete enabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "keyVaultsShouldHaveSoftDeleteEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Key Vault' Policy: 'Resource logs in Key Vault should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInKeyVaultMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInKeyVaultRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: '[Preview]: Azure Arc enabled Kubernetes clusters should have Microsoft Defender for Cloud extension installed' // ----------------------------------------------------------------------------------------------------------------------------- "arcEnabledKubernetesClustersShouldHaveAzureDefendersExtensionInstalled": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: '[Preview]: Azure Arc enabled Kubernetes clusters should have the Azure Policy extension installed' // ----------------------------------------------------------------------------------------------------------------------------- "arcEnabledKubernetesClustersShouldHaveAzurePolicyExtensionInstalledEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: '[Preview]: Azure Kubernetes Service clusters should have Defender profile enabled' // ----------------------------------------------------------------------------------------------------------------------------- "azureKubernetesServiceClustersShouldHaveSecurityProfileEnabled": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: '[Preview]: Kubernetes clusters should gate deployment of vulnerable images' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "BlockVulnerableImagesExcludeFindingIDs": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = Disabled // No Default: "BlockVulnerableImagesExcludedImages": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = Disabled "BlockVulnerableImagesInKubernetesClusterEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled "BlockVulnerableImagesSeverityThresholdForExcludingNotPatchableFindings": "None", - // Alowed Values = ["None","Low","Medium","High"] + // Allowed Values = ["None","Low","Medium","High"] // 'Azure Security Benchmark': effect default = Disabled "BlockVulnerableImagesInKubernetesClusterNamespaceExclusion": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = Disabled "severity": { "High": 0, "Low": 0, "Medium": 0 }, - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Azure Policy Add-on for Kubernetes service (AKS) should be installed and enabled on your clusters' // ----------------------------------------------------------------------------------------------------------------------------- "azurePolicyAddonStatusEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Both operating systems and data disks in Azure Kubernetes Service clusters should be encrypted by customer-managed keys' // ----------------------------------------------------------------------------------------------------------------------------- "effect-7d7be79c-23ba-4033-84dd-45e2a5ccdd67": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits' // ----------------------------------------------------------------------------------------------------------------------------- "memoryLimit-e345eecc-fa47-480f-9e88-67dcc122b164": "0", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "memoryAndCPULimitsInKubernetesClusterNamespaceExclusion": [ "kube-system", @@ -1132,67 +1132,67 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-e345eecc-fa47-480f-9e88-67dcc122b164": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "excludedNamespaces": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "cpuLimit-e345eecc-fa47-480f-9e88-67dcc122b164": "0", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "memoryInKubernetesClusterLimit": "64Gi", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "memoryAndCPULimitsInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "CPUInKubernetesClusterLimit": "32", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster containers should not share host process ID or host IPC namespace' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "effect-47a1ee2f-2a2a-4576-bf2a-e0e36709c2b8": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "NoSharingSensitiveHostNamespacesInKubernetesEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "NoSharingSensitiveHostNamespacesInKubernetesNamespaceExclusion": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -1204,55 +1204,55 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "AllowedAppArmorProfilesInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "AllowedAppArmorProfilesInKubernetesClusterList": [ "runtime/default" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "effect-511f5417-5d12-434d-ab2e-816901e72a5e": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "allowedProfiles-511f5417-5d12-434d-ab2e-816901e72a5e": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster containers should only use allowed capabilities' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "requiredDropCapabilities-c26596ff-4d70-4e6a-9a30-c2506bd2f80c": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "AllowedCapabilitiesInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // No Default: "allowedCapabilities-c26596ff-4d70-4e6a-9a30-c2506bd2f80c": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "AllowedCapabilitiesInKubernetesClusterNamespaceExclusion": [ "kube-system", @@ -1260,41 +1260,41 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "DropCapabilitiesInKubernetesClusterList": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "effect-c26596ff-4d70-4e6a-9a30-c2506bd2f80c": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "AllowedCapabilitiesInKubernetesClusterList": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster containers should only use allowed images' // ----------------------------------------------------------------------------------------------------------------------------- "effect-febd0533-8e55-448f-b837-bd0e06f16469": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedContainerImagesInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedContainerImagesInKubernetesClusterRegex": "^(.+){0}$", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "allowedContainerImagesRegex-febd0533-8e55-448f-b837-bd0e06f16469": "^(.+){0}$", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedContainerImagesNamespaceExclusion": [ "kube-system", @@ -1302,23 +1302,23 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster containers should run with a read only root file system' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-df49d893-a74c-421d-bc95-c663042e5b80": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "ReadOnlyRootFileSystemInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "ReadOnlyRootFileSystemInKubernetesClusterNamespaceExclusion": [ "kube-system", @@ -1326,40 +1326,40 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster pod hostPath volumes should only use allowed host paths' // ----------------------------------------------------------------------------------------------------------------------------- "AllowedHostPathVolumesInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "effect-098fc59e-46c7-4d99-9b16-64990e543d75": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedHostPaths-098fc59e-46c7-4d99-9b16-64990e543d75": { "paths": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "AllowedHostPathVolumesInKubernetesClusterNamespaceExclusion": [ "kube-system", @@ -1367,55 +1367,55 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "AllowedHostPathVolumesInKubernetesClusterList": { "paths": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster pods and containers should only run with approved user and group IDs' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "runAsUserRanges-f06ddb64-5fa3-4b77-b166-acb36f7f6042": { "ranges": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "runAsGroupRanges-f06ddb64-5fa3-4b77-b166-acb36f7f6042": { "ranges": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "MustRunAsNonRootNamespaceEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "supplementalGroupsRanges-f06ddb64-5fa3-4b77-b166-acb36f7f6042": { "ranges": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "runAsUserRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042": "MustRunAsNonRoot", - // Alowed Values = ["MustRunAs","MustRunAsNonRoot","RunAsAny"] + // Allowed Values = ["MustRunAs","MustRunAsNonRoot","RunAsAny"] // 'NIST SP 800-53 Rev. 5': effect default = audit "runAsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042": "RunAsAny", - // Alowed Values = ["MustRunAs","MayRunAs","RunAsAny"] + // Allowed Values = ["MustRunAs","MayRunAs","RunAsAny"] // 'NIST SP 800-53 Rev. 5': effect default = audit "fsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042": "RunAsAny", - // Alowed Values = ["MustRunAs","MayRunAs","RunAsAny"] + // Allowed Values = ["MustRunAs","MayRunAs","RunAsAny"] // 'NIST SP 800-53 Rev. 5': effect default = audit "MustRunAsNonRootNamespaceExclusion": [ "kube-system", @@ -1423,112 +1423,112 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "supplementalGroupsRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042": "RunAsAny", - // Alowed Values = ["MustRunAs","MayRunAs","RunAsAny"] + // Allowed Values = ["MustRunAs","MayRunAs","RunAsAny"] // 'NIST SP 800-53 Rev. 5': effect default = audit "fsGroupRanges-f06ddb64-5fa3-4b77-b166-acb36f7f6042": { "ranges": [] }, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-f06ddb64-5fa3-4b77-b166-acb36f7f6042": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster pods should only use approved host network and port range' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "allowHostNetwork-82985f06-dc18-4a48-bc1c-b9f4f0098cfe": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "AllowedHostNetworkingAndPortsInKubernetesClusterNamespaceExclusion": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "AllowedHostMaxPortInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "AllowHostNetworkingInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "effect-82985f06-dc18-4a48-bc1c-b9f4f0098cfe": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "AllowedHostNetworkingAndPortsInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // No Default: "minPort-82985f06-dc18-4a48-bc1c-b9f4f0098cfe": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "maxPort-82985f06-dc18-4a48-bc1c-b9f4f0098cfe": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "AllowedHostMinPortInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster services should listen only on allowed ports' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "allowedServicePortsList-233a2a17-77ca-4fb1-9b6b-69223d272a44": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedServicePortsInKubernetesClusterNamespaceExclusion": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "allowedservicePortsInKubernetesClusterPorts": [ "-1" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "effect-233a2a17-77ca-4fb1-9b6b-69223d272a44": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "allowedServicePortsInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes cluster should not allow privileged containers' // ----------------------------------------------------------------------------------------------------------------------------- "effect-95edb821-ddaf-4404-9732-666045e056b4": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "privilegedContainersShouldBeAvoidedEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "privilegedContainerNamespaceExclusion": [ "kube-system", @@ -1536,58 +1536,58 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "excludedContainers-95edb821-ddaf-4404-9732-666045e056b4": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes clusters should be accessible only over HTTPS' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "kubernetesClustersShouldBeAccessibleOnlyOverHTTPSExcludedNamespaces": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "kubernetesClustersShouldBeAccessibleOnlyOverHTTPSMonitoringEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes clusters should disable automounting API credentials' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "KubernetesClustersShouldDisableAutomountingAPICredentialsMonitoringEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "KubernetesClustersShouldDisableAutomountingAPICredentialsMonitoringNamespaceExclusion": [ "kube-system", @@ -1595,46 +1595,46 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes clusters should not allow container privilege escalation' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "excludedNamespaces": ["kube-system","gatekeeper-system","azure-arc"], - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // Duplicate: "labelSelector": {}, - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit "effect-1c6e92c9-99f0-4e55-9cf2-0c234dc48f99": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit "NoPrivilegeEscalationInKubernetesClusterEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "NoPrivilegeEscalationInKubernetesClusterNamespaceExclusion": [ "kube-system", "gatekeeper-system", "azure-arc" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // No Default: "namespaces": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes clusters should not grant CAP_SYS_ADMIN security capabilities' // ----------------------------------------------------------------------------------------------------------------------------- // No Default: "excludedImagesInKubernetesCluster": "undefined", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit "KubernetesClustersShouldNotGrantCAPSYSADMINSecurityCapabilitiesMonitoringEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "KubernetesClustersShouldNotGrantCAPSYSADMINSecurityCapabilitiesMonitoringNamespaceExclusion": [ "kube-system", @@ -1642,174 +1642,174 @@ "azure-arc", "azuredefender" ], - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Kubernetes clusters should not use the default namespace' // ----------------------------------------------------------------------------------------------------------------------------- "KubernetesClustersShouldNotUseTheDefaultNamespaceMonitoringEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Resource logs in Azure Kubernetes Service should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "diagnosticsLogsInKubernetesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInKubernetesRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Kubernetes' Policy: 'Temp disks and cache for agent node pools in Azure Kubernetes Service clusters should be encrypted at host' // ----------------------------------------------------------------------------------------------------------------------------- "effect-41425d9f-d1a5-499a-9932-f8ed8453932c": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Logic Apps' Policy: 'Logic Apps Integration Service Environment should be encrypted with customer-managed keys' // ----------------------------------------------------------------------------------------------------------------------------- "effect-1fafeaf6-7927-4059-a50a-8eb2a7a6f2b5": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Logic Apps' Policy: 'Resource logs in Logic Apps should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInLogicAppsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInLogicAppsRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Machine Learning' Policy: 'Azure Machine Learning workspaces should be encrypted with a customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-ba769a63-b8cc-4b2d-abf6-ac33c7204be8": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "azureMachineLearningWorkspacesShouldBeEncryptedWithACustomerManagedKeyMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Machine Learning' Policy: 'Azure Machine Learning workspaces should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "azureMachineLearningWorkspacesShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-40cec1dd-a100-4920-b15b-3024fe8901ab": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: '[Preview]: Log Analytics extension should be installed on your Linux Azure Arc machines' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "ArcLinuxMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: '[Preview]: Log Analytics extension should be installed on your Windows Azure Arc machines' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "ArcWindowsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: '[Preview]: Network traffic data collection agent should be installed on Linux virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "ASCDependencyAgentAuditLinuxEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: '[Preview]: Network traffic data collection agent should be installed on Windows virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "ASCDependencyAgentAuditWindowsEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: 'Azure Monitor Logs clusters should be created with infrastructure-encryption enabled (double encryption)' // ----------------------------------------------------------------------------------------------------------------------------- "effect-ea0dfaed-95fb-448c-934e-d6e713ce393d": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: 'Azure Monitor Logs clusters should be encrypted with customer-managed key' // ----------------------------------------------------------------------------------------------------------------------------- "effect-1f68a601-6e6d-4e42-babf-3f643a047ea2": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Monitoring' Policy: 'Saved-queries in Azure Monitor should be saved in customer storage account for logs encryption' // ----------------------------------------------------------------------------------------------------------------------------- "effect-fa298e57-9444-42ba-bf04-86e8470e32c7": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Network' Policy: '[Preview]: All Internet traffic should be routed via your deployed Azure Firewall' // ----------------------------------------------------------------------------------------------------------------------------- "AzureFirewallEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Network' Policy: 'Azure Web Application Firewall should be enabled for Azure Front Door entry-points' // ----------------------------------------------------------------------------------------------------------------------------- "webApplicationFirewallShouldBeEnabledForAzureFrontDoorServiceServiceMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-055aa869-bc98-4af8-bafc-23f1ab6ffe2c": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Network' Policy: 'Network Watcher should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6": "NetworkWatcherRG", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "networkWatcherShouldBeEnabledResourceGroupName": "NetworkWatcherRG", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "networkWatcherShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Network' Policy: 'Web Application Firewall (WAF) should be enabled for Application Gateway' // ----------------------------------------------------------------------------------------------------------------------------- "effect-564feb30-bf6a-4854-b4bb-0d2d2d1e6c66": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "webApplicationFirewallShouldBeEnabledForApplicationGatewayMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Search' Policy: 'Azure Cognitive Search service should use a SKU that supports private link' // ----------------------------------------------------------------------------------------------------------------------------- "effect-a049bf77-880b-470f-ba6d-9f21c530cf83": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Search' Policy: 'Azure Cognitive Search services should disable public network access' // ----------------------------------------------------------------------------------------------------------------------------- "effect-ee980b6d-0eca-4501-8d54-f6290fd512c3": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -1821,279 +1821,279 @@ // 'Search' Policy: 'Resource logs in Search services should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInSearchServiceMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInSearchServiceRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: Guest Attestation extension should be installed on supported Linux virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "GuestAttestationExtensionShouldBeInstalledOnSupportedLinuxVirtualMachinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: Guest Attestation extension should be installed on supported Linux virtual machines scale sets' // ----------------------------------------------------------------------------------------------------------------------------- "GuestAttestationExtensionShouldBeInstalledOnSupportedLinuxVirtualMachinesScaleSetsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: Guest Attestation extension should be installed on supported Windows virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "GuestAttestationExtensionShouldBeInstalledOnSupportedWindowsVirtualMachinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: Guest Attestation extension should be installed on supported Windows virtual machines scale sets' // ----------------------------------------------------------------------------------------------------------------------------- "GuestAttestationExtensionShouldBeInstalledOnSupportedWindowsVirtualMachinesScaleSetsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: Secure Boot should be enabled on supported Windows virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "SecureBootShouldBeEnabledOnSupportedWindowsVirtualMachinesMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: '[Preview]: vTPM should be enabled on supported virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "VtpmShouldBeEnabledOnSupportedVirtualMachinesMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'A maximum of 3 owners should be designated for your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityDesignateLessThanOwnersMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'A vulnerability assessment solution should be enabled on your virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "serverVulnerabilityAssessmentEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Adaptive application controls for defining safe applications should be enabled on your machines' // ----------------------------------------------------------------------------------------------------------------------------- "adaptiveApplicationControlsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Adaptive network hardening recommendations should be applied on internet facing virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "adaptiveNetworkHardeningsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'All network ports should be restricted on network security groups associated to your virtual machine' // ----------------------------------------------------------------------------------------------------------------------------- "nextGenerationFirewallMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Allowlist rules in your adaptive application control policy should be updated' // ----------------------------------------------------------------------------------------------------------------------------- "adaptiveApplicationControlsUpdateMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Authorized IP ranges should be defined on Kubernetes Services' // ----------------------------------------------------------------------------------------------------------------------------- "kubernetesServiceAuthorizedIPRangesEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Auto provisioning of the Log Analytics agent should be enabled on your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "autoProvisioningOfTheLogAnalyticsAgentShouldBeEnabledOnYourSubscriptionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure DDoS Protection Standard should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "vnetEnableDDoSProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for App Service should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "appServicesAdvancedThreatProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for Azure SQL Database servers should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "sqlServersAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for DNS should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "AzureDefenderForDNSShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for Key Vault should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "keyVaultsAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for open-source relational databases should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "AzureDefenderForOpenSourceRelationalDatabasesShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for Resource Manager should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "AzureDefenderForResourceManagerShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for servers should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "virtualMachinesAdvancedThreatProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for SQL servers on machines should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "sqlServersVirtualMachinesAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Azure Defender for Storage should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "storageAccountsAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Container registry images should have vulnerability findings resolved' // ----------------------------------------------------------------------------------------------------------------------------- "containerRegistryVulnerabilityAssessmentEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Deprecated accounts should be removed from your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityRemoveDeprecatedAccountMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Deprecated accounts with owner permissions should be removed from your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityRemoveDeprecatedAccountWithOwnerPermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Email notification for high severity alerts should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "emailNotificationForHighSeverityAlertsShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Email notification to subscription owner for high severity alerts should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "emailNotificationToSubscriptionOwnerForHighSeverityAlertsShouldBeEnabledMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Endpoint protection health issues should be resolved on your machines' // ----------------------------------------------------------------------------------------------------------------------------- "endpointProtectionHealthIssuesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Endpoint protection should be installed on your machines' // ----------------------------------------------------------------------------------------------------------------------------- "installEndpointProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Endpoint protection solution should be installed on virtual machine scale sets' // ----------------------------------------------------------------------------------------------------------------------------- "vmssEndpointProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'External accounts with owner permissions should be removed from your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityRemoveExternalAccountWithOwnerPermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'External accounts with read permissions should be removed from your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityRemoveExternalAccountWithReadPermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'External accounts with write permissions should be removed from your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityRemoveExternalAccountWithWritePermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Guest Configuration extension should be installed on your machines' // ----------------------------------------------------------------------------------------------------------------------------- "azurePolicyforWindowsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Internet-facing virtual machines should be protected with network security groups' // ----------------------------------------------------------------------------------------------------------------------------- "networkSecurityGroupsOnVirtualMachinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'IP Forwarding on your virtual machine should be disabled' // ----------------------------------------------------------------------------------------------------------------------------- "disableIPForwardingMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2105,168 +2105,168 @@ // 'Security Center' Policy: 'Log Analytics agent should be installed on your virtual machine for Azure Security Center monitoring' // ----------------------------------------------------------------------------------------------------------------------------- "installLogAnalyticsAgentOnVmMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Log Analytics agent should be installed on your virtual machine scale sets for Azure Security Center monitoring' // ----------------------------------------------------------------------------------------------------------------------------- "installLogAnalyticsAgentOnVmssMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Management ports of virtual machines should be protected with just-in-time network access control' // ----------------------------------------------------------------------------------------------------------------------------- "jitNetworkAccessMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Management ports should be closed on your virtual machines' // ----------------------------------------------------------------------------------------------------------------------------- "restrictAccessToManagementPortsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'MFA should be enabled accounts with write permissions on your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityEnableMFAForWritePermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'MFA should be enabled on accounts with owner permissions on your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityEnableMFAForOwnerPermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'MFA should be enabled on accounts with read permissions on your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityEnableMFAForReadPermissionsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Microsoft Defender for Containers should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "containersAdvancedThreatProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Monitor missing Endpoint Protection in Azure Security Center' // ----------------------------------------------------------------------------------------------------------------------------- "endpointProtectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Non-internet-facing virtual machines should be protected with network security groups' // ----------------------------------------------------------------------------------------------------------------------------- "networkSecurityGroupsOnInternalVirtualMachinesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Role-Based Access Control (RBAC) should be used on Kubernetes Services' // ----------------------------------------------------------------------------------------------------------------------------- "kubernetesServiceRbacEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Running container images should have vulnerability findings resolved' // ----------------------------------------------------------------------------------------------------------------------------- "kubernetesRunningImagesVulnerabilityAssessmentEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'SQL databases should have vulnerability findings resolved' // ----------------------------------------------------------------------------------------------------------------------------- "sqlDbVulnerabilityAssesmentMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'SQL servers on machines should have vulnerability findings resolved' // ----------------------------------------------------------------------------------------------------------------------------- "serverSqlDbVulnerabilityAssesmentMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Subnets should be associated with a Network Security Group' // ----------------------------------------------------------------------------------------------------------------------------- "networkSecurityGroupsOnSubnetsMonitoringEffect": "Disabled", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Subscriptions should have a contact email address for security issues' // ----------------------------------------------------------------------------------------------------------------------------- "subscriptionsShouldHaveAContactEmailAddressForSecurityIssuesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'System updates on virtual machine scale sets should be installed' // ----------------------------------------------------------------------------------------------------------------------------- "vmssSystemUpdatesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'System updates should be installed on your machines' // ----------------------------------------------------------------------------------------------------------------------------- "systemUpdatesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'There should be more than one owner assigned to your subscription' // ----------------------------------------------------------------------------------------------------------------------------- "identityDesignateMoreThanOneOwnerMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Virtual machines should encrypt temp disks, caches, and data flows between Compute and Storage resources' // ----------------------------------------------------------------------------------------------------------------------------- "diskEncryptionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Virtual machines' Guest Configuration extension should be deployed with system-assigned managed identity' // ----------------------------------------------------------------------------------------------------------------------------- "gcExtOnVMWithNoSAMIMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Vulnerabilities in container security configurations should be remediated' // ----------------------------------------------------------------------------------------------------------------------------- "containerBenchmarkMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Vulnerabilities in security configuration on your machines should be remediated' // ----------------------------------------------------------------------------------------------------------------------------- "systemConfigurationsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Security Center' Policy: 'Vulnerabilities in security configuration on your virtual machine scale sets should be remediated' // ----------------------------------------------------------------------------------------------------------------------------- "vmssOsVulnerabilitiesMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2278,13 +2278,13 @@ // 'Service Bus' Policy: 'Resource logs in Service Bus should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInServiceBusMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInServiceBusRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2296,107 +2296,107 @@ // 'Service Fabric' Policy: 'Service Fabric clusters should have the ClusterProtectionLevel property set to EncryptAndSign' // ----------------------------------------------------------------------------------------------------------------------------- "effect-617c02be-7f02-4efd-8836-3180d47b6c68": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "clusterProtectionLevelInServiceFabricMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Service Fabric' Policy: 'Service Fabric clusters should only use Azure Active Directory for client authentication' // ----------------------------------------------------------------------------------------------------------------------------- "aadAuthenticationInServiceFabricMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-b54ed75b-3e1a-44ac-a333-05ba39b99ff0": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SignalR' Policy: 'Azure SignalR Service should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "azureSignalRServiceShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'An Azure Active Directory administrator should be provisioned for SQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "aadAuthenticationInSqlServerMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Auditing on SQL server should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "setting-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9": "enabled", - // Alowed Values = ["enabled","disabled"] + // Allowed Values = ["enabled","disabled"] // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "sqlServerAuditingMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Azure Defender for SQL should be enabled for unprotected Azure SQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "sqlServerAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Azure Defender for SQL should be enabled for unprotected SQL Managed Instances' // ----------------------------------------------------------------------------------------------------------------------------- "sqlManagedInstanceAdvancedDataSecurityMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Enforce SSL connection should be enabled for MySQL database servers' // ----------------------------------------------------------------------------------------------------------------------------- "enforceSSLConnectionShouldBeEnabledForMysqlDatabaseServersMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Enforce SSL connection should be enabled for PostgreSQL database servers' // ----------------------------------------------------------------------------------------------------------------------------- "enforceSSLConnectionShouldBeEnabledForPostgresqlDatabaseServersMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Geo-redundant backup should be enabled for Azure Database for MariaDB' // ----------------------------------------------------------------------------------------------------------------------------- "georedundantBackupShouldBeEnabledForAzureDatabaseForMariadbMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Geo-redundant backup should be enabled for Azure Database for MySQL' // ----------------------------------------------------------------------------------------------------------------------------- "georedundantBackupShouldBeEnabledForAzureDatabaseForMysqlMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Geo-redundant backup should be enabled for Azure Database for PostgreSQL' // ----------------------------------------------------------------------------------------------------------------------------- "georedundantBackupShouldBeEnabledForAzureDatabaseForPostgresqlMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Infrastructure encryption should be enabled for Azure Database for MySQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "effect-3a58212a-c829-4f13-9872-6371df2fd0b4": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Infrastructure encryption should be enabled for Azure Database for PostgreSQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "effect-24fba194-95d6-48c0-aea7-f65bf859c598": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2408,125 +2408,125 @@ // 'SQL' Policy: 'MySQL servers should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "bringYourOwnKeyDataProtectionShouldBeEnabledForMySqlServersMonitoringEffect": "Disabled", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'PostgreSQL servers should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "bringYourOwnKeyDataProtectionShouldBeEnabledForPostgreSqlServersMonitoringEffect": "Disabled", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Private endpoint connections on Azure SQL Database should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "privateEndpointConnectionsOnAzureSQLDatabaseShouldBeEnabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Private endpoint should be enabled for MariaDB servers' // ----------------------------------------------------------------------------------------------------------------------------- "privateEndpointShouldBeEnabledForMariadbServersMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Private endpoint should be enabled for MySQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "privateEndpointShouldBeEnabledForMysqlServersMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Private endpoint should be enabled for PostgreSQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "privateEndpointShouldBeEnabledForPostgresqlServersMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Public network access on Azure SQL Database should be disabled' // ----------------------------------------------------------------------------------------------------------------------------- "publicNetworkAccessOnAzureSQLDatabaseShouldBeDisabledMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-1b8ca024-1d5c-4dec-8995-b1a932b41780": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Public network access should be disabled for MariaDB servers' // ----------------------------------------------------------------------------------------------------------------------------- "publicNetworkAccessShouldBeDisabledForMariaDbServersMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Public network access should be disabled for MySQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "publicNetworkAccessShouldBeDisabledForMySqlServersMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Public network access should be disabled for PostgreSQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "publicNetworkAccessShouldBeDisabledForPostgreSqlServersMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'SQL managed instances should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "ensureManagedInstanceTDEIsEncryptedWithYourOwnKeyWithDenyMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'SQL servers should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "ensureServerTDEIsEncryptedWithYourOwnKeyWithDenyMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'SQL servers with auditing to storage account destination should be configured with 90 days retention or higher' // ----------------------------------------------------------------------------------------------------------------------------- "sQLServersShouldBeConfiguredWithAuditingRetentionDaysGreaterThan90DaysMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Transparent Data Encryption on SQL databases should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "sqlDbEncryptionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Vulnerability assessment should be enabled on SQL Managed Instance' // ----------------------------------------------------------------------------------------------------------------------------- "vulnerabilityAssessmentOnManagedInstanceMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'SQL' Policy: 'Vulnerability assessment should be enabled on your SQL servers' // ----------------------------------------------------------------------------------------------------------------------------- "vulnerabilityAssessmentOnServerMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: '[Preview]: Storage account public access should be disallowed' // ----------------------------------------------------------------------------------------------------------------------------- "disallowPublicBlobAccessEffect": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'Azure Security Benchmark': effect default = audit "effect-4fa4b6c0-31ca-4c0d-b10d-24b96f62a751": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2543,102 +2543,102 @@ // 'Storage' Policy: 'HPC Cache accounts should use customer-managed key for encryption' // ----------------------------------------------------------------------------------------------------------------------------- "effect-970f84d8-71b6-4091-9979-ace7e3fb6dbb": "Audit", - // Alowed Values = ["Audit","Disabled","Deny"] + // Allowed Values = ["Audit","Disabled","Deny"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Secure transfer to storage accounts should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- "effect-404c3081-a854-4457-ae30-26a93ef643f9": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "secureTransferToStorageAccountMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage account encryption scopes should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-b5ec538c-daa0-4006-8596-35468b9148e8": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should be migrated to new Azure Resource Manager resources' // ----------------------------------------------------------------------------------------------------------------------------- "classicStorageAccountsMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-37e0d2fe-28a5-43d6-a273-67d37d1f5606": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should have infrastructure encryption' // ----------------------------------------------------------------------------------------------------------------------------- "effect-4733ea7b-a883-42fe-8cac-97454c2a9e4a": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should restrict network access' // ----------------------------------------------------------------------------------------------------------------------------- "effect-34c877ad-507e-4c82-993e-3452a6e0ad3c": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit "disableUnrestrictedNetworkToStorageAccountMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should restrict network access using virtual network rules' // ----------------------------------------------------------------------------------------------------------------------------- "storageAccountsShouldRestrictNetworkAccessUsingVirtualNetworkRulesMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-2a1a9cdf-e04d-429a-8416-3bfb72a1b26f": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should use customer-managed key for encryption' // ----------------------------------------------------------------------------------------------------------------------------- "storageAccountsShouldUseCustomerManagedKeyForEncryptionMonitoringEffect": "Disabled", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Disabled // // ----------------------------------------------------------------------------------------------------------------------------- // 'Storage' Policy: 'Storage accounts should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "storageAccountShouldUseAPrivateLinkConnectionMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Stream Analytics' Policy: 'Azure Stream Analytics jobs should use customer-managed keys to encrypt data' // ----------------------------------------------------------------------------------------------------------------------------- "effect-87ba29ef-1ab3-4d82-b763-87fcd4f531f7": "audit", - // Alowed Values = ["audit","deny","disabled"] + // Allowed Values = ["audit","deny","disabled"] // 'NIST SP 800-53 Rev. 5': effect default = audit // // ----------------------------------------------------------------------------------------------------------------------------- // 'Stream Analytics' Policy: 'Resource logs in Azure Stream Analytics should be enabled' // ----------------------------------------------------------------------------------------------------------------------------- // Duplicate: "requiredRetentionDays": "365", - // Alowed Values = n/a + // Allowed Values = n/a // 'NIST SP 800-53 Rev. 5': effect fixed = AuditIfNotExists "diagnosticsLogsInStreamAnalyticsRetentionDays": "1", - // Alowed Values = n/a + // Allowed Values = n/a // 'Azure Security Benchmark': effect default = AuditIfNotExists "diagnosticsLogsInStreamAnalyticsMonitoringEffect": "AuditIfNotExists", - // Alowed Values = ["AuditIfNotExists","Disabled"] + // Allowed Values = ["AuditIfNotExists","Disabled"] // 'Azure Security Benchmark': effect default = AuditIfNotExists // // ----------------------------------------------------------------------------------------------------------------------------- // 'Synapse' Policy: 'Azure Synapse workspaces should use customer-managed keys to encrypt data at rest' // ----------------------------------------------------------------------------------------------------------------------------- "effect-f7d52b2d-e161-4dfa-a82b-55e564167385": "Audit", - // Alowed Values = ["Audit","Deny","Disabled"] + // Allowed Values = ["Audit","Deny","Disabled"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- @@ -2655,10 +2655,10 @@ // 'VM Image Builder' Policy: 'VM Image Builder templates should use private link' // ----------------------------------------------------------------------------------------------------------------------------- "vmImageBuilderTemplatesShouldUsePrivateLinkMonitoringEffect": "Audit", - // Alowed Values = ["Audit","Disabled"] + // Allowed Values = ["Audit","Disabled"] // 'Azure Security Benchmark': effect default = Audit "effect-2154edb9-244f-4741-9970-660785bccdaa": "Audit", - // Alowed Values = ["Audit","Disabled","Deny"] + // Allowed Values = ["Audit","Disabled","Deny"] // 'NIST SP 800-53 Rev. 5': effect default = Audit // // ----------------------------------------------------------------------------------------------------------------------------- diff --git a/StarterKit/Definitions/Assignments/tag-assignments.jsonc b/StarterKit/Definitions/Assignments/tag-assignments.jsonc index 0fec3102..78fceffa 100644 --- a/StarterKit/Definitions/Assignments/tag-assignments.jsonc +++ b/StarterKit/Definitions/Assignments/tag-assignments.jsonc @@ -43,17 +43,6 @@ "effect": "Audit" }, "children": [ - { - "nodeName": "Account", - "assignment": { - "name": "Account", - "displayName": "Account", - "description": "Account" - }, - "parameters": { - "tagName": "Account" - } - }, { "nodeName": "Contact", "assignment": { @@ -86,28 +75,6 @@ "parameters": { "tagName": "CostCenter" } - }, - { - "nodeName": "TaggingVersion", - "assignment": { - "name": "TaggingVersion", - "displayName": "TaggingVersion", - "description": "TaggingVersion" - }, - "parameters": { - "tagName": "TaggingVersion" - } - }, - { - "nodeName": "Version", - "assignment": { - "name": "Version", - "displayName": "Version", - "description": "Version" - }, - "parameters": { - "tagName": "Version" - } } ] }, @@ -133,17 +100,6 @@ "tagName": "Environment" } }, - { - "nodeName": "Account", - "assignment": { - "name": "Account", - "displayName": "Account", - "description": "Account" - }, - "parameters": { - "tagName": "Account" - } - }, { "nodeName": "Contact", "assignment": { @@ -165,39 +121,6 @@ "parameters": { "tagName": "AppName" } - }, - { - "nodeName": "CostCenter", - "assignment": { - "name": "CostCenter", - "displayName": "CostCenter", - "description": "CostCenter" - }, - "parameters": { - "tagName": "CostCenter" - } - }, - { - "nodeName": "TaggingVersion", - "assignment": { - "name": "TaggingVersion", - "displayName": "TaggingVersion", - "description": "TaggingVersion" - }, - "parameters": { - "tagName": "TaggingVersion" - } - }, - { - "nodeName": "Version", - "assignment": { - "name": "Version", - "displayName": "Version", - "description": "Version" - }, - "parameters": { - "tagName": "Version" - } } ] } diff --git a/StarterKit/Definitions/DocumentationSpecs/contoso.jsonc b/StarterKit/Definitions/Documentation/contoso.jsonc similarity index 100% rename from StarterKit/Definitions/DocumentationSpecs/contoso.jsonc rename to StarterKit/Definitions/Documentation/contoso.jsonc diff --git a/StarterKit/Definitions/global-settings.jsonc b/StarterKit/Definitions/global-settings.jsonc index 96708fa5..a6ea8ab8 100644 --- a/StarterKit/Definitions/global-settings.jsonc +++ b/StarterKit/Definitions/global-settings.jsonc @@ -10,18 +10,6 @@ "/providers/Microsoft.Management/managementGroups/Policy-as-Code" ] }, - /* "notScope" Instructions - Formats of array entries: - managementGroups: "/providers/Microsoft.Management/managementGroups/myManagementGroupId" - subscriptions: "/subscriptions/00000000-0000-0000-000000000000" - resourceGroups: "/subscriptions/00000000-0000-0000-000000000000/resourceGroups/myResourceGroup" - resourceGroupPatterns: Extra feature in EPAC: - No wild card or single * wild card at beginning or end of name or both; wild card in middle is invalid - "/resourceGroupPatterns/name" - "/resourceGroupPatterns/name*" - "/resourceGroupPatterns/*name" - "/resourceGroupPatterns/*name*" - */ "pacEnvironments": [ { "pacSelector": "dev", diff --git a/StarterKit/Pipelines/AzureDevOps/pipeline.yml b/StarterKit/Pipelines/AzureDevOps/pipeline.yml index 71e48a0b..ef749d61 100644 --- a/StarterKit/Pipelines/AzureDevOps/pipeline.yml +++ b/StarterKit/Pipelines/AzureDevOps/pipeline.yml @@ -52,6 +52,11 @@ stages: deploy: steps: - checkout: self + # - task: PowerShell@2 + # displayName: Convert Excel (.xlsx) to CSV + # inputs: + # pwsh: true + # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" - task: AzureCLI@2 name: planStep displayName: Plan @@ -119,6 +124,11 @@ stages: - job: planJob steps: - checkout: self + # - task: PowerShell@2 + # displayName: Convert Excel (.xlsx) to CSV + # inputs: + # pwsh: true + # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" - task: AzureCLI@2 displayName: Plan inputs: @@ -151,6 +161,11 @@ stages: # - job: planJob # steps: # - checkout: self + # - task: PowerShell@2 + # displayName: Convert Excel (.xlsx) to CSV + # inputs: + # pwsh: true + # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" # - task: AzureCLI@2 # displayName: Plan # inputs: @@ -183,6 +198,11 @@ stages: # - job: planJob # steps: # - checkout: self + # # - task: PowerShell@2 + # # displayName: Convert Excel (.xlsx) to CSV + # # inputs: + # # pwsh: true + # # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" # - task: AzureCLI@2 # displayName: Plan # inputs: @@ -233,6 +253,11 @@ stages: deploy: steps: - checkout: self + # - task: PowerShell@2 + # displayName: Convert Excel (.xlsx) to CSV + # inputs: + # pwsh: true + # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" - task: AzureCLI@2 name: planStep displayName: Plan @@ -300,6 +325,11 @@ stages: - job: planJob steps: - checkout: self + # - task: PowerShell@2 + # displayName: Convert Excel (.xlsx) to CSV + # inputs: + # pwsh: true + # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" - task: AzureCLI@2 name: planStep displayName: Plan @@ -398,6 +428,11 @@ stages: # - job: planJob # steps: # - checkout: self + # # - task: PowerShell@2 + # # displayName: Convert Excel (.xlsx) to CSV + # # inputs: + # # pwsh: true + # # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" # - task: AzureCLI@2 # name: planStep # displayName: Plan @@ -496,6 +531,11 @@ stages: # - job: planJob # steps: # - checkout: self + # # - task: PowerShell@2 + # # displayName: Convert Excel (.xlsx) to CSV + # # inputs: + # # pwsh: true + # # filePath: "Scripts/Deploy/Convert-XlsToCsv.ps1" # - task: AzureCLI@2 # name: planStep # displayName: Plan diff --git a/Sync-Repo.ps1 b/Sync-Repo.ps1 index 3c6c4e9f..e195af28 100644 --- a/Sync-Repo.ps1 +++ b/Sync-Repo.ps1 @@ -93,7 +93,7 @@ if (Test-Path $sourceDirectory -PathType Container) { } if (!$omitDocFiles.IsPresent) { - Write-Information "Copying documentaion files from '$sourceDirectory'" + Write-Information "Copying documentation files from '$sourceDirectory'" if (!(Test-Path "$destinationDirectory/Definitions")) { New-Item "$destinationDirectory/Definitions" -ItemType Directory }