From 81e6387fac15c450e972f0767e2deb5dc6b9dfc1 Mon Sep 17 00:00:00 2001 From: Tao Yang Date: Wed, 20 May 2026 16:39:17 +1000 Subject: [PATCH 1/4] Add Azure Search Services policies and effects for Dev and Prod environments --- policyAssignments/dev/pa-d-pedns.json | 7 ++ policyAssignments/dev/pa-d-search.json | 32 +++++++ policyAssignments/prod/pa-p-pedns.json | 7 ++ policyAssignments/prod/pa-p-search.json | 32 +++++++ policyInitiatives/polset-pedns.json | 36 ++++++++ policyInitiatives/polset-search.json | 108 ++++++++++++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 policyAssignments/dev/pa-d-search.json create mode 100644 policyAssignments/prod/pa-p-search.json create mode 100644 policyInitiatives/polset-search.json diff --git a/policyAssignments/dev/pa-d-pedns.json b/policyAssignments/dev/pa-d-pedns.json index 05f0d28..085019d 100644 --- a/policyAssignments/dev/pa-d-pedns.json +++ b/policyAssignments/dev/pa-d-pedns.json @@ -61,6 +61,9 @@ "PEDNS-017_Effect": { "value": "DeployIfNotExists" }, + "PEDNS-018_Effect": { + "value": "DeployIfNotExists" + }, "evaluationDelay": { "value": "AfterProvisioning" }, @@ -139,6 +142,10 @@ { "policyDefinitionReferenceId": "PEDNS-017", "message": "PolicyID: PEDNS-017 Violation in polset-pedns Initiative - 'The Private Endpoint Private DNS Zone group for Cosmos DB SQL Private Endpoint must be configured'" + }, + { + "policyDefinitionReferenceId": "PEDNS-018", + "message": "PolicyID: PEDNS-018 Violation in polset-pedns Initiative - 'The Private Endpoint Private DNS Zone group for Azure Search Services Private Endpoint must be configured'" } ] }, diff --git a/policyAssignments/dev/pa-d-search.json b/policyAssignments/dev/pa-d-search.json new file mode 100644 index 0000000..8372bef --- /dev/null +++ b/policyAssignments/dev/pa-d-search.json @@ -0,0 +1,32 @@ +{ + "$schema": "../policyAssignment.schema.json", + "policyAssignment": { + "name": "pa-d-search", + "displayName": "Azure Search Services Policies Dev", + "description": "Policy Assignment for Azure Search Services - Dev", + "metadata": { + "category": "Azure Search Services" + }, + "policyDefinitionId": "{policyLocationResourceId}/providers/Microsoft.Authorization/policySetDefinitions/polset-search", + "identity": "SystemAssigned", + "parameters": { + "SRCH-001_Effect": { + "value": "Deny" + }, + "SRCH-002_Effect": { + "value": "Modify" + }, + "SRCH-003_Effect": { + "value": "Deny" + } + + }, + "nonComplianceMessages": [ + ], + "roleDefinitionIds": [ + "/providers/microsoft.authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0" + ] + }, + "definitionSourceManagementGroupId": "/providers/Microsoft.Management/managementGroups/CONTOSO-DEV", + "managementGroupId": "CONTOSO-DEV" +} diff --git a/policyAssignments/prod/pa-p-pedns.json b/policyAssignments/prod/pa-p-pedns.json index 94ac9bc..85b070b 100644 --- a/policyAssignments/prod/pa-p-pedns.json +++ b/policyAssignments/prod/pa-p-pedns.json @@ -61,6 +61,9 @@ "PEDNS-017_Effect": { "value": "DeployIfNotExists" }, + "PEDNS-018_Effect": { + "value": "DeployIfNotExists" + }, "evaluationDelay": { "value": "AfterProvisioning" }, @@ -139,6 +142,10 @@ { "policyDefinitionReferenceId": "PEDNS-017", "message": "PolicyID: PEDNS-017 Violation in polset-pedns Initiative - 'The Private Endpoint Private DNS Zone group for Cosmos DB SQL Private Endpoint must be configured'" + }, + { + "policyDefinitionReferenceId": "PEDNS-018", + "message": "PolicyID: PEDNS-018 Violation in polset-pedns Initiative - 'The Private Endpoint Private DNS Zone group for Azure Search Services Private Endpoint must be configured'" } ] }, diff --git a/policyAssignments/prod/pa-p-search.json b/policyAssignments/prod/pa-p-search.json new file mode 100644 index 0000000..787b32b --- /dev/null +++ b/policyAssignments/prod/pa-p-search.json @@ -0,0 +1,32 @@ +{ + "$schema": "../policyAssignment.schema.json", + "policyAssignment": { + "name": "pa-p-search", + "displayName": "Azure Search Services Policies Prod", + "description": "Policy Assignment for Azure Search Services - Prod", + "metadata": { + "category": "Azure Search Services" + }, + "policyDefinitionId": "{policyLocationResourceId}/providers/Microsoft.Authorization/policySetDefinitions/polset-search", + "identity": "SystemAssigned", + "parameters": { + "SRCH-001_Effect": { + "value": "Deny" + }, + "SRCH-002_Effect": { + "value": "Modify" + }, + "SRCH-003_Effect": { + "value": "Deny" + } + + }, + "nonComplianceMessages": [ + ], + "roleDefinitionIds": [ + "/providers/microsoft.authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0" + ] + }, + "definitionSourceManagementGroupId": "/providers/Microsoft.Management/managementGroups/CONTOSO", + "managementGroupId": "CONTOSO" +} diff --git a/policyInitiatives/polset-pedns.json b/policyInitiatives/polset-pedns.json index ace7d2d..eea9ee0 100755 --- a/policyInitiatives/polset-pedns.json +++ b/policyInitiatives/polset-pedns.json @@ -214,6 +214,18 @@ ], "defaultValue": "DeployIfNotExists" }, + "PEDNS-018_Effect": { + "type": "string", + "metadata": { + "displayName": "PEDNS-018 Effect: Azure AI Search", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + }, "evaluationDelay": { "type": "string", "metadata": { @@ -659,6 +671,30 @@ "groupNames": [ "ISO27001-2013_A.13.1.3" ] + }, + { + "policyDefinitionReferenceId": "PEDNS-018", + "policyDefinitionId": "{policyLocationResourceId}/providers/Microsoft.Authorization/policyDefinitions/pol-deploy-pe-dns-records-single-dns-zone-all-locations", + "parameters": { + "Effect": { + "value": "[parameters('PEDNS-018_Effect')]" + }, + "evaluationDelay": { + "value": "[parameters('evaluationDelay')]" + }, + "groupId": { + "value": "searchService" + }, + "privateDnsZoneId": { + "value": "[concat(parameters('privateDnsZoneResourceGroup'), '/providers/Microsoft.Network/privateDnsZones/', 'privatelink.search.windows.net')]" + }, + "privateLinkServiceResourceType": { + "value": "Microsoft.Search/searchServices" + } + }, + "groupNames": [ + "ISO27001-2013_A.13.1.3" + ] } ] } diff --git a/policyInitiatives/polset-search.json b/policyInitiatives/polset-search.json new file mode 100644 index 0000000..679c138 --- /dev/null +++ b/policyInitiatives/polset-search.json @@ -0,0 +1,108 @@ +{ + "name": "polset-search", + "properties": { + "displayName": "Azure Search Services Policy Initiative", + "description": "This policy initiative defines the foundation security requirements for Azure Search Services", + "metadata": { + "category": "Search", + "version": "1.0.0", + "preview": false, + "deprecated": false + }, + "parameters": { + "SRCH-001_Effect": { + "type": "String", + "metadata": { + "displayName": "SRCH-001 Effect: Azure AI Search service should use a SKU that supports private link", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "Audit", + "Deny", + "Disabled" + ], + "defaultValue": "Deny" + }, + "SRCH-002_Effect": { + "type": "String", + "metadata": { + "displayName": "SRCH-002 Effect: Configure Azure AI Search services to disable local authentication", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "Modify", + "Disabled" + ], + "defaultValue": "Modify" + }, + "SRCH-003_Effect": { + "type": "String", + "metadata": { + "displayName": "SRCH-003 Effect: Azure AI Search services should restrict public network access", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "Audit", + "Deny", + "Disabled" + ], + "defaultValue": "Deny" + } + }, + "policyDefinitionGroups": [ + { + "name": "ISO27001-2013_A.9.2.3", + "additionalMetadataId": "/providers/Microsoft.PolicyInsights/policyMetadata/ISO27001-2013_A.9.2.3" + }, + { + "name": "ISO27001-2013_A.13.1.1", + "additionalMetadataId": "/providers/Microsoft.PolicyInsights/policyMetadata/ISO27001-2013_A.13.1.1" + }, + { + "name": "ISO27001-2013_A.13.1.3", + "additionalMetadataId": "/providers/Microsoft.PolicyInsights/policyMetadata/ISO27001-2013_A.13.1.3" + } + ], + "policyDefinitions": [ + { + "policyDefinitionReferenceId": "SRCH-001", + "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/a049bf77-880b-470f-ba6d-9f21c530cf83", + "definitionVersion": "1.0.*", + "parameters": { + "effect": { + "value": "[parameters('SRCH-001_Effect')]" + } + }, + "groupNames": [ + "ISO27001-2013_A.13.1.1" + ] + }, + { + "policyDefinitionReferenceId": "SRCH-002", + "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/4eb216f2-9dba-4979-86e6-5d7e63ce3b75", + "definitionVersion": "2.0.*", + "parameters": { + "effect": { + "value": "[parameters('SRCH-002_Effect')]" + } + }, + "groupNames": [ + "ISO27001-2013_A.9.2.3" + ] + }, + { + "policyDefinitionReferenceId": "SRCH-003", + "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/ee980b6d-0eca-4501-8d54-f6290fd512c3", + "definitionVersion": "1.0.*", + "parameters": { + "effect": { + "value": "[parameters('SRCH-003_Effect')]" + } + }, + "groupNames": [ + "ISO27001-2013_A.13.1.3" + ] + } + ] + } +} From 60f11e28f70df136d2121b3760858c743a68638e Mon Sep 17 00:00:00 2001 From: Tao Yang Date: Thu, 21 May 2026 11:42:40 +1000 Subject: [PATCH 2/4] Add integration tests for Azure AI Search Service policies and templates --- .../policy-integration-tests/search/README.md | 23 ++++++ .../search/config.json | 16 ++++ .../search/main.bad.bicep | 34 ++++++++ .../search/main.good.bicep | 34 ++++++++ .../search/main.test.bicep | 77 +++++++++++++++++++ .../policy-integration-tests/search/tests.ps1 | 75 ++++++++++++++++++ 6 files changed, 259 insertions(+) create mode 100644 tests/policy-integration-tests/search/README.md create mode 100644 tests/policy-integration-tests/search/config.json create mode 100644 tests/policy-integration-tests/search/main.bad.bicep create mode 100644 tests/policy-integration-tests/search/main.good.bicep create mode 100644 tests/policy-integration-tests/search/main.test.bicep create mode 100644 tests/policy-integration-tests/search/tests.ps1 diff --git a/tests/policy-integration-tests/search/README.md b/tests/policy-integration-tests/search/README.md new file mode 100644 index 0000000..80482ce --- /dev/null +++ b/tests/policy-integration-tests/search/README.md @@ -0,0 +1,23 @@ +# Policy Integration Test - Policy Integration Test Cases for xxx + +## Introduction + +This folder contains a sample test case for xxx related policies. + +The test case is designed to test the following policy assignments: + +| Policy Assignment Name | Policy Assignment Scope | Description | +| :--------------------- | :--------------------- | :---------- | +| `pa-d-search` | `/providers/Microsoft.Management/managementGroups/CONTOSO-DEV` | Policy Assignment for the Azure Search Service initiative | +| `pa-d-pedns` | `/providers/Microsoft.Management/managementGroups/CONTOSO-DEV` | Policy Assignment for Azure Private Endpoint DNS Records Policy Initiative (deploy DNS records for Private Endpoints) | +| `pa-d-diag-settings` | `/providers/Microsoft.Management/managementGroups/CONTOSO-DEV` | Policy Assignment for Azure Diagnostic Settings Policy Initiative (deploy diagnostic settings for all applicable Azure resources) | + +The following policies are in scope for testing: + +| Policy Assignment | Policy Reference ID | Policy Name | Policy Effect | +| :---------------- | :---------------- | :------------ | :------------ | +| `pa-d-search` | `SRCH-001` | Azure AI Search service should use a SKU that supports private link | Deny | +| `pa-d-search` | `SRCH-002` | Configure Azure AI Search services to disable local authentication | Modify | +| `pa-d-search` | `SRCH-003` | Azure AI Search services should restrict public network access | Deny | +| `pa-d-diag-settings` | `DS-045` | Configure Diagnostic Setting for Azure Search Service | DeployIfNotExists | +| `pa-d-pedns` | `PEDNS-017` | Private DNS Record for Azure Search Service Private Endpoint must exist | DeployIfNotExists | diff --git a/tests/policy-integration-tests/search/config.json b/tests/policy-integration-tests/search/config.json new file mode 100644 index 0000000..d1fe59c --- /dev/null +++ b/tests/policy-integration-tests/search/config.json @@ -0,0 +1,16 @@ +{ + "policyAssignmentIds": [ + "/providers/Microsoft.Management/managementGroups/CONTOSO-DEV/providers/Microsoft.Authorization/policyAssignments/pa-d-pedns", + "/providers/Microsoft.Management/managementGroups/CONTOSO-DEV/providers/Microsoft.Authorization/policyAssignments/pa-d-search", + "/providers/Microsoft.Management/managementGroups/CONTOSO-DEV/providers/Microsoft.Authorization/policyAssignments/pa-d-diag-settings" + ], + "testName": "SearchService", + "searchServiceAssignmentName": "pa-d-search", + "diagSettingsAssignmentName": "pa-d-diag-settings", + "peDNSAssignmentName": "pa-d-pedns", + "testSubscription": "sub-d-lz-corp-01", + "testResourceGroup": "rg-ae-d-policy-test-search-001", + "location": "australiaeast", + "tagsForResourceGroup": false, + "removeTestResourceGroup": true +} diff --git a/tests/policy-integration-tests/search/main.bad.bicep b/tests/policy-integration-tests/search/main.bad.bicep new file mode 100644 index 0000000..425d008 --- /dev/null +++ b/tests/policy-integration-tests/search/main.bad.bicep @@ -0,0 +1,34 @@ +metadata itemDisplayName = 'Test Template for AI Search Service' +metadata description = 'This template deploys the testing resource for AI Search Service.' +metadata summary = 'Deploys test AI Search Service resources that should violate some policy assignments.' + +// ============ // +// variables // +// ============ // +// Load the configuration file +var globalConfig = loadJsonContent('../.shared/policy_integration_test_config.jsonc') +var localConfig = loadJsonContent('config.json') + +var location = localConfig.location +var namePrefix = globalConfig.namePrefix + +// define template specific variables +var serviceShort = 'srch3' + +resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { + name: '${namePrefix}${serviceShort}01' + location: location + sku: { + name: 'Basic' //This should violate policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since Basic SKU does not support private link + } + identity: { + type: 'SystemAssigned' + } + properties: { + hostingMode: 'Default' + publicNetworkAccess: 'Enabled' //This should violate policy SRCH-003: Azure AI Search services should restrict public network access + replicaCount: 1 + partitionCount: 1 + computeType: 'Default' + } +} diff --git a/tests/policy-integration-tests/search/main.good.bicep b/tests/policy-integration-tests/search/main.good.bicep new file mode 100644 index 0000000..4121a87 --- /dev/null +++ b/tests/policy-integration-tests/search/main.good.bicep @@ -0,0 +1,34 @@ +metadata itemDisplayName = 'Test Template for AI Search Service' +metadata description = 'This template deploys the testing resource for AI Search Service.' +metadata summary = 'Deploys test AI Search Service resources that should comply with all policy assignments.' + +// ============ // +// variables // +// ============ // +// Load the configuration file +var globalConfig = loadJsonContent('../.shared/policy_integration_test_config.jsonc') +var localConfig = loadJsonContent('config.json') + +var location = localConfig.location +var namePrefix = globalConfig.namePrefix + +// define template specific variables +var serviceShort = 'srch2' + +resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { + name: '${namePrefix}${serviceShort}01' + location: location + sku: { + name: 'Standard' //This should comply with policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since Basic SKU does not support private link + } + identity: { + type: 'SystemAssigned' + } + properties: { + hostingMode: 'Default' + publicNetworkAccess: 'Disabled' //This should comply with policy SRCH-003: Azure AI Search services should restrict public network access + replicaCount: 1 + partitionCount: 1 + computeType: 'Default' + } +} diff --git a/tests/policy-integration-tests/search/main.test.bicep b/tests/policy-integration-tests/search/main.test.bicep new file mode 100644 index 0000000..e4f3aa8 --- /dev/null +++ b/tests/policy-integration-tests/search/main.test.bicep @@ -0,0 +1,77 @@ +metadata itemDisplayName = 'Test Template for AI Search Service' +metadata description = 'This template deploys the testing resource for AI Search Service.' +metadata summary = 'Deploys test AI Search Service resources.' + +// ============ // +// variables // +// ============ // +// Load the configuration file +var globalConfig = loadJsonContent('../.shared/policy_integration_test_config.jsonc') +var localConfig = loadJsonContent('config.json') +//Define required variables from the configuration files - change these based on your requirements +var tags = globalConfig.tags +var location = localConfig.location +var namePrefix = globalConfig.namePrefix +var subName = localConfig.testSubscription +var vnetResourceGroup = globalConfig.subscriptions[subName].networkResourceGroup +var vnetName = globalConfig.subscriptions[subName].vNet +var peSubnetName = globalConfig.subscriptions[subName].peSubnet +var serviceShort = 'srch1' //use this to form the name of the resources deployed by this template. This is helpful to identify the resource in the portal and also useful if you want to have a policy that targets specific resources by name. For example, if you have a policy that audits whether storage accounts have secure transfer enabled, you can set serviceShort to 'st' and then in the policy definition, you can target resources with name starting with 'st' to only audit the storage accounts deployed by this test template. + +// ============ // +// resources // +// ============ // +resource vnet 'Microsoft.Network/virtualNetworks@2025-05-01' existing = { + name: vnetName + scope: az.resourceGroup(vnetResourceGroup) + + resource peSubnet 'subnets' existing = { name: peSubnetName } +} + +resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { + name: '${namePrefix}${serviceShort}01' + location: location + tags: tags + sku: { + name: 'Standard' + } + properties: { + hostingMode: 'Default' + publicNetworkAccess: 'Disabled' + replicaCount: 1 + partitionCount: 1 + computeType: 'Default' + disableLocalAuth: false //This should be modified to true by the policy SRCH-002: Configure Azure AI Search services to disable local authentication + } +} + +resource pe 'Microsoft.Network/privateEndpoints@2025-05-01' = { + name: 'pe-${namePrefix}${serviceShort}01' + location: location + tags: tags + properties: { + subnet: { + id: vnet::peSubnet.id + } + privateLinkServiceConnections: [ + { + name: 'pe-${namePrefix}${serviceShort}01' + properties: { + privateLinkServiceId: searchService.id + groupIds: [ + 'searchService' + ] + } + } + ] + } +} + +// ============ // +// outputs // +// ============ // +//Specify the outputs that are required for the test +output name string = searchService.name +output resourceId string = searchService.id +output privateEndpointResourceId string = pe.id +output location string = searchService.location diff --git a/tests/policy-integration-tests/search/tests.ps1 b/tests/policy-integration-tests/search/tests.ps1 new file mode 100644 index 0000000..e1a51a3 --- /dev/null +++ b/tests/policy-integration-tests/search/tests.ps1 @@ -0,0 +1,75 @@ +#region generic sections for all tests +#Requires -Modules Az.Accounts, Az.PolicyInsights, Az.Resources +#Requires -Version 7.0 + +using module AzResourceTest + +$helperFunctionScriptPath = (resolve-path -relativeBasePath $PSScriptRoot -path '../../../scripts/pipelines/helper/helper-functions.ps1').Path + +#load helper +. $helperFunctionScriptPath + +#Run initiate-test script to set environment variables for test configuration and deployment +$globalConfigFilePath = (resolve-path -RelativeBasePath $PSScriptRoot -path '../.shared/policy_integration_test_config.jsonc').Path +$TestDirectory = $PSScriptRoot +Write-Output "Initiating test with global config file: $globalConfigFilePath and test directory: $TestDirectory" +$initiateTestScriptPath = (resolve-path -RelativeBasePath $PSScriptRoot -path '../.shared/initiate-test.ps1').Path +. $initiateTestScriptPath -globalConfigFilePath $globalConfigFilePath -TestDirectory $TestDirectory + +# Refer to the ../../docs/policy-integration-test-get-started.md for details on the expected variables to be set by the initiate-test script and the structure of those variables. +#endregion + +#region defining tests +<# +The list of tested policies are documented in the ./README.md file. +#> + + +#Parse deployment outputs +$resourceId = $script:bicepDeploymentOutputs.resourceId.value +$diagSettingsPolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_diagSettingsAssignmentName`$" } +$peDNSPolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_peDNSAssignmentName`$" } +$diagnosticSettingsId = "{0}{1}" -f $resourceId, $script:GlobalConfig_diagnosticSettingsIdSuffix +$searchServicePolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_cosmosAssignmentName`$" } +$privateEndpointResourceId = $script:bicepDeploymentOutputs.privateEndpointResourceId.value +$privateEndpointPrivateDNSZoneGroupId = '{0}{1}' -f $privateEndpointResourceId, $script:GlobalConfig_privateEndpointPrivateDNSZoneGroupIdSuffix +$violatingPolicies = @( + @{ + policyAssignmentId = $searchServicePolicyAssignmentId + policyDefinitionReferenceId = 'SRCH-001' + } + @{ + policyAssignmentId = $searchServicePolicyAssignmentId + policyDefinitionReferenceId = 'SRCH-003' + } +) +#define tests +$tests = @() +#Modify / Append Policies +$tests += New-ARTPropertyValueTestConfig 'SRCH-002: Local authentication should be disabled' $script:token $resourceId 'boolean' 'properties.disableLocalAuth' 'equals' $true + +#DeployIfNotExists Policies +$tests += New-ARTResourceExistenceTestConfig 'DS-045: Deploy Diagnostic Settings for Azure Search Service to Log Analytics workspace.' $script:token $diagnosticSettingsId 'exists' $script:GlobalConfig_diagnosticSettingsAPIVersion +$tests += New-ARTPolicyStateTestConfig 'DS-045: Diagnostic Settings Policy Must Be Compliant' $script:token $resourceId $diagSettingsPolicyAssignmentId 'Compliant' 'DS-045' +$tests += New-ARTResourceExistenceTestConfig 'PEDNS-018: Private DNS Record for Azure Search Service Private Endpoint must exist' $script:token $privateEndpointPrivateDNSZoneGroupId 'exists' $script:GlobalConfig_privateDNSZoneGroupAPIVersion +$tests += New-ARTPolicyStateTestConfig 'PEDNS-018: Private DNS Record Policy Must Be Compliant' $script:token $privateEndpointResourceId $peDNSPolicyAssignmentId 'Compliant' 'PEDNS-018' + + +#Deny policies (testing both positive and negative scenarios) +$tests += New-ARTWhatIfDeploymentTestConfig 'Policy abiding deployment should succeed' $script:token $script:whatIfComplyBicepTemplatePath $script:bicepDeploymentResult.bicepDeploymentTarget 'Succeeded' -maxRetry $script:GlobalConfig_whatIfMaxRetry +$tests += New-ARTWhatIfDeploymentTestConfig 'Policy violating deployment should fail' $script:token $script:whatIfViolateBicepTemplatePath $script:bicepDeploymentResult.bicepDeploymentTarget 'Failed' $violatingPolicies -maxRetry $script:GlobalConfig_whatIfMaxRetry + +#endregion + +#region Invoke tests - do not modify +$params = @{ + tests = $tests + testTitle = $script:testTitle + contextTitle = $script:contextTitle + testSuiteName = $script:testSuiteName + OutputFile = $script:outputFilePath + OutputFormat = $script:GlobalConfig_testOutputFormat +} +Test-ARTResourceConfiguration @params + +#endregion From c51efba71f7b95cb141bf2230575e969128a3b39 Mon Sep 17 00:00:00 2001 From: Tao Yang Date: Thu, 21 May 2026 12:19:41 +1000 Subject: [PATCH 3/4] Update AI Search Service SKU names to ensure compliance with policy SRCH-001 --- tests/policy-integration-tests/search/main.bad.bicep | 2 +- tests/policy-integration-tests/search/main.good.bicep | 2 +- tests/policy-integration-tests/search/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/policy-integration-tests/search/main.bad.bicep b/tests/policy-integration-tests/search/main.bad.bicep index 425d008..c09eebc 100644 --- a/tests/policy-integration-tests/search/main.bad.bicep +++ b/tests/policy-integration-tests/search/main.bad.bicep @@ -19,7 +19,7 @@ resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { name: '${namePrefix}${serviceShort}01' location: location sku: { - name: 'Basic' //This should violate policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since Basic SKU does not support private link + name: 'free' //This should violate policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since free SKU does not support private link } identity: { type: 'SystemAssigned' diff --git a/tests/policy-integration-tests/search/main.good.bicep b/tests/policy-integration-tests/search/main.good.bicep index 4121a87..4aaff9a 100644 --- a/tests/policy-integration-tests/search/main.good.bicep +++ b/tests/policy-integration-tests/search/main.good.bicep @@ -19,7 +19,7 @@ resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { name: '${namePrefix}${serviceShort}01' location: location sku: { - name: 'Standard' //This should comply with policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since Basic SKU does not support private link + name: 'standard' //This should comply with policy SRCH-001: Azure AI Search service should use a SKU that supports private link, since Basic SKU does not support private link } identity: { type: 'SystemAssigned' diff --git a/tests/policy-integration-tests/search/main.test.bicep b/tests/policy-integration-tests/search/main.test.bicep index e4f3aa8..cee47c2 100644 --- a/tests/policy-integration-tests/search/main.test.bicep +++ b/tests/policy-integration-tests/search/main.test.bicep @@ -33,7 +33,7 @@ resource searchService 'Microsoft.Search/searchServices@2026-03-01-preview' = { location: location tags: tags sku: { - name: 'Standard' + name: 'standard' } properties: { hostingMode: 'Default' From 483920c656fd5dc7906714941618c975e2410649 Mon Sep 17 00:00:00 2001 From: Tao Yang Date: Thu, 21 May 2026 13:39:39 +1000 Subject: [PATCH 4/4] Fix search service policy assignment ID in integration tests --- tests/policy-integration-tests/search/tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/policy-integration-tests/search/tests.ps1 b/tests/policy-integration-tests/search/tests.ps1 index e1a51a3..b29f881 100644 --- a/tests/policy-integration-tests/search/tests.ps1 +++ b/tests/policy-integration-tests/search/tests.ps1 @@ -30,7 +30,7 @@ $resourceId = $script:bicepDeploymentOutputs.resourceId.value $diagSettingsPolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_diagSettingsAssignmentName`$" } $peDNSPolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_peDNSAssignmentName`$" } $diagnosticSettingsId = "{0}{1}" -f $resourceId, $script:GlobalConfig_diagnosticSettingsIdSuffix -$searchServicePolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_cosmosAssignmentName`$" } +$searchServicePolicyAssignmentId = $script:LocalConfig_policyAssignmentIds | Where-Object { $_ -imatch "$script:LocalConfig_searchServiceAssignmentName`$" } $privateEndpointResourceId = $script:bicepDeploymentOutputs.privateEndpointResourceId.value $privateEndpointPrivateDNSZoneGroupId = '{0}{1}' -f $privateEndpointResourceId, $script:GlobalConfig_privateEndpointPrivateDNSZoneGroupIdSuffix $violatingPolicies = @(