From f8a3e59f05650180d752857bfc8e0e91fa3ab7b5 Mon Sep 17 00:00:00 2001 From: "Menghua Chen (WICRESOFT NORTH AMERICA LTD)" Date: Wed, 11 Sep 2024 15:19:35 +0800 Subject: [PATCH] add ptn module ml-ai-environment update avmTelemetry parameter update avmTelemetry parameter update main.json add @batchSize(1) update test parameter update test parameter update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep update hub.bicep --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/avm_module_issue.yml | 1 + .../avm.ptn.azd.ml-ai-environment.yml | 88 + avm/ptn/azd/ml-ai-environment/README.md | 492 + avm/ptn/azd/ml-ai-environment/main.bicep | 185 + avm/ptn/azd/ml-ai-environment/main.json | 26764 ++++++++++++++++ .../azd/ml-ai-environment/modules/hub.bicep | 143 + .../tests/e2e/defaults/main.test.bicep | 52 + .../tests/e2e/max/main.test.bicep | 70 + avm/ptn/azd/ml-ai-environment/version.json | 7 + avm/ptn/azd/ml-hub-dependencies/main.bicep | 475 + avm/ptn/azd/ml-project/main.bicep | 170 + 12 files changed, 28448 insertions(+) create mode 100644 .github/workflows/avm.ptn.azd.ml-ai-environment.yml create mode 100644 avm/ptn/azd/ml-ai-environment/README.md create mode 100644 avm/ptn/azd/ml-ai-environment/main.bicep create mode 100644 avm/ptn/azd/ml-ai-environment/main.json create mode 100644 avm/ptn/azd/ml-ai-environment/modules/hub.bicep create mode 100644 avm/ptn/azd/ml-ai-environment/tests/e2e/defaults/main.test.bicep create mode 100644 avm/ptn/azd/ml-ai-environment/tests/e2e/max/main.test.bicep create mode 100644 avm/ptn/azd/ml-ai-environment/version.json create mode 100644 avm/ptn/azd/ml-hub-dependencies/main.bicep create mode 100644 avm/ptn/azd/ml-project/main.bicep diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 69fd75e5c7..64047defa1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,6 +15,7 @@ /avm/ptn/azd/apim-api/ @Azure/avm-ptn-azd-apimapi-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/azd/container-apps/ @Azure/avm-ptn-azd-containerapps-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/azd/insights-dashboard/ @Azure/avm-ptn-azd-insightsdashboard-module-owners-bicep @Azure/avm-module-reviewers-bicep +/avm/ptn/azd/ml-ai-environment/ @Azure/avm-ptn-azd-mlaienvironment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/deployment-script/import-image-to-acr/ @Azure/avm-ptn-deploymentscript-importimagetoacr-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/dev-ops/cicd-agents-and-runners/ @Azure/avm-ptn-devops-cicdagentsandrunners-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/finops-toolkit/finops-hub/ @Azure/avm-ptn-finopstoolkit-finopshub-module-owners-bicep @Azure/avm-module-reviewers-bicep diff --git a/.github/ISSUE_TEMPLATE/avm_module_issue.yml b/.github/ISSUE_TEMPLATE/avm_module_issue.yml index 76f4173ed1..ff7d4ca5f9 100644 --- a/.github/ISSUE_TEMPLATE/avm_module_issue.yml +++ b/.github/ISSUE_TEMPLATE/avm_module_issue.yml @@ -50,6 +50,7 @@ body: - "avm/ptn/azd/apim-api" - "avm/ptn/azd/container-apps" - "avm/ptn/azd/insights-dashboard" + - "avm/ptn/azd/ml-ai-environment" - "avm/ptn/deployment-script/import-image-to-acr" - "avm/ptn/dev-ops/cicd-agents-and-runners" - "avm/ptn/finops-toolkit/finops-hub" diff --git a/.github/workflows/avm.ptn.azd.ml-ai-environment.yml b/.github/workflows/avm.ptn.azd.ml-ai-environment.yml new file mode 100644 index 0000000000..2bf27870e8 --- /dev/null +++ b/.github/workflows/avm.ptn.azd.ml-ai-environment.yml @@ -0,0 +1,88 @@ +name: "avm.ptn.azd.ml-ai-environment" + +on: + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + customLocation: + type: string + description: "Default location overwrite (e.g., eastus)" + required: false + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.ptn.azd.ml-ai-environment" + - "avm/ptn/azd/ml-ai-environment/**" + - "avm/utilities/pipelines/**" + - "!avm/utilities/pipelines/platform/**" + - "!*/**/README.md" + +env: + modulePath: "avm/ptn/azd/ml-ai-environment" + workflowPath: ".github/workflows/avm.ptn.azd.ml-ai-environment.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit \ No newline at end of file diff --git a/avm/ptn/azd/ml-ai-environment/README.md b/avm/ptn/azd/ml-ai-environment/README.md new file mode 100644 index 0000000000..9e5843aa0a --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/README.md @@ -0,0 +1,492 @@ +# Azure Machine Learning Environment `[Azd/MlAiEnvironment]` + +Create Azure Machine Learning workspaces of type 'Hub' and 'Project' and their required dependencies. + +**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.CognitiveServices/accounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2023-05-01/accounts) | +| `Microsoft.CognitiveServices/accounts/deployments` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2023-05-01/accounts/deployments) | +| `Microsoft.ContainerRegistry/registries` | [2023-06-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries) | +| `Microsoft.ContainerRegistry/registries/cacheRules` | [2023-06-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries/cacheRules) | +| `Microsoft.ContainerRegistry/registries/credentialSets` | [2023-11-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries/credentialSets) | +| `Microsoft.ContainerRegistry/registries/replications` | [2023-06-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries/replications) | +| `Microsoft.ContainerRegistry/registries/scopeMaps` | [2023-06-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries/scopeMaps) | +| `Microsoft.ContainerRegistry/registries/webhooks` | [2023-06-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerRegistry/registries/webhooks) | +| `Microsoft.Insights/components` | [2020-02-02](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2020-02-02/components) | +| `microsoft.insights/components/linkedStorageAccounts` | [2020-03-01-preview](https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/2020-03-01-preview/components/linkedStorageAccounts) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.KeyVault/vaults` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults) | +| `Microsoft.KeyVault/vaults/accessPolicies` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/accessPolicies) | +| `Microsoft.KeyVault/vaults/keys` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/keys) | +| `Microsoft.KeyVault/vaults/secrets` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/secrets) | +| `Microsoft.MachineLearningServices/workspaces` | [2024-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01/workspaces) | +| `Microsoft.MachineLearningServices/workspaces` | [2024-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01-preview/workspaces) | +| `Microsoft.MachineLearningServices/workspaces/computes` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2022-10-01/workspaces/computes) | +| `Microsoft.MachineLearningServices/workspaces/connections` | [2024-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01/workspaces/connections) | +| `Microsoft.MachineLearningServices/workspaces/connections` | [2024-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01-preview/workspaces/connections) | +| `Microsoft.ManagedIdentity/userAssignedIdentities` | [2023-01-31](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ManagedIdentity/2023-01-31/userAssignedIdentities) | +| `Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials` | [2023-01-31](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ManagedIdentity/2023-01-31/userAssignedIdentities/federatedIdentityCredentials) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.OperationalInsights/workspaces` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces) | +| `Microsoft.OperationalInsights/workspaces/dataExports` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataExports) | +| `Microsoft.OperationalInsights/workspaces/dataSources` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataSources) | +| `Microsoft.OperationalInsights/workspaces/linkedServices` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedServices) | +| `Microsoft.OperationalInsights/workspaces/linkedStorageAccounts` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedStorageAccounts) | +| `Microsoft.OperationalInsights/workspaces/savedSearches` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/savedSearches) | +| `Microsoft.OperationalInsights/workspaces/storageInsightConfigs` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/storageInsightConfigs) | +| `Microsoft.OperationalInsights/workspaces/tables` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces/tables) | +| `Microsoft.OperationsManagement/solutions` | [2015-11-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationsManagement/2015-11-01-preview/solutions) | +| `Microsoft.Portal/dashboards` | [2020-09-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Portal/2020-09-01-preview/dashboards) | +| `Microsoft.Search/searchServices` | [2024-03-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Search/2024-03-01-preview/searchServices) | +| `Microsoft.Search/searchServices/sharedPrivateLinkResources` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Search/2023-11-01/searchServices/sharedPrivateLinkResources) | +| `Microsoft.Storage/storageAccounts` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts) | +| `Microsoft.Storage/storageAccounts/blobServices` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices) | +| `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | +| `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers/immutabilityPolicies) | +| `Microsoft.Storage/storageAccounts/fileServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices) | +| `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | +| `Microsoft.Storage/storageAccounts/localUsers` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/localUsers) | +| `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/managementPolicies) | +| `Microsoft.Storage/storageAccounts/queueServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices) | +| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices/queues) | +| `Microsoft.Storage/storageAccounts/tableServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices) | +| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices/tables) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/ptn/azd/ml-ai-environment:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module mlAiEnvironment 'br/public:avm/ptn/azd/ml-ai-environment:' = { + name: 'mlAiEnvironmentDeployment' + params: { + // Required parameters + cognitiveServicesName: 'maemincs001' + hubName: 'maeminhub001' + keyVaultName: 'maeminkv00' + openAiConnectionName: 'maeminai001-connection' + projectName: 'maeminpro001' + searchConnectionName: 'maeminsearch001-connection' + storageAccountName: 'maeminsa001' + userAssignedtName: 'maeminua001' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "cognitiveServicesName": { + "value": "maemincs001" + }, + "hubName": { + "value": "maeminhub001" + }, + "keyVaultName": { + "value": "maeminkv00" + }, + "openAiConnectionName": { + "value": "maeminai001-connection" + }, + "projectName": { + "value": "maeminpro001" + }, + "searchConnectionName": { + "value": "maeminsearch001-connection" + }, + "storageAccountName": { + "value": "maeminsa001" + }, + "userAssignedtName": { + "value": "maeminua001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 2: _Using large parameter set_ + +This instance deploys the module using large parameters. + + +

+ +via Bicep module + +```bicep +module mlAiEnvironment 'br/public:avm/ptn/azd/ml-ai-environment:' = { + name: 'mlAiEnvironmentDeployment' + params: { + // Required parameters + cognitiveServicesName: 'maemaxcs001' + hubName: 'maemaxhub001' + keyVaultName: 'maemaxkv001' + openAiConnectionName: 'maemaxai001-connection' + projectName: 'maemaxpro001' + searchConnectionName: 'maemaxsearch001-connection' + storageAccountName: 'maemaxsta001' + userAssignedtName: 'maemaxua001' + // Non-required parameters + applicationInsightsName: 'maemaxappin001' + cognitiveServicesDeployments: [ + { + model: { + format: 'OpenAI' + name: 'gpt-35-turbo' + version: '0613' + } + name: 'gpt-35-turbo' + sku: { + capacity: 20 + name: 'Standard' + } + } + ] + containerRegistryName: 'maemaxcr001' + location: '' + logAnalyticsName: 'maemaxla001' + searchServiceName: 'maemaxsearch001' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "cognitiveServicesName": { + "value": "maemaxcs001" + }, + "hubName": { + "value": "maemaxhub001" + }, + "keyVaultName": { + "value": "maemaxkv001" + }, + "openAiConnectionName": { + "value": "maemaxai001-connection" + }, + "projectName": { + "value": "maemaxpro001" + }, + "searchConnectionName": { + "value": "maemaxsearch001-connection" + }, + "storageAccountName": { + "value": "maemaxsta001" + }, + "userAssignedtName": { + "value": "maemaxua001" + }, + // Non-required parameters + "applicationInsightsName": { + "value": "maemaxappin001" + }, + "cognitiveServicesDeployments": { + "value": [ + { + "model": { + "format": "OpenAI", + "name": "gpt-35-turbo", + "version": "0613" + }, + "name": "gpt-35-turbo", + "sku": { + "capacity": 20, + "name": "Standard" + } + } + ] + }, + "containerRegistryName": { + "value": "maemaxcr001" + }, + "location": { + "value": "" + }, + "logAnalyticsName": { + "value": "maemaxla001" + }, + "searchServiceName": { + "value": "maemaxsearch001" + } + } +} +``` + +
+

+ +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`cognitiveServicesName`](#parameter-cognitiveservicesname) | string | The Cognitive Services name. | +| [`hubName`](#parameter-hubname) | string | The AI Studio Hub Resource name. | +| [`keyVaultName`](#parameter-keyvaultname) | string | The Key Vault resource name. | +| [`projectName`](#parameter-projectname) | string | The AI Project resource name. | +| [`storageAccountName`](#parameter-storageaccountname) | string | The Storage Account resource name. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationInsightsName`](#parameter-applicationinsightsname) | string | The Application Insights resource name. | +| [`cognitiveServicesDeployments`](#parameter-cognitiveservicesdeployments) | array | Array of deployments about cognitive service accounts to create. | +| [`containerRegistryName`](#parameter-containerregistryname) | string | The Container Registry resource name. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location for all Resources. | +| [`logAnalyticsName`](#parameter-loganalyticsname) | string | The Log Analytics resource name. | +| [`openAiConnectionName`](#parameter-openaiconnectionname) | string | The Open AI connection name. | +| [`replicaCount`](#parameter-replicacount) | int | The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU. | +| [`searchConnectionName`](#parameter-searchconnectionname) | string | The Azure Search connection name. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`userAssignedtName`](#parameter-userassignedtname) | string | The User Assigned Identity resource name. | + +**Condition parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`searchServiceName`](#parameter-searchservicename) | string | The Azure Search resource name. Required if the parameter searchServiceName is not empty. | + +### Parameter: `cognitiveServicesName` + +The Cognitive Services name. + +- Required: Yes +- Type: string + +### Parameter: `hubName` + +The AI Studio Hub Resource name. + +- Required: Yes +- Type: string + +### Parameter: `keyVaultName` + +The Key Vault resource name. + +- Required: Yes +- Type: string + +### Parameter: `projectName` + +The AI Project resource name. + +- Required: Yes +- Type: string + +### Parameter: `storageAccountName` + +The Storage Account resource name. + +- Required: Yes +- Type: string + +### Parameter: `applicationInsightsName` + +The Application Insights resource name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `cognitiveServicesDeployments` + +Array of deployments about cognitive service accounts to create. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `containerRegistryName` + +The Container Registry resource name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location for all Resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `logAnalyticsName` + +The Log Analytics resource name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `openAiConnectionName` + +The Open AI connection name. + +- Required: Yes +- Type: string + +### Parameter: `replicaCount` + +The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `searchConnectionName` + +The Azure Search connection name. + +- Required: Yes +- Type: string + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object +- Example: + ```Bicep + { + "key1": "value1" + "key2": "value2" + } + ``` + +### Parameter: `userAssignedtName` + +The User Assigned Identity resource name. + +- Required: Yes +- Type: string + +### Parameter: `searchServiceName` + +The Azure Search resource name. Required if the parameter searchServiceName is not empty. + +- Required: No +- Type: string +- Default: `''` + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `applicationInsightsName` | string | The name of the application insights. | +| `containerRegistryEndpoint` | string | The endpoint of the container registry. | +| `containerRegistryName` | string | The name of the container registry. | +| `hubName` | string | The name of the ai studio hub. | +| `hubPrincipalId` | string | The principal ID of the ai studio hub. | +| `keyVaultEndpoint` | string | The endpoint of the key vault. | +| `keyVaultName` | string | The name of the key vault. | +| `logAnalyticsWorkspaceName` | string | The name of the log analytics workspace. | +| `openAiEndpoint` | string | The endpoint of the cognitive services. | +| `openAiName` | string | The name of the cognitive services. | +| `projectName` | string | The name of the ai studio project. | +| `projectPrincipalId` | string | The principal ID of the ai studio project. | +| `resourceGroupName` | string | The name of the resource group the module was deployed to. | +| `searchServiceEndpoint` | string | The endpoint of the search service. | +| `searchServiceName` | string | The name of the search service. | +| `storageAccountName` | string | The name of the storage account. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `ptn/azd/ml-hub-dependencies` | Local reference | +| `ptn/azd/ml-project` | Local reference | +| `br/public:avm/ptn/azd/insights-dashboard:0.1.0` | Remote reference | +| `br/public:avm/res/cognitive-services/account:0.7.0` | Remote reference | +| `br/public:avm/res/container-registry/registry:0.4.0` | Remote reference | +| `br/public:avm/res/key-vault/vault:0.7.1` | Remote reference | +| `br/public:avm/res/key-vault/vault:0.9.0` | Remote reference | +| `br/public:avm/res/machine-learning-services/workspace:0.7.0` | Remote reference | +| `br/public:avm/res/managed-identity/user-assigned-identity:0.4.0` | Remote reference | +| `br/public:avm/res/operational-insights/workspace:0.6.0` | Remote reference | +| `br/public:avm/res/search/search-service:0.6.0` | Remote reference | +| `br/public:avm/res/storage/storage-account:0.9.1` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/ptn/azd/ml-ai-environment/main.bicep b/avm/ptn/azd/ml-ai-environment/main.bicep new file mode 100644 index 0000000000..358ffbdca0 --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/main.bicep @@ -0,0 +1,185 @@ +metadata name = 'Azure Machine Learning Environment' +metadata description = '''Create Azure Machine Learning workspaces of type 'Hub' and 'Project' and their required dependencies. + +**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.''' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The AI Studio Hub Resource name.') +param hubName string + +@description('Required. The AI Project resource name.') +param projectName string + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +@metadata({ + example: ''' + { + "key1": "value1" + "key2": "value2" + } + ''' +}) +param tags object? + +@description('Optional. The Container Registry resource name.') +param containerRegistryName string = '' + +@description('Required. The Cognitive Services name.') +param cognitiveServicesName string + +@description('Required. The Key Vault resource name.') +param keyVaultName string + +@description('Required. The Storage Account resource name.') +param storageAccountName string + +@description('Optional. The Application Insights resource name.') +param applicationInsightsName string = '' + +@description('Optional. The Log Analytics resource name.') +param logAnalyticsName string = '' + +@description('Optional. Array of deployments about cognitive service accounts to create.') +param cognitiveServicesDeployments array = [] + +@description('Condition. The Azure Search resource name. Required if the parameter searchServiceName is not empty.') +param searchServiceName string = '' + +@description('Optional. The Open AI connection name.') +param openAiConnectionName string + +@description('Optional. The Azure Search connection name.') +param searchConnectionName string + +@description('Optional. The User Assigned Identity resource name.') +param userAssignedtName string + +@description('Optional. The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU.') +@minValue(1) +@maxValue(12) +param replicaCount int = 1 + +// ============== // +// Resources // +// ============== // + +#disable-next-line no-deployments-resources +resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { + name: '46d3xbcp.ptn.azd-mlaienvironment.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +module hubDependencies '../ml-hub-dependencies/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-dependencies' + params: { + location: location + tags: tags + cognitiveServicesName: cognitiveServicesName + keyVaultName: keyVaultName + storageAccountName: storageAccountName + applicationInsightsName: applicationInsightsName + logAnalyticsName: logAnalyticsName + containerRegistryName: containerRegistryName + cognitiveServicesDeployments: cognitiveServicesDeployments + searchServiceName: searchServiceName + replicaCount: replicaCount + } +} + +module hub './modules/hub.bicep' = { + name: 'hub' + params: { + location: location + tags: tags + name: hubName + keyVaultResourceId: hubDependencies.outputs.keyVaultResourceId + storageAccountResourceId: hubDependencies.outputs.storageAccountResourceId + containerRegistryResourceId: hubDependencies.outputs.containerRegistryResourceId + applicationInsightsResourceId: hubDependencies.outputs.applicationInsightsResourceId + openAiName: hubDependencies.outputs.cognitiveServicesName + aiSearchName: hubDependencies.outputs.searchServiceName + aiSearchConnectionName: searchConnectionName + openAiContentSafetyConnectionName: openAiConnectionName + } +} + +module project '../ml-project/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-project' + params: { + name: projectName + hubResourceId: hub.outputs.resourceId + keyVaultName: hubDependencies.outputs.keyVaultName + userAssignedtName: userAssignedtName + } +} + +// ============ // +// Outputs // +// ============ // + +@description('The name of the resource group the module was deployed to.') +output resourceGroupName string = resourceGroup().name + +@description('The name of the ai studio hub.') +output hubName string = hub.outputs.name + +@description('The principal ID of the ai studio hub.') +output hubPrincipalId string = hub.outputs.principalId + +@description('The name of the ai studio project.') +output projectName string = project.outputs.projectName + +@description('The principal ID of the ai studio project.') +output projectPrincipalId string = project.outputs.projectPrincipalId + +@description('The name of the key vault.') +output keyVaultName string = hubDependencies.outputs.keyVaultName + +@description('The endpoint of the key vault.') +output keyVaultEndpoint string = hubDependencies.outputs.keyVaultEndpoint + +@description('The name of the application insights.') +output applicationInsightsName string = hubDependencies.outputs.applicationInsightsName + +@description('The name of the log analytics workspace.') +output logAnalyticsWorkspaceName string = hubDependencies.outputs.logAnalyticsWorkspaceName + +@description('The name of the container registry.') +output containerRegistryName string = hubDependencies.outputs.containerRegistryName + +@description('The endpoint of the container registry.') +output containerRegistryEndpoint string = hubDependencies.outputs.containerRegistryEndpoint + +@description('The name of the storage account.') +output storageAccountName string = hubDependencies.outputs.storageAccountName + +@description('The name of the cognitive services.') +output openAiName string = hubDependencies.outputs.cognitiveServicesName + +@description('The endpoint of the cognitive services.') +output openAiEndpoint string = hubDependencies.outputs.cognitiveServicesEndpoint + +@description('The name of the search service.') +output searchServiceName string = hubDependencies.outputs.searchServiceName + +@description('The endpoint of the search service.') +output searchServiceEndpoint string = hubDependencies.outputs.searchServiceEndpoint diff --git a/avm/ptn/azd/ml-ai-environment/main.json b/avm/ptn/azd/ml-ai-environment/main.json new file mode 100644 index 0000000000..f7e659a3c4 --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/main.json @@ -0,0 +1,26764 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "9652571987002611788" + }, + "name": "Azure Machine Learning Environment", + "description": "Create Azure Machine Learning workspaces of type 'Hub' and 'Project' and their required dependencies.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "hubName": { + "type": "string", + "metadata": { + "description": "Required. The AI Studio Hub Resource name." + } + }, + "projectName": { + "type": "string", + "metadata": { + "description": "Required. The AI Project resource name." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ", + "description": "Optional. Tags of the resource." + } + }, + "containerRegistryName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Container Registry resource name." + } + }, + "cognitiveServicesName": { + "type": "string", + "metadata": { + "description": "Required. The Cognitive Services name." + } + }, + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Required. The Key Vault resource name." + } + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "Required. The Storage Account resource name." + } + }, + "applicationInsightsName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Application Insights resource name." + } + }, + "logAnalyticsName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Log Analytics resource name." + } + }, + "cognitiveServicesDeployments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of deployments about cognitive service accounts to create." + } + }, + "searchServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Condition. The Azure Search resource name. Required if the parameter searchServiceName is not empty." + } + }, + "openAiConnectionName": { + "type": "string", + "metadata": { + "description": "Optional. The Open AI connection name." + } + }, + "searchConnectionName": { + "type": "string", + "metadata": { + "description": "Optional. The Azure Search connection name." + } + }, + "userAssignedtName": { + "type": "string", + "metadata": { + "description": "Optional. The User Assigned Identity resource name." + } + }, + "replicaCount": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 12, + "metadata": { + "description": "Optional. The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.ptn.azd-mlaienvironment.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "hubDependencies": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-dependencies', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "cognitiveServicesName": { + "value": "[parameters('cognitiveServicesName')]" + }, + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "applicationInsightsName": { + "value": "[parameters('applicationInsightsName')]" + }, + "logAnalyticsName": { + "value": "[parameters('logAnalyticsName')]" + }, + "containerRegistryName": { + "value": "[parameters('containerRegistryName')]" + }, + "cognitiveServicesDeployments": { + "value": "[parameters('cognitiveServicesDeployments')]" + }, + "searchServiceName": { + "value": "[parameters('searchServiceName')]" + }, + "replicaCount": { + "value": "[parameters('replicaCount')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "6799127393431161652" + }, + "name": "Azure Machine Learning Dependencies", + "description": "Creates all the dependencies required for a Machine Learning Service.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, + "nullable": true + } + }, + "parameters": { + "applicationInsightsDashboardName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource portal dashboards name." + } + }, + "applicationInsightsName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource insights components name." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "logAnalyticsName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource operational insights workspaces name." + } + }, + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Required. Name of the key vault." + } + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "Required. Name of the storage account." + } + }, + "cognitiveServicesName": { + "type": "string", + "metadata": { + "description": "Required. Name of the OpenAI cognitive services." + } + }, + "containerRegistryName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the container registry." + } + }, + "searchServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the Azure Cognitive Search service." + } + }, + "allowBlobPublicAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." + } + }, + "dnsEndpointType": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "", + "AzureDnsZone", + "Standard" + ], + "metadata": { + "description": "Optional. Allows you to specify the type of endpoint in the storage account. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "", + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for the storage account. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "networkAcls": { + "type": "object", + "defaultValue": { + "bypass": "AzureServices", + "defaultAction": "Allow" + }, + "metadata": { + "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." + } + }, + "blobServices": { + "type": "object", + "defaultValue": { + "containers": [ + { + "name": "default" + } + ], + "corsRules": [ + { + "allowedOrigins": [ + "https://mlworkspace.azure.ai", + "https://ml.azure.com", + "https://*.ml.azure.com", + "https://ai.azure.com", + "https://*.ai.azure.com", + "https://mlworkspacecanary.azure.ai", + "https://mlworkspace.azureml-test.net" + ], + "allowedMethods": [ + "GET", + "HEAD", + "POST", + "PUT", + "DELETE", + "OPTIONS", + "PATCH" + ], + "maxAgeInSeconds": 1800, + "exposedHeaders": [ + "*" + ], + "allowedHeaders": [ + "*" + ] + } + ], + "deleteRetentionPolicyEnabled": true, + "containerDeleteRetentionPolicyDays": 7, + "deleteRetentionPolicyDays": 6, + "deleteRetentionPolicyAllowPermanentDelete": true + }, + "metadata": { + "description": "Optional. Blob service and containers to deploy." + } + }, + "fileServices": { + "type": "object", + "defaultValue": { + "name": "default" + }, + "metadata": { + "description": "Optional. File service and shares to deploy." + } + }, + "queueServices": { + "type": "object", + "defaultValue": { + "name": "default" + }, + "metadata": { + "description": "Optional. Queue service and queues to create." + } + }, + "tableServices": { + "type": "object", + "defaultValue": { + "name": "default" + }, + "metadata": { + "description": "Optional. Table service and tables to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ", + "description": "Optional. Tags of the resource." + } + }, + "cognitiveServicesKind": { + "type": "string", + "defaultValue": "AIServices", + "metadata": { + "description": "Optional. Kind of the Cognitive Services." + } + }, + "cognitiveServicesDeployments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of deployments about cognitive service accounts to create." + } + }, + "cognitiveServicesCustomSubDomainName": { + "type": "string", + "defaultValue": "[parameters('cognitiveServicesName')]", + "metadata": { + "description": "Optional. The custom subdomain name used to access the API. Defaults to the value of the name parameter." + } + }, + "cognitiveServicesDisableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Allow only Azure AD authentication. Should be enabled for security reasons." + } + }, + "cognitiveServicesPublicNetworkAccess": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "cognitiveServicesNetworkAcls": { + "type": "object", + "defaultValue": { + "defaultAction": "Allow" + }, + "metadata": { + "description": "Optional. A collection of rules governing the accessibility from specific network locations." + } + }, + "cognitiveServicesSku": { + "type": "string", + "defaultValue": "S0", + "metadata": { + "description": "Optional. SKU of the Cognitive Services resource." + } + }, + "registryAcrSku": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Tier of your Azure container registry." + } + }, + "registryPublicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "metadata": { + "description": "Optional. Public network access setting." + } + }, + "enableRbacAuthorization": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Property that controls how data actions are authorized. When true, the key vault will use Role Based Access Control (RBAC) for authorization of data actions, and the access policies specified in vault properties will be ignored. When false, the key vault will use the access policies specified in vault properties, and any policy stored on Azure Resource Manager will be ignored. Note that management actions are always authorized with RBAC." + } + }, + "enableVaultForDeployment": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for deployment by script or compute." + } + }, + "enableVaultForTemplateDeployment": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for a template deployment." + } + }, + "enablePurgeProtection": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Provide 'true' to enable Key Vault's purge protection feature." + } + }, + "keyVaultSku": { + "type": "string", + "defaultValue": "standard", + "allowedValues": [ + "premium", + "standard" + ], + "metadata": { + "description": "Optional. Specifies the SKU for the vault." + } + }, + "logAnalyticsSkuName": { + "type": "string", + "defaultValue": "PerGB2018", + "allowedValues": [ + "CapacityReservation", + "Free", + "LACluster", + "PerGB2018", + "PerNode", + "Premium", + "Standalone", + "Standard" + ], + "metadata": { + "description": "Optional. The name of the SKU." + } + }, + "dataRetention": { + "type": "int", + "defaultValue": 30, + "minValue": 0, + "maxValue": 730, + "metadata": { + "description": "Optional. Number of days data will be retained for." + } + }, + "authOptions": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Defines the options for how the data plane API of a Search service authenticates requests. Must remain an empty object {} if 'disableLocalAuth' is set to true." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. When set to true, calls to the search service will not be permitted to utilize API keys for authentication. This cannot be set to true if 'authOptions' are defined." + } + }, + "cmkEnforcement": { + "type": "string", + "defaultValue": "Unspecified", + "allowedValues": [ + "Disabled", + "Enabled", + "Unspecified" + ], + "metadata": { + "description": "Optional. Describes a policy that determines how resources within the search service are to be encrypted with Customer Managed Keys." + } + }, + "hostingMode": { + "type": "string", + "defaultValue": "default", + "allowedValues": [ + "default", + "highDensity" + ], + "metadata": { + "description": "Optional. Applicable only for the standard3 SKU. You can set this property to enable up to 3 high density partitions that allow up to 1000 indexes, which is much higher than the maximum indexes allowed for any other SKU. For the standard3 SKU, the value is either 'default' or 'highDensity'. For all other SKUs, this value must be 'default'." + } + }, + "networkRuleSet": { + "type": "object", + "defaultValue": { + "bypass": "None", + "ipRules": [] + }, + "metadata": { + "description": "Optional. Network specific rules that determine how the Azure Cognitive Search service may be reached." + } + }, + "partitionCount": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 12, + "metadata": { + "description": "Optional. The number of partitions in the search service; if specified, it can be 1, 2, 3, 4, 6, or 12. Values greater than 1 are only valid for standard SKUs. For 'standard3' services with hostingMode set to 'highDensity', the allowed values are between 1 and 3." + } + }, + "searchServicePublicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. This value can be set to 'Enabled' to avoid breaking changes on existing customer resources and templates. If set to 'Disabled', traffic over public interface is not allowed, and private endpoint connections would be the exclusive access method." + } + }, + "replicaCount": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 12, + "metadata": { + "description": "Optional. The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU." + } + }, + "semanticSearch": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "free", + "standard" + ], + "metadata": { + "description": "Optional. Sets options that control the availability of semantic search. This configuration is only possible for certain search SKUs in certain locations." + } + }, + "searchServiceSku": { + "type": "string", + "defaultValue": "standard", + "allowedValues": [ + "basic", + "free", + "standard", + "standard2", + "standard3", + "storage_optimized_l1", + "storage_optimized_l2" + ], + "metadata": { + "description": "Optional. Defines the SKU of an Azure Cognitive Search Service, which determines price tier and capacity limits." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "nullable": true, + "metadata": { + "description": "Conditional. The managed identity definition for this resource. Required if `assignRbacRole` is `true` and `managedIdentityName` is `null`." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.ptn.azd-mlhubdependencies.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "keyVault": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-keyvault', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('keyVaultName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "enableRbacAuthorization": { + "value": "[parameters('enableRbacAuthorization')]" + }, + "enableVaultForDeployment": { + "value": "[parameters('enableVaultForDeployment')]" + }, + "enableVaultForTemplateDeployment": { + "value": "[parameters('enableVaultForTemplateDeployment')]" + }, + "enablePurgeProtection": { + "value": "[parameters('enablePurgeProtection')]" + }, + "sku": { + "value": "[parameters('keyVaultSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "6878673228466609441" + }, + "name": "Key Vaults", + "description": "This module deploys a Key Vault.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "accessPoliciesType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tenant ID that is used for authenticating requests to the key vault." + } + }, + "objectId": { + "type": "string", + "metadata": { + "description": "Required. The object ID of a user, service principal or security group in the tenant for the vault." + } + }, + "applicationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Application ID of the client making request on behalf of a principal." + } + }, + "permissions": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "getrotationpolicy", + "import", + "list", + "purge", + "recover", + "release", + "restore", + "rotate", + "setrotationpolicy", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to keys." + } + }, + "secrets": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to secrets." + } + }, + "certificates": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "purge", + "recover", + "restore", + "setissuers", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to certificates." + } + }, + "storage": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "deletesas", + "get", + "getsas", + "list", + "listsas", + "purge", + "recover", + "regeneratekey", + "restore", + "set", + "setsas", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to storage accounts." + } + } + }, + "metadata": { + "description": "Required. Permissions the identity has for keys, secrets and certificates." + } + } + } + }, + "nullable": true + }, + "secretsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributes": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Defines whether the secret is enabled or disabled." + } + }, + "exp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Defines when the secret will become invalid. Defined in seconds since 1970-01-01T00:00:00Z." + } + }, + "nbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. If set, defines the date from which onwards the secret becomes valid. Defined in seconds since 1970-01-01T00:00:00Z." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Contains attributes of the secret." + } + }, + "contentType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The content type of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + } + }, + "nullable": true + }, + "keysType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the key." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributes": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Defines whether the key is enabled or disabled." + } + }, + "exp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Defines when the key will become invalid. Defined in seconds since 1970-01-01T00:00:00Z." + } + }, + "nbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. If set, defines the date from which onwards the key becomes valid. Defined in seconds since 1970-01-01T00:00:00Z." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Contains attributes of the key." + } + }, + "curveName": { + "type": "string", + "allowedValues": [ + "P-256", + "P-256K", + "P-384", + "P-521" + ], + "nullable": true, + "metadata": { + "description": "Optional. The elliptic curve name. Only works if \"keySize\" equals \"EC\" or \"EC-HSM\". Default is \"P-256\"." + } + }, + "keyOps": { + "type": "array", + "allowedValues": [ + "decrypt", + "encrypt", + "import", + "release", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. The allowed operations on this key." + } + }, + "keySize": { + "type": "int", + "allowedValues": [ + 2048, + 3072, + 4096 + ], + "nullable": true, + "metadata": { + "description": "Optional. The key size in bits. Only works if \"keySize\" equals \"RSA\" or \"RSA-HSM\". Default is \"4096\"." + } + }, + "kty": { + "type": "string", + "allowedValues": [ + "EC", + "EC-HSM", + "RSA", + "RSA-HSM" + ], + "nullable": true, + "metadata": { + "description": "Optional. The type of the key. Default is \"EC\"." + } + }, + "releasePolicy": { + "type": "object", + "properties": { + "contentType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Content type and version of key release policy." + } + }, + "data": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Blob encoding the policy rules under which the key can be released." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Key release policy." + } + }, + "rotationPolicy": { + "$ref": "#/definitions/rotationPoliciesType", + "nullable": true, + "metadata": { + "description": "Optional. Key rotation policy." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + } + }, + "nullable": true + }, + "rotationPoliciesType": { + "type": "object", + "properties": { + "attributes": { + "type": "object", + "properties": { + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiration time for the new key version. It should be in ISO8601 format. Eg: \"P90D\", \"P1Y\"." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The attributes of key rotation policy." + } + }, + "lifetimeActions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "action": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "Notify", + "Rotate" + ], + "nullable": true, + "metadata": { + "description": "Optional. The type of action." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The action of key rotation policy lifetimeAction." + } + }, + "trigger": { + "type": "object", + "properties": { + "timeAfterCreate": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The time duration after key creation to rotate the key. It only applies to rotate. It will be in ISO 8601 duration format. Eg: \"P90D\", \"P1Y\"." + } + }, + "timeBeforeExpiry": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The time duration before key expiring to rotate or notify. It will be in ISO 8601 duration format. Eg: \"P90D\", \"P1Y\"." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The trigger of key rotation policy lifetimeAction." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The lifetimeActions for key rotation action." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Required. Name of the Key Vault. Must be globally unique." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "accessPolicies": { + "$ref": "#/definitions/accessPoliciesType", + "metadata": { + "description": "Optional. All access policies to create." + } + }, + "secrets": { + "$ref": "#/definitions/secretsType", + "nullable": true, + "metadata": { + "description": "Optional. All secrets to create." + } + }, + "keys": { + "$ref": "#/definitions/keysType", + "nullable": true, + "metadata": { + "description": "Optional. All keys to create." + } + }, + "enableVaultForDeployment": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for deployment by script or compute." + } + }, + "enableVaultForTemplateDeployment": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for a template deployment." + } + }, + "enableVaultForDiskEncryption": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the azure platform has access to the vault for enabling disk encryption scenarios." + } + }, + "enableSoftDelete": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Switch to enable/disable Key Vault's soft delete feature." + } + }, + "softDeleteRetentionInDays": { + "type": "int", + "defaultValue": 90, + "metadata": { + "description": "Optional. softDelete data retention days. It accepts >=7 and <=90." + } + }, + "enableRbacAuthorization": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Property that controls how data actions are authorized. When true, the key vault will use Role Based Access Control (RBAC) for authorization of data actions, and the access policies specified in vault properties will be ignored. When false, the key vault will use the access policies specified in vault properties, and any policy stored on Azure Resource Manager will be ignored. Note that management actions are always authorized with RBAC." + } + }, + "createMode": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The vault's create mode to indicate whether the vault need to be recovered or not. - recover or default." + } + }, + "enablePurgeProtection": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Provide 'true' to enable Key Vault's purge protection feature." + } + }, + "sku": { + "type": "string", + "defaultValue": "premium", + "allowedValues": [ + "premium", + "standard" + ], + "metadata": { + "description": "Optional. Specifies the SKU for the vault." + } + }, + "networkAcls": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Rules governing the accessibility of the resource from specific network locations." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + }, + { + "name": "formattedAccessPolicies", + "count": "[length(coalesce(parameters('accessPolicies'), createArray()))]", + "input": { + "applicationId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'applicationId'), '')]", + "objectId": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].objectId]", + "permissions": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].permissions]", + "tenantId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'tenantId'), tenant().tenantId)]" + } + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Certificates Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985')]", + "Key Vault Certificate User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db79e9a7-68ee-4b58-9aeb-b90e7c24fcba')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Crypto Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')]", + "Key Vault Crypto Service Encryption User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]", + "Key Vault Crypto User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Key Vault Secrets Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')]", + "Key Vault Secrets User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.keyvault-vault.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "keyVault": { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "enabledForDeployment": "[parameters('enableVaultForDeployment')]", + "enabledForTemplateDeployment": "[parameters('enableVaultForTemplateDeployment')]", + "enabledForDiskEncryption": "[parameters('enableVaultForDiskEncryption')]", + "enableSoftDelete": "[parameters('enableSoftDelete')]", + "softDeleteRetentionInDays": "[parameters('softDeleteRetentionInDays')]", + "enableRbacAuthorization": "[parameters('enableRbacAuthorization')]", + "createMode": "[parameters('createMode')]", + "enablePurgeProtection": "[if(parameters('enablePurgeProtection'), parameters('enablePurgeProtection'), null())]", + "tenantId": "[subscription().tenantId]", + "accessPolicies": "[variables('formattedAccessPolicies')]", + "sku": { + "name": "[parameters('sku')]", + "family": "A" + }, + "networkAcls": "[if(not(empty(coalesce(parameters('networkAcls'), createObject()))), createObject('bypass', tryGet(parameters('networkAcls'), 'bypass'), 'defaultAction', tryGet(parameters('networkAcls'), 'defaultAction'), 'virtualNetworkRules', coalesce(tryGet(parameters('networkAcls'), 'virtualNetworkRules'), createArray()), 'ipRules', coalesce(tryGet(parameters('networkAcls'), 'ipRules'), createArray())), null())]", + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(coalesce(parameters('privateEndpoints'), createArray()))), empty(coalesce(parameters('networkAcls'), createObject()))), 'Disabled', null()))]" + } + }, + "keyVault_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_diagnosticSettings": { + "copy": { + "name": "keyVault_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_roleAssignments": { + "copy": { + "name": "keyVault_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_accessPolicies": { + "condition": "[not(empty(parameters('accessPolicies')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-AccessPolicies', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('name')]" + }, + "accessPolicies": { + "value": "[parameters('accessPolicies')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "7494731697751039419" + }, + "name": "Key Vault Access Policies", + "description": "This module deploys a Key Vault Access Policy.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "accessPoliciesType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tenant ID that is used for authenticating requests to the key vault." + } + }, + "objectId": { + "type": "string", + "metadata": { + "description": "Required. The object ID of a user, service principal or security group in the tenant for the vault." + } + }, + "applicationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Application ID of the client making request on behalf of a principal." + } + }, + "permissions": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "getrotationpolicy", + "import", + "list", + "purge", + "recover", + "release", + "restore", + "rotate", + "setrotationpolicy", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to keys." + } + }, + "secrets": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to secrets." + } + }, + "certificates": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "purge", + "recover", + "restore", + "setissuers", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to certificates." + } + }, + "storage": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "deletesas", + "get", + "getsas", + "list", + "listsas", + "purge", + "recover", + "regeneratekey", + "restore", + "set", + "setsas", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to storage accounts." + } + } + }, + "metadata": { + "description": "Required. Permissions the identity has for keys, secrets and certificates." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "accessPolicies": { + "$ref": "#/definitions/accessPoliciesType", + "metadata": { + "description": "Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault's tenant ID." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedAccessPolicies", + "count": "[length(coalesce(parameters('accessPolicies'), createArray()))]", + "input": { + "applicationId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'applicationId'), '')]", + "objectId": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].objectId]", + "permissions": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].permissions]", + "tenantId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'tenantId'), tenant().tenantId)]" + } + } + ] + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "policies": { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), 'add')]", + "properties": { + "accessPolicies": "[variables('formattedAccessPolicies')]" + }, + "dependsOn": [ + "keyVault" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the access policies assignment was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the access policies assignment." + }, + "value": "add" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the access policies assignment." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/accessPolicies', parameters('keyVaultName'), 'add')]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_secrets": { + "copy": { + "name": "keyVault_secrets", + "count": "[length(coalesce(parameters('secrets'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-Secret-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('secrets'), createArray())[copyIndex()].name]" + }, + "value": { + "value": "[coalesce(parameters('secrets'), createArray())[copyIndex()].value]" + }, + "keyVaultName": { + "value": "[parameters('name')]" + }, + "attributesEnabled": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'enabled')]" + }, + "attributesExp": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'exp')]" + }, + "attributesNbf": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'nbf')]" + }, + "contentType": { + "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'contentType')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "4990258423482296566" + }, + "name": "Key Vault Secrets", + "description": "This module deploys a Key Vault Secret.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributesEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Determines whether the object is enabled." + } + }, + "attributesExp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Expiry date in seconds since 1970-01-01T00:00:00Z. For security reasons, it is recommended to set an expiration date whenever possible." + } + }, + "attributesNbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Not before date in seconds since 1970-01-01T00:00:00Z." + } + }, + "contentType": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Optional. The content type of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Key Vault Secrets Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')]", + "Key Vault Secrets User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "secret": { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "contentType": "[parameters('contentType')]", + "attributes": { + "enabled": "[parameters('attributesEnabled')]", + "exp": "[parameters('attributesExp')]", + "nbf": "[parameters('attributesNbf')]" + }, + "value": "[parameters('value')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "secret_roleAssignments": { + "copy": { + "name": "secret_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}/secrets/{1}', parameters('keyVaultName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "secret" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_keys": { + "copy": { + "name": "keyVault_keys", + "count": "[length(coalesce(parameters('keys'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-Key-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('keys'), createArray())[copyIndex()].name]" + }, + "keyVaultName": { + "value": "[parameters('name')]" + }, + "attributesEnabled": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'enabled')]" + }, + "attributesExp": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'exp')]" + }, + "attributesNbf": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'nbf')]" + }, + "curveName": "[if(and(not(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA')), not(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA-HSM'))), createObject('value', coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'curveName'), 'P-256')), createObject('value', null()))]", + "keyOps": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'keyOps')]" + }, + "keySize": "[if(or(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA'), equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA-HSM')), createObject('value', coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'keySize'), 4096)), createObject('value', null()))]", + "releasePolicy": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'releasePolicy'), createObject())]" + }, + "kty": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'EC')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "rotationPolicy": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'rotationPolicy')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "10436564794447478489" + }, + "name": "Key Vault Keys", + "description": "This module deploys a Key Vault Key.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the key." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributesEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Determines whether the object is enabled." + } + }, + "attributesExp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Expiry date in seconds since 1970-01-01T00:00:00Z. For security reasons, it is recommended to set an expiration date whenever possible." + } + }, + "attributesNbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Not before date in seconds since 1970-01-01T00:00:00Z." + } + }, + "curveName": { + "type": "string", + "defaultValue": "P-256", + "allowedValues": [ + "P-256", + "P-256K", + "P-384", + "P-521" + ], + "metadata": { + "description": "Optional. The elliptic curve name." + } + }, + "keyOps": { + "type": "array", + "nullable": true, + "allowedValues": [ + "decrypt", + "encrypt", + "import", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ], + "metadata": { + "description": "Optional. Array of JsonWebKeyOperation." + } + }, + "keySize": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The key size in bits. For example: 2048, 3072, or 4096 for RSA." + } + }, + "kty": { + "type": "string", + "defaultValue": "EC", + "allowedValues": [ + "EC", + "EC-HSM", + "RSA", + "RSA-HSM" + ], + "metadata": { + "description": "Optional. The type of the key." + } + }, + "releasePolicy": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Key release policy." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "rotationPolicy": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Key rotation policy properties object." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Crypto Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')]", + "Key Vault Crypto Service Encryption User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]", + "Key Vault Crypto User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "key": { + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "attributes": { + "enabled": "[parameters('attributesEnabled')]", + "exp": "[parameters('attributesExp')]", + "nbf": "[parameters('attributesNbf')]" + }, + "curveName": "[parameters('curveName')]", + "keyOps": "[parameters('keyOps')]", + "keySize": "[parameters('keySize')]", + "kty": "[parameters('kty')]", + "rotationPolicy": "[coalesce(parameters('rotationPolicy'), createObject())]", + "release_policy": "[coalesce(parameters('releasePolicy'), createObject())]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "key_roleAssignments": { + "copy": { + "name": "key_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}/keys/{1}', parameters('keyVaultName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "key" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the key." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the key was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_privateEndpoints": { + "copy": { + "name": "keyVault_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-keyVault-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.KeyVault/vaults', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.KeyVault/vaults', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4120048060064073955" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the key vault." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the key vault was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the key vault." + }, + "value": "[parameters('name')]" + }, + "uri": { + "type": "string", + "metadata": { + "description": "The URI of the key vault." + }, + "value": "[reference('keyVault').vaultUri]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('keyVault', '2022-07-01', 'full').location]" + } + } + } + } + }, + "storageAccount": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-storage', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('storageAccountName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "allowBlobPublicAccess": { + "value": "[parameters('allowBlobPublicAccess')]" + }, + "dnsEndpointType": { + "value": "[parameters('dnsEndpointType')]" + }, + "publicNetworkAccess": { + "value": "[parameters('publicNetworkAccess')]" + }, + "networkAcls": { + "value": "[parameters('networkAcls')]" + }, + "blobServices": { + "value": "[parameters('blobServices')]" + }, + "fileServices": { + "value": "[parameters('fileServices')]" + }, + "queueServices": { + "value": "[parameters('queueServices')]" + }, + "tableServices": { + "value": "[parameters('tableServices')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "3958760216991467865" + }, + "name": "Storage Accounts", + "description": "This module deploys a Storage Account.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "networkAclsType": { + "type": "object", + "properties": { + "resourceAccessRules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The ID of the tenant in which the resource resides in." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Sets the resource access rules. Array entries must consist of \"tenantId\" and \"resourceId\" fields only." + } + }, + "bypass": { + "type": "string", + "allowedValues": [ + "AzureServices", + "AzureServices, Logging", + "AzureServices, Logging, Metrics", + "AzureServices, Metrics", + "Logging", + "Logging, Metrics", + "Metrics", + "None" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, \"Logging, Metrics\"), or None to bypass none of those traffics." + } + }, + "virtualNetworkRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Sets the virtual network rules." + } + }, + "ipRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Sets the IP ACL rules." + } + }, + "defaultAction": { + "type": "string", + "allowedValues": [ + "Allow", + "Deny" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the default action of allow or deny when no other rules match." + } + } + } + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. If used must also be specified in `managedIdentities.userAssignedResourceIds`. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Required. Name of the Storage Account. Must be lower-case." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "kind": { + "type": "string", + "defaultValue": "StorageV2", + "allowedValues": [ + "Storage", + "StorageV2", + "BlobStorage", + "FileStorage", + "BlockBlobStorage" + ], + "metadata": { + "description": "Optional. Type of Storage Account to create." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Standard_GRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_RAGRS", + "Standard_ZRS", + "Premium_LRS", + "Premium_ZRS", + "Standard_GZRS", + "Standard_RAGZRS" + ], + "metadata": { + "description": "Optional. Storage Account Sku Name." + } + }, + "accessTier": { + "type": "string", + "defaultValue": "Hot", + "allowedValues": [ + "Premium", + "Hot", + "Cool" + ], + "metadata": { + "description": "Conditional. Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The \"Premium\" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type." + } + }, + "largeFileSharesState": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Allow large file shares if sets to 'Enabled'. It cannot be disabled once it is enabled. Only supported on locally redundant and zone redundant file shares. It cannot be set on FileStorage storage accounts (storage accounts for premium file shares)." + } + }, + "azureFilesIdentityBasedAuthentication": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Provides the identity based authentication settings for Azure Files." + } + }, + "defaultToOAuthAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A boolean flag which indicates whether the default authentication is OAuth or not." + } + }, + "allowSharedKeyAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "managementPolicyRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The Storage Account ManagementPolicies Rules." + } + }, + "networkAcls": { + "$ref": "#/definitions/networkAclsType", + "nullable": true, + "metadata": { + "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." + } + }, + "requireInfrastructureEncryption": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. A Boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest. For security reasons, it is recommended to set it to true." + } + }, + "allowCrossTenantReplication": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Allow or disallow cross AAD tenant object replication." + } + }, + "customDomainName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Sets the custom domain name assigned to the storage account. Name is the CNAME source." + } + }, + "customDomainUseSubDomainName": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether indirect CName validation is enabled. This should only be set on updates." + } + }, + "dnsEndpointType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "AzureDnsZone", + "Standard" + ], + "metadata": { + "description": "Optional. Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier." + } + }, + "blobServices": { + "type": "object", + "defaultValue": "[if(not(equals(parameters('kind'), 'FileStorage')), createObject('containerDeleteRetentionPolicyEnabled', true(), 'containerDeleteRetentionPolicyDays', 7, 'deleteRetentionPolicyEnabled', true(), 'deleteRetentionPolicyDays', 6), createObject())]", + "metadata": { + "description": "Optional. Blob service and containers to deploy." + } + }, + "fileServices": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. File service and shares to deploy." + } + }, + "queueServices": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Queue service and queues to create." + } + }, + "tableServices": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Table service and tables to create." + } + }, + "allowBlobPublicAccess": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." + } + }, + "minimumTlsVersion": { + "type": "string", + "defaultValue": "TLS1_2", + "allowedValues": [ + "TLS1_0", + "TLS1_1", + "TLS1_2" + ], + "metadata": { + "description": "Optional. Set the minimum TLS version on request to storage." + } + }, + "enableHierarchicalNamespace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Conditional. If true, enables Hierarchical Namespace for the storage account. Required if enableSftp or enableNfsV3 is set to true." + } + }, + "enableSftp": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true." + } + }, + "localUsers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Local users to deploy for SFTP authentication." + } + }, + "isLocalUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables local users feature, if set to true." + } + }, + "enableNfsV3": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "allowedCopyScope": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "AAD", + "PrivateLink" + ], + "metadata": { + "description": "Optional. Restrict copy to and from Storage Accounts within an AAD tenant or with Private Links to the same VNet." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "supportsHttpsTrafficOnly": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Allows HTTPS traffic only to storage service if sets to true." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "sasExpirationPeriod": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The SAS expiration period. DD.HH:MM:SS." + } + }, + "keyType": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Account", + "Service" + ], + "metadata": { + "description": "Optional. The keyType to use with Queue & Table services." + } + } + }, + "variables": { + "supportsBlobService": "[or(or(or(equals(parameters('kind'), 'BlockBlobStorage'), equals(parameters('kind'), 'BlobStorage')), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]", + "supportsFileService": "[or(or(equals(parameters('kind'), 'FileStorage'), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]", + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", + "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]", + "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]", + "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]", + "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]", + "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]", + "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", + "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", + "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", + "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", + "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", + "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.storage-storageaccount.{0}.{1}', replace('0.9.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "storageAccount": { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "kind": "[parameters('kind')]", + "sku": { + "name": "[parameters('skuName')]" + }, + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "properties": { + "allowSharedKeyAccess": "[parameters('allowSharedKeyAccess')]", + "defaultToOAuthAuthentication": "[parameters('defaultToOAuthAuthentication')]", + "allowCrossTenantReplication": "[parameters('allowCrossTenantReplication')]", + "allowedCopyScope": "[if(not(empty(parameters('allowedCopyScope'))), parameters('allowedCopyScope'), null())]", + "customDomain": { + "name": "[parameters('customDomainName')]", + "useSubDomainName": "[parameters('customDomainUseSubDomainName')]" + }, + "dnsEndpointType": "[if(not(empty(parameters('dnsEndpointType'))), parameters('dnsEndpointType'), null())]", + "isLocalUserEnabled": "[parameters('isLocalUserEnabled')]", + "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true(), 'keyType', parameters('keyType')), 'queue', createObject('enabled', true(), 'keyType', parameters('keyType'))), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", + "accessTier": "[if(and(not(equals(parameters('kind'), 'Storage')), not(equals(parameters('kind'), 'BlockBlobStorage'))), parameters('accessTier'), null())]", + "sasPolicy": "[if(not(empty(parameters('sasExpirationPeriod'))), createObject('expirationAction', 'Log', 'sasExpirationPeriod', parameters('sasExpirationPeriod')), null())]", + "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]", + "isHnsEnabled": "[if(parameters('enableHierarchicalNamespace'), parameters('enableHierarchicalNamespace'), null())]", + "isSftpEnabled": "[parameters('enableSftp')]", + "isNfsV3Enabled": "[if(parameters('enableNfsV3'), parameters('enableNfsV3'), '')]", + "largeFileSharesState": "[if(or(equals(parameters('skuName'), 'Standard_LRS'), equals(parameters('skuName'), 'Standard_ZRS')), parameters('largeFileSharesState'), null())]", + "minimumTlsVersion": "[parameters('minimumTlsVersion')]", + "networkAcls": "[if(not(empty(parameters('networkAcls'))), union(createObject('resourceAccessRules', tryGet(parameters('networkAcls'), 'resourceAccessRules'), 'defaultAction', coalesce(tryGet(parameters('networkAcls'), 'defaultAction'), 'Deny'), 'virtualNetworkRules', tryGet(parameters('networkAcls'), 'virtualNetworkRules'), 'ipRules', tryGet(parameters('networkAcls'), 'ipRules')), if(contains(parameters('networkAcls'), 'bypass'), createObject('bypass', tryGet(parameters('networkAcls'), 'bypass')), createObject())), createObject('bypass', 'AzureServices', 'defaultAction', 'Deny'))]", + "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]", + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkAcls'))), 'Disabled', null()))]", + "azureFilesIdentityBasedAuthentication": "[if(not(empty(parameters('azureFilesIdentityBasedAuthentication'))), parameters('azureFilesIdentityBasedAuthentication'), null())]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "storageAccount_diagnosticSettings": { + "copy": { + "name": "storageAccount_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_roleAssignments": { + "copy": { + "name": "storageAccount_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_privateEndpoints": { + "copy": { + "name": "storageAccount_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-StorageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4120048060064073955" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_managementPolicies": { + "condition": "[not(empty(coalesce(parameters('managementPolicyRules'), createArray())))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-ManagementPolicies', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "rules": { + "value": "[coalesce(parameters('managementPolicyRules'), createArray())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "9473195527943694039" + }, + "name": "Storage Account Management Policies", + "description": "This module deploys a Storage Account Management Policy.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "rules": { + "type": "array", + "metadata": { + "description": "Required. The Storage Account ManagementPolicies Rules." + } + } + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts/managementPolicies", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", + "properties": { + "policy": { + "rules": "[parameters('rules')]" + } + } + } + ], + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed management policy." + }, + "value": "default" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed management policy." + }, + "value": "default" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed management policy." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount", + "storageAccount_blobServices" + ] + }, + "storageAccount_localUsers": { + "copy": { + "name": "storageAccount_localUsers", + "count": "[length(parameters('localUsers'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-LocalUsers-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('localUsers')[copyIndex()].name]" + }, + "hasSshKey": { + "value": "[parameters('localUsers')[copyIndex()].hasSshKey]" + }, + "hasSshPassword": { + "value": "[parameters('localUsers')[copyIndex()].hasSshPassword]" + }, + "permissionScopes": { + "value": "[parameters('localUsers')[copyIndex()].permissionScopes]" + }, + "hasSharedKey": { + "value": "[tryGet(parameters('localUsers')[copyIndex()], 'hasSharedKey')]" + }, + "homeDirectory": { + "value": "[tryGet(parameters('localUsers')[copyIndex()], 'homeDirectory')]" + }, + "sshAuthorizedKeys": { + "value": "[tryGet(parameters('localUsers')[copyIndex()], 'sshAuthorizedKeys')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "14968464858285923305" + }, + "name": "Storage Account Local Users", + "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "sshAuthorizedKeysType": { + "type": "secureObject", + "properties": { + "secureList": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Description used to store the function/usage of the key." + } + }, + "key": { + "type": "string", + "metadata": { + "description": "Required. SSH public key base64 encoded. The format should be: '{keyType} {keyData}', e.g. ssh-rsa AAAABBBB." + } + } + } + }, + "metadata": { + "description": "Optional. The list of SSH authorized keys." + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the local user used for SFTP Authentication." + } + }, + "hasSharedKey": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether shared key exists. Set it to false to remove existing shared key." + } + }, + "hasSshKey": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether SSH key exists. Set it to false to remove existing SSH key." + } + }, + "hasSshPassword": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether SSH password exists. Set it to false to remove existing SSH password." + } + }, + "homeDirectory": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The local user home directory." + } + }, + "permissionScopes": { + "type": "array", + "metadata": { + "description": "Required. The permission scopes of the local user." + } + }, + "sshAuthorizedKeys": { + "$ref": "#/definitions/sshAuthorizedKeysType", + "metadata": { + "description": "Optional. The local user SSH authorized keys for SFTP." + } + } + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "localUsers": { + "type": "Microsoft.Storage/storageAccounts/localUsers", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", + "properties": { + "hasSharedKey": "[parameters('hasSharedKey')]", + "hasSshKey": "[parameters('hasSshKey')]", + "hasSshPassword": "[parameters('hasSshPassword')]", + "homeDirectory": "[parameters('homeDirectory')]", + "permissionScopes": "[parameters('permissionScopes')]", + "sshAuthorizedKeys": "[tryGet(parameters('sshAuthorizedKeys'), 'secureList')]" + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed local user." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed local user." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed local user." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/localUsers', parameters('storageAccountName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_blobServices": { + "condition": "[not(empty(parameters('blobServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-BlobServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "containers": { + "value": "[tryGet(parameters('blobServices'), 'containers')]" + }, + "automaticSnapshotPolicyEnabled": { + "value": "[tryGet(parameters('blobServices'), 'automaticSnapshotPolicyEnabled')]" + }, + "changeFeedEnabled": { + "value": "[tryGet(parameters('blobServices'), 'changeFeedEnabled')]" + }, + "changeFeedRetentionInDays": { + "value": "[tryGet(parameters('blobServices'), 'changeFeedRetentionInDays')]" + }, + "containerDeleteRetentionPolicyEnabled": { + "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyEnabled')]" + }, + "containerDeleteRetentionPolicyDays": { + "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyDays')]" + }, + "containerDeleteRetentionPolicyAllowPermanentDelete": { + "value": "[tryGet(parameters('blobServices'), 'containerDeleteRetentionPolicyAllowPermanentDelete')]" + }, + "corsRules": { + "value": "[tryGet(parameters('blobServices'), 'corsRules')]" + }, + "defaultServiceVersion": { + "value": "[tryGet(parameters('blobServices'), 'defaultServiceVersion')]" + }, + "deleteRetentionPolicyAllowPermanentDelete": { + "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyAllowPermanentDelete')]" + }, + "deleteRetentionPolicyEnabled": { + "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyEnabled')]" + }, + "deleteRetentionPolicyDays": { + "value": "[tryGet(parameters('blobServices'), 'deleteRetentionPolicyDays')]" + }, + "isVersioningEnabled": { + "value": "[tryGet(parameters('blobServices'), 'isVersioningEnabled')]" + }, + "lastAccessTimeTrackingPolicyEnabled": { + "value": "[tryGet(parameters('blobServices'), 'lastAccessTimeTrackingPolicyEnabled')]" + }, + "restorePolicyEnabled": { + "value": "[tryGet(parameters('blobServices'), 'restorePolicyEnabled')]" + }, + "restorePolicyDays": { + "value": "[tryGet(parameters('blobServices'), 'restorePolicyDays')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('blobServices'), 'diagnosticSettings')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "2306287879023715578" + }, + "name": "Storage Account blob Services", + "description": "This module deploys a Storage Account Blob Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "automaticSnapshotPolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Automatic Snapshot is enabled if set to true." + } + }, + "changeFeedEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The blob service properties for change feed events. Indicates whether change feed event logging is enabled for the Blob service." + } + }, + "changeFeedRetentionInDays": { + "type": "int", + "nullable": true, + "minValue": 1, + "maxValue": 146000, + "metadata": { + "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed." + } + }, + "containerDeleteRetentionPolicyEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. The blob service properties for container soft delete. Indicates whether DeleteRetentionPolicy is enabled." + } + }, + "containerDeleteRetentionPolicyDays": { + "type": "int", + "nullable": true, + "minValue": 1, + "maxValue": 365, + "metadata": { + "description": "Optional. Indicates the number of days that the deleted item should be retained." + } + }, + "containerDeleteRetentionPolicyAllowPermanentDelete": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. This property when set to true allows deletion of the soft deleted blob versions and snapshots. This property cannot be used with blob restore policy. This property only applies to blob service and does not apply to containers or file share." + } + }, + "corsRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob service." + } + }, + "defaultServiceVersion": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Indicates the default version to use for requests to the Blob service if an incoming request's version is not specified. Possible values include version 2008-10-27 and all more recent versions." + } + }, + "deleteRetentionPolicyEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. The blob service properties for blob soft delete." + } + }, + "deleteRetentionPolicyDays": { + "type": "int", + "defaultValue": 7, + "minValue": 1, + "maxValue": 365, + "metadata": { + "description": "Optional. Indicates the number of days that the deleted blob should be retained." + } + }, + "deleteRetentionPolicyAllowPermanentDelete": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. This property when set to true allows deletion of the soft deleted blob versions and snapshots. This property cannot be used with blob restore policy. This property only applies to blob service and does not apply to containers or file share." + } + }, + "isVersioningEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Use versioning to automatically maintain previous versions of your blobs." + } + }, + "lastAccessTimeTrackingPolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The blob service property to configure last access time based tracking policy. When set to true last access time based tracking is enabled." + } + }, + "restorePolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The blob service properties for blob restore policy. If point-in-time restore is enabled, then versioning, change feed, and blob soft delete must also be enabled." + } + }, + "restorePolicyDays": { + "type": "int", + "defaultValue": 6, + "minValue": 1, + "metadata": { + "description": "Optional. How long this blob can be restored. It should be less than DeleteRetentionPolicy days." + } + }, + "containers": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Blob containers to create." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "name": "default" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "[parameters('storageAccountName')]" + }, + "blobServices": { + "type": "Microsoft.Storage/storageAccounts/blobServices", + "apiVersion": "2022-09-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", + "properties": { + "automaticSnapshotPolicyEnabled": "[parameters('automaticSnapshotPolicyEnabled')]", + "changeFeed": "[if(parameters('changeFeedEnabled'), createObject('enabled', true(), 'retentionInDays', parameters('changeFeedRetentionInDays')), null())]", + "containerDeleteRetentionPolicy": { + "enabled": "[parameters('containerDeleteRetentionPolicyEnabled')]", + "days": "[parameters('containerDeleteRetentionPolicyDays')]", + "allowPermanentDelete": "[if(equals(parameters('containerDeleteRetentionPolicyEnabled'), true()), parameters('containerDeleteRetentionPolicyAllowPermanentDelete'), null())]" + }, + "cors": { + "corsRules": "[parameters('corsRules')]" + }, + "defaultServiceVersion": "[if(not(empty(parameters('defaultServiceVersion'))), parameters('defaultServiceVersion'), null())]", + "deleteRetentionPolicy": { + "enabled": "[parameters('deleteRetentionPolicyEnabled')]", + "days": "[parameters('deleteRetentionPolicyDays')]", + "allowPermanentDelete": "[if(and(parameters('deleteRetentionPolicyEnabled'), parameters('deleteRetentionPolicyAllowPermanentDelete')), true(), null())]" + }, + "isVersioningEnabled": "[parameters('isVersioningEnabled')]", + "lastAccessTimeTrackingPolicy": "[if(not(equals(reference('storageAccount', '2022-09-01', 'full').kind, 'Storage')), createObject('enable', parameters('lastAccessTimeTrackingPolicyEnabled'), 'name', if(equals(parameters('lastAccessTimeTrackingPolicyEnabled'), true()), 'AccessTimeTracking', null()), 'trackingGranularityInDays', if(equals(parameters('lastAccessTimeTrackingPolicyEnabled'), true()), 1, null())), null())]", + "restorePolicy": "[if(parameters('restorePolicyEnabled'), createObject('enabled', true(), 'days', parameters('restorePolicyDays')), null())]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "blobServices_diagnosticSettings": { + "copy": { + "name": "blobServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', parameters('storageAccountName'), variables('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "blobServices" + ] + }, + "blobServices_container": { + "copy": { + "name": "blobServices_container", + "count": "[length(coalesce(parameters('containers'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Container-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "name": { + "value": "[coalesce(parameters('containers'), createArray())[copyIndex()].name]" + }, + "defaultEncryptionScope": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'defaultEncryptionScope')]" + }, + "denyEncryptionScopeOverride": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'denyEncryptionScopeOverride')]" + }, + "enableNfsV3AllSquash": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'enableNfsV3AllSquash')]" + }, + "enableNfsV3RootSquash": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'enableNfsV3RootSquash')]" + }, + "immutableStorageWithVersioningEnabled": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'immutableStorageWithVersioningEnabled')]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'metadata')]" + }, + "publicAccess": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'publicAccess')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "immutabilityPolicyProperties": { + "value": "[tryGet(coalesce(parameters('containers'), createArray())[copyIndex()], 'immutabilityPolicyProperties')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "7045309160947869799" + }, + "name": "Storage Account Blob Containers", + "description": "This module deploys a Storage Account Blob Container.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the storage container to deploy." + } + }, + "defaultEncryptionScope": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Default the container to use specified encryption scope for all writes." + } + }, + "denyEncryptionScopeOverride": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Block override of encryption scope from the container default." + } + }, + "enableNfsV3AllSquash": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable NFSv3 all squash on blob container." + } + }, + "enableNfsV3RootSquash": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable NFSv3 root squash on blob container." + } + }, + "immutableStorageWithVersioningEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. This is an immutable property, when set to true it enables object level immutability at the container level. The property is immutable and can only be set to true at the container creation time. Existing containers must undergo a migration process." + } + }, + "immutabilityPolicyName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. Name of the immutable policy." + } + }, + "immutabilityPolicyProperties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Configure immutability policy." + } + }, + "metadata": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. A name-value pair to associate with the container as metadata." + } + }, + "publicAccess": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "Container", + "Blob", + "None" + ], + "metadata": { + "description": "Optional. Specifies whether data in the container may be accessed publicly and the level of access." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", + "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]", + "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "storageAccount::blobServices": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/blobServices", + "apiVersion": "2022-09-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "[parameters('storageAccountName')]" + }, + "container": { + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2022-09-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "properties": { + "defaultEncryptionScope": "[if(not(empty(parameters('defaultEncryptionScope'))), parameters('defaultEncryptionScope'), null())]", + "denyEncryptionScopeOverride": "[if(equals(parameters('denyEncryptionScopeOverride'), true()), parameters('denyEncryptionScopeOverride'), null())]", + "enableNfsV3AllSquash": "[if(equals(parameters('enableNfsV3AllSquash'), true()), parameters('enableNfsV3AllSquash'), null())]", + "enableNfsV3RootSquash": "[if(equals(parameters('enableNfsV3RootSquash'), true()), parameters('enableNfsV3RootSquash'), null())]", + "immutableStorageWithVersioning": "[if(equals(parameters('immutableStorageWithVersioningEnabled'), true()), createObject('enabled', parameters('immutableStorageWithVersioningEnabled')), null())]", + "metadata": "[parameters('metadata')]", + "publicAccess": "[parameters('publicAccess')]" + }, + "dependsOn": [ + "storageAccount::blobServices" + ] + }, + "container_roleAssignments": { + "copy": { + "name": "container_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}/containers/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "container" + ] + }, + "immutabilityPolicy": { + "condition": "[not(empty(coalesce(parameters('immutabilityPolicyProperties'), createObject())))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[parameters('immutabilityPolicyName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "containerName": { + "value": "[parameters('name')]" + }, + "immutabilityPeriodSinceCreationInDays": { + "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'immutabilityPeriodSinceCreationInDays')]" + }, + "allowProtectedAppendWrites": { + "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'allowProtectedAppendWrites')]" + }, + "allowProtectedAppendWritesAll": { + "value": "[tryGet(parameters('immutabilityPolicyProperties'), 'allowProtectedAppendWritesAll')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "2543276032744560941" + }, + "name": "Storage Account Blob Container Immutability Policies", + "description": "This module deploys a Storage Account Blob Container Immutability Policy.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "containerName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent container to apply the policy to. Required if the template is used in a standalone deployment." + } + }, + "immutabilityPeriodSinceCreationInDays": { + "type": "int", + "defaultValue": 365, + "metadata": { + "description": "Optional. The immutability period for the blobs in the container since the policy creation, in days." + } + }, + "allowProtectedAppendWrites": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property can only be changed for unlocked time-based retention policies. When enabled, new blocks can be written to an append blob while maintaining immutability protection and compliance. Only new blocks can be added and any existing blocks cannot be modified or deleted. This property cannot be changed with ExtendImmutabilityPolicy API." + } + }, + "allowProtectedAppendWritesAll": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property can only be changed for unlocked time-based retention policies. When enabled, new blocks can be written to both \"Append and Block Blobs\" while maintaining immutability protection and compliance. Only new blocks can be added and any existing blocks cannot be modified or deleted. This property cannot be changed with ExtendImmutabilityPolicy API. The \"allowProtectedAppendWrites\" and \"allowProtectedAppendWritesAll\" properties are mutually exclusive." + } + } + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies", + "apiVersion": "2022-09-01", + "name": "[format('{0}/{1}/{2}/{3}', parameters('storageAccountName'), 'default', parameters('containerName'), 'default')]", + "properties": { + "immutabilityPeriodSinceCreationInDays": "[parameters('immutabilityPeriodSinceCreationInDays')]", + "allowProtectedAppendWrites": "[parameters('allowProtectedAppendWrites')]", + "allowProtectedAppendWritesAll": "[parameters('allowProtectedAppendWritesAll')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed immutability policy." + }, + "value": "default" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed immutability policy." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies', parameters('storageAccountName'), 'default', parameters('containerName'), 'default')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed immutability policy." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "container", + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed container." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed container." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed container." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed blob service." + }, + "value": "[variables('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed blob service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccountName'), variables('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the deployed blob service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_fileServices": { + "condition": "[not(empty(parameters('fileServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-FileServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('fileServices'), 'diagnosticSettings')]" + }, + "protocolSettings": { + "value": "[tryGet(parameters('fileServices'), 'protocolSettings')]" + }, + "shareDeleteRetentionPolicy": { + "value": "[tryGet(parameters('fileServices'), 'shareDeleteRetentionPolicy')]" + }, + "shares": { + "value": "[tryGet(parameters('fileServices'), 'shares')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "7463227074634701879" + }, + "name": "Storage Account File Share Services", + "description": "This module deploys a Storage Account File Share Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the file service." + } + }, + "protocolSettings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Protocol settings for file service." + } + }, + "shareDeleteRetentionPolicy": { + "type": "object", + "defaultValue": { + "enabled": true, + "days": 7 + }, + "metadata": { + "description": "Optional. The service properties for soft delete." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "shares": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. File shares to create." + } + } + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "fileServices": { + "type": "Microsoft.Storage/storageAccounts/fileServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", + "properties": { + "protocolSettings": "[parameters('protocolSettings')]", + "shareDeleteRetentionPolicy": "[parameters('shareDeleteRetentionPolicy')]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "fileServices_diagnosticSettings": { + "copy": { + "name": "fileServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/fileServices/{1}', parameters('storageAccountName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "fileServices" + ] + }, + "fileServices_shares": { + "copy": { + "name": "fileServices_shares", + "count": "[length(coalesce(parameters('shares'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-shares-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "fileServicesName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('shares'), createArray())[copyIndex()].name]" + }, + "accessTier": { + "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2023-04-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]" + }, + "enabledProtocols": { + "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'enabledProtocols')]" + }, + "rootSquash": { + "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'rootSquash')]" + }, + "shareQuota": { + "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'shareQuota')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "1342480740201032357" + }, + "name": "Storage Account File Shares", + "description": "This module deploys a Storage Account File Share.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "fileServicesName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Conditional. The name of the parent file service. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the file share to create." + } + }, + "accessTier": { + "type": "string", + "defaultValue": "TransactionOptimized", + "allowedValues": [ + "Premium", + "Hot", + "Cool", + "TransactionOptimized" + ], + "metadata": { + "description": "Conditional. Access tier for specific share. Required if the Storage Account kind is set to FileStorage (should be set to \"Premium\"). GpV2 account can choose between TransactionOptimized (default), Hot, and Cool." + } + }, + "shareQuota": { + "type": "int", + "defaultValue": 5120, + "metadata": { + "description": "Optional. The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5120 (5TB). For Large File Shares, the maximum size is 102400 (100TB)." + } + }, + "enabledProtocols": { + "type": "string", + "defaultValue": "SMB", + "allowedValues": [ + "NFS", + "SMB" + ], + "metadata": { + "description": "Optional. The authentication protocol that is used for the file share. Can only be specified when creating a share." + } + }, + "rootSquash": { + "type": "string", + "defaultValue": "NoRootSquash", + "allowedValues": [ + "AllSquash", + "NoRootSquash", + "RootSquash" + ], + "metadata": { + "description": "Optional. Permissions for NFS file shares are enforced by the client OS rather than the Azure Files service. Toggling the root squash behavior reduces the rights of the root user for NFS shares." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "resources": { + "storageAccount::fileService": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/fileServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]", + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "fileShare": { + "type": "Microsoft.Storage/storageAccounts/fileServices/shares", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]", + "properties": { + "accessTier": "[parameters('accessTier')]", + "shareQuota": "[parameters('shareQuota')]", + "rootSquash": "[if(equals(parameters('enabledProtocols'), 'NFS'), parameters('rootSquash'), null())]", + "enabledProtocols": "[parameters('enabledProtocols')]" + }, + "dependsOn": [ + "storageAccount::fileService" + ] + }, + "fileShare_roleAssignments": { + "condition": "[not(empty(parameters('roleAssignments')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Share-Rbac', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "fileShareResourceId": { + "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]" + }, + "roleAssignments": { + "value": "[parameters('roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "8779226603522513073" + } + }, + "parameters": { + "roleAssignments": { + "type": "array", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "fileShareResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the file share to assign the roles to." + } + } + }, + "variables": { + "$fxv#0": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "scope": { + "type": "string", + "metadata": { + "description": "Required. The scope to deploy the role assignment to." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the role assignment." + } + }, + "roleDefinitionId": { + "type": "string", + "metadata": { + "description": "Required. The role definition Id to assign." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User", + "" + ], + "defaultValue": "", + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "defaultValue": "2.0", + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[[parameters('scope')]", + "name": "[[parameters('name')]", + "properties": { + "roleDefinitionId": "[[parameters('roleDefinitionId')]", + "principalId": "[[parameters('principalId')]", + "description": "[[parameters('description')]", + "principalType": "[[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "condition": "[[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "delegatedManagedIdentityResourceId": "[[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" + } + } + ] + }, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]", + "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]", + "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": [ + { + "copy": { + "name": "fileShare_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('{0}-Share-Rbac-{1}', uniqueString(deployment().name), copyIndex())]", + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "Outer" + }, + "template": "[variables('$fxv#0')]", + "parameters": { + "scope": { + "value": "[replace(parameters('fileShareResourceId'), '/shares/', '/fileShares/')]" + }, + "name": { + "value": "[guid(parameters('fileShareResourceId'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, 'tyfa')]" + }, + "roleDefinitionId": { + "value": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]" + }, + "principalId": { + "value": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]" + }, + "principalType": { + "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]" + }, + "description": { + "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]" + }, + "condition": { + "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]" + }, + "conditionVersion": { + "value": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]" + }, + "delegatedManagedIdentityResourceId": { + "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + } + } + } + } + ] + } + }, + "dependsOn": [ + "fileShare" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('storageAccountName'), parameters('fileServicesName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "fileServices", + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('storageAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_queueServices": { + "condition": "[not(empty(parameters('queueServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-QueueServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('queueServices'), 'diagnosticSettings')]" + }, + "queues": { + "value": "[tryGet(parameters('queueServices'), 'queues')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "10678250016540336570" + }, + "name": "Storage Account Queue Services", + "description": "This module deploys a Storage Account Queue Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "queues": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Queues to create." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "name": "default" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "queueServices": { + "type": "Microsoft.Storage/storageAccounts/queueServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", + "properties": {}, + "dependsOn": [ + "storageAccount" + ] + }, + "queueServices_diagnosticSettings": { + "copy": { + "name": "queueServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "queueServices" + ] + }, + "queueServices_queues": { + "copy": { + "name": "queueServices_queues", + "count": "[length(coalesce(parameters('queues'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Queue-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "name": { + "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'metadata')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "13487964166280180730" + }, + "name": "Storage Account Queues", + "description": "This module deploys a Storage Account Queue.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the storage queue to deploy." + } + }, + "metadata": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Required. A name-value pair that represents queue metadata." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", + "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", + "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", + "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "storageAccount::queueServices": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/queueServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "queue": { + "type": "Microsoft.Storage/storageAccounts/queueServices/queues", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]" + }, + "dependsOn": [ + "storageAccount::queueServices" + ] + }, + "queue_roleAssignments": { + "copy": { + "name": "queue_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}/queues/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "queue" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed queue." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed queue." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed queue." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[variables('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccountName'), variables('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_tableServices": { + "condition": "[not(empty(parameters('tableServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-TableServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('tableServices'), 'diagnosticSettings')]" + }, + "tables": { + "value": "[tryGet(parameters('tableServices'), 'tables')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "16839054392438941735" + }, + "name": "Storage Account Table Services", + "description": "This module deploys a Storage Account Table Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "tables": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. tables to create." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "name": "default" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "tableServices": { + "type": "Microsoft.Storage/storageAccounts/tableServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", + "properties": {}, + "dependsOn": [ + "storageAccount" + ] + }, + "tableServices_diagnosticSettings": { + "copy": { + "name": "tableServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "tableServices" + ] + }, + "tableServices_tables": { + "copy": { + "name": "tableServices_tables", + "count": "[length(parameters('tables'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Table-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('tables')[copyIndex()].name]" + }, + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "roleAssignments": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "3177845984945141330" + }, + "name": "Storage Account Table", + "description": "This module deploys a Storage Account Table.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the table." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", + "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "storageAccount::tableServices": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/tableServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "table": { + "type": "Microsoft.Storage/storageAccounts/tableServices/tables", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "dependsOn": [ + "storageAccount::tableServices" + ] + }, + "table_roleAssignments": { + "copy": { + "name": "table_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}/tables/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "table" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed table service." + }, + "value": "[variables('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed table service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccountName'), variables('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed table service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed storage account." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed storage account." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed storage account." + }, + "value": "[resourceGroup().name]" + }, + "primaryBlobEndpoint": { + "type": "string", + "metadata": { + "description": "The primary blob endpoint reference if blob services are deployed." + }, + "value": "[if(and(not(empty(parameters('blobServices'))), contains(parameters('blobServices'), 'containers')), reference(format('Microsoft.Storage/storageAccounts/{0}', parameters('name')), '2019-04-01').primaryEndpoints.blob, '')]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('storageAccount', '2022-09-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('storageAccount', '2022-09-01', 'full').location]" + } + } + } + } + }, + "cognitiveServices": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cognitive', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('cognitiveServicesName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "kind": { + "value": "[parameters('cognitiveServicesKind')]" + }, + "customSubDomainName": { + "value": "[parameters('cognitiveServicesCustomSubDomainName')]" + }, + "publicNetworkAccess": { + "value": "[parameters('cognitiveServicesPublicNetworkAccess')]" + }, + "networkAcls": { + "value": "[parameters('cognitiveServicesNetworkAcls')]" + }, + "disableLocalAuth": { + "value": "[parameters('cognitiveServicesDisableLocalAuth')]" + }, + "sku": { + "value": "[parameters('cognitiveServicesSku')]" + }, + "deployments": { + "value": "[parameters('cognitiveServicesDeployments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "7976342392137470716" + }, + "name": "Cognitive Services", + "description": "This module deploys a Cognitive Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "deploymentsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of cognitive service account deployment." + } + }, + "model": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of Cognitive Services account deployment model." + } + }, + "format": { + "type": "string", + "metadata": { + "description": "Required. The format of Cognitive Services account deployment model." + } + }, + "version": { + "type": "string", + "metadata": { + "description": "Required. The version of Cognitive Services account deployment model." + } + } + }, + "metadata": { + "description": "Required. Properties of Cognitive Services account deployment model." + } + }, + "sku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource model definition representing SKU." + } + }, + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the resource model definition representing SKU." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource model definition representing SKU." + } + }, + "raiPolicyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of RAI policy." + } + } + } + }, + "nullable": true + }, + "endpointsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Type of the endpoint." + } + }, + "endpoint": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The endpoint URI." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of Cognitive Services account." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "AIServices", + "AnomalyDetector", + "CognitiveServices", + "ComputerVision", + "ContentModerator", + "ContentSafety", + "ConversationalLanguageUnderstanding", + "CustomVision.Prediction", + "CustomVision.Training", + "Face", + "FormRecognizer", + "HealthInsights", + "ImmersiveReader", + "Internal.AllInOne", + "LUIS", + "LUIS.Authoring", + "LanguageAuthoring", + "MetricsAdvisor", + "OpenAI", + "Personalizer", + "QnAMaker.v2", + "SpeechServices", + "TextAnalytics", + "TextTranslation" + ], + "metadata": { + "description": "Required. Kind of the Cognitive Services. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'SKU' for your Azure region." + } + }, + "sku": { + "type": "string", + "defaultValue": "S0", + "allowedValues": [ + "C2", + "C3", + "C4", + "F0", + "F1", + "S", + "S0", + "S1", + "S10", + "S2", + "S3", + "S4", + "S5", + "S6", + "S7", + "S8", + "S9" + ], + "metadata": { + "description": "Optional. SKU of the Cognitive Services resource. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'SKU' for your Azure region." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "publicNetworkAccess": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "customSubDomainName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. Subdomain name used for token-based authentication. Required if 'networkAcls' or 'privateEndpoints' are set." + } + }, + "networkAcls": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. A collection of rules governing the accessibility from specific network locations." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "allowedFqdnList": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. List of allowed FQDN." + } + }, + "apiProperties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The API properties for special APIs." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Allow only Azure AD authentication. Should be enabled for security reasons." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "dynamicThrottlingEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag to enable dynamic throttling." + } + }, + "migrationToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource migration token." + } + }, + "restore": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Restore a soft-deleted cognitive service at deployment time. Will fail if no such soft-deleted resource exists." + } + }, + "restrictOutboundNetworkAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Restrict outbound network access." + } + }, + "userOwnedStorage": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The storage accounts for this resource." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "deployments": { + "$ref": "#/definitions/deploymentsType", + "metadata": { + "description": "Optional. Array of deployments about cognitive service accounts to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned, UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Cognitive Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68')]", + "Cognitive Services Custom Vision Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c1ff6cc2-c111-46fe-8896-e0ef812ad9f3')]", + "Cognitive Services Custom Vision Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5c4089e1-6d96-4d2f-b296-c1bc7137275f')]", + "Cognitive Services Custom Vision Labeler": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '88424f51-ebe7-446f-bc41-7fa16989e96c')]", + "Cognitive Services Custom Vision Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '93586559-c37d-4a6b-ba08-b9f0940c2d73')]", + "Cognitive Services Custom Vision Trainer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a5ae4ab-0d65-4eeb-be61-29fc9b54394b')]", + "Cognitive Services Data Reader (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b59867f0-fa02-499b-be73-45a86b5b3e1c')]", + "Cognitive Services Face Recognizer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9894cab4-e18a-44aa-828b-cb588cd6f2d7')]", + "Cognitive Services Immersive Reader User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b2de6794-95db-4659-8781-7e080d3f2b9d')]", + "Cognitive Services Language Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f07febfe-79bc-46b1-8b37-790e26e6e498')]", + "Cognitive Services Language Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7628b7b8-a8b2-4cdc-b46f-e9b35248918e')]", + "Cognitive Services Language Writer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f2310ca1-dc64-4889-bb49-c8e0fa3d47a8')]", + "Cognitive Services LUIS Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f72c8140-2111-481c-87ff-72b910f6e3f8')]", + "Cognitive Services LUIS Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18e81cdc-4e98-4e29-a639-e7d10c5a6226')]", + "Cognitive Services LUIS Writer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6322a993-d5c9-4bed-b113-e49bbea25b27')]", + "Cognitive Services Metrics Advisor Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cb43c632-a144-4ec5-977c-e80c4affc34a')]", + "Cognitive Services Metrics Advisor User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3b20f47b-3825-43cb-8114-4bd2201156a8')]", + "Cognitive Services OpenAI Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a001fd3d-188f-4b5d-821b-7da978bf7442')]", + "Cognitive Services OpenAI User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd')]", + "Cognitive Services QnA Maker Editor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f4cc2bf9-21be-47a1-bdf1-5c5804381025')]", + "Cognitive Services QnA Maker Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '466ccd10-b268-4a11-b098-b4849f024126')]", + "Cognitive Services Speech Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0e75ca1e-0464-4b4d-8b93-68208a576181')]", + "Cognitive Services Speech User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f2dc8367-1007-4938-bd23-fe263f013447')]", + "Cognitive Services User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a97b65f3-24c7-4388-baec-2e87135dc908')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.cognitiveservices-account.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "cognitiveService": { + "type": "Microsoft.CognitiveServices/accounts", + "apiVersion": "2023-05-01", + "name": "[parameters('name')]", + "kind": "[parameters('kind')]", + "identity": "[variables('identity')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('sku')]" + }, + "properties": { + "customSubDomainName": "[parameters('customSubDomainName')]", + "networkAcls": "[if(not(empty(coalesce(parameters('networkAcls'), createObject()))), createObject('defaultAction', tryGet(parameters('networkAcls'), 'defaultAction'), 'virtualNetworkRules', coalesce(tryGet(parameters('networkAcls'), 'virtualNetworkRules'), createArray()), 'ipRules', coalesce(tryGet(parameters('networkAcls'), 'ipRules'), createArray())), null())]", + "publicNetworkAccess": "[if(not(equals(parameters('publicNetworkAccess'), null())), parameters('publicNetworkAccess'), if(not(empty(parameters('networkAcls'))), 'Enabled', 'Disabled'))]", + "allowedFqdnList": "[parameters('allowedFqdnList')]", + "apiProperties": "[parameters('apiProperties')]", + "disableLocalAuth": "[parameters('disableLocalAuth')]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createObject('identityClientId', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyVaultUri', reference('cMKKeyVault').vaultUri, 'keyName', parameters('customerManagedKey').keyName, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), null())]", + "migrationToken": "[parameters('migrationToken')]", + "restore": "[parameters('restore')]", + "restrictOutboundNetworkAccess": "[parameters('restrictOutboundNetworkAccess')]", + "userOwnedStorage": "[parameters('userOwnedStorage')]", + "dynamicThrottlingEnabled": "[parameters('dynamicThrottlingEnabled')]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "cognitiveService_deployments": { + "copy": { + "name": "cognitiveService_deployments", + "count": "[length(coalesce(parameters('deployments'), createArray()))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.CognitiveServices/accounts/deployments", + "apiVersion": "2023-05-01", + "name": "[format('{0}/{1}', parameters('name'), coalesce(tryGet(coalesce(parameters('deployments'), createArray())[copyIndex()], 'name'), format('{0}-deployments', parameters('name'))))]", + "properties": { + "model": "[coalesce(parameters('deployments'), createArray())[copyIndex()].model]", + "raiPolicyName": "[tryGet(coalesce(parameters('deployments'), createArray())[copyIndex()], 'raiPolicyName')]" + }, + "sku": "[coalesce(tryGet(coalesce(parameters('deployments'), createArray())[copyIndex()], 'sku'), createObject('name', parameters('sku')))]", + "dependsOn": [ + "cognitiveService" + ] + }, + "cognitiveService_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "cognitiveService" + ] + }, + "cognitiveService_diagnosticSettings": { + "copy": { + "name": "cognitiveService_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "cognitiveService" + ] + }, + "cognitiveService_roleAssignments": { + "copy": { + "name": "cognitiveService_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "cognitiveService" + ] + }, + "cognitiveService_privateEndpoints": { + "copy": { + "name": "cognitiveService_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cognitiveService-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'account'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'account'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'account')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'account'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'account')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "13720311665093076615" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "15263454436186512874" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + } + } + } + }, + "dependsOn": [ + "cognitiveService" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the cognitive services account." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the cognitive services account." + }, + "value": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the cognitive services account was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "endpoint": { + "type": "string", + "metadata": { + "description": "The service endpoint of the cognitive services account." + }, + "value": "[reference('cognitiveService').endpoint]" + }, + "endpoints": { + "$ref": "#/definitions/endpointsType", + "metadata": { + "description": "All endpoints available for the cognitive services account, types depends on the cognitive service kind." + }, + "value": "[reference('cognitiveService').endpoints]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('cognitiveService', '2023-05-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('cognitiveService', '2023-05-01', 'full').location]" + } + } + } + } + }, + "logAnalytics": { + "condition": "[not(empty(parameters('logAnalyticsName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-loganalytics', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('logAnalyticsName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "dataRetention": { + "value": "[parameters('dataRetention')]" + }, + "skuName": { + "value": "[parameters('logAnalyticsSkuName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "14441228139596902410" + }, + "name": "Log Analytics Workspaces", + "description": "This module deploys a Log Analytics Workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "useThisWorkspace": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Instead of using an external reference, use the deployed instance as the target for its diagnostic settings. If set to `true`, the `workspaceResourceId` property is ignored." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the Log Analytics workspace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "skuName": { + "type": "string", + "defaultValue": "PerGB2018", + "allowedValues": [ + "CapacityReservation", + "Free", + "LACluster", + "PerGB2018", + "PerNode", + "Premium", + "Standalone", + "Standard" + ], + "metadata": { + "description": "Optional. The name of the SKU." + } + }, + "skuCapacityReservationLevel": { + "type": "int", + "defaultValue": 100, + "minValue": 100, + "maxValue": 5000, + "metadata": { + "description": "Optional. The capacity reservation level in GB for this workspace, when CapacityReservation sku is selected. Must be in increments of 100 between 100 and 5000." + } + }, + "storageInsightsConfigs": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of storage accounts to be read by the workspace." + } + }, + "linkedServices": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of services to be linked." + } + }, + "linkedStorageAccounts": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Conditional. List of Storage Accounts to be linked. Required if 'forceCmkForQuery' is set to 'true' and 'savedSearches' is not empty." + } + }, + "savedSearches": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Kusto Query Language searches to save." + } + }, + "dataExports": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. LAW data export instances to be deployed." + } + }, + "dataSources": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. LAW data sources to configure." + } + }, + "tables": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. LAW custom tables to be deployed." + } + }, + "gallerySolutions": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of gallerySolutions to be created in the log analytics workspace." + } + }, + "dataRetention": { + "type": "int", + "defaultValue": 365, + "minValue": 0, + "maxValue": 730, + "metadata": { + "description": "Optional. Number of days data will be retained for." + } + }, + "dailyQuotaGb": { + "type": "int", + "defaultValue": -1, + "minValue": -1, + "metadata": { + "description": "Optional. The workspace daily quota for ingestion." + } + }, + "publicNetworkAccessForIngestion": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. The network access type for accessing Log Analytics ingestion." + } + }, + "publicNetworkAccessForQuery": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. The network access type for accessing Log Analytics query." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both." + } + }, + "useResourcePermissions": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "forceCmkForQuery": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether customer managed storage is mandatory for query management." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), 'SystemAssigned', if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Security Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb1c8493-542b-48eb-b624-b4c8fea62acd')]", + "Security Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '39bc4728-0917-49c7-9d2c-d95423bc2eb4')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.operationalinsights-workspace.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "logAnalyticsWorkspace": { + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "features": { + "searchVersion": 1, + "enableLogAccessUsingOnlyResourcePermissions": "[parameters('useResourcePermissions')]" + }, + "sku": { + "name": "[parameters('skuName')]", + "capacityReservationLevel": "[if(equals(parameters('skuName'), 'CapacityReservation'), parameters('skuCapacityReservationLevel'), null())]" + }, + "retentionInDays": "[parameters('dataRetention')]", + "workspaceCapping": { + "dailyQuotaGb": "[parameters('dailyQuotaGb')]" + }, + "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", + "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]", + "forceCmkForQuery": "[parameters('forceCmkForQuery')]" + }, + "identity": "[variables('identity')]" + }, + "logAnalyticsWorkspace_diagnosticSettings": { + "copy": { + "name": "logAnalyticsWorkspace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[if(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'useThisWorkspace'), false()), resourceId('Microsoft.OperationalInsights/workspaces', parameters('name')), tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId'))]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_roleAssignments": { + "copy": { + "name": "logAnalyticsWorkspace_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.OperationalInsights/workspaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_storageInsightConfigs": { + "copy": { + "name": "logAnalyticsWorkspace_storageInsightConfigs", + "count": "[length(parameters('storageInsightsConfigs'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-StorageInsightsConfig-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "containers": { + "value": "[tryGet(parameters('storageInsightsConfigs')[copyIndex()], 'containers')]" + }, + "tables": { + "value": "[tryGet(parameters('storageInsightsConfigs')[copyIndex()], 'tables')]" + }, + "storageAccountResourceId": { + "value": "[parameters('storageInsightsConfigs')[copyIndex()].storageAccountResourceId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "1745671120474305926" + }, + "name": "Log Analytics Workspace Storage Insight Configs", + "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[format('{0}-stinsconfig', last(split(parameters('storageAccountResourceId'), '/')))]", + "metadata": { + "description": "Optional. The name of the storage insights config." + } + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. The Azure Resource Manager ID of the storage account resource." + } + }, + "containers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The names of the blob containers that the workspace should read." + } + }, + "tables": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The names of the Azure tables that the workspace should read." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to configure in the resource." + } + } + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "[last(split(parameters('storageAccountResourceId'), '/'))]" + }, + "workspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "storageinsightconfig": { + "type": "Microsoft.OperationalInsights/workspaces/storageInsightConfigs", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "containers": "[parameters('containers')]", + "tables": "[parameters('tables')]", + "storageAccount": { + "id": "[parameters('storageAccountResourceId')]", + "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2022-09-01').keys[0].value]" + } + }, + "dependsOn": [ + "storageAccount", + "workspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed storage insights configuration." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/storageInsightConfigs', parameters('logAnalyticsWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the storage insight configuration is deployed." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the storage insights configuration." + }, + "value": "[parameters('name')]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_linkedServices": { + "copy": { + "name": "logAnalyticsWorkspace_linkedServices", + "count": "[length(parameters('linkedServices'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-LinkedService-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('linkedServices')[copyIndex()].name]" + }, + "resourceId": { + "value": "[tryGet(parameters('linkedServices')[copyIndex()], 'resourceId')]" + }, + "writeAccessResourceId": { + "value": "[tryGet(parameters('linkedServices')[copyIndex()], 'writeAccessResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "12032441371027552374" + }, + "name": "Log Analytics Workspace Linked Services", + "description": "This module deploys a Log Analytics Workspace Linked Service.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the link." + } + }, + "resourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Required. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require read access." + } + }, + "writeAccessResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require write access." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to configure in the resource." + } + } + }, + "resources": { + "workspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "linkedService": { + "type": "Microsoft.OperationalInsights/workspaces/linkedServices", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "resourceId": "[parameters('resourceId')]", + "writeAccessResourceId": "[if(empty(parameters('writeAccessResourceId')), null(), parameters('writeAccessResourceId'))]" + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed linked service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed linked service." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/linkedServices', parameters('logAnalyticsWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the linked service is deployed." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_linkedStorageAccounts": { + "copy": { + "name": "logAnalyticsWorkspace_linkedStorageAccounts", + "count": "[length(parameters('linkedStorageAccounts'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-LinkedStorageAccount-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('linkedStorageAccounts')[copyIndex()].name]" + }, + "resourceId": { + "value": "[parameters('linkedStorageAccounts')[copyIndex()].resourceId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "12623216644328477682" + }, + "name": "Log Analytics Workspace Linked Storage Accounts", + "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "allowedValues": [ + "Query", + "Alerts", + "CustomLogs", + "AzureWatson" + ], + "metadata": { + "description": "Required. Name of the link." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require read access." + } + } + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/linkedStorageAccounts", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", + "properties": { + "storageAccountIds": [ + "[parameters('resourceId')]" + ] + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed linked storage account." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed linked storage account." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/linkedStorageAccounts', parameters('logAnalyticsWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the linked storage account is deployed." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_savedSearches": { + "copy": { + "name": "logAnalyticsWorkspace_savedSearches", + "count": "[length(parameters('savedSearches'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-SavedSearch-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[format('{0}{1}', parameters('savedSearches')[copyIndex()].name, uniqueString(deployment().name))]" + }, + "etag": { + "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'etag')]" + }, + "displayName": { + "value": "[parameters('savedSearches')[copyIndex()].displayName]" + }, + "category": { + "value": "[parameters('savedSearches')[copyIndex()].category]" + }, + "query": { + "value": "[parameters('savedSearches')[copyIndex()].query]" + }, + "functionAlias": { + "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'functionAlias')]" + }, + "functionParameters": { + "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'functionParameters')]" + }, + "version": { + "value": "[tryGet(parameters('savedSearches')[copyIndex()], 'version')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "7683333179440464721" + }, + "name": "Log Analytics Workspace Saved Searches", + "description": "This module deploys a Log Analytics Workspace Saved Search.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the saved search." + } + }, + "displayName": { + "type": "string", + "metadata": { + "description": "Required. Display name for the search." + } + }, + "category": { + "type": "string", + "metadata": { + "description": "Required. Query category." + } + }, + "query": { + "type": "string", + "metadata": { + "description": "Required. Kusto Query to be stored." + } + }, + "tags": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Tags to configure in the resource." + } + }, + "functionAlias": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The function alias if query serves as a function." + } + }, + "functionParameters": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The optional function parameters if query serves as a function. Value should be in the following format: \"param-name1:type1 = default_value1, param-name2:type2 = default_value2\". For more examples and proper syntax please refer to /azure/kusto/query/functions/user-defined-functions." + } + }, + "version": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The version number of the query language." + } + }, + "etag": { + "type": "string", + "defaultValue": "*", + "metadata": { + "description": "Optional. The ETag of the saved search. To override an existing saved search, use \"*\" or specify the current Etag." + } + } + }, + "resources": { + "workspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "savedSearch": { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", + "properties": { + "etag": "[parameters('etag')]", + "tags": "[coalesce(parameters('tags'), createArray())]", + "displayName": "[parameters('displayName')]", + "category": "[parameters('category')]", + "query": "[parameters('query')]", + "functionAlias": "[parameters('functionAlias')]", + "functionParameters": "[parameters('functionParameters')]", + "version": "[parameters('version')]" + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed saved search." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('logAnalyticsWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the saved search is deployed." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed saved search." + }, + "value": "[parameters('name')]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace", + "logAnalyticsWorkspace_linkedStorageAccounts" + ] + }, + "logAnalyticsWorkspace_dataExports": { + "copy": { + "name": "logAnalyticsWorkspace_dataExports", + "count": "[length(parameters('dataExports'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-DataExport-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('dataExports')[copyIndex()].name]" + }, + "destination": { + "value": "[tryGet(parameters('dataExports')[copyIndex()], 'destination')]" + }, + "enable": { + "value": "[tryGet(parameters('dataExports')[copyIndex()], 'enable')]" + }, + "tableNames": { + "value": "[tryGet(parameters('dataExports')[copyIndex()], 'tableNames')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "5765609820817623497" + }, + "name": "Log Analytics Workspace Data Exports", + "description": "This module deploys a Log Analytics Workspace Data Export.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "minLength": 4, + "maxLength": 63, + "metadata": { + "description": "Required. The data export rule name." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent workspaces. Required if the template is used in a standalone deployment." + } + }, + "destination": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Destination properties." + } + }, + "enable": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Active when enabled." + } + }, + "tableNames": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An array of tables to export, for example: ['Heartbeat', 'SecurityEvent']." + } + } + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/dataExports", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "destination": "[parameters('destination')]", + "enable": "[parameters('enable')]", + "tableNames": "[parameters('tableNames')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the data export." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the data export." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/dataExports', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the data export was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_dataSources": { + "copy": { + "name": "logAnalyticsWorkspace_dataSources", + "count": "[length(parameters('dataSources'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-DataSource-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('dataSources')[copyIndex()].name]" + }, + "kind": { + "value": "[parameters('dataSources')[copyIndex()].kind]" + }, + "linkedResourceId": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'linkedResourceId')]" + }, + "eventLogName": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'eventLogName')]" + }, + "eventTypes": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'eventTypes')]" + }, + "objectName": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'objectName')]" + }, + "instanceName": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'instanceName')]" + }, + "intervalSeconds": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'intervalSeconds')]" + }, + "counterName": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'counterName')]" + }, + "state": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'state')]" + }, + "syslogName": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'syslogName')]" + }, + "syslogSeverities": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'syslogSeverities')]" + }, + "performanceCounters": { + "value": "[tryGet(parameters('dataSources')[copyIndex()], 'performanceCounters')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "13460038983765020046" + }, + "name": "Log Analytics Workspace Datasources", + "description": "This module deploys a Log Analytics Workspace Data Source.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Log Analytics workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the solution." + } + }, + "kind": { + "type": "string", + "defaultValue": "AzureActivityLog", + "allowedValues": [ + "AzureActivityLog", + "WindowsEvent", + "WindowsPerformanceCounter", + "IISLogs", + "LinuxSyslog", + "LinuxSyslogCollection", + "LinuxPerformanceObject", + "LinuxPerformanceCollection" + ], + "metadata": { + "description": "Required. The kind of the DataSource." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to configure in the resource." + } + }, + "linkedResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the resource to be linked." + } + }, + "eventLogName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Windows event log name to configure when kind is WindowsEvent." + } + }, + "eventTypes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Windows event types to configure when kind is WindowsEvent." + } + }, + "objectName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the object to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject." + } + }, + "instanceName": { + "type": "string", + "defaultValue": "*", + "metadata": { + "description": "Optional. Name of the instance to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject." + } + }, + "intervalSeconds": { + "type": "int", + "defaultValue": 60, + "metadata": { + "description": "Optional. Interval in seconds to configure when kind is WindowsPerformanceCounter or LinuxPerformanceObject." + } + }, + "performanceCounters": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of counters to configure when the kind is LinuxPerformanceObject." + } + }, + "counterName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Counter name to configure when kind is WindowsPerformanceCounter." + } + }, + "state": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. State to configure when kind is IISLogs or LinuxSyslogCollection or LinuxPerformanceCollection." + } + }, + "syslogName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. System log to configure when kind is LinuxSyslog." + } + }, + "syslogSeverities": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Severities to configure when kind is LinuxSyslog." + } + } + }, + "resources": { + "workspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "dataSource": { + "type": "Microsoft.OperationalInsights/workspaces/dataSources", + "apiVersion": "2020-08-01", + "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", + "kind": "[parameters('kind')]", + "tags": "[parameters('tags')]", + "properties": { + "linkedResourceId": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'AzureActivityLog')), parameters('linkedResourceId'), null())]", + "eventLogName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsEvent')), parameters('eventLogName'), null())]", + "eventTypes": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsEvent')), parameters('eventTypes'), null())]", + "objectName": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('objectName'), null())]", + "instanceName": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('instanceName'), null())]", + "intervalSeconds": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'WindowsPerformanceCounter'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('intervalSeconds'), null())]", + "counterName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'WindowsPerformanceCounter')), parameters('counterName'), null())]", + "state": "[if(and(not(empty(parameters('kind'))), or(or(equals(parameters('kind'), 'IISLogs'), equals(parameters('kind'), 'LinuxSyslogCollection')), equals(parameters('kind'), 'LinuxPerformanceCollection'))), parameters('state'), null())]", + "syslogName": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'LinuxSyslog')), parameters('syslogName'), null())]", + "syslogSeverities": "[if(and(not(empty(parameters('kind'))), or(equals(parameters('kind'), 'LinuxSyslog'), equals(parameters('kind'), 'LinuxPerformanceObject'))), parameters('syslogSeverities'), null())]", + "performanceCounters": "[if(and(not(empty(parameters('kind'))), equals(parameters('kind'), 'LinuxPerformanceObject')), parameters('performanceCounters'), null())]" + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed data source." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/dataSources', parameters('logAnalyticsWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the data source is deployed." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed data source." + }, + "value": "[parameters('name')]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_tables": { + "copy": { + "name": "logAnalyticsWorkspace_tables", + "count": "[length(parameters('tables'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-Table-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('tables')[copyIndex()].name]" + }, + "plan": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'plan')]" + }, + "schema": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'schema')]" + }, + "retentionInDays": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'retentionInDays')]" + }, + "totalRetentionInDays": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'totalRetentionInDays')]" + }, + "restoredLogs": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'restoredLogs')]" + }, + "searchResults": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'searchResults')]" + }, + "roleAssignments": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "6905244456918791391" + }, + "name": "Log Analytics Workspace Tables", + "description": "This module deploys a Log Analytics Workspace Table.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the table." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent workspaces. Required if the template is used in a standalone deployment." + } + }, + "plan": { + "type": "string", + "defaultValue": "Analytics", + "allowedValues": [ + "Basic", + "Analytics" + ], + "metadata": { + "description": "Optional. Instruct the system how to handle and charge the logs ingested to this table." + } + }, + "restoredLogs": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Restore parameters." + } + }, + "retentionInDays": { + "type": "int", + "defaultValue": -1, + "minValue": -1, + "maxValue": 730, + "metadata": { + "description": "Optional. The table retention in days, between 4 and 730. Setting this property to -1 will default to the workspace retention." + } + }, + "schema": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Table's schema." + } + }, + "searchResults": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Parameters of the search job that initiated this table." + } + }, + "totalRetentionInDays": { + "type": "int", + "defaultValue": -1, + "minValue": -1, + "maxValue": 2555, + "metadata": { + "description": "Optional. The table total retention in days, between 4 and 2555. Setting this property to -1 will default to table retention." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "workspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('workspaceName')]" + }, + "table": { + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "plan": "[parameters('plan')]", + "restoredLogs": "[parameters('restoredLogs')]", + "retentionInDays": "[parameters('retentionInDays')]", + "schema": "[parameters('schema')]", + "searchResults": "[parameters('searchResults')]", + "totalRetentionInDays": "[parameters('totalRetentionInDays')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "table_roleAssignments": { + "copy": { + "name": "table_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}/tables/{1}', parameters('workspaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "table" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the table." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the table." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the table was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, + "logAnalyticsWorkspace_solutions": { + "copy": { + "name": "logAnalyticsWorkspace_solutions", + "count": "[length(parameters('gallerySolutions'))]" + }, + "condition": "[not(empty(parameters('gallerySolutions')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-LAW-Solution-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('gallerySolutions')[copyIndex()].name]" + }, + "location": { + "value": "[parameters('location')]" + }, + "logAnalyticsWorkspaceName": { + "value": "[parameters('name')]" + }, + "product": { + "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'product')]" + }, + "publisher": { + "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'publisher')]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(parameters('gallerySolutions')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18444780972506374592" + }, + "name": "Operations Management Solutions", + "description": "This module deploys an Operations Management Solution.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`." + } + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Required. Name of the Log Analytics workspace where the solution will be deployed/enabled." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "product": { + "type": "string", + "defaultValue": "OMSGallery", + "metadata": { + "description": "Optional. The product of the deployed solution. For Microsoft published gallery solution it should be `OMSGallery` and the target solution resource product will be composed as `OMSGallery/{name}`. For third party solution, it can be anything. This is case sensitive." + } + }, + "publisher": { + "type": "string", + "defaultValue": "Microsoft", + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "solutionName": "[if(equals(parameters('publisher'), 'Microsoft'), format('{0}({1})', parameters('name'), parameters('logAnalyticsWorkspaceName')), parameters('name'))]", + "solutionProduct": "[if(equals(parameters('publisher'), 'Microsoft'), format('OMSGallery/{0}', parameters('name')), parameters('product'))]" + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + { + "type": "Microsoft.OperationsManagement/solutions", + "apiVersion": "2015-11-01-preview", + "name": "[variables('solutionName')]", + "location": "[parameters('location')]", + "properties": { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" + }, + "plan": { + "name": "[variables('solutionName')]", + "promotionCode": "", + "product": "[variables('solutionProduct')]", + "publisher": "[parameters('publisher')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed solution." + }, + "value": "[variables('solutionName')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed solution." + }, + "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the solution is deployed." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + } + } + } + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed log analytics workspace." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed log analytics workspace." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed log analytics workspace." + }, + "value": "[parameters('name')]" + }, + "logAnalyticsWorkspaceId": { + "type": "string", + "metadata": { + "description": "The ID associated with the workspace." + }, + "value": "[reference('logAnalyticsWorkspace').customerId]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('logAnalyticsWorkspace', '2022-10-01', 'full').location]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('logAnalyticsWorkspace', '2022-10-01', 'full'), 'identity'), 'principalId'), '')]" + } + } + } + } + }, + "applicationInsights": { + "condition": "[and(not(empty(parameters('applicationInsightsName'))), not(empty(parameters('logAnalyticsName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-insights', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "name": { + "value": "[parameters('applicationInsightsName')]" + }, + "dashboardName": { + "value": "[parameters('applicationInsightsDashboardName')]" + }, + "logAnalyticsWorkspaceResourceId": "[if(not(empty(parameters('logAnalyticsName'))), createObject('value', reference('logAnalytics').outputs.resourceId.value), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "17156187352453961206" + }, + "name": "Application Insights Components", + "description": "Creates an Application Insights instance based on an existing Log Analytics workspace.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The resource insights components name." + } + }, + "dashboardName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource portal dashboards name." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the loganalytics workspace." + } + }, + "kind": { + "type": "string", + "defaultValue": "web", + "metadata": { + "description": "Optional. The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone." + } + }, + "applicationType": { + "type": "string", + "defaultValue": "web", + "allowedValues": [ + "web", + "other" + ], + "metadata": { + "description": "Optional. Application type." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ", + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.ptn.azd-insightsdashboard.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "applicationInsights": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-appinsights', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "kind": { + "value": "[parameters('kind')]" + }, + "applicationType": { + "value": "[parameters('applicationType')]" + }, + "workspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "10653241142071426932" + }, + "name": "Application Insights", + "description": "This component deploys an Application Insights instance.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the Application Insights." + } + }, + "applicationType": { + "type": "string", + "defaultValue": "web", + "allowedValues": [ + "web", + "other" + ], + "metadata": { + "description": "Optional. Application type." + } + }, + "workspaceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the log analytics workspace which the data will be ingested to. This property is required to create an application with this API version. Applications from older versions will not have this property." + } + }, + "disableIpMasking": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Disable IP masking. Default value is set to true." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Disable Non-AAD based Auth. Default value is set to false." + } + }, + "forceCustomerStorageForProfiler": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Force users to create their own storage account for profiler and debugger." + } + }, + "linkedStorageAccountResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Linked storage account resource ID." + } + }, + "publicNetworkAccessForIngestion": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled." + } + }, + "publicNetworkAccessForQuery": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. The network access type for accessing Application Insights query. - Enabled or Disabled." + } + }, + "retentionInDays": { + "type": "int", + "defaultValue": 365, + "allowedValues": [ + 30, + 60, + 90, + 120, + 180, + 270, + 365, + 550, + 730 + ], + "metadata": { + "description": "Optional. Retention period in days." + } + }, + "samplingPercentage": { + "type": "int", + "defaultValue": 100, + "minValue": 0, + "maxValue": 100, + "metadata": { + "description": "Optional. Percentage of the data produced by the application being monitored that is being sampled for Application Insights telemetry." + } + }, + "kind": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Application Insights Component Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ae349356-3a1b-4a5e-921d-050484c6347e')]", + "Application Insights Snapshot Debugger": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '08954f03-6346-4c2e-81c0-ec3a5cfae23b')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.insights-component.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "appInsights": { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "kind": "[parameters('kind')]", + "properties": { + "Application_Type": "[parameters('applicationType')]", + "DisableIpMasking": "[parameters('disableIpMasking')]", + "DisableLocalAuth": "[parameters('disableLocalAuth')]", + "ForceCustomerStorageForProfiler": "[parameters('forceCustomerStorageForProfiler')]", + "WorkspaceResourceId": "[parameters('workspaceResourceId')]", + "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", + "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]", + "RetentionInDays": "[parameters('retentionInDays')]", + "SamplingPercentage": "[parameters('samplingPercentage')]" + } + }, + "appInsights_roleAssignments": { + "copy": { + "name": "appInsights_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Insights/components/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Insights/components', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "appInsights" + ] + }, + "appInsights_diagnosticSettings": { + "copy": { + "name": "appInsights_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Insights/components/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "appInsights" + ] + }, + "linkedStorageAccount": { + "condition": "[not(empty(parameters('linkedStorageAccountResourceId')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-appInsights-linkedStorageAccount', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "appInsightsName": { + "value": "[parameters('name')]" + }, + "storageAccountResourceId": { + "value": "[parameters('linkedStorageAccountResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "216781367921725873" + }, + "name": "Application Insights Linked Storage Account", + "description": "This component deploys an Application Insights Linked Storage Account.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "appInsightsName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Application Insights instance. Required if the template is used in a standalone deployment." + } + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. Linked storage account resource ID." + } + } + }, + "resources": [ + { + "type": "microsoft.insights/components/linkedStorageAccounts", + "apiVersion": "2020-03-01-preview", + "name": "[format('{0}/{1}', parameters('appInsightsName'), 'ServiceProfiler')]", + "properties": { + "linkedStorageAccount": "[parameters('storageAccountResourceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Linked Storage Account." + }, + "value": "ServiceProfiler" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Linked Storage Account." + }, + "value": "[resourceId('microsoft.insights/components/linkedStorageAccounts', parameters('appInsightsName'), 'ServiceProfiler')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the agent pool was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "appInsights" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the application insights component." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the application insights component." + }, + "value": "[resourceId('Microsoft.Insights/components', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the application insights component was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "applicationId": { + "type": "string", + "metadata": { + "description": "The application ID of the application insights component." + }, + "value": "[reference('appInsights').AppId]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('appInsights', '2020-02-02', 'full').location]" + }, + "instrumentationKey": { + "type": "string", + "metadata": { + "description": "Application Insights Instrumentation key. A read-only value that applications can use to identify the destination for all telemetry sent to Azure Application Insights. This value will be supplied upon construction of each new Application Insights component." + }, + "value": "[reference('appInsights').InstrumentationKey]" + }, + "connectionString": { + "type": "string", + "metadata": { + "description": "Application Insights Connection String." + }, + "value": "[reference('appInsights').ConnectionString]" + } + } + } + } + }, + "applicationInsightsDashboard": { + "condition": "[not(empty(parameters('dashboardName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "application-insights-dashboard", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('dashboardName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "applicationInsightsName": { + "value": "[reference('applicationInsights').outputs.name.value]" + }, + "applicationInsightsResourceId": { + "value": "[reference('applicationInsights').outputs.resourceId.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "9856731218551847403" + }, + "name": "Azure Portal Dashboard", + "description": "Creates a dashboard for an Application Insights instance.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The portal dashboard name." + } + }, + "applicationInsightsName": { + "type": "string", + "metadata": { + "description": "Required. The resource insights components name." + } + }, + "applicationInsightsResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource insights components ID." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ", + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "dashboard": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "dashboard-deployment", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "lenses": { + "value": [ + { + "order": 0, + "parts": [ + { + "position": { + "x": 0, + "y": 0, + "colSpan": 2, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "id", + "value": "[parameters('applicationInsightsResourceId')]" + }, + { + "name": "Version", + "value": "1.0" + } + ], + "type": "Extension/AppInsightsExtension/PartType/AspNetOverviewPinnedPart", + "asset": { + "idInputName": "id", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "overview" + } + }, + { + "position": { + "x": 2, + "y": 0, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "Version", + "value": "1.0" + } + ], + "type": "Extension/AppInsightsExtension/PartType/ProactiveDetectionAsyncPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "ProactiveDetection" + } + }, + { + "position": { + "x": 3, + "y": 0, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "ResourceId", + "value": "[parameters('applicationInsightsResourceId')]" + } + ], + "type": "Extension/AppInsightsExtension/PartType/QuickPulseButtonSmallPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } + } + }, + { + "position": { + "x": 4, + "y": 0, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "endTime": null, + "createdTime": "2018-05-04T01:20:33.345Z", + "isInitialTime": true, + "grain": 1, + "useDashboardTimeRange": false + } + }, + { + "name": "Version", + "value": "1.0" + } + ], + "type": "Extension/AppInsightsExtension/PartType/AvailabilityNavButtonPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } + } + }, + { + "position": { + "x": 5, + "y": 0, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "endTime": null, + "createdTime": "2018-05-08T18:47:35.237Z", + "isInitialTime": true, + "grain": 1, + "useDashboardTimeRange": false + } + }, + { + "name": "ConfigurationId", + "value": "78ce933e-e864-4b05-a27b-71fd55a6afad" + } + ], + "type": "Extension/AppInsightsExtension/PartType/AppMapButtonPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } + } + }, + { + "position": { + "x": 0, + "y": 1, + "colSpan": 3, + "rowSpan": 1 + }, + "metadata": { + "inputs": [], + "type": "Extension/HubsExtension/PartType/MarkdownPart", + "settings": { + "content": { + "settings": { + "content": "# Usage", + "title": "", + "subtitle": "" + } + } + } + } + }, + { + "position": { + "x": 3, + "y": 1, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "endTime": null, + "createdTime": "2018-05-04T01:22:35.782Z", + "isInitialTime": true, + "grain": 1, + "useDashboardTimeRange": false + } + } + ], + "type": "Extension/AppInsightsExtension/PartType/UsageUsersOverviewPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } + } + }, + { + "position": { + "x": 4, + "y": 1, + "colSpan": 3, + "rowSpan": 1 + }, + "metadata": { + "inputs": [], + "type": "Extension/HubsExtension/PartType/MarkdownPart", + "settings": { + "content": { + "settings": { + "content": "# Reliability", + "title": "", + "subtitle": "" + } + } + } + } + }, + { + "position": { + "x": 7, + "y": 1, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ResourceId", + "value": "[parameters('applicationInsightsResourceId')]" + }, + { + "name": "DataModel", + "value": { + "version": "1.0.0", + "timeContext": { + "durationMs": 86400000, + "createdTime": "2018-05-04T23:42:40.072Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + } + }, + "isOptional": true + }, + { + "name": "ConfigurationId", + "value": "8a02f7bf-ac0f-40e1-afe9-f0e72cfee77f", + "isOptional": true + } + ], + "type": "Extension/AppInsightsExtension/PartType/CuratedBladeFailuresPinnedPart", + "isAdapter": true, + "asset": { + "idInputName": "ResourceId", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "failures" + } + }, + { + "position": { + "x": 8, + "y": 1, + "colSpan": 3, + "rowSpan": 1 + }, + "metadata": { + "inputs": [], + "type": "Extension/HubsExtension/PartType/MarkdownPart", + "settings": { + "content": { + "settings": { + "content": "# Responsiveness\r\n", + "title": "", + "subtitle": "" + } + } + } + } + }, + { + "position": { + "x": 11, + "y": 1, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ResourceId", + "value": "[parameters('applicationInsightsResourceId')]" + }, + { + "name": "DataModel", + "value": { + "version": "1.0.0", + "timeContext": { + "durationMs": 86400000, + "createdTime": "2018-05-04T23:43:37.804Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + } + }, + "isOptional": true + }, + { + "name": "ConfigurationId", + "value": "2a8ede4f-2bee-4b9c-aed9-2db0e8a01865", + "isOptional": true + } + ], + "type": "Extension/AppInsightsExtension/PartType/CuratedBladePerformancePinnedPart", + "isAdapter": true, + "asset": { + "idInputName": "ResourceId", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "performance" + } + }, + { + "position": { + "x": 12, + "y": 1, + "colSpan": 3, + "rowSpan": 1 + }, + "metadata": { + "inputs": [], + "type": "Extension/HubsExtension/PartType/MarkdownPart", + "settings": { + "content": { + "settings": { + "content": "# Browser", + "title": "", + "subtitle": "" + } + } + } + } + }, + { + "position": { + "x": 15, + "y": 1, + "colSpan": 1, + "rowSpan": 1 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "MetricsExplorerJsonDefinitionId", + "value": "BrowserPerformanceTimelineMetrics" + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "createdTime": "2018-05-08T12:16:27.534Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + } + }, + { + "name": "CurrentFilter", + "value": { + "eventTypes": [ + 4, + 1, + 3, + 5, + 2, + 6, + 13 + ], + "typeFacets": {}, + "isPermissive": false + } + }, + { + "name": "id", + "value": { + "Name": "[parameters('applicationInsightsName')]", + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]" + } + }, + { + "name": "Version", + "value": "1.0" + } + ], + "type": "Extension/AppInsightsExtension/PartType/MetricsExplorerBladePinnedPart", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "browser" + } + }, + { + "position": { + "x": 0, + "y": 2, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "sessions/count", + "aggregationType": 5, + "namespace": "microsoft.insights/components/kusto", + "metricVisualization": { + "displayName": "Sessions", + "color": "#47BDF5" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "users/count", + "aggregationType": 5, + "namespace": "microsoft.insights/components/kusto", + "metricVisualization": { + "displayName": "Users", + "color": "#7E58FF" + } + } + ], + "title": "Unique sessions and users", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + }, + "openBladeOnClick": { + "openBlade": true, + "destinationBlade": { + "extensionName": "HubsExtension", + "bladeName": "ResourceMenuBlade", + "parameters": { + "id": "[parameters('applicationInsightsResourceId')]", + "menuid": "segmentationUsers" + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 4, + "y": 2, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "requests/failed", + "aggregationType": 7, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Failed requests", + "color": "#EC008C" + } + } + ], + "title": "Failed requests", + "visualization": { + "chartType": 3, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + }, + "openBladeOnClick": { + "openBlade": true, + "destinationBlade": { + "extensionName": "HubsExtension", + "bladeName": "ResourceMenuBlade", + "parameters": { + "id": "[parameters('applicationInsightsResourceId')]", + "menuid": "failures" + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 8, + "y": 2, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "requests/duration", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Server response time", + "color": "#00BCF2" + } + } + ], + "title": "Server response time", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + }, + "openBladeOnClick": { + "openBlade": true, + "destinationBlade": { + "extensionName": "HubsExtension", + "bladeName": "ResourceMenuBlade", + "parameters": { + "id": "[parameters('applicationInsightsResourceId')]", + "menuid": "performance" + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 12, + "y": 2, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "browserTimings/networkDuration", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Page load network connect time", + "color": "#7E58FF" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "browserTimings/processingDuration", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Client processing time", + "color": "#44F1C8" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "browserTimings/sendDuration", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Send request time", + "color": "#EB9371" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "browserTimings/receiveDuration", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Receiving response time", + "color": "#0672F1" + } + } + ], + "title": "Average page load time breakdown", + "visualization": { + "chartType": 3, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 0, + "y": 5, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "availabilityResults/availabilityPercentage", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Availability", + "color": "#47BDF5" + } + } + ], + "title": "Average availability", + "visualization": { + "chartType": 3, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + }, + "openBladeOnClick": { + "openBlade": true, + "destinationBlade": { + "extensionName": "HubsExtension", + "bladeName": "ResourceMenuBlade", + "parameters": { + "id": "[parameters('applicationInsightsResourceId')]", + "menuid": "availability" + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 4, + "y": 5, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "exceptions/server", + "aggregationType": 7, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Server exceptions", + "color": "#47BDF5" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "dependencies/failed", + "aggregationType": 7, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Dependency failures", + "color": "#7E58FF" + } + } + ], + "title": "Server exceptions and Dependency failures", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 8, + "y": 5, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "performanceCounters/processorCpuPercentage", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Processor time", + "color": "#47BDF5" + } + }, + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "performanceCounters/processCpuPercentage", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Process CPU", + "color": "#7E58FF" + } + } + ], + "title": "Average processor and process CPU utilization", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 12, + "y": 5, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "exceptions/browser", + "aggregationType": 7, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Browser exceptions", + "color": "#47BDF5" + } + } + ], + "title": "Browser exceptions", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 0, + "y": 8, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "availabilityResults/count", + "aggregationType": 7, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Availability test results count", + "color": "#47BDF5" + } + } + ], + "title": "Availability test results count", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 4, + "y": 8, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "performanceCounters/processIOBytesPerSecond", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Process IO rate", + "color": "#47BDF5" + } + } + ], + "title": "Average process I/O rate", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + }, + { + "position": { + "x": 8, + "y": 8, + "colSpan": 4, + "rowSpan": 3 + }, + "metadata": { + "inputs": [ + { + "name": "options", + "value": { + "chart": { + "metrics": [ + { + "resourceMetadata": { + "id": "[parameters('applicationInsightsResourceId')]" + }, + "name": "performanceCounters/memoryAvailableBytes", + "aggregationType": 4, + "namespace": "microsoft.insights/components", + "metricVisualization": { + "displayName": "Available memory", + "color": "#47BDF5" + } + } + ], + "title": "Average available memory", + "visualization": { + "chartType": 2, + "legendVisualization": { + "isVisible": true, + "position": 2, + "hideSubtitle": false + }, + "axisVisualization": { + "x": { + "isVisible": true, + "axisType": 2 + }, + "y": { + "isVisible": true, + "axisType": 1 + } + } + } + } + } + }, + { + "name": "sharedTimeRange", + "isOptional": true + } + ], + "type": "Extension/HubsExtension/PartType/MonitorChartPart", + "settings": {} + } + } + ] + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "12676032921679464791" + }, + "name": "Portal Dashboards", + "description": "This module deploys a Portal Dashboard.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the dashboard to create." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "lenses": { + "type": "array", + "items": { + "type": "object" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. The dashboard lenses." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The dashboard metadata." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.portal-dashboard.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "dashboard": { + "type": "Microsoft.Portal/dashboards", + "apiVersion": "2020-09-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "lenses": "[parameters('lenses')]", + "metadata": "[parameters('metadata')]" + } + }, + "dashboard_roleAssignments": { + "copy": { + "name": "dashboard_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Portal/dashboards/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Portal/dashboards', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "dashboard" + ] + }, + "dashboard_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Portal/dashboards/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "dashboard" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the dashboard." + }, + "value": "[resourceId('Microsoft.Portal/dashboards', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the dashboard was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the dashboard." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the dashboard was deployed into." + }, + "value": "[reference('dashboard', '2020-09-01-preview', 'full').location]" + } + } + } + } + } + }, + "outputs": { + "dashboardResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the dashboard." + }, + "value": "[reference('dashboard').outputs.resourceId.value]" + }, + "dashboardName": { + "type": "string", + "metadata": { + "description": "The resource name of the dashboard." + }, + "value": "[reference('dashboard').outputs.name.value]" + } + } + } + }, + "dependsOn": [ + "applicationInsights" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the application insights components were deployed into." + }, + "value": "[resourceGroup().name]" + }, + "applicationInsightsName": { + "type": "string", + "metadata": { + "description": "The name of the application insights." + }, + "value": "[reference('applicationInsights').outputs.name.value]" + }, + "dashboardName": { + "type": "string", + "metadata": { + "description": "The resource name of the dashboard." + }, + "value": "[if(not(empty(parameters('dashboardName'))), reference('applicationInsightsDashboard').outputs.dashboardName.value, '')]" + }, + "applicationInsightsResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the application insights." + }, + "value": "[reference('applicationInsights').outputs.resourceId.value]" + }, + "dashboardResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the dashboard." + }, + "value": "[if(not(empty(parameters('dashboardName'))), reference('applicationInsightsDashboard').outputs.dashboardResourceId.value, '')]" + }, + "applicationInsightsConnectionString": { + "type": "string", + "metadata": { + "description": "The connection string of the application insights." + }, + "value": "[reference('applicationInsights').outputs.connectionString.value]" + }, + "applicationInsightsInstrumentationKey": { + "type": "string", + "metadata": { + "description": "The instrumentation key of the application insights." + }, + "value": "[reference('applicationInsights').outputs.instrumentationKey.value]" + } + } + } + }, + "dependsOn": [ + "logAnalytics" + ] + }, + "containerRegistry": { + "condition": "[not(empty(parameters('containerRegistryName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-registry', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('containerRegistryName')]" + }, + "acrSku": { + "value": "[parameters('registryAcrSku')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "publicNetworkAccess": { + "value": "[parameters('registryPublicNetworkAccess')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "8799580877381308457" + }, + "name": "Azure Container Registries (ACR)", + "description": "This module deploys an Azure Container Registry (ACR).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + }, + "scopeMapsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the scope map." + } + }, + "actions": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The list of scoped permissions for registry artifacts." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The user friendly description of the scope map." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "minLength": 5, + "maxLength": 50, + "metadata": { + "description": "Required. Name of your Azure Container Registry." + } + }, + "acrAdminUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable admin user that have push / pull permission to the registry." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "acrSku": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Tier of your Azure container registry." + } + }, + "exportPolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the export policy is enabled or not." + } + }, + "quarantinePolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the quarantine policy is enabled or not. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "trustPolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the trust policy is enabled or not. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "retentionPolicyStatus": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the retention policy is enabled or not." + } + }, + "retentionPolicyDays": { + "type": "int", + "defaultValue": 15, + "metadata": { + "description": "Optional. The number of days to retain an untagged manifest after which it gets purged." + } + }, + "azureADAuthenticationAsArmPolicyStatus": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled." + } + }, + "softDeletePolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. Soft Delete policy status. Default is disabled." + } + }, + "softDeletePolicyDays": { + "type": "int", + "defaultValue": 7, + "metadata": { + "description": "Optional. The number of days after which a soft-deleted item is permanently deleted." + } + }, + "dataEndpointEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable a single data endpoint per region for serving data. Not relevant in case of disabled public access. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "publicNetworkAccess": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkRuleSetIpRules are not set. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "networkRuleBypassOptions": { + "type": "string", + "defaultValue": "AzureServices", + "allowedValues": [ + "AzureServices", + "None" + ], + "metadata": { + "description": "Optional. Whether to allow trusted Azure services to access a network restricted registry." + } + }, + "networkRuleSetDefaultAction": { + "type": "string", + "defaultValue": "Deny", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Optional. The default action of allow or deny when no other rules match." + } + }, + "networkRuleSetIpRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The IP ACL rules. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "zoneRedundancy": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Whether or not zone redundancy is enabled for this container registry." + } + }, + "replications": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. All replications to create." + } + }, + "webhooks": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. All webhooks to create." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "anonymousPullEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables registry-wide pull from unauthenticated clients. It's in preview and available in the Standard and Premium service tiers." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "cacheRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Array of Cache Rules." + } + }, + "credentialSets": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of Credential Sets." + } + }, + "scopeMaps": { + "$ref": "#/definitions/scopeMapsType", + "metadata": { + "description": "Optional. Scope maps setting." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned, UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6cef56e8-d556-48e5-a04f-b8e64114680f')]", + "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", + "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", + "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", + "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.containerregistry-registry.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "registry": { + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('acrSku')]" + }, + "properties": { + "anonymousPullEnabled": "[parameters('anonymousPullEnabled')]", + "adminUserEnabled": "[parameters('acrAdminUserEnabled')]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('status', 'enabled', 'keyVaultProperties', createObject('identity', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyIdentifier', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), reference('cMKKeyVault::cMKKey').keyUriWithVersion))), null())]", + "policies": { + "azureADAuthenticationAsArmPolicy": { + "status": "[parameters('azureADAuthenticationAsArmPolicyStatus')]" + }, + "exportPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('status', parameters('exportPolicyStatus')), null())]", + "quarantinePolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('status', parameters('quarantinePolicyStatus')), null())]", + "trustPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('type', 'Notary', 'status', parameters('trustPolicyStatus')), null())]", + "retentionPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('days', parameters('retentionPolicyDays'), 'status', parameters('retentionPolicyStatus')), null())]", + "softDeletePolicy": { + "retentionDays": "[parameters('softDeletePolicyDays')]", + "status": "[parameters('softDeletePolicyStatus')]" + } + }, + "dataEndpointEnabled": "[parameters('dataEndpointEnabled')]", + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSetIpRules'))), 'Disabled', null()))]", + "networkRuleBypassOptions": "[parameters('networkRuleBypassOptions')]", + "networkRuleSet": "[if(not(empty(parameters('networkRuleSetIpRules'))), createObject('defaultAction', parameters('networkRuleSetDefaultAction'), 'ipRules', parameters('networkRuleSetIpRules')), null())]", + "zoneRedundancy": "[if(equals(parameters('acrSku'), 'Premium'), parameters('zoneRedundancy'), null())]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "registry_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_diagnosticSettings": { + "copy": { + "name": "registry_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_roleAssignments": { + "copy": { + "name": "registry_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_scopeMaps": { + "copy": { + "name": "registry_scopeMaps", + "count": "[length(coalesce(parameters('scopeMaps'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Scope-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(coalesce(parameters('scopeMaps'), createArray())[copyIndex()], 'name')]" + }, + "actions": { + "value": "[coalesce(parameters('scopeMaps'), createArray())[copyIndex()].actions]" + }, + "description": { + "value": "[tryGet(coalesce(parameters('scopeMaps'), createArray())[copyIndex()], 'description')]" + }, + "registryName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "9144531012597082524" + }, + "name": "Container Registries scopeMaps", + "description": "This module deploys an Azure Container Registry (ACR) scopeMap.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[format('{0}-scopemaps', parameters('registryName'))]", + "metadata": { + "description": "Optional. The name of the scope map." + } + }, + "actions": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The list of scoped permissions for registry artifacts." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The user friendly description of the scope map." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "scopeMap": { + "type": "Microsoft.ContainerRegistry/registries/scopeMaps", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "properties": { + "actions": "[parameters('actions')]", + "description": "[parameters('description')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the scope map." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the scope map was created in." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the scope map." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/scopeMaps', parameters('registryName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_replications": { + "copy": { + "name": "registry_replications", + "count": "[length(coalesce(parameters('replications'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Replication-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].name]" + }, + "registryName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].location]" + }, + "regionEndpointEnabled": { + "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'regionEndpointEnabled')]" + }, + "zoneRedundancy": { + "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'zoneRedundancy')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "8531695368487734118" + }, + "name": "Azure Container Registry (ACR) Replications", + "description": "This module deploys an Azure Container Registry (ACR) Replication.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "regionEndpointEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether the replication regional endpoint is enabled. Requests will not be routed to a replication whose regional endpoint is disabled, however its data will continue to be synced with other replications." + } + }, + "zoneRedundancy": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Whether or not zone redundancy is enabled for this container registry." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "replication": { + "type": "Microsoft.ContainerRegistry/registries/replications", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "regionEndpointEnabled": "[parameters('regionEndpointEnabled')]", + "zoneRedundancy": "[parameters('zoneRedundancy')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the replication." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the replication." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/replications', parameters('registryName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the replication was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('replication', '2023-06-01-preview', 'full').location]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_credentialSets": { + "copy": { + "name": "registry_credentialSets", + "count": "[length(coalesce(parameters('credentialSets'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-CredentialSet-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('credentialSets'), createArray())[copyIndex()].name]" + }, + "registryName": { + "value": "[parameters('name')]" + }, + "managedIdentities": { + "value": "[coalesce(parameters('credentialSets'), createArray())[copyIndex()].managedIdentities]" + }, + "authCredentials": { + "value": "[coalesce(parameters('credentialSets'), createArray())[copyIndex()].authCredentials]" + }, + "loginServer": { + "value": "[coalesce(parameters('credentialSets'), createArray())[copyIndex()].loginServer]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "12196074162662855376" + }, + "name": "Container Registries Credential Sets", + "description": "This module deploys an ACR Credential Set.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + } + } + }, + "authCredentialsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the credential." + } + }, + "usernameSecretIdentifier": { + "type": "string", + "metadata": { + "description": "Required. KeyVault Secret URI for accessing the username." + } + }, + "passwordSecretIdentifier": { + "type": "string", + "metadata": { + "description": "Required. KeyVault Secret URI for accessing the password." + } + } + } + } + } + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Required. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the credential set." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Required. The managed identity definition for this resource." + } + }, + "authCredentials": { + "$ref": "#/definitions/authCredentialsType", + "metadata": { + "description": "Required. List of authentication credentials stored for an upstream. Usually consists of a primary and an optional secondary credential." + } + }, + "loginServer": { + "type": "string", + "metadata": { + "description": "Required. The credentials are stored for this upstream or login server." + } + } + }, + "variables": { + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), 'SystemAssigned', null())), null())]" + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "credentialSet": { + "type": "Microsoft.ContainerRegistry/registries/credentialSets", + "apiVersion": "2023-11-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "identity": "[variables('identity')]", + "properties": { + "authCredentials": "[parameters('authCredentials')]", + "loginServer": "[parameters('loginServer')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The Name of the Credential Set." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Credential Set." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Credential Set." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/credentialSets', parameters('registryName'), parameters('name'))]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('credentialSet', '2023-11-01-preview', 'full'), 'identity'), 'principalId'), '')]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_cacheRules": { + "copy": { + "name": "registry_cacheRules", + "count": "[length(coalesce(parameters('cacheRules'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Cache-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "registryName": { + "value": "[parameters('name')]" + }, + "sourceRepository": { + "value": "[coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository]" + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'name'), replace(replace(coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository, '/', '-'), '.', '-'))]" + }, + "targetRepository": { + "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'targetRepository'), coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository)]" + }, + "credentialSetResourceId": { + "value": "[tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'credentialSetResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "4294329625336671928" + }, + "name": "Container Registries Cache", + "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache)).", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Required. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-')]", + "metadata": { + "description": "Optional. The name of the cache rule. Will be dereived from the source repository name if not defined." + } + }, + "sourceRepository": { + "type": "string", + "metadata": { + "description": "Required. Source repository pulled from upstream." + } + }, + "targetRepository": { + "type": "string", + "defaultValue": "[parameters('sourceRepository')]", + "metadata": { + "description": "Optional. Target repository specified in docker pull command. E.g.: docker pull myregistry.azurecr.io/{targetRepository}:{tag}." + } + }, + "credentialSetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the credential store which is associated with the cache rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.ContainerRegistry/registries/cacheRules", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "properties": { + "sourceRepository": "[parameters('sourceRepository')]", + "targetRepository": "[parameters('targetRepository')]", + "credentialSetResourceId": "[parameters('credentialSetResourceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The Name of the Cache Rule." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Cache Rule." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Cache Rule." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/cacheRules', parameters('registryName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "registry", + "registry_credentialSets" + ] + }, + "registry_webhooks": { + "copy": { + "name": "registry_webhooks", + "count": "[length(coalesce(parameters('webhooks'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Webhook-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].name]" + }, + "registryName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'location'), parameters('location'))]" + }, + "action": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'action'), createArray('chart_delete', 'chart_push', 'delete', 'push', 'quarantine'))]" + }, + "customHeaders": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'customHeaders')]" + }, + "scope": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'scope')]" + }, + "status": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'status')]" + }, + "serviceUri": { + "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].serviceUri]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "14912363209364245195" + }, + "name": "Azure Container Registry (ACR) Webhooks", + "description": "This module deploys an Azure Container Registry (ACR) Webhook.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[format('{0}webhook', parameters('registryName'))]", + "minLength": 5, + "maxLength": 50, + "metadata": { + "description": "Optional. The name of the registry webhook." + } + }, + "serviceUri": { + "type": "string", + "metadata": { + "description": "Required. The service URI for the webhook to post notifications." + } + }, + "status": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The status of the webhook at the time the operation was called." + } + }, + "action": { + "type": "array", + "defaultValue": [ + "chart_delete", + "chart_push", + "delete", + "push", + "quarantine" + ], + "metadata": { + "description": "Optional. The list of actions that trigger the webhook to post notifications." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "customHeaders": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Custom headers that will be added to the webhook notifications." + } + }, + "scope": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The scope of repositories where the event can be triggered. For example, 'foo:*' means events for all tags under repository 'foo'. 'foo:bar' means events for 'foo:bar' only. 'foo' is equivalent to 'foo:latest'. Empty means all events." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "webhook": { + "type": "Microsoft.ContainerRegistry/registries/webhooks", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "actions": "[parameters('action')]", + "customHeaders": "[parameters('customHeaders')]", + "scope": "[parameters('scope')]", + "serviceUri": "[parameters('serviceUri')]", + "status": "[parameters('status')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the webhook." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/webhooks', parameters('registryName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the webhook." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Azure container registry." + }, + "value": "[resourceGroup().name]" + }, + "actions": { + "type": "array", + "metadata": { + "description": "The actions of the webhook." + }, + "value": "[reference('webhook').actions]" + }, + "status": { + "type": "string", + "metadata": { + "description": "The status of the webhook." + }, + "value": "[reference('webhook').status]" + }, + "provistioningState": { + "type": "string", + "metadata": { + "description": "The provisioning state of the webhook." + }, + "value": "[reference('webhook').provisioningState]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('webhook', '2023-06-01-preview', 'full').location]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_privateEndpoints": { + "copy": { + "name": "registry_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-registry-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4120048060064073955" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The Name of the Azure container registry." + }, + "value": "[parameters('name')]" + }, + "loginServer": { + "type": "string", + "metadata": { + "description": "The reference to the Azure container registry." + }, + "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2019-05-01').loginServer]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Azure container registry." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Azure container registry." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('registry', '2023-06-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('registry', '2023-06-01-preview', 'full').location]" + }, + "credentialSetsSystemAssignedMIPrincipalIds": { + "type": "array", + "metadata": { + "description": "The Principal IDs of the ACR Credential Sets system-assigned identities." + }, + "copy": { + "count": "[length(range(0, length(parameters('credentialSets'))))]", + "input": "[reference(format('registry_credentialSets[{0}]', range(0, length(parameters('credentialSets')))[copyIndex()])).outputs.systemAssignedMIPrincipalId.value]" + } + }, + "credentialSetsResourceIds": { + "type": "array", + "metadata": { + "description": "The Resource IDs of the ACR Credential Sets." + }, + "copy": { + "count": "[length(range(0, length(parameters('credentialSets'))))]", + "input": "[reference(format('registry_credentialSets[{0}]', range(0, length(parameters('credentialSets')))[copyIndex()])).outputs.resourceId.value]" + } + } + } + } + } + }, + "searchService": { + "condition": "[not(empty(parameters('searchServiceName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-searchservice', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('searchServiceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "authOptions": { + "value": "[parameters('authOptions')]" + }, + "disableLocalAuth": { + "value": "[parameters('disableLocalAuth')]" + }, + "cmkEnforcement": { + "value": "[parameters('cmkEnforcement')]" + }, + "hostingMode": { + "value": "[parameters('hostingMode')]" + }, + "networkRuleSet": { + "value": "[parameters('networkRuleSet')]" + }, + "partitionCount": { + "value": "[parameters('partitionCount')]" + }, + "publicNetworkAccess": { + "value": "[parameters('searchServicePublicNetworkAccess')]" + }, + "replicaCount": { + "value": "[parameters('replicaCount')]" + }, + "semanticSearch": { + "value": "[parameters('semanticSearch')]" + }, + "sku": { + "value": "[parameters('searchServiceSku')]" + }, + "managedIdentities": { + "value": "[parameters('managedIdentities')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "14924554723661229870" + }, + "name": "Search Services", + "description": "This module deploys a Search Service.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Azure Cognitive Search service to create or update. Search service names must only contain lowercase letters, digits or dashes, cannot use dash as the first two or last one characters, cannot contain consecutive dashes, and must be between 2 and 60 characters in length. Search service names must be globally unique since they are part of the service URI (https://.search.windows.net). You cannot change the service name after the service is created." + } + }, + "authOptions": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Defines the options for how the data plane API of a Search service authenticates requests. Must remain an empty object {} if 'disableLocalAuth' is set to true." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. When set to true, calls to the search service will not be permitted to utilize API keys for authentication. This cannot be set to true if 'authOptions' are defined." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "cmkEnforcement": { + "type": "string", + "defaultValue": "Unspecified", + "allowedValues": [ + "Disabled", + "Enabled", + "Unspecified" + ], + "metadata": { + "description": "Optional. Describes a policy that determines how resources within the search service are to be encrypted with Customer Managed Keys." + } + }, + "hostingMode": { + "type": "string", + "defaultValue": "default", + "allowedValues": [ + "default", + "highDensity" + ], + "metadata": { + "description": "Optional. Applicable only for the standard3 SKU. You can set this property to enable up to 3 high density partitions that allow up to 1000 indexes, which is much higher than the maximum indexes allowed for any other SKU. For the standard3 SKU, the value is either 'default' or 'highDensity'. For all other SKUs, this value must be 'default'." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "networkRuleSet": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Network specific rules that determine how the Azure Cognitive Search service may be reached." + } + }, + "partitionCount": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 12, + "metadata": { + "description": "Optional. The number of partitions in the search service; if specified, it can be 1, 2, 3, 4, 6, or 12. Values greater than 1 are only valid for standard SKUs. For 'standard3' services with hostingMode set to 'highDensity', the allowed values are between 1 and 3." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "sharedPrivateLinkResources": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The sharedPrivateLinkResources to create as part of the search Service." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. This value can be set to 'Enabled' to avoid breaking changes on existing customer resources and templates. If set to 'Disabled', traffic over public interface is not allowed, and private endpoint connections would be the exclusive access method." + } + }, + "replicaCount": { + "type": "int", + "defaultValue": 3, + "minValue": 1, + "maxValue": 12, + "metadata": { + "description": "Optional. The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "semanticSearch": { + "type": "string", + "nullable": true, + "allowedValues": [ + "disabled", + "free", + "standard" + ], + "metadata": { + "description": "Optional. Sets options that control the availability of semantic search. This configuration is only possible for certain search SKUs in certain locations." + } + }, + "sku": { + "type": "string", + "defaultValue": "standard", + "allowedValues": [ + "basic", + "free", + "standard", + "standard2", + "standard3", + "storage_optimized_l1", + "storage_optimized_l2" + ], + "metadata": { + "description": "Optional. Defines the SKU of an Azure Cognitive Search Service, which determines price tier and capacity limits." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to help categorize the resource in the Azure portal." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', '')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Search Index Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8ebe5a00-799e-43f5-93ac-243d3dce84a7')]", + "Search Index Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1407120a-92aa-4202-b7e9-c0e197c71c8f')]", + "Search Service Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7ca78c08-252a-4471-8644-bb5ff32d4ba0')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.search-searchservice.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "searchService": { + "type": "Microsoft.Search/searchServices", + "apiVersion": "2024-03-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('sku')]" + }, + "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", + "properties": { + "authOptions": "[if(not(empty(parameters('authOptions'))), parameters('authOptions'), null())]", + "disableLocalAuth": "[parameters('disableLocalAuth')]", + "encryptionWithCmk": { + "enforcement": "[parameters('cmkEnforcement')]" + }, + "hostingMode": "[parameters('hostingMode')]", + "networkRuleSet": "[parameters('networkRuleSet')]", + "partitionCount": "[parameters('partitionCount')]", + "replicaCount": "[parameters('replicaCount')]", + "publicNetworkAccess": "[toLower(parameters('publicNetworkAccess'))]", + "semanticSearch": "[parameters('semanticSearch')]" + } + }, + "searchService_diagnosticSettings": { + "copy": { + "name": "searchService_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Search/searchServices/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "searchService" + ] + }, + "searchService_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Search/searchServices/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "searchService" + ] + }, + "searchService_roleAssignments": { + "copy": { + "name": "searchService_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Search/searchServices/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Search/searchServices', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "searchService" + ] + }, + "searchService_privateEndpoints": { + "copy": { + "name": "searchService_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-searchService-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Search/searchServices', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'searchService'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Search/searchServices', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'searchService'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Search/searchServices', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'searchService')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Search/searchServices', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'searchService'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Search/searchServices', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'searchService')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDnsZoneConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", + "input": { + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" + } + } + } + ] + }, + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + } + } + } + }, + "dependsOn": [ + "searchService" + ] + }, + "searchService_sharedPrivateLinkResources": { + "copy": { + "name": "searchService_sharedPrivateLinkResources", + "count": "[length(parameters('sharedPrivateLinkResources'))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-searchService-SharedPrivateLink-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(parameters('sharedPrivateLinkResources')[copyIndex()], 'name'), format('spl-{0}-{1}-{2}', last(split(resourceId('Microsoft.Search/searchServices', parameters('name')), '/')), parameters('sharedPrivateLinkResources')[copyIndex()].groupId, copyIndex()))]" + }, + "searchServiceName": { + "value": "[parameters('name')]" + }, + "privateLinkResourceId": { + "value": "[parameters('sharedPrivateLinkResources')[copyIndex()].privateLinkResourceId]" + }, + "groupId": { + "value": "[parameters('sharedPrivateLinkResources')[copyIndex()].groupId]" + }, + "requestMessage": { + "value": "[parameters('sharedPrivateLinkResources')[copyIndex()].requestMessage]" + }, + "resourceRegion": { + "value": "[tryGet(parameters('sharedPrivateLinkResources')[copyIndex()], 'resourceRegion')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "2330033720810948871" + }, + "name": "Search Services Private Link Resources", + "description": "This module deploys a Search Service Private Link Resource.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "searchServiceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent searchServices. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the shared private link resource managed by the Azure Cognitive Search service within the specified resource group." + } + }, + "privateLinkResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource the shared private link resource is for." + } + }, + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The group ID from the provider of resource the shared private link resource is for." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Required. The request message for requesting approval of the shared private link resource." + } + }, + "resourceRegion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Can be used to specify the Azure Resource Manager location of the resource to which a shared private link is to be created. This is only required for those resources whose DNS configuration are regional (such as Azure Kubernetes Service)." + } + } + }, + "resources": { + "searchService": { + "existing": true, + "type": "Microsoft.Search/searchServices", + "apiVersion": "2023-11-01", + "name": "[parameters('searchServiceName')]" + }, + "sharedPrivateLinkResource": { + "type": "Microsoft.Search/searchServices/sharedPrivateLinkResources", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('searchServiceName'), parameters('name'))]", + "properties": { + "privateLinkResourceId": "[parameters('privateLinkResourceId')]", + "groupId": "[parameters('groupId')]", + "requestMessage": "[parameters('requestMessage')]", + "resourceRegion": "[parameters('resourceRegion')]" + }, + "dependsOn": [ + "searchService" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the shared private link resource." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the shared private link resource." + }, + "value": "[resourceId('Microsoft.Search/searchServices/sharedPrivateLinkResources', parameters('searchServiceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the shared private link resource was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "searchService" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the search service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the search service." + }, + "value": "[resourceId('Microsoft.Search/searchServices', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the search service was created in." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('searchService', '2024-03-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('searchService', '2024-03-01-preview', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the search service." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('searchService_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('searchService_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('searchService_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('searchService_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('searchService_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + } + } + } + } + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the module was deployed to." + }, + "value": "[resourceGroup().name]" + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the key vault." + }, + "value": "[reference('keyVault').outputs.resourceId.value]" + }, + "keyVaultName": { + "type": "string", + "metadata": { + "description": "The name of the key vault." + }, + "value": "[reference('keyVault').outputs.name.value]" + }, + "keyVaultEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the key vault." + }, + "value": "[reference('keyVault').outputs.uri.value]" + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the storage account." + }, + "value": "[reference('storageAccount').outputs.resourceId.value]" + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "The name of the storage account." + }, + "value": "[reference('storageAccount').outputs.name.value]" + }, + "containerRegistryResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the container registry." + }, + "value": "[if(not(empty(parameters('containerRegistryName'))), reference('containerRegistry').outputs.resourceId.value, '')]" + }, + "containerRegistryName": { + "type": "string", + "metadata": { + "description": "The name of the container registry." + }, + "value": "[if(not(empty(parameters('containerRegistryName'))), reference('containerRegistry').outputs.name.value, '')]" + }, + "containerRegistryEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the container registry." + }, + "value": "[if(not(empty(parameters('containerRegistryName'))), reference('containerRegistry').outputs.loginServer.value, '')]" + }, + "applicationInsightsResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the application insights." + }, + "value": "[if(not(empty(parameters('applicationInsightsName'))), reference('applicationInsights').outputs.applicationInsightsResourceId.value, '')]" + }, + "applicationInsightsName": { + "type": "string", + "metadata": { + "description": "The name of the application insights." + }, + "value": "[if(not(empty(parameters('applicationInsightsName'))), reference('applicationInsights').outputs.applicationInsightsName.value, '')]" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the loganalytics workspace." + }, + "value": "[if(not(empty(parameters('logAnalyticsName'))), reference('logAnalytics').outputs.resourceId.value, '')]" + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "The name of the loganalytics workspace." + }, + "value": "[if(not(empty(parameters('logAnalyticsName'))), reference('logAnalytics').outputs.name.value, '')]" + }, + "cognitiveServicesResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the cognitive services." + }, + "value": "[reference('cognitiveServices').outputs.resourceId.value]" + }, + "cognitiveServicesName": { + "type": "string", + "metadata": { + "description": "The name of the cognitive services." + }, + "value": "[reference('cognitiveServices').outputs.name.value]" + }, + "cognitiveServicesEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the cognitive services." + }, + "value": "[reference('cognitiveServices').outputs.endpoint.value]" + }, + "searchServiceResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the search service." + }, + "value": "[if(not(empty(parameters('searchServiceName'))), reference('searchService').outputs.resourceId.value, '')]" + }, + "searchServiceName": { + "type": "string", + "metadata": { + "description": "The name of the search service." + }, + "value": "[if(not(empty(parameters('searchServiceName'))), reference('searchService').outputs.name.value, '')]" + }, + "searchServiceEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the search service." + }, + "value": "[if(not(empty(parameters('searchServiceName'))), format('https://{0}.search.windows.net/', reference('searchService').outputs.name.value), '')]" + }, + "applicationInsightsConnectionString": { + "type": "string", + "metadata": { + "description": "The connection string of the application insights." + }, + "value": "[if(not(empty(parameters('applicationInsightsName'))), reference('applicationInsights').outputs.applicationInsightsConnectionString.value, '')]" + }, + "applicationInsightsInstrumentationKey": { + "type": "string", + "metadata": { + "description": "The instrumentation key of the application insights." + }, + "value": "[if(not(empty(parameters('applicationInsightsName'))), reference('applicationInsights').outputs.applicationInsightsInstrumentationKey.value, '')]" + }, + "systemAssignedMiPrincipalId": { + "type": "string", + "metadata": { + "description": "The system assigned mi principal Id key of the search service." + }, + "value": "[if(not(empty(parameters('searchServiceName'))), reference('searchService').outputs.systemAssignedMIPrincipalId.value, '')]" + } + } + } + } + }, + "hub": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "hub", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "name": { + "value": "[parameters('hubName')]" + }, + "keyVaultResourceId": { + "value": "[reference('hubDependencies').outputs.keyVaultResourceId.value]" + }, + "storageAccountResourceId": { + "value": "[reference('hubDependencies').outputs.storageAccountResourceId.value]" + }, + "containerRegistryResourceId": { + "value": "[reference('hubDependencies').outputs.containerRegistryResourceId.value]" + }, + "applicationInsightsResourceId": { + "value": "[reference('hubDependencies').outputs.applicationInsightsResourceId.value]" + }, + "openAiName": { + "value": "[reference('hubDependencies').outputs.cognitiveServicesName.value]" + }, + "aiSearchName": { + "value": "[reference('hubDependencies').outputs.searchServiceName.value]" + }, + "aiSearchConnectionName": { + "value": "[parameters('searchConnectionName')]" + }, + "openAiContentSafetyConnectionName": { + "value": "[parameters('openAiConnectionName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "1067386930679309754" + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The AI Studio Hub Resource name." + } + }, + "displayName": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. The display name of the AI Studio Hub Resource." + } + }, + "storageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. The storage account ID to use for the AI Studio Hub Resource." + } + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The key vault ID to use for the AI Studio Hub Resource." + } + }, + "applicationInsightsResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The application insights ID to use for the AI Studio Hub Resource." + } + }, + "containerRegistryResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The container registry ID to use for the AI Studio Hub Resource." + } + }, + "openAiName": { + "type": "string", + "metadata": { + "description": "Required. The OpenAI Cognitive Services account name to use for the AI Studio Hub Resource." + } + }, + "aiSearchName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Azure Cognitive Search service name to use for the AI Studio Hub Resource." + } + }, + "aiSearchConnectionName": { + "type": "string", + "metadata": { + "description": "Required. The Azure Cognitive Search service connection name to use for the AI Studio Hub Resource." + } + }, + "openAiContentSafetyConnectionName": { + "type": "string", + "metadata": { + "description": "Required. The OpenAI Content Safety connection name to use for the AI Studio Hub Resource." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Basic", + "metadata": { + "description": "Optional. The SKU name to use for the AI Studio Hub Resource." + } + }, + "skuTier": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Free", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. The SKU tier to use for the AI Studio Hub Resource." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. The public network access setting to use for the AI Studio Hub Resource." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": [ + { + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01-preview", + "name": "[format('{0}/{1}', parameters('name'), 'aoai-connection')]", + "properties": { + "category": "AzureOpenAI", + "authType": "ApiKey", + "isSharedToAll": true, + "target": "[reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName')), '2023-05-01').endpoints['OpenAI Language Model Instance API']]", + "metadata": { + "ApiVersion": "2024-02-01", + "ApiType": "azure", + "ResourceId": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName'))]" + }, + "credentials": { + "key": "[listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName')), '2023-05-01').key1]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01", + "name": "[format('{0}/{1}', parameters('name'), parameters('openAiContentSafetyConnectionName'))]", + "properties": { + "category": "AzureOpenAI", + "authType": "ApiKey", + "isSharedToAll": true, + "target": "[reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName')), '2023-05-01').endpoints['Content Safety']]", + "metadata": { + "ApiVersion": "2023-07-01-preview", + "ApiType": "azure", + "ResourceId": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName'))]" + }, + "credentials": { + "key": "[listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('openAiName')), '2023-05-01').key1]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name'))]" + ] + }, + { + "condition": "[not(empty(parameters('aiSearchName')))]", + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01", + "name": "[format('{0}/{1}', parameters('name'), parameters('aiSearchConnectionName'))]", + "properties": { + "category": "CognitiveSearch", + "authType": "ApiKey", + "isSharedToAll": true, + "target": "[format('https://{0}.search.windows.net/', parameters('aiSearchName'))]", + "credentials": { + "key": "[if(not(empty(parameters('aiSearchName'))), listAdminKeys(resourceId('Microsoft.Search/searchServices', parameters('aiSearchName')), '2021-04-01-preview').primaryKey, '')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2024-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('skuName')]", + "tier": "[parameters('skuTier')]" + }, + "kind": "Hub", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "friendlyName": "[parameters('displayName')]", + "storageAccount": "[parameters('storageAccountResourceId')]", + "keyVault": "[parameters('keyVaultResourceId')]", + "applicationInsights": "[if(not(empty(parameters('applicationInsightsResourceId'))), parameters('applicationInsightsResourceId'), null())]", + "containerRegistry": "[if(not(empty(parameters('containerRegistryResourceId'))), parameters('containerRegistryResourceId'), null())]", + "hbiWorkspace": false, + "managedNetwork": { + "isolationMode": "Disabled" + }, + "v1LegacyMode": false, + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "discoveryUrl": "[format('https://{0}.api.azureml.ms/discovery', parameters('location'))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name'))]" + }, + "principalId": { + "type": "string", + "value": "[reference(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), '2024-04-01', 'full').identity.principalId]" + } + } + } + }, + "dependsOn": [ + "hubDependencies" + ] + }, + "project": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-project', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('projectName')]" + }, + "hubResourceId": { + "value": "[reference('hub').outputs.resourceId.value]" + }, + "keyVaultName": { + "value": "[reference('hubDependencies').outputs.keyVaultName.value]" + }, + "userAssignedtName": { + "value": "[parameters('userAssignedtName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.28.1.47646", + "templateHash": "8421874757119193320" + }, + "name": "Machine Learning workspace", + "description": "Create a machine learning workspace, configure the key vault access policy and assign role permissions to the machine learning instance.\n\n**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource. Must be false if `primaryUserAssignedIdentity` is provided." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the machine learning workspace." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "example": " {\n \"key1\": \"value1\"\n \"key2\": \"value2\"\n }\n ", + "description": "Optional. Tags of the resource." + } + }, + "projectSku": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Free", + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Optional. Specifies the SKU, also referred as 'edition' of the Azure Machine Learning workspace." + } + }, + "projectKind": { + "type": "string", + "defaultValue": "Project", + "allowedValues": [ + "Default", + "Project", + "Hub", + "FeatureStore" + ], + "metadata": { + "description": "Optional. The type of Azure Machine Learning workspace to create." + } + }, + "hbiWorkspace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag to signal HBI data in the workspace and reduce diagnostic data collected by the service." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this machine learning resource. For security reasons it should be disabled." + } + }, + "hubResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the AI Studio Hub Resource where this project should be created." + } + }, + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the key vault." + } + }, + "projectManagedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "defaultValue": { + "systemAssigned": true + }, + "metadata": { + "description": "Optional. The managed identity definition for the machine learning resource. At least one identity type is required." + } + }, + "userAssignedtName": { + "type": "string", + "metadata": { + "description": "Required. The User Assigned Identity resource name." + } + }, + "roleDefinitionIdOrName": { + "type": "array", + "defaultValue": [ + "f6c7c914-8db3-469d-8ca1-694a8f32e121", + "ea01e6af-a1c1-4350-9563-ad00f8c72ec5" + ], + "metadata": { + "description": "Optional. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.ptn.azd-mlproject.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "project": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-project', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('name')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "sku": { + "value": "[parameters('projectSku')]" + }, + "kind": { + "value": "[parameters('projectKind')]" + }, + "managedIdentities": { + "value": "[parameters('projectManagedIdentities')]" + }, + "hbiWorkspace": { + "value": "[parameters('hbiWorkspace')]" + }, + "publicNetworkAccess": { + "value": "[parameters('publicNetworkAccess')]" + }, + "hubResourceId": { + "value": "[parameters('hubResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "8914196510655371542" + }, + "name": "Machine Learning Services Workspaces", + "description": "This module deploys a Machine Learning Services Workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource. Must be false if `primaryUserAssignedIdentity` is provided." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + } + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "featureStoreSettingType": { + "type": "object", + "properties": { + "computeRuntime": { + "type": "object", + "properties": { + "sparkRuntimeVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The spark runtime version." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Compute runtime config for feature store type workspace." + } + }, + "offlineStoreConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The offline store connection name." + } + }, + "onlineStoreConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The online store connection name." + } + } + }, + "nullable": true + }, + "OutboundRuleType": { + "type": "object", + "discriminator": { + "propertyName": "type", + "mapping": { + "FQDN": { + "$ref": "#/definitions/FqdnOutboundRuleType" + }, + "PrivateEndpoint": { + "$ref": "#/definitions/PrivateEndpointOutboundRule" + }, + "ServiceTag": { + "$ref": "#/definitions/ServiceTagOutboundRule" + } + } + } + }, + "FqdnOutboundRuleType": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "FQDN" + ], + "metadata": { + "description": "Required. Type of a managed network Outbound Rule of a machine learning workspace. Only supported when 'isolationMode' is 'AllowOnlyApprovedOutbound'." + } + }, + "destination": { + "type": "string", + "metadata": { + "description": "Required. Fully Qualified Domain Name to allow for outbound traffic." + } + }, + "category": { + "type": "string", + "allowedValues": [ + "Dependency", + "Recommended", + "Required", + "UserDefined" + ], + "nullable": true, + "metadata": { + "description": "Optional. Category of a managed network Outbound Rule of a machine learning workspace." + } + } + } + }, + "PrivateEndpointOutboundRule": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "PrivateEndpoint" + ], + "metadata": { + "description": "Required. Type of a managed network Outbound Rule of a machine learning workspace. Only supported when 'isolationMode' is 'AllowOnlyApprovedOutbound' or 'AllowInternetOutbound'." + } + }, + "destination": { + "type": "object", + "properties": { + "serviceResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the target resource for the private endpoint." + } + }, + "sparkEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether the private endpoint can be used by jobs running on Spark." + } + }, + "subresourceTarget": { + "type": "string", + "metadata": { + "description": "Required. The sub resource to connect for the private endpoint." + } + } + }, + "metadata": { + "description": "Required. Service Tag destination for a Service Tag Outbound Rule for the managed network of a machine learning workspace." + } + }, + "category": { + "type": "string", + "allowedValues": [ + "Dependency", + "Recommended", + "Required", + "UserDefined" + ], + "nullable": true, + "metadata": { + "description": "Optional. Category of a managed network Outbound Rule of a machine learning workspace." + } + } + } + }, + "ServiceTagOutboundRule": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "ServiceTag" + ], + "metadata": { + "description": "Required. Type of a managed network Outbound Rule of a machine learning workspace. Only supported when 'isolationMode' is 'AllowOnlyApprovedOutbound'." + } + }, + "destination": { + "type": "object", + "properties": { + "portRanges": { + "type": "string", + "metadata": { + "description": "Required. The name of the service tag to allow." + } + }, + "protocol": { + "type": "string", + "allowedValues": [ + "*", + "ICMP", + "TCP", + "UDP" + ], + "metadata": { + "description": "Required. The protocol to allow. Provide an asterisk(*) to allow any protocol." + } + }, + "serviceTag": { + "type": "string", + "metadata": { + "description": "Required. Which ports will be allow traffic by this rule. Provide an asterisk(*) to allow any port." + } + } + }, + "metadata": { + "description": "Required. Service Tag destination for a Service Tag Outbound Rule for the managed network of a machine learning workspace." + } + }, + "category": { + "type": "string", + "allowedValues": [ + "Dependency", + "Recommended", + "Required", + "UserDefined" + ], + "nullable": true, + "metadata": { + "description": "Optional. Category of a managed network Outbound Rule of a machine learning workspace." + } + } + } + }, + "managedNetworkSettingType": { + "type": "object", + "properties": { + "isolationMode": { + "type": "string", + "allowedValues": [ + "AllowInternetOutbound", + "AllowOnlyApprovedOutbound", + "Disabled" + ], + "metadata": { + "description": "Required. Isolation mode for the managed network of a machine learning workspace." + } + }, + "outboundRules": { + "type": "object", + "properties": {}, + "additionalProperties": { + "$ref": "#/definitions/OutboundRuleType", + "metadata": { + "description": "Required. The outbound rule. The name of the rule is the object key." + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Outbound rules for the managed network of a machine learning workspace." + } + } + }, + "nullable": true + }, + "serverlessComputeSettingType": { + "type": "object", + "properties": { + "serverlessComputeCustomSubnet": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of an existing virtual network subnet in which serverless compute nodes should be deployed." + } + }, + "serverlessComputeNoPublicIP": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The flag to signal if serverless compute nodes deployed in custom vNet would have no public IP addresses for a workspace with private endpoint." + } + } + }, + "nullable": true + }, + "workspaceHubConfigType": { + "type": "object", + "properties": { + "additionalWorkspaceStorageAccounts": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource IDs of additional storage accounts to attach to the workspace." + } + }, + "defaultWorkspaceResourceGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the default resource group for projects created in the workspace hub." + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + }, + "connectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the connection to create." + } + }, + "category": { + "$ref": "#/definitions/categoryType", + "metadata": { + "description": "Required. Category of the connection." + } + }, + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiry time of the connection." + } + }, + "isSharedToAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether the connection is shared to all users in the workspace." + } + }, + "metadata": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. The metadata key-value pairs." + } + }, + "nullable": true, + "metadata": { + "description": "Optional. User metadata for the connection." + } + }, + "sharedUserList": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The shared user list of the connection." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Required. The target of the connection." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Value details of the workspace connection." + } + }, + "connectionProperties": { + "$ref": "#/definitions/connectionPropertyType", + "metadata": { + "description": "Required. The properties of the connection, specific to the auth type." + } + } + } + }, + "_1.aadAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AAD" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.accessKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccessKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionAccessKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.apiKeyAuthWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ApiKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionApiKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.customKeysType": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. Key-value pairs for the custom keys." + } + }, + "metadata": { + "description": "Required. The custom keys for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.customKeysWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "CustomKeys" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.customKeysType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.managedIdentityAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ManagedIdentity" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionManagedIdentityType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.noneAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "None" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.oauth2AuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "OAuth2" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionOAuth2Type", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.patAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "PAT" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionPersonalAccessTokenType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.sasAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "SAS" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionSharedAccessSignatureType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.servicePrincipalAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ServicePrincipal" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionServicePrincipalType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.usernamePasswordAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "UsernamePassword" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionUsernamePasswordType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionAccessKeyType": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "metadata": { + "description": "Required. The connection access key ID." + } + }, + "secretAccessKey": { + "type": "string", + "metadata": { + "description": "Required. The connection secret access key." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionApiKeyType": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection API key." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionManagedIdentityType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity ID." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity resource ID." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionOAuth2Type": { + "type": "object", + "properties": { + "authUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection auth URL. Required by Concur connection category." + } + }, + "clientId": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Required. The connection client ID in the format of UUID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "developerToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection developer token. Required by GoogleAdWords connection category." + } + }, + "password": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + }, + "refreshToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The connection tenant ID. Required by QuickBooks and Xero connection categories." + } + }, + "username": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionPersonalAccessTokenType": { + "type": "object", + "properties": { + "pat": { + "type": "string", + "metadata": { + "description": "Required. The connection personal access token." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionServicePrincipalType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection client ID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The connection tenant ID." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionSharedAccessSignatureType": { + "type": "object", + "properties": { + "sas": { + "type": "string", + "metadata": { + "description": "Required. The connection SAS token." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionUsernamePasswordType": { + "type": "object", + "properties": { + "password": { + "type": "string", + "metadata": { + "description": "Required. The connection password." + } + }, + "securityToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to 'UsernamePassword'." + } + }, + "username": { + "type": "string", + "metadata": { + "description": "Required. The connection username." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "categoryType": { + "type": "string", + "allowedValues": [ + "ADLSGen2", + "AIServices", + "AmazonMws", + "AmazonRdsForOracle", + "AmazonRdsForSqlServer", + "AmazonRedshift", + "AmazonS3Compatible", + "ApiKey", + "AzureBlob", + "AzureDataExplorer", + "AzureDatabricksDeltaLake", + "AzureMariaDb", + "AzureMySqlDb", + "AzureOneLake", + "AzureOpenAI", + "AzurePostgresDb", + "AzureSqlDb", + "AzureSqlMi", + "AzureSynapseAnalytics", + "AzureTableStorage", + "BingLLMSearch", + "Cassandra", + "CognitiveSearch", + "CognitiveService", + "Concur", + "ContainerRegistry", + "CosmosDb", + "CosmosDbMongoDbApi", + "Couchbase", + "CustomKeys", + "Db2", + "Drill", + "Dynamics", + "DynamicsAx", + "DynamicsCrm", + "Eloqua", + "FileServer", + "FtpServer", + "GenericContainerRegistry", + "GenericHttp", + "GenericRest", + "Git", + "GoogleAdWords", + "GoogleBigQuery", + "GoogleCloudStorage", + "Greenplum", + "Hbase", + "Hdfs", + "Hive", + "Hubspot", + "Impala", + "Informix", + "Jira", + "Magento", + "MariaDb", + "Marketo", + "MicrosoftAccess", + "MongoDbAtlas", + "MongoDbV2", + "MySql", + "Netezza", + "ODataRest", + "Odbc", + "Office365", + "OpenAI", + "Oracle", + "OracleCloudStorage", + "OracleServiceCloud", + "PayPal", + "Phoenix", + "PostgreSql", + "Presto", + "PythonFeed", + "QuickBooks", + "Redis", + "Responsys", + "S3", + "Salesforce", + "SalesforceMarketingCloud", + "SalesforceServiceCloud", + "SapBw", + "SapCloudForCustomer", + "SapEcc", + "SapHana", + "SapOpenHub", + "SapTable", + "Serp", + "Serverless", + "ServiceNow", + "Sftp", + "SharePointOnlineList", + "Shopify", + "Snowflake", + "Spark", + "SqlServer", + "Square", + "Sybase", + "Teradata", + "Vertica", + "WebTable", + "Xero", + "Zoho" + ], + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "connectionPropertyType": { + "type": "secureObject", + "discriminator": { + "propertyName": "authType", + "mapping": { + "AAD": { + "$ref": "#/definitions/_1.aadAuthTypeWorkspaceConnectionPropertyType" + }, + "AccessKey": { + "$ref": "#/definitions/_1.accessKeyAuthTypeWorkspaceConnectionPropertyType" + }, + "ApiKey": { + "$ref": "#/definitions/_1.apiKeyAuthWorkspaceConnectionPropertyType" + }, + "CustomKeys": { + "$ref": "#/definitions/_1.customKeysWorkspaceConnectionPropertyType" + }, + "ManagedIdentity": { + "$ref": "#/definitions/_1.managedIdentityAuthTypeWorkspaceConnectionPropertyType" + }, + "None": { + "$ref": "#/definitions/_1.noneAuthTypeWorkspaceConnectionPropertyType" + }, + "OAuth2": { + "$ref": "#/definitions/_1.oauth2AuthTypeWorkspaceConnectionPropertyType" + }, + "PAT": { + "$ref": "#/definitions/_1.patAuthTypeWorkspaceConnectionPropertyType" + }, + "SAS": { + "$ref": "#/definitions/_1.sasAuthTypeWorkspaceConnectionPropertyType" + }, + "ServicePrincipal": { + "$ref": "#/definitions/_1.servicePrincipalAuthTypeWorkspaceConnectionPropertyType" + }, + "UsernamePassword": { + "$ref": "#/definitions/_1.usernamePasswordAuthTypeWorkspaceConnectionPropertyType" + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the machine learning workspace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "sku": { + "type": "string", + "allowedValues": [ + "Free", + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Required. Specifies the SKU, also referred as 'edition' of the Azure Machine Learning workspace." + } + }, + "kind": { + "type": "string", + "defaultValue": "Default", + "allowedValues": [ + "Default", + "Project", + "Hub", + "FeatureStore" + ], + "metadata": { + "description": "Optional. The type of Azure Machine Learning workspace to create." + } + }, + "associatedStorageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The resource ID of the associated Storage Account. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." + } + }, + "associatedKeyVaultResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The resource ID of the associated Key Vault. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." + } + }, + "associatedApplicationInsightsResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The resource ID of the associated Application Insights. Required if 'kind' is 'Default' or 'FeatureStore'." + } + }, + "associatedContainerRegistryResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the associated Container Registry." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "hbiWorkspace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag to signal HBI data in the workspace and reduce diagnostic data collected by the service." + } + }, + "hubResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The resource ID of the hub to associate with the workspace. Required if 'kind' is set to 'Project'." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "computes": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Computes to create respectively attach to the workspace." + } + }, + "connections": { + "type": "array", + "items": { + "$ref": "#/definitions/connectionType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Connections to create in the workspace." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "defaultValue": { + "systemAssigned": true + }, + "metadata": { + "description": "Optional. The managed identity definition for this resource. At least one identity type is required." + } + }, + "featureStoreSettings": { + "$ref": "#/definitions/featureStoreSettingType", + "metadata": { + "description": "Conditional. Settings for feature store type workspaces. Required if 'kind' is set to 'FeatureStore'." + } + }, + "managedNetworkSettings": { + "$ref": "#/definitions/managedNetworkSettingType", + "metadata": { + "description": "Optional. Managed Network settings for a machine learning workspace." + } + }, + "serverlessComputeSettings": { + "$ref": "#/definitions/serverlessComputeSettingType", + "metadata": { + "description": "Optional. Settings for serverless compute created in the workspace." + } + }, + "systemDatastoresAuthMode": { + "type": "string", + "nullable": true, + "allowedValues": [ + "accessKey", + "identity" + ], + "metadata": { + "description": "Optional. The authentication mode used by the workspace when connecting to the default storage account." + } + }, + "workspaceHubConfig": { + "$ref": "#/definitions/workspaceHubConfigType", + "metadata": { + "description": "Optional. Configuration for workspace hub settings." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of this workspace." + } + }, + "discoveryUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. URL for the discovery service to identify regional endpoints for machine learning experimentation services." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "imageBuildCompute": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The compute name for image build." + } + }, + "primaryUserAssignedIdentity": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The user assigned identity resource ID that represents the workspace identity. Required if 'userAssignedIdentities' is not empty and may not be used if 'systemAssignedIdentity' is enabled." + } + }, + "serviceManagedResourcesSettings": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The service managed resource settings." + } + }, + "sharedPrivateLinkResources": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of shared private link resources in this workspace. Note: This property is not idempotent." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "AzureML Compute Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e503ece1-11d0-4e8e-8e2c-7a6c3bf38815')]", + "AzureML Data Scientist": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f6c7c914-8db3-469d-8ca1-694a8f32e121')]", + "AzureML Metrics Writer (preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '635dd51f-9968-44d3-b7fb-6d9a6bd613ae')]", + "AzureML Registry User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1823dd4f-9b8c-4ab6-ab4e-7397a3684615')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.machinelearningservices-workspace.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "workspace": { + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2024-04-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('sku')]", + "tier": "[parameters('sku')]" + }, + "identity": "[variables('identity')]", + "properties": "[union(createObject('friendlyName', parameters('name'), 'storageAccount', parameters('associatedStorageAccountResourceId'), 'keyVault', parameters('associatedKeyVaultResourceId'), 'applicationInsights', parameters('associatedApplicationInsightsResourceId'), 'containerRegistry', parameters('associatedContainerRegistryResourceId'), 'hbiWorkspace', parameters('hbiWorkspace'), 'description', parameters('description'), 'discoveryUrl', parameters('discoveryUrl'), 'encryption', if(not(empty(parameters('customerManagedKey'))), createObject('status', 'Enabled', 'identity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), null()), 'keyVaultProperties', createObject('keyVaultArmId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]), 'Microsoft.KeyVault/vaults', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))), 'keyIdentifier', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), reference('cMKKeyVault::cMKKey').keyUriWithVersion))), null()), 'imageBuildCompute', parameters('imageBuildCompute'), 'primaryUserAssignedIdentity', parameters('primaryUserAssignedIdentity'), 'systemDatastoresAuthMode', parameters('systemDatastoresAuthMode'), 'publicNetworkAccess', parameters('publicNetworkAccess'), 'serviceManagedResourcesSettings', parameters('serviceManagedResourcesSettings'), 'featureStoreSettings', parameters('featureStoreSettings'), 'hubResourceId', parameters('hubResourceId'), 'managedNetwork', parameters('managedNetworkSettings'), 'serverlessComputeSettings', parameters('serverlessComputeSettings'), 'workspaceHubConfig', parameters('workspaceHubConfig')), if(not(empty(parameters('sharedPrivateLinkResources'))), createObject('sharedPrivateLinkResources', parameters('sharedPrivateLinkResources')), createObject()))]", + "kind": "[parameters('kind')]", + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "workspace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.MachineLearningServices/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_diagnosticSettings": { + "copy": { + "name": "workspace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.MachineLearningServices/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_roleAssignments": { + "copy": { + "name": "workspace_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.MachineLearningServices/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_computes": { + "copy": { + "name": "workspace_computes", + "count": "[length(coalesce(parameters('computes'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}-compute', parameters('name'), coalesce(parameters('computes'), createArray())[copyIndex()].name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "machineLearningWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].name]" + }, + "location": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].location]" + }, + "sku": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'sku')]" + }, + "managedIdentities": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'managedIdentities')]" + }, + "tags": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'tags')]" + }, + "deployCompute": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'deployCompute')]" + }, + "computeLocation": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'computeLocation')]" + }, + "description": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'description')]" + }, + "disableLocalAuth": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'disableLocalAuth')]" + }, + "resourceId": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'resourceId')]" + }, + "computeType": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].computeType]" + }, + "properties": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'properties')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "8580750401363518569" + }, + "name": "Machine Learning Services Workspaces Computes", + "description": "This module deploys a Machine Learning Services Workspaces Compute.\n\nAttaching a compute is not idempotent and will fail in case you try to redeploy over an existing compute in AML (see parameter `deployCompute`).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + } + }, + "parameters": { + "machineLearningWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "minLength": 2, + "maxLength": 16, + "metadata": { + "description": "Required. Name of the compute." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Specifies the location of the resource." + } + }, + "sku": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Basic", + "Free", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Specifies the sku, also referred as \"edition\". Required for creating a compute resource." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Contains resource tags defined as key-value pairs. Ignored when attaching a compute resource, i.e. when you provide a resource ID." + } + }, + "deployCompute": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Flag to specify whether to deploy the compute. Required only for attach (i.e. providing a resource ID), as in this case the operation is not idempotent, i.e. a second deployment will fail. Therefore, this flag needs to be set to \"false\" as long as the compute resource exists." + } + }, + "computeLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for the underlying compute. Ignored when attaching a compute resource, i.e. when you provide a resource ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the Machine Learning compute." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Opt-out of local authentication and ensure customers can use only MSI and AAD exclusively for authentication." + } + }, + "resourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ARM resource ID of the underlying compute." + } + }, + "computeType": { + "type": "string", + "allowedValues": [ + "AKS", + "AmlCompute", + "ComputeInstance", + "Databricks", + "DataFactory", + "DataLakeAnalytics", + "HDInsight", + "Kubernetes", + "SynapseSpark", + "VirtualMachine" + ], + "metadata": { + "description": "Required. Set the object type." + } + }, + "properties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the compute. Will be ignored in case \"resourceId\" is set." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + } + }, + "variables": { + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" + }, + "resources": { + "machineLearningWorkspace": { + "existing": true, + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('machineLearningWorkspaceName')]" + }, + "compute": { + "condition": "[equals(parameters('deployCompute'), true())]", + "type": "Microsoft.MachineLearningServices/workspaces/computes", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('machineLearningWorkspaceName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[if(empty(parameters('resourceId')), parameters('tags'), null())]", + "sku": "[if(empty(parameters('resourceId')), createObject('name', parameters('sku'), 'tier', parameters('sku')), null())]", + "identity": "[if(empty(parameters('resourceId')), variables('identity'), null())]", + "properties": "[union(createObject('description', parameters('description'), 'disableLocalAuth', parameters('disableLocalAuth'), 'computeType', parameters('computeType')), if(not(empty(parameters('resourceId'))), createObject('resourceId', parameters('resourceId')), createObject('computeLocation', parameters('computeLocation'), 'properties', parameters('properties'))))]", + "dependsOn": [ + "machineLearningWorkspace" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the compute." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the compute." + }, + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/computes', parameters('machineLearningWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the compute was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('compute', '2022-10-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('compute', '2022-10-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "workspace", + "workspace_privateEndpoints" + ] + }, + "workspace_connections": { + "copy": { + "name": "workspace_connections", + "count": "[length(parameters('connections'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}-connection', parameters('name'), parameters('connections')[copyIndex()].name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "machineLearningWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('connections')[copyIndex()].name]" + }, + "category": { + "value": "[parameters('connections')[copyIndex()].category]" + }, + "expiryTime": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'expiryTime')]" + }, + "isSharedToAll": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'isSharedToAll')]" + }, + "metadata": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'metadata')]" + }, + "sharedUserList": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'sharedUserList')]" + }, + "target": { + "value": "[parameters('connections')[copyIndex()].target]" + }, + "value": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'value')]" + }, + "connectionProperties": { + "value": "[parameters('connections')[copyIndex()].connectionProperties]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "2277907099827503661" + }, + "name": "Machine Learning Services Workspaces Connections", + "description": "This module creates a connection in a Machine Learning Services workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "metadataType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. The metadata key-value pairs." + } + } + }, + "categoryType": { + "type": "string", + "allowedValues": [ + "ADLSGen2", + "AIServices", + "AmazonMws", + "AmazonRdsForOracle", + "AmazonRdsForSqlServer", + "AmazonRedshift", + "AmazonS3Compatible", + "ApiKey", + "AzureBlob", + "AzureDataExplorer", + "AzureDatabricksDeltaLake", + "AzureMariaDb", + "AzureMySqlDb", + "AzureOneLake", + "AzureOpenAI", + "AzurePostgresDb", + "AzureSqlDb", + "AzureSqlMi", + "AzureSynapseAnalytics", + "AzureTableStorage", + "BingLLMSearch", + "Cassandra", + "CognitiveSearch", + "CognitiveService", + "Concur", + "ContainerRegistry", + "CosmosDb", + "CosmosDbMongoDbApi", + "Couchbase", + "CustomKeys", + "Db2", + "Drill", + "Dynamics", + "DynamicsAx", + "DynamicsCrm", + "Eloqua", + "FileServer", + "FtpServer", + "GenericContainerRegistry", + "GenericHttp", + "GenericRest", + "Git", + "GoogleAdWords", + "GoogleBigQuery", + "GoogleCloudStorage", + "Greenplum", + "Hbase", + "Hdfs", + "Hive", + "Hubspot", + "Impala", + "Informix", + "Jira", + "Magento", + "MariaDb", + "Marketo", + "MicrosoftAccess", + "MongoDbAtlas", + "MongoDbV2", + "MySql", + "Netezza", + "ODataRest", + "Odbc", + "Office365", + "OpenAI", + "Oracle", + "OracleCloudStorage", + "OracleServiceCloud", + "PayPal", + "Phoenix", + "PostgreSql", + "Presto", + "PythonFeed", + "QuickBooks", + "Redis", + "Responsys", + "S3", + "Salesforce", + "SalesforceMarketingCloud", + "SalesforceServiceCloud", + "SapBw", + "SapCloudForCustomer", + "SapEcc", + "SapHana", + "SapOpenHub", + "SapTable", + "Serp", + "Serverless", + "ServiceNow", + "Sftp", + "SharePointOnlineList", + "Shopify", + "Snowflake", + "Spark", + "SqlServer", + "Square", + "Sybase", + "Teradata", + "Vertica", + "WebTable", + "Xero", + "Zoho" + ], + "metadata": { + "__bicep_export!": true + } + }, + "aadAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AAD" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "accessKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccessKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccessKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "accountKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccountKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccountKey", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "apiKeyAuthWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ApiKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionApiKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "CustomKeys" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/customKeysType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "managedIdentityAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ManagedIdentity" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionManagedIdentityType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "noneAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "None" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "oauth2AuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "OAuth2" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionOAuth2Type", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "patAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "PAT" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionPersonalAccessTokenType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "sasAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "SAS" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionSharedAccessSignatureType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "servicePrincipalAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ServicePrincipal" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionServicePrincipalType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "usernamePasswordAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "UsernamePassword" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionUsernamePasswordType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysType": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. Key-value pairs for the custom keys." + } + }, + "metadata": { + "description": "Required. The custom keys for the connection." + } + } + } + }, + "workspaceConnectionAccessKeyType": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "metadata": { + "description": "Required. The connection access key ID." + } + }, + "secretAccessKey": { + "type": "string", + "metadata": { + "description": "Required. The connection secret access key." + } + } + } + }, + "workspaceConnectionAccountKey": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection key." + } + } + } + }, + "workspaceConnectionApiKeyType": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection API key." + } + } + } + }, + "workspaceConnectionManagedIdentityType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity ID." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity resource ID." + } + } + } + }, + "workspaceConnectionOAuth2Type": { + "type": "object", + "properties": { + "authUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection auth URL. Required by Concur connection category." + } + }, + "clientId": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Required. The connection client ID in the format of UUID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "developerToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection developer token. Required by GoogleAdWords connection category." + } + }, + "password": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + }, + "refreshToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The connection tenant ID. Required by QuickBooks and Xero connection categories." + } + }, + "username": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + } + } + }, + "workspaceConnectionPersonalAccessTokenType": { + "type": "object", + "properties": { + "pat": { + "type": "string", + "metadata": { + "description": "Required. The connection personal access token." + } + } + } + }, + "workspaceConnectionSharedAccessSignatureType": { + "type": "object", + "properties": { + "sas": { + "type": "string", + "metadata": { + "description": "Required. The connection SAS token." + } + } + } + }, + "workspaceConnectionServicePrincipalType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection client ID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The connection tenant ID." + } + } + } + }, + "workspaceConnectionUsernamePasswordType": { + "type": "object", + "properties": { + "password": { + "type": "string", + "metadata": { + "description": "Required. The connection password." + } + }, + "securityToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to 'UsernamePassword'." + } + }, + "username": { + "type": "string", + "metadata": { + "description": "Required. The connection username." + } + } + } + }, + "connectionPropertyType": { + "type": "secureObject", + "discriminator": { + "propertyName": "authType", + "mapping": { + "AAD": { + "$ref": "#/definitions/aadAuthTypeWorkspaceConnectionPropertyType" + }, + "AccessKey": { + "$ref": "#/definitions/accessKeyAuthTypeWorkspaceConnectionPropertyType" + }, + "ApiKey": { + "$ref": "#/definitions/apiKeyAuthWorkspaceConnectionPropertyType" + }, + "CustomKeys": { + "$ref": "#/definitions/customKeysWorkspaceConnectionPropertyType" + }, + "ManagedIdentity": { + "$ref": "#/definitions/managedIdentityAuthTypeWorkspaceConnectionPropertyType" + }, + "None": { + "$ref": "#/definitions/noneAuthTypeWorkspaceConnectionPropertyType" + }, + "OAuth2": { + "$ref": "#/definitions/oauth2AuthTypeWorkspaceConnectionPropertyType" + }, + "PAT": { + "$ref": "#/definitions/patAuthTypeWorkspaceConnectionPropertyType" + }, + "SAS": { + "$ref": "#/definitions/sasAuthTypeWorkspaceConnectionPropertyType" + }, + "ServicePrincipal": { + "$ref": "#/definitions/servicePrincipalAuthTypeWorkspaceConnectionPropertyType" + }, + "UsernamePassword": { + "$ref": "#/definitions/usernamePasswordAuthTypeWorkspaceConnectionPropertyType" + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the connection to create." + } + }, + "machineLearningWorkspaceName": { + "type": "string", + "metadata": { + "description": "Required. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." + } + }, + "category": { + "$ref": "#/definitions/categoryType", + "metadata": { + "description": "Required. Category of the connection." + } + }, + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiry time of the connection." + } + }, + "isSharedToAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether the connection is shared to all users in the workspace." + } + }, + "metadata": { + "$ref": "#/definitions/metadataType", + "defaultValue": {}, + "metadata": { + "description": "Optional. User metadata for the connection." + } + }, + "sharedUserList": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The shared user list of the connection." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Required. The target of the connection." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Value details of the workspace connection." + } + }, + "connectionProperties": { + "$ref": "#/definitions/connectionPropertyType", + "metadata": { + "description": "Required. The properties of the connection, specific to the auth type." + } + } + }, + "resources": { + "machineLearningWorkspace": { + "existing": true, + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('machineLearningWorkspaceName')]" + }, + "connection": { + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01", + "name": "[format('{0}/{1}', parameters('machineLearningWorkspaceName'), parameters('name'))]", + "properties": "[union(createObject('category', parameters('category'), 'expiryTime', parameters('expiryTime'), 'isSharedToAll', parameters('isSharedToAll'), 'metadata', parameters('metadata'), 'sharedUserList', parameters('sharedUserList'), 'target', parameters('target'), 'value', parameters('value')), parameters('connectionProperties'))]", + "dependsOn": [ + "machineLearningWorkspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the connection." + }, + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/connections', parameters('machineLearningWorkspaceName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the connection." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the connection was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_privateEndpoints": { + "copy": { + "name": "workspace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'amlworkspace'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'amlworkspace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'amlworkspace')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'amlworkspace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'amlworkspace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "3308873178893851812" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDnsZoneConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", + "input": { + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" + } + } + } + ] + }, + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the machine learning service." + }, + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the machine learning service was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the machine learning service." + }, + "value": "[parameters('name')]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('workspace', '2024-04-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('workspace', '2024-04-01-preview', 'full').location]" + } + } + } + } + }, + "keyVaultAccess": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-keyvault', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('keyVaultName')]" + }, + "accessPolicies": { + "value": [ + { + "objectId": "[reference('project').outputs.systemAssignedMIPrincipalId.value]", + "permissions": { + "secrets": [ + "get", + "list" + ] + } + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "10085839006881327962" + }, + "name": "Key Vaults", + "description": "This module deploys a Key Vault.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "accessPoliciesType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tenant ID that is used for authenticating requests to the key vault." + } + }, + "objectId": { + "type": "string", + "metadata": { + "description": "Required. The object ID of a user, service principal or security group in the tenant for the vault." + } + }, + "applicationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Application ID of the client making request on behalf of a principal." + } + }, + "permissions": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "getrotationpolicy", + "import", + "list", + "purge", + "recover", + "release", + "restore", + "rotate", + "setrotationpolicy", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to keys." + } + }, + "secrets": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to secrets." + } + }, + "certificates": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "purge", + "recover", + "restore", + "setissuers", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to certificates." + } + }, + "storage": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "deletesas", + "get", + "getsas", + "list", + "listsas", + "purge", + "recover", + "regeneratekey", + "restore", + "set", + "setsas", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to storage accounts." + } + } + }, + "metadata": { + "description": "Required. Permissions the identity has for keys, secrets and certificates." + } + } + } + }, + "nullable": true + }, + "secretsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributes": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Defines whether the secret is enabled or disabled." + } + }, + "exp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Defines when the secret will become invalid. Defined in seconds since 1970-01-01T00:00:00Z." + } + }, + "nbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. If set, defines the date from which onwards the secret becomes valid. Defined in seconds since 1970-01-01T00:00:00Z." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Contains attributes of the secret." + } + }, + "contentType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The content type of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + } + }, + "nullable": true + }, + "keysType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the key." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributes": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Defines whether the key is enabled or disabled." + } + }, + "exp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Defines when the key will become invalid. Defined in seconds since 1970-01-01T00:00:00Z." + } + }, + "nbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. If set, defines the date from which onwards the key becomes valid. Defined in seconds since 1970-01-01T00:00:00Z." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Contains attributes of the key." + } + }, + "curveName": { + "type": "string", + "allowedValues": [ + "P-256", + "P-256K", + "P-384", + "P-521" + ], + "nullable": true, + "metadata": { + "description": "Optional. The elliptic curve name. Only works if \"keySize\" equals \"EC\" or \"EC-HSM\". Default is \"P-256\"." + } + }, + "keyOps": { + "type": "array", + "allowedValues": [ + "decrypt", + "encrypt", + "import", + "release", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. The allowed operations on this key." + } + }, + "keySize": { + "type": "int", + "allowedValues": [ + 2048, + 3072, + 4096 + ], + "nullable": true, + "metadata": { + "description": "Optional. The key size in bits. Only works if \"keySize\" equals \"RSA\" or \"RSA-HSM\". Default is \"4096\"." + } + }, + "kty": { + "type": "string", + "allowedValues": [ + "EC", + "EC-HSM", + "RSA", + "RSA-HSM" + ], + "nullable": true, + "metadata": { + "description": "Optional. The type of the key. Default is \"EC\"." + } + }, + "releasePolicy": { + "type": "object", + "properties": { + "contentType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Content type and version of key release policy." + } + }, + "data": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Blob encoding the policy rules under which the key can be released." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Key release policy." + } + }, + "rotationPolicy": { + "$ref": "#/definitions/rotationPoliciesType", + "nullable": true, + "metadata": { + "description": "Optional. Key rotation policy." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + } + }, + "nullable": true + }, + "rotationPoliciesType": { + "type": "object", + "properties": { + "attributes": { + "type": "object", + "properties": { + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiration time for the new key version. It should be in ISO8601 format. Eg: \"P90D\", \"P1Y\"." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The attributes of key rotation policy." + } + }, + "lifetimeActions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "action": { + "type": "object", + "properties": { + "type": { + "type": "string", + "allowedValues": [ + "Notify", + "Rotate" + ], + "nullable": true, + "metadata": { + "description": "Optional. The type of action." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The action of key rotation policy lifetimeAction." + } + }, + "trigger": { + "type": "object", + "properties": { + "timeAfterCreate": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The time duration after key creation to rotate the key. It only applies to rotate. It will be in ISO 8601 duration format. Eg: \"P90D\", \"P1Y\"." + } + }, + "timeBeforeExpiry": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The time duration before key expiring to rotate or notify. It will be in ISO 8601 duration format. Eg: \"P90D\", \"P1Y\"." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The trigger of key rotation policy lifetimeAction." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The lifetimeActions for key rotation action." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Required. Name of the Key Vault. Must be globally unique." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "accessPolicies": { + "$ref": "#/definitions/accessPoliciesType", + "metadata": { + "description": "Optional. All access policies to create." + } + }, + "secrets": { + "$ref": "#/definitions/secretsType", + "nullable": true, + "metadata": { + "description": "Optional. All secrets to create." + } + }, + "keys": { + "$ref": "#/definitions/keysType", + "nullable": true, + "metadata": { + "description": "Optional. All keys to create." + } + }, + "enableVaultForDeployment": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for deployment by script or compute." + } + }, + "enableVaultForTemplateDeployment": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the vault is enabled for a template deployment." + } + }, + "enableVaultForDiskEncryption": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if the azure platform has access to the vault for enabling disk encryption scenarios." + } + }, + "enableSoftDelete": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Switch to enable/disable Key Vault's soft delete feature." + } + }, + "softDeleteRetentionInDays": { + "type": "int", + "defaultValue": 90, + "metadata": { + "description": "Optional. softDelete data retention days. It accepts >=7 and <=90." + } + }, + "enableRbacAuthorization": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Property that controls how data actions are authorized. When true, the key vault will use Role Based Access Control (RBAC) for authorization of data actions, and the access policies specified in vault properties will be ignored. When false, the key vault will use the access policies specified in vault properties, and any policy stored on Azure Resource Manager will be ignored. Note that management actions are always authorized with RBAC." + } + }, + "createMode": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The vault's create mode to indicate whether the vault need to be recovered or not. - recover or default." + } + }, + "enablePurgeProtection": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Provide 'true' to enable Key Vault's purge protection feature." + } + }, + "sku": { + "type": "string", + "defaultValue": "premium", + "allowedValues": [ + "premium", + "standard" + ], + "metadata": { + "description": "Optional. Specifies the SKU for the vault." + } + }, + "networkAcls": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Rules governing the accessibility of the resource from specific network locations." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + }, + { + "name": "formattedAccessPolicies", + "count": "[length(coalesce(parameters('accessPolicies'), createArray()))]", + "input": { + "applicationId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'applicationId'), '')]", + "objectId": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].objectId]", + "permissions": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].permissions]", + "tenantId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'tenantId'), tenant().tenantId)]" + } + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Certificates Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985')]", + "Key Vault Certificate User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db79e9a7-68ee-4b58-9aeb-b90e7c24fcba')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Crypto Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')]", + "Key Vault Crypto Service Encryption User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]", + "Key Vault Crypto User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Key Vault Secrets Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')]", + "Key Vault Secrets User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.keyvault-vault.{0}.{1}', replace('0.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "keyVault": { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "enabledForDeployment": "[parameters('enableVaultForDeployment')]", + "enabledForTemplateDeployment": "[parameters('enableVaultForTemplateDeployment')]", + "enabledForDiskEncryption": "[parameters('enableVaultForDiskEncryption')]", + "enableSoftDelete": "[parameters('enableSoftDelete')]", + "softDeleteRetentionInDays": "[parameters('softDeleteRetentionInDays')]", + "enableRbacAuthorization": "[parameters('enableRbacAuthorization')]", + "createMode": "[parameters('createMode')]", + "enablePurgeProtection": "[if(parameters('enablePurgeProtection'), parameters('enablePurgeProtection'), null())]", + "tenantId": "[subscription().tenantId]", + "accessPolicies": "[variables('formattedAccessPolicies')]", + "sku": { + "name": "[parameters('sku')]", + "family": "A" + }, + "networkAcls": "[if(not(empty(coalesce(parameters('networkAcls'), createObject()))), createObject('bypass', tryGet(parameters('networkAcls'), 'bypass'), 'defaultAction', tryGet(parameters('networkAcls'), 'defaultAction'), 'virtualNetworkRules', coalesce(tryGet(parameters('networkAcls'), 'virtualNetworkRules'), createArray()), 'ipRules', coalesce(tryGet(parameters('networkAcls'), 'ipRules'), createArray())), null())]", + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(coalesce(parameters('privateEndpoints'), createArray()))), empty(coalesce(parameters('networkAcls'), createObject()))), 'Disabled', null()))]" + } + }, + "keyVault_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_diagnosticSettings": { + "copy": { + "name": "keyVault_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_roleAssignments": { + "copy": { + "name": "keyVault_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_accessPolicies": { + "condition": "[not(empty(parameters('accessPolicies')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-AccessPolicies', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('name')]" + }, + "accessPolicies": { + "value": "[parameters('accessPolicies')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "7494731697751039419" + }, + "name": "Key Vault Access Policies", + "description": "This module deploys a Key Vault Access Policy.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "accessPoliciesType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tenant ID that is used for authenticating requests to the key vault." + } + }, + "objectId": { + "type": "string", + "metadata": { + "description": "Required. The object ID of a user, service principal or security group in the tenant for the vault." + } + }, + "applicationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Application ID of the client making request on behalf of a principal." + } + }, + "permissions": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "getrotationpolicy", + "import", + "list", + "purge", + "recover", + "release", + "restore", + "rotate", + "setrotationpolicy", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to keys." + } + }, + "secrets": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to secrets." + } + }, + "certificates": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "purge", + "recover", + "restore", + "setissuers", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to certificates." + } + }, + "storage": { + "type": "array", + "allowedValues": [ + "all", + "backup", + "delete", + "deletesas", + "get", + "getsas", + "list", + "listsas", + "purge", + "recover", + "regeneratekey", + "restore", + "set", + "setsas", + "update" + ], + "nullable": true, + "metadata": { + "description": "Optional. Permissions to storage accounts." + } + } + }, + "metadata": { + "description": "Required. Permissions the identity has for keys, secrets and certificates." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "accessPolicies": { + "$ref": "#/definitions/accessPoliciesType", + "metadata": { + "description": "Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault's tenant ID." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedAccessPolicies", + "count": "[length(coalesce(parameters('accessPolicies'), createArray()))]", + "input": { + "applicationId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'applicationId'), '')]", + "objectId": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].objectId]", + "permissions": "[coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')].permissions]", + "tenantId": "[coalesce(tryGet(coalesce(parameters('accessPolicies'), createArray())[copyIndex('formattedAccessPolicies')], 'tenantId'), tenant().tenantId)]" + } + } + ] + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "policies": { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), 'add')]", + "properties": { + "accessPolicies": "[variables('formattedAccessPolicies')]" + }, + "dependsOn": [ + "keyVault" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the access policies assignment was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the access policies assignment." + }, + "value": "add" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the access policies assignment." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/accessPolicies', parameters('keyVaultName'), 'add')]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_secrets": { + "copy": { + "name": "keyVault_secrets", + "count": "[length(coalesce(parameters('secrets'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-Secret-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('secrets'), createArray())[copyIndex()].name]" + }, + "value": { + "value": "[coalesce(parameters('secrets'), createArray())[copyIndex()].value]" + }, + "keyVaultName": { + "value": "[parameters('name')]" + }, + "attributesEnabled": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'enabled')]" + }, + "attributesExp": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'exp')]" + }, + "attributesNbf": { + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'nbf')]" + }, + "contentType": { + "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'contentType')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "114626909766354577" + }, + "name": "Key Vault Secrets", + "description": "This module deploys a Key Vault Secret.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributesEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Determines whether the object is enabled." + } + }, + "attributesExp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Expiry date in seconds since 1970-01-01T00:00:00Z. For security reasons, it is recommended to set an expiration date whenever possible." + } + }, + "attributesNbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Not before date in seconds since 1970-01-01T00:00:00Z." + } + }, + "contentType": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Optional. The content type of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Key Vault Secrets Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')]", + "Key Vault Secrets User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "secret": { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "contentType": "[parameters('contentType')]", + "attributes": { + "enabled": "[parameters('attributesEnabled')]", + "exp": "[parameters('attributesExp')]", + "nbf": "[parameters('attributesNbf')]" + }, + "value": "[parameters('value')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "secret_roleAssignments": { + "copy": { + "name": "secret_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}/secrets/{1}', parameters('keyVaultName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "secret" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_keys": { + "copy": { + "name": "keyVault_keys", + "count": "[length(coalesce(parameters('keys'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-KeyVault-Key-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('keys'), createArray())[copyIndex()].name]" + }, + "keyVaultName": { + "value": "[parameters('name')]" + }, + "attributesEnabled": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'enabled')]" + }, + "attributesExp": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'exp')]" + }, + "attributesNbf": { + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'nbf')]" + }, + "curveName": "[if(and(not(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA')), not(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA-HSM'))), createObject('value', coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'curveName'), 'P-256')), createObject('value', null()))]", + "keyOps": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'keyOps')]" + }, + "keySize": "[if(or(equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA'), equals(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'RSA-HSM')), createObject('value', coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'keySize'), 4096)), createObject('value', null()))]", + "releasePolicy": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'releasePolicy'), createObject())]" + }, + "kty": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'kty'), 'EC')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "rotationPolicy": { + "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'rotationPolicy')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "14269695922191217406" + }, + "name": "Key Vault Keys", + "description": "This module deploys a Key Vault Key.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the key." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "attributesEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Determines whether the object is enabled." + } + }, + "attributesExp": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Expiry date in seconds since 1970-01-01T00:00:00Z. For security reasons, it is recommended to set an expiration date whenever possible." + } + }, + "attributesNbf": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Not before date in seconds since 1970-01-01T00:00:00Z." + } + }, + "curveName": { + "type": "string", + "defaultValue": "P-256", + "allowedValues": [ + "P-256", + "P-256K", + "P-384", + "P-521" + ], + "metadata": { + "description": "Optional. The elliptic curve name." + } + }, + "keyOps": { + "type": "array", + "nullable": true, + "allowedValues": [ + "decrypt", + "encrypt", + "import", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ], + "metadata": { + "description": "Optional. Array of JsonWebKeyOperation." + } + }, + "keySize": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The key size in bits. For example: 2048, 3072, or 4096 for RSA." + } + }, + "kty": { + "type": "string", + "defaultValue": "EC", + "allowedValues": [ + "EC", + "EC-HSM", + "RSA", + "RSA-HSM" + ], + "metadata": { + "description": "Optional. The type of the key." + } + }, + "releasePolicy": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Key release policy." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "rotationPolicy": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Key rotation policy properties object." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Key Vault Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')]", + "Key Vault Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')]", + "Key Vault Crypto Officer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')]", + "Key Vault Crypto Service Encryption User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]", + "Key Vault Crypto User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "Key Vault Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "key": { + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "attributes": { + "enabled": "[parameters('attributesEnabled')]", + "exp": "[parameters('attributesExp')]", + "nbf": "[parameters('attributesNbf')]" + }, + "curveName": "[parameters('curveName')]", + "keyOps": "[parameters('keyOps')]", + "keySize": "[parameters('keySize')]", + "kty": "[parameters('kty')]", + "rotationPolicy": "[coalesce(parameters('rotationPolicy'), createObject())]", + "release_policy": "[coalesce(parameters('releasePolicy'), createObject())]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "key_roleAssignments": { + "copy": { + "name": "key_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}/keys/{1}', parameters('keyVaultName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "key" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the key." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the key was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + }, + "keyVault_privateEndpoints": { + "copy": { + "name": "keyVault_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-keyVault-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.KeyVault/vaults', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.KeyVault/vaults', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.KeyVault/vaults', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDnsZoneConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", + "input": { + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" + } + } + } + ] + }, + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + } + } + } + }, + "dependsOn": [ + "keyVault" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the key vault." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the key vault was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the key vault." + }, + "value": "[parameters('name')]" + }, + "uri": { + "type": "string", + "metadata": { + "description": "The URI of the key vault." + }, + "value": "[reference('keyVault').vaultUri]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('keyVault', '2022-07-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the key vault." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + } + } + } + }, + "dependsOn": [ + "keyVault", + "project" + ] + }, + "mlServiceRoleAssigned": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-roleassignment', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('userAssignedtName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "roleAssignments": { + "copy": [ + { + "name": "value", + "count": "[length(parameters('roleDefinitionIdOrName'))]", + "input": "[createObject('principalId', reference('project').outputs.systemAssignedMIPrincipalId.value, 'roleDefinitionIdOrName', parameters('roleDefinitionIdOrName')[copyIndex('value')], 'principalType', 'ServicePrincipal')]" + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "10609859695208799167" + }, + "name": "User Assigned Identities", + "description": "This module deploys a User Assigned Identity.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "federatedIdentityCredentialsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the federated identity credential." + } + }, + "audiences": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The list of audiences that can appear in the issued token." + } + }, + "issuer": { + "type": "string", + "metadata": { + "description": "Required. The URL of the issuer to be trusted." + } + }, + "subject": { + "type": "string", + "metadata": { + "description": "Required. The identifier of the external identity." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the User Assigned Identity." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "federatedIdentityCredentials": { + "$ref": "#/definitions/federatedIdentityCredentialsType", + "metadata": { + "description": "Optional. The federated identity credentials list to indicate which token from the external IdP should be trusted by your application. Federated identity credentials are supported on applications only. A maximum of 20 federated identity credentials can be added per application object." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Managed Identity Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e40ec5ca-96e0-45a2-b4ff-59039f2c2b59')]", + "Managed Identity Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f1a07417-d97a-45cb-824c-7a7467783830')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.managedidentity-userassignedidentity.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "userAssignedIdentity": { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]" + }, + "userAssignedIdentity_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ManagedIdentity/userAssignedIdentities/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "userAssignedIdentity" + ] + }, + "userAssignedIdentity_roleAssignments": { + "copy": { + "name": "userAssignedIdentity_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ManagedIdentity/userAssignedIdentities/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "userAssignedIdentity" + ] + }, + "userAssignedIdentity_federatedIdentityCredentials": { + "copy": { + "name": "userAssignedIdentity_federatedIdentityCredentials", + "count": "[length(coalesce(parameters('federatedIdentityCredentials'), createArray()))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-UserMSI-FederatedIdentityCredential-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].name]" + }, + "userAssignedIdentityName": { + "value": "[parameters('name')]" + }, + "audiences": { + "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].audiences]" + }, + "issuer": { + "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].issuer]" + }, + "subject": { + "value": "[coalesce(parameters('federatedIdentityCredentials'), createArray())[copyIndex()].subject]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "3716898257490923786" + }, + "name": "User Assigned Identity Federated Identity Credential", + "description": "This module deploys a User Assigned Identity Federated Identity Credential.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "userAssignedIdentityName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent user assigned identity. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "audiences": { + "type": "array", + "metadata": { + "description": "Required. The list of audiences that can appear in the issued token. Should be set to api://AzureADTokenExchange for Azure AD. It says what Microsoft identity platform should accept in the aud claim in the incoming token. This value represents Azure AD in your external identity provider and has no fixed value across identity providers - you might need to create a new application registration in your IdP to serve as the audience of this token." + } + }, + "issuer": { + "type": "string", + "metadata": { + "description": "Required. The URL of the issuer to be trusted. Must match the issuer claim of the external token being exchanged." + } + }, + "subject": { + "type": "string", + "metadata": { + "description": "Required. The identifier of the external software workload within the external identity provider. Like the audience value, it has no fixed format, as each IdP uses their own - sometimes a GUID, sometimes a colon delimited identifier, sometimes arbitrary strings. The value here must match the sub claim within the token presented to Azure AD." + } + } + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials", + "apiVersion": "2023-01-31", + "name": "[format('{0}/{1}', parameters('userAssignedIdentityName'), parameters('name'))]", + "properties": { + "audiences": "[parameters('audiences')]", + "issuer": "[parameters('issuer')]", + "subject": "[parameters('subject')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the federated identity credential." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the federated identity credential." + }, + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials', parameters('userAssignedIdentityName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the federated identity credential was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "userAssignedIdentity" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the user assigned identity." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the user assigned identity." + }, + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name'))]" + }, + "principalId": { + "type": "string", + "metadata": { + "description": "The principal ID (object ID) of the user assigned identity." + }, + "value": "[reference('userAssignedIdentity').principalId]" + }, + "clientId": { + "type": "string", + "metadata": { + "description": "The client ID (application ID) of the user assigned identity." + }, + "value": "[reference('userAssignedIdentity').clientId]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the user assigned identity was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('userAssignedIdentity', '2023-01-31', 'full').location]" + } + } + } + }, + "dependsOn": [ + "project" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the machine learning workspace were deployed into." + }, + "value": "[resourceGroup().name]" + }, + "projectResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the machine learning workspace." + }, + "value": "[reference('project').outputs.resourceId.value]" + }, + "projectName": { + "type": "string", + "metadata": { + "description": "The resource name of the machine learning workspace." + }, + "value": "[reference('project').outputs.name.value]" + }, + "projectPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the machine learning workspace." + }, + "value": "[reference('project').outputs.systemAssignedMIPrincipalId.value]" + } + } + } + }, + "dependsOn": [ + "hub", + "hubDependencies" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the module was deployed to." + }, + "value": "[resourceGroup().name]" + }, + "hubName": { + "type": "string", + "metadata": { + "description": "The name of the ai studio hub." + }, + "value": "[reference('hub').outputs.name.value]" + }, + "hubPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the ai studio hub." + }, + "value": "[reference('hub').outputs.principalId.value]" + }, + "projectName": { + "type": "string", + "metadata": { + "description": "The name of the ai studio project." + }, + "value": "[reference('project').outputs.projectName.value]" + }, + "projectPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the ai studio project." + }, + "value": "[reference('project').outputs.projectPrincipalId.value]" + }, + "keyVaultName": { + "type": "string", + "metadata": { + "description": "The name of the key vault." + }, + "value": "[reference('hubDependencies').outputs.keyVaultName.value]" + }, + "keyVaultEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the key vault." + }, + "value": "[reference('hubDependencies').outputs.keyVaultEndpoint.value]" + }, + "applicationInsightsName": { + "type": "string", + "metadata": { + "description": "The name of the application insights." + }, + "value": "[reference('hubDependencies').outputs.applicationInsightsName.value]" + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "The name of the log analytics workspace." + }, + "value": "[reference('hubDependencies').outputs.logAnalyticsWorkspaceName.value]" + }, + "containerRegistryName": { + "type": "string", + "metadata": { + "description": "The name of the container registry." + }, + "value": "[reference('hubDependencies').outputs.containerRegistryName.value]" + }, + "containerRegistryEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the container registry." + }, + "value": "[reference('hubDependencies').outputs.containerRegistryEndpoint.value]" + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "The name of the storage account." + }, + "value": "[reference('hubDependencies').outputs.storageAccountName.value]" + }, + "openAiName": { + "type": "string", + "metadata": { + "description": "The name of the cognitive services." + }, + "value": "[reference('hubDependencies').outputs.cognitiveServicesName.value]" + }, + "openAiEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the cognitive services." + }, + "value": "[reference('hubDependencies').outputs.cognitiveServicesEndpoint.value]" + }, + "searchServiceName": { + "type": "string", + "metadata": { + "description": "The name of the search service." + }, + "value": "[reference('hubDependencies').outputs.searchServiceName.value]" + }, + "searchServiceEndpoint": { + "type": "string", + "metadata": { + "description": "The endpoint of the search service." + }, + "value": "[reference('hubDependencies').outputs.searchServiceEndpoint.value]" + } + } +} \ No newline at end of file diff --git a/avm/ptn/azd/ml-ai-environment/modules/hub.bicep b/avm/ptn/azd/ml-ai-environment/modules/hub.bicep new file mode 100644 index 0000000000..a7fbd421ff --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/modules/hub.bicep @@ -0,0 +1,143 @@ +@description('Required. The AI Studio Hub Resource name.') +param name string + +@description('Optional. The display name of the AI Studio Hub Resource.') +param displayName string = name + +@description('Required. The storage account ID to use for the AI Studio Hub Resource.') +param storageAccountResourceId string + +@description('Required. The key vault ID to use for the AI Studio Hub Resource.') +param keyVaultResourceId string + +@description('Optional. The application insights ID to use for the AI Studio Hub Resource.') +param applicationInsightsResourceId string = '' + +@description('Optional. The container registry ID to use for the AI Studio Hub Resource.') +param containerRegistryResourceId string = '' + +@description('Required. The OpenAI Cognitive Services account name to use for the AI Studio Hub Resource.') +param openAiName string + +@description('Optional. The Azure Cognitive Search service name to use for the AI Studio Hub Resource.') +param aiSearchName string = '' + +@description('Required. The Azure Cognitive Search service connection name to use for the AI Studio Hub Resource.') +param aiSearchConnectionName string + +@description('Required. The OpenAI Content Safety connection name to use for the AI Studio Hub Resource.') +param openAiContentSafetyConnectionName string + +@description('Optional. The SKU name to use for the AI Studio Hub Resource.') +param skuName string = 'Basic' + +@description('Optional. The SKU tier to use for the AI Studio Hub Resource.') +@allowed(['Basic', 'Free', 'Premium', 'Standard']) +param skuTier string = 'Basic' + +@description('Optional. The public network access setting to use for the AI Studio Hub Resource.') +@allowed(['Enabled', 'Disabled']) +param publicNetworkAccess string = 'Enabled' + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object = {} + +// ================ // +// Resources // +// ================ // + +resource hub 'Microsoft.MachineLearningServices/workspaces@2024-04-01' = { + name: name + location: location + tags: tags + sku: { + name: skuName + tier: skuTier + } + kind: 'Hub' + identity: { + type: 'SystemAssigned' + } + properties: { + friendlyName: displayName + storageAccount: storageAccountResourceId + keyVault: keyVaultResourceId + applicationInsights: !empty(applicationInsightsResourceId) ? applicationInsightsResourceId : null + containerRegistry: !empty(containerRegistryResourceId) ? containerRegistryResourceId : null + hbiWorkspace: false + managedNetwork: { + isolationMode: 'Disabled' + } + v1LegacyMode: false + publicNetworkAccess: publicNetworkAccess + discoveryUrl: 'https://${location}.api.azureml.ms/discovery' + } + + resource openAiConnection 'connections@2024-04-01-preview' = { + name: 'aoai-connection' + properties: { + category: 'AzureOpenAI' + authType: 'ApiKey' + isSharedToAll: true + target: openAi.properties.endpoints['OpenAI Language Model Instance API'] + metadata: { + ApiVersion: '2024-02-01' + ApiType: 'azure' + ResourceId: openAi.id + } + credentials: { + key: openAi.listKeys().key1 + } + } + } + + resource contentSafetyConnection 'connections' = { + name: openAiContentSafetyConnectionName + properties: { + category: 'AzureOpenAI' + authType: 'ApiKey' + isSharedToAll: true + target: openAi.properties.endpoints['Content Safety'] + metadata: { + ApiVersion: '2023-07-01-preview' + ApiType: 'azure' + ResourceId: openAi.id + } + credentials: { + key: openAi.listKeys().key1 + } + } + } + + resource searchConnection 'connections' = if (!empty(aiSearchName)) { + name: aiSearchConnectionName + properties: { + category: 'CognitiveSearch' + authType: 'ApiKey' + isSharedToAll: true + target: 'https://${search.name}.search.windows.net/' + credentials: { + key: !empty(aiSearchName) ? search.listAdminKeys().primaryKey : '' + } + } + } +} + +resource openAi 'Microsoft.CognitiveServices/accounts@2023-05-01' existing = { + name: openAiName +} + +resource search 'Microsoft.Search/searchServices@2021-04-01-preview' existing = if (!empty(aiSearchName)) { + name: aiSearchName +} + +// ================ // +// Outputs // +// ================ // + +output name string = hub.name +output resourceId string = hub.id +output principalId string = hub.identity.principalId diff --git a/avm/ptn/azd/ml-ai-environment/tests/e2e/defaults/main.test.bicep b/avm/ptn/azd/ml-ai-environment/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..103d0e465a --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,52 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-azd-ml-ai-environment-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'maemin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + location: resourceLocation + keyVaultName: '${namePrefix}${serviceShort}kv00' + storageAccountName: '${namePrefix}${serviceShort}sa001' + hubName: '${namePrefix}${serviceShort}hub001' + projectName: '${namePrefix}${serviceShort}pro001' + userAssignedtName: '${namePrefix}${serviceShort}ua001' + cognitiveServicesName: '${namePrefix}${serviceShort}cs001' + openAiConnectionName: '${namePrefix}${serviceShort}ai001-connection' + searchConnectionName: '${namePrefix}${serviceShort}search001-connection' + } +} diff --git a/avm/ptn/azd/ml-ai-environment/tests/e2e/max/main.test.bicep b/avm/ptn/azd/ml-ai-environment/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..db92b357b2 --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/tests/e2e/max/main.test.bicep @@ -0,0 +1,70 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module using large parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-azd-ml-ai-environment-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'maemax' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + location: resourceLocation + hubName: '${namePrefix}${serviceShort}hub001' + keyVaultName: '${namePrefix}${serviceShort}kv001' + cognitiveServicesName: '${namePrefix}${serviceShort}cs001' + projectName: '${namePrefix}${serviceShort}pro001' + storageAccountName: '${namePrefix}${serviceShort}sta001' + userAssignedtName: '${namePrefix}${serviceShort}ua001' + containerRegistryName: '${namePrefix}${serviceShort}cr001' + applicationInsightsName: '${namePrefix}${serviceShort}appin001' + logAnalyticsName: '${namePrefix}${serviceShort}la001' + searchServiceName: '${namePrefix}${serviceShort}search001' + openAiConnectionName: '${namePrefix}${serviceShort}ai001-connection' + searchConnectionName: '${namePrefix}${serviceShort}search001-connection' + cognitiveServicesDeployments: [ + { + name: 'gpt-35-turbo' + model: { + name: 'gpt-35-turbo' + format: 'OpenAI' + version: '0613' + } + sku: { + name: 'Standard' + capacity: 20 + } + } + ] + } +} diff --git a/avm/ptn/azd/ml-ai-environment/version.json b/avm/ptn/azd/ml-ai-environment/version.json new file mode 100644 index 0000000000..8def869ede --- /dev/null +++ b/avm/ptn/azd/ml-ai-environment/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/ptn/azd/ml-hub-dependencies/main.bicep b/avm/ptn/azd/ml-hub-dependencies/main.bicep new file mode 100644 index 0000000000..0d2d3e3c37 --- /dev/null +++ b/avm/ptn/azd/ml-hub-dependencies/main.bicep @@ -0,0 +1,475 @@ +metadata name = 'Azure Machine Learning Dependencies' +metadata description = '''Creates all the dependencies required for a Machine Learning Service. + +**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.''' +metadata owner = 'Azure/module-maintainers' + +@description('Optional. The resource portal dashboards name.') +param applicationInsightsDashboardName string = '' + +@description('Optional. The resource insights components name.') +param applicationInsightsName string = '' + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. The resource operational insights workspaces name.') +param logAnalyticsName string = '' + +@description('Required. Name of the key vault.') +param keyVaultName string + +@description('Required. Name of the storage account.') +param storageAccountName string + +@description('Required. Name of the OpenAI cognitive services.') +param cognitiveServicesName string + +@description('Optional. Name of the container registry.') +param containerRegistryName string = '' + +@description('Optional. Name of the Azure Cognitive Search service.') +param searchServiceName string = '' + +@description('Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false.') +param allowBlobPublicAccess bool = true + +@description('Optional. Allows you to specify the type of endpoint in the storage account. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier.') +@allowed([ + '' + 'AzureDnsZone' + 'Standard' +]) +param dnsEndpointType string = 'Standard' + +@description('Optional. Whether or not public network access is allowed for the storage account. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set.') +@allowed([ + '' + 'Enabled' + 'Disabled' +]) +param publicNetworkAccess string = 'Enabled' + +@description('Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny.') +param networkAcls object = { + bypass: 'AzureServices' + defaultAction: 'Allow' +} + +@description('Optional. Blob service and containers to deploy.') +param blobServices object = { + containers: [ + { + name: 'default' + } + ] + corsRules: [ + { + allowedOrigins: [ + 'https://mlworkspace.azure.ai' + 'https://ml.azure.com' + 'https://*.ml.azure.com' + 'https://ai.azure.com' + 'https://*.ai.azure.com' + 'https://mlworkspacecanary.azure.ai' + 'https://mlworkspace.azureml-test.net' + ] + allowedMethods: [ + 'GET' + 'HEAD' + 'POST' + 'PUT' + 'DELETE' + 'OPTIONS' + 'PATCH' + ] + maxAgeInSeconds: 1800 + exposedHeaders: [ + '*' + ] + allowedHeaders: [ + '*' + ] + } + ] + deleteRetentionPolicyEnabled: true + containerDeleteRetentionPolicyDays: 7 + deleteRetentionPolicyDays: 6 + deleteRetentionPolicyAllowPermanentDelete: true +} + +@description('Optional. File service and shares to deploy.') +param fileServices object = { + name: 'default' +} + +@description('Optional. Queue service and queues to create.') +param queueServices object = { + name: 'default' +} + +@description('Optional. Table service and tables to create.') +param tableServices object = { + name: 'default' +} + +@description('Optional. Tags of the resource.') +@metadata({ + example: ''' + { + "key1": "value1" + "key2": "value2" + } + ''' +}) +param tags object? + +@description('Optional. Kind of the Cognitive Services.') +param cognitiveServicesKind string = 'AIServices' + +@description('Optional. Array of deployments about cognitive service accounts to create.') +param cognitiveServicesDeployments array = [] + +@description('Optional. The custom subdomain name used to access the API. Defaults to the value of the name parameter.') +param cognitiveServicesCustomSubDomainName string = cognitiveServicesName + +@description('Optional. Allow only Azure AD authentication. Should be enabled for security reasons.') +param cognitiveServicesDisableLocalAuth bool = false + +@description('Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set.') +@allowed([ + 'Enabled' + 'Disabled' +]) +param cognitiveServicesPublicNetworkAccess string = 'Disabled' + +@description('Optional. A collection of rules governing the accessibility from specific network locations.') +param cognitiveServicesNetworkAcls object = { + defaultAction: 'Allow' +} + +@description('Optional. SKU of the Cognitive Services resource.') +param cognitiveServicesSku string = 'S0' + +@description('Optional. Tier of your Azure container registry.') +@allowed([ + 'Basic' + 'Premium' + 'Standard' +]) +param registryAcrSku string = 'Basic' + +@description('Optional. Public network access setting.') +param registryPublicNetworkAccess string = 'Enabled' + +@description('Optional. Property that controls how data actions are authorized. When true, the key vault will use Role Based Access Control (RBAC) for authorization of data actions, and the access policies specified in vault properties will be ignored. When false, the key vault will use the access policies specified in vault properties, and any policy stored on Azure Resource Manager will be ignored. Note that management actions are always authorized with RBAC.') +param enableRbacAuthorization bool = false + +@description('Optional. Specifies if the vault is enabled for deployment by script or compute.') +param enableVaultForDeployment bool = false + +@description('Optional. Specifies if the vault is enabled for a template deployment.') +param enableVaultForTemplateDeployment bool = false + +@description('Optional. Provide \'true\' to enable Key Vault\'s purge protection feature.') +param enablePurgeProtection bool = false + +@description('Optional. Specifies the SKU for the vault.') +@allowed([ + 'premium' + 'standard' +]) +param keyVaultSku string = 'standard' + +@description('Optional. The name of the SKU.') +@allowed([ + 'CapacityReservation' + 'Free' + 'LACluster' + 'PerGB2018' + 'PerNode' + 'Premium' + 'Standalone' + 'Standard' +]) +param logAnalyticsSkuName string = 'PerGB2018' + +@description('Optional. Number of days data will be retained for.') +@minValue(0) +@maxValue(730) +param dataRetention int = 30 + +@description('Optional. Defines the options for how the data plane API of a Search service authenticates requests. Must remain an empty object {} if \'disableLocalAuth\' is set to true.') +param authOptions object = {} + +@description('Optional. When set to true, calls to the search service will not be permitted to utilize API keys for authentication. This cannot be set to true if \'authOptions\' are defined.') +param disableLocalAuth bool = false + +@description('Optional. Describes a policy that determines how resources within the search service are to be encrypted with Customer Managed Keys.') +@allowed([ + 'Disabled' + 'Enabled' + 'Unspecified' +]) +param cmkEnforcement string = 'Unspecified' + +@description('Optional. Applicable only for the standard3 SKU. You can set this property to enable up to 3 high density partitions that allow up to 1000 indexes, which is much higher than the maximum indexes allowed for any other SKU. For the standard3 SKU, the value is either \'default\' or \'highDensity\'. For all other SKUs, this value must be \'default\'.') +@allowed([ + 'default' + 'highDensity' +]) +param hostingMode string = 'default' + +@description('Optional. Network specific rules that determine how the Azure Cognitive Search service may be reached.') +param networkRuleSet object = { + bypass: 'None' + ipRules: [] +} + +@description('Optional. The number of partitions in the search service; if specified, it can be 1, 2, 3, 4, 6, or 12. Values greater than 1 are only valid for standard SKUs. For \'standard3\' services with hostingMode set to \'highDensity\', the allowed values are between 1 and 3.') +@minValue(1) +@maxValue(12) +param partitionCount int = 1 + +@description('Optional. This value can be set to \'Enabled\' to avoid breaking changes on existing customer resources and templates. If set to \'Disabled\', traffic over public interface is not allowed, and private endpoint connections would be the exclusive access method.') +@allowed([ + 'Enabled' + 'Disabled' +]) +param searchServicePublicNetworkAccess string = 'Enabled' + +@description('Optional. The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU.') +@minValue(1) +@maxValue(12) +param replicaCount int = 1 + +@allowed([ + 'disabled' + 'free' + 'standard' +]) +@description('Optional. Sets options that control the availability of semantic search. This configuration is only possible for certain search SKUs in certain locations.') +param semanticSearch string = 'disabled' + +@description('Optional. Defines the SKU of an Azure Cognitive Search Service, which determines price tier and capacity limits.') +@allowed([ + 'basic' + 'free' + 'standard' + 'standard2' + 'standard3' + 'storage_optimized_l1' + 'storage_optimized_l2' +]) +param searchServiceSku string = 'standard' + +@description('Conditional. The managed identity definition for this resource. Required if `assignRbacRole` is `true` and `managedIdentityName` is `null`.') +param managedIdentities managedIdentitiesType? + +// ============== // +// Resources // +// ============== // + +#disable-next-line no-deployments-resources +resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { + name: '46d3xbcp.ptn.azd-mlhubdependencies.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +module keyVault 'br/public:avm/res/key-vault/vault:0.7.1' = { + name: '${uniqueString(deployment().name, location)}-keyvault' + params: { + name: keyVaultName + location: location + tags: tags + enableRbacAuthorization: enableRbacAuthorization + enableVaultForDeployment: enableVaultForDeployment + enableVaultForTemplateDeployment: enableVaultForTemplateDeployment + enablePurgeProtection: enablePurgeProtection + sku: keyVaultSku + } +} + +module storageAccount 'br/public:avm/res/storage/storage-account:0.9.1' = { + name: '${uniqueString(deployment().name, location)}-storage' + params: { + name: storageAccountName + location: location + tags: tags + allowBlobPublicAccess: allowBlobPublicAccess + dnsEndpointType: dnsEndpointType + publicNetworkAccess: publicNetworkAccess + networkAcls: networkAcls + blobServices: blobServices + fileServices: fileServices + queueServices: queueServices + tableServices: tableServices + } +} + +module cognitiveServices 'br/public:avm/res/cognitive-services/account:0.7.0' = { + name: '${uniqueString(deployment().name, location)}-cognitive' + params: { + name: cognitiveServicesName + location: location + tags: tags + kind: cognitiveServicesKind + customSubDomainName: cognitiveServicesCustomSubDomainName + publicNetworkAccess: cognitiveServicesPublicNetworkAccess + networkAcls: cognitiveServicesNetworkAcls + disableLocalAuth: cognitiveServicesDisableLocalAuth + sku: cognitiveServicesSku + deployments: cognitiveServicesDeployments + } +} + +module logAnalytics 'br/public:avm/res/operational-insights/workspace:0.6.0' = if (!empty(logAnalyticsName)) { + name: '${uniqueString(deployment().name, location)}-loganalytics' + params: { + name: logAnalyticsName + location: location + tags: tags + dataRetention: dataRetention + skuName: logAnalyticsSkuName + } +} + +module applicationInsights 'br/public:avm/ptn/azd/insights-dashboard:0.1.0' = if (!empty(applicationInsightsName) && !empty(logAnalyticsName)) { + name: '${uniqueString(deployment().name, location)}-insights' + params: { + location: location + tags: tags + name: applicationInsightsName + dashboardName: applicationInsightsDashboardName + logAnalyticsWorkspaceResourceId: !empty(logAnalyticsName) ? logAnalytics.outputs.resourceId : '' + } +} + +module containerRegistry 'br/public:avm/res/container-registry/registry:0.4.0' = if (!empty(containerRegistryName)) { + name: '${uniqueString(deployment().name, location)}-registry' + params: { + name: containerRegistryName + acrSku: registryAcrSku + tags: tags + location: location + publicNetworkAccess: registryPublicNetworkAccess + } +} + +module searchService 'br/public:avm/res/search/search-service:0.6.0' = if (!empty(searchServiceName)) { + name: '${uniqueString(deployment().name, location)}-searchservice' + params: { + name: searchServiceName + location: location + tags: tags + authOptions: authOptions + disableLocalAuth: disableLocalAuth + cmkEnforcement: cmkEnforcement + hostingMode: hostingMode + networkRuleSet: networkRuleSet + partitionCount: partitionCount + publicNetworkAccess: searchServicePublicNetworkAccess + replicaCount: replicaCount + semanticSearch: semanticSearch + sku: searchServiceSku + managedIdentities: managedIdentities + } +} + +// ============ // +// Outputs // +// ============ // + +@description('The name of the resource group the module was deployed to.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the key vault.') +output keyVaultResourceId string = keyVault.outputs.resourceId + +@description('The name of the key vault.') +output keyVaultName string = keyVault.outputs.name + +@description('The endpoint of the key vault.') +output keyVaultEndpoint string = keyVault.outputs.uri + +@description('The resource ID of the storage account.') +output storageAccountResourceId string = storageAccount.outputs.resourceId + +@description('The name of the storage account.') +output storageAccountName string = storageAccount.outputs.name + +@description('The resource ID of the container registry.') +output containerRegistryResourceId string = !empty(containerRegistryName) ? containerRegistry.outputs.resourceId : '' + +@description('The name of the container registry.') +output containerRegistryName string = !empty(containerRegistryName) ? containerRegistry.outputs.name : '' + +@description('The endpoint of the container registry.') +output containerRegistryEndpoint string = !empty(containerRegistryName) ? containerRegistry.outputs.loginServer : '' + +@description('The resource ID of the application insights.') +output applicationInsightsResourceId string = !empty(applicationInsightsName) ? applicationInsights.outputs.applicationInsightsResourceId : '' + +@description('The name of the application insights.') +output applicationInsightsName string = !empty(applicationInsightsName) ? applicationInsights.outputs.applicationInsightsName : '' + +@description('The resource ID of the loganalytics workspace.') +output logAnalyticsWorkspaceResourceId string = !empty(logAnalyticsName) ? logAnalytics.outputs.resourceId : '' + +@description('The name of the loganalytics workspace.') +output logAnalyticsWorkspaceName string = !empty(logAnalyticsName) ? logAnalytics.outputs.name : '' + +@description('The resource ID of the cognitive services.') +output cognitiveServicesResourceId string = cognitiveServices.outputs.resourceId + +@description('The name of the cognitive services.') +output cognitiveServicesName string = cognitiveServices.outputs.name + +@description('The endpoint of the cognitive services.') +output cognitiveServicesEndpoint string = cognitiveServices.outputs.endpoint + +@description('The resource ID of the search service.') +output searchServiceResourceId string = !empty(searchServiceName) ? searchService.outputs.resourceId : '' + +@description('The name of the search service.') +output searchServiceName string = !empty(searchServiceName) ? searchService.outputs.name : '' + +@description('The endpoint of the search service.') +output searchServiceEndpoint string = !empty(searchServiceName) ? 'https://${searchService.outputs.name}.search.windows.net/' : '' + +@description('The connection string of the application insights.') +output applicationInsightsConnectionString string = !empty(applicationInsightsName) ? applicationInsights.outputs.applicationInsightsConnectionString : '' + +@description('The instrumentation key of the application insights.') +output applicationInsightsInstrumentationKey string = !empty(applicationInsightsName) ? applicationInsights.outputs.applicationInsightsInstrumentationKey : '' + +@description('The system assigned mi principal Id key of the search service.') +output systemAssignedMiPrincipalId string = !empty(searchServiceName) ? searchService.outputs.systemAssignedMIPrincipalId : '' + +// ================ // +// Definitions // +// ================ // + +type managedIdentitiesType = { + @description('Optional. Enables system assigned managed identity on the resource.') + systemAssigned: bool? + + @description('Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption.') + userAssignedResourceIds: string[]? +}? diff --git a/avm/ptn/azd/ml-project/main.bicep b/avm/ptn/azd/ml-project/main.bicep new file mode 100644 index 0000000000..eac4cc8d78 --- /dev/null +++ b/avm/ptn/azd/ml-project/main.bicep @@ -0,0 +1,170 @@ +metadata name = 'Machine Learning workspace' +metadata description = '''Create a machine learning workspace, configure the key vault access policy and assign role permissions to the machine learning instance. + +**Note:** This module is not intended for broad, generic use, as it was designed to cater for the requirements of the AZD CLI product. Feature requests and bug fix requests are welcome if they support the development of the AZD CLI but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case.''' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the machine learning workspace.') +param name string + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. Location for all Resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +@metadata({ + example: ''' + { + "key1": "value1" + "key2": "value2" + } + ''' +}) +param tags object? + +@description('Optional. Specifies the SKU, also referred as \'edition\' of the Azure Machine Learning workspace.') +@allowed([ + 'Free' + 'Basic' + 'Standard' + 'Premium' +]) +param projectSku string = 'Basic' + +@description('Optional. The type of Azure Machine Learning workspace to create.') +@allowed([ + 'Default' + 'Project' + 'Hub' + 'FeatureStore' +]) +param projectKind string = 'Project' + +@description('Optional. The flag to signal HBI data in the workspace and reduce diagnostic data collected by the service.') +param hbiWorkspace bool = false + +@description('Optional. Whether or not public network access is allowed for this machine learning resource. For security reasons it should be disabled.') +@allowed([ + 'Enabled' + 'Disabled' +]) +param publicNetworkAccess string = 'Enabled' + +@description('Required. The resource ID of the AI Studio Hub Resource where this project should be created.') +param hubResourceId string + +@description('Required. The name of the key vault.') +param keyVaultName string + +@description('Optional. The managed identity definition for the machine learning resource. At least one identity type is required.') +param projectManagedIdentities managedIdentitiesType = { + systemAssigned: true +} + +@description('Required. The User Assigned Identity resource name.') +param userAssignedtName string + +@description('Optional. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleDefinitionIdOrName array = [ + 'f6c7c914-8db3-469d-8ca1-694a8f32e121' + 'ea01e6af-a1c1-4350-9563-ad00f8c72ec5' +] + +// ============== // +// Resources // +// ============== // + +#disable-next-line no-deployments-resources +resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { + name: '46d3xbcp.ptn.azd-mlproject.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +module project 'br/public:avm/res/machine-learning-services/workspace:0.7.0' = { + name: '${uniqueString(deployment().name, location)}-project' + params: { + name: name + tags: tags + sku: projectSku + kind: projectKind + managedIdentities: projectManagedIdentities + hbiWorkspace: hbiWorkspace + publicNetworkAccess: publicNetworkAccess + hubResourceId: hubResourceId + } +} + +module keyVaultAccess 'br/public:avm/res/key-vault/vault:0.9.0' = { + name: '${uniqueString(deployment().name, location)}-keyvault' + params: { + name: keyVault.name + accessPolicies: [ + { + objectId: project.outputs.systemAssignedMIPrincipalId + permissions: { secrets: [ 'get', 'list' ] } + } + ] + } +} + +module mlServiceRoleAssigned 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = { + name: '${uniqueString(deployment().name, location)}-roleassignment' + params: { + name: userAssignedtName + location: location + roleAssignments: [ + for id in roleDefinitionIdOrName: { + principalId: project.outputs.systemAssignedMIPrincipalId + roleDefinitionIdOrName: id + principalType: 'ServicePrincipal' + } + ] + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { + name: keyVaultName +} + +// ============ // +// Outputs // +// ============ // + +@description('The resource group the machine learning workspace were deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the machine learning workspace.') +output projectResourceId string = project.outputs.resourceId + +@description('The resource name of the machine learning workspace.') +output projectName string = project.outputs.name + +@description('The principal ID of the machine learning workspace.') +output projectPrincipalId string = project.outputs.systemAssignedMIPrincipalId + +// =============== // +// Definitions // +// =============== // + +type managedIdentitiesType = { + @description('Optional. Enables system assigned managed identity on the resource. Must be false if `primaryUserAssignedIdentity` is provided.') + systemAssigned: bool? + + @description('Optional. The resource ID(s) to assign to the resource.') + userAssignedResourceIds: string[]? +}