diff --git a/.github/workflows/avm.ptn.deployment-script.import-image-to-acr.yml b/.github/workflows/avm.ptn.deployment-script.import-image-to-acr.yml index 1dc2c635a1..6f0179678d 100644 --- a/.github/workflows/avm.ptn.deployment-script.import-image-to-acr.yml +++ b/.github/workflows/avm.ptn.deployment-script.import-image-to-acr.yml @@ -1,8 +1,6 @@ name: "avm.ptn.deployment-script.import-image-to-acr" on: - schedule: - - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) workflow_dispatch: inputs: staticValidation: diff --git a/.github/workflows/avm.res.hybrid-compute.machine.yml b/.github/workflows/avm.res.hybrid-compute.machine.yml index 1b37947d8e..6e6103ad2d 100644 --- a/.github/workflows/avm.res.hybrid-compute.machine.yml +++ b/.github/workflows/avm.res.hybrid-compute.machine.yml @@ -1,8 +1,6 @@ name: "avm.res.hybrid-compute.machine" on: - schedule: - - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) workflow_dispatch: inputs: staticValidation: diff --git a/.github/workflows/platform.ossf-scorecard.yml b/.github/workflows/platform.ossf-scorecard.yml index f2b9ddba70..e387559274 100644 --- a/.github/workflows/platform.ossf-scorecard.yml +++ b/.github/workflows/platform.ossf-scorecard.yml @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3 with: sarif_file: results.sarif diff --git a/avm/ptn/azd/apim-api/README.md b/avm/ptn/azd/apim-api/README.md index a063fabfb7..51481ecc85 100644 --- a/avm/ptn/azd/apim-api/README.md +++ b/avm/ptn/azd/apim-api/README.md @@ -19,7 +19,7 @@ Creates and configure an API within an API Management service instance. | `Microsoft.ApiManagement/service/apis` | [2022-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2022-08-01/service/apis) | | `Microsoft.ApiManagement/service/apis/diagnostics` | [2022-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2022-08-01/service/apis/diagnostics) | | `Microsoft.ApiManagement/service/apis/policies` | [2022-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2022-08-01/service/apis/policies) | -| `Microsoft.Web/sites/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-09-01/sites/config) | ## Usage examples diff --git a/avm/ptn/data/private-analytical-workspace/README.md b/avm/ptn/data/private-analytical-workspace/README.md index 5f0106847f..2361e5b719 100644 --- a/avm/ptn/data/private-analytical-workspace/README.md +++ b/avm/ptn/data/private-analytical-workspace/README.md @@ -37,12 +37,10 @@ This pattern module enables you to use Azure services that are typical for data | `Microsoft.Network/privateDnsZones/TXT` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/TXT) | | `Microsoft.Network/privateDnsZones/virtualNetworkLinks` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/virtualNetworkLinks) | | `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | -| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | -| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | -| `Microsoft.Network/virtualNetworks` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualNetworks) | -| `Microsoft.Network/virtualNetworks/subnets` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualNetworks/subnets) | -| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualNetworks/virtualNetworkPeerings) | +| `Microsoft.Network/virtualNetworks` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks) | +| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/subnets) | +| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/virtualNetworkPeerings) | | `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) | @@ -86,7 +84,14 @@ This instance deploys the module with the minimum set of required parameters. module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-workspace:' = { name: 'privateAnalyticalWorkspaceDeployment' params: { - name: 'dpawmin001' + // Required parameters + name: 'dpawmin002' + // Non-required parameters + advancedOptions: { + keyVault: { + enablePurgeProtection: false + } + } } } ``` @@ -103,8 +108,17 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { + // Required parameters "name": { - "value": "dpawmin001" + "value": "dpawmin002" + }, + // Non-required parameters + "advancedOptions": { + "value": { + "keyVault": { + "enablePurgeProtection": false + } + } } } } @@ -120,7 +134,14 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor ```bicep-params using 'br/public:avm/ptn/data/private-analytical-workspace:' -param name = 'dpawmin001' +// Required parameters +param name = 'dpawmin002' +// Non-required parameters +param advancedOptions = { + keyVault: { + enablePurgeProtection: false + } +} ``` @@ -140,12 +161,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawmax001' + name: 'dpawmax002' // Non-required parameters advancedOptions: { keyVault: { createMode: 'default' - enablePurgeProtection: true + enablePurgeProtection: false enableSoftDelete: false sku: 'standard' softDeleteRetentionInDays: 7 @@ -184,14 +205,14 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawmax001" + "value": "dpawmax002" }, // Non-required parameters "advancedOptions": { "value": { "keyVault": { "createMode": "default", - "enablePurgeProtection": true, + "enablePurgeProtection": false, "enableSoftDelete": false, "sku": "standard", "softDeleteRetentionInDays": 7 @@ -234,12 +255,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawmax001' +param name = 'dpawmax002' // Non-required parameters param advancedOptions = { keyVault: { createMode: 'default' - enablePurgeProtection: true + enablePurgeProtection: false enableSoftDelete: false sku: 'standard' softDeleteRetentionInDays: 7 @@ -279,8 +300,13 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawminpriv001' + name: 'dpawminpriv002' // Non-required parameters + advancedOptions: { + keyVault: { + enablePurgeProtection: false + } + } enableDatabricks: false tags: { CostCenter: '123-456-789' @@ -304,9 +330,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawminpriv001" + "value": "dpawminpriv002" }, // Non-required parameters + "advancedOptions": { + "value": { + "keyVault": { + "enablePurgeProtection": false + } + } + }, "enableDatabricks": { "value": false }, @@ -331,8 +364,13 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawminpriv001' +param name = 'dpawminpriv002' // Non-required parameters +param advancedOptions = { + keyVault: { + enablePurgeProtection: false + } +} param enableDatabricks = false param tags = { CostCenter: '123-456-789' @@ -357,9 +395,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawminpub001' + name: 'dpawminpu002' // Non-required parameters advancedOptions: { + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -389,11 +430,14 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawminpub001" + "value": "dpawminpu002" }, // Non-required parameters "advancedOptions": { "value": { + "keyVault": { + "enablePurgeProtection": false + }, "networkAcls": { "ipRules": [ "104.43.16.94" @@ -425,9 +469,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawminpub001' +param name = 'dpawminpu002' // Non-required parameters param advancedOptions = { + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -458,8 +505,13 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc01priv001' + name: 'dpawu1pr002' // Non-required parameters + advancedOptions: { + keyVault: { + enablePurgeProtection: false + } + } enableDatabricks: true tags: { CostCenter: '123-456-789' @@ -483,9 +535,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc01priv001" + "value": "dpawu1pr002" }, // Non-required parameters + "advancedOptions": { + "value": { + "keyVault": { + "enablePurgeProtection": false + } + } + }, "enableDatabricks": { "value": true }, @@ -510,8 +569,13 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc01priv001' +param name = 'dpawu1pr002' // Non-required parameters +param advancedOptions = { + keyVault: { + enablePurgeProtection: false + } +} param enableDatabricks = true param tags = { CostCenter: '123-456-789' @@ -536,9 +600,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc01pub001' + name: 'dpawu1pu002' // Non-required parameters advancedOptions: { + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -568,11 +635,14 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc01pub001" + "value": "dpawu1pu002" }, // Non-required parameters "advancedOptions": { "value": { + "keyVault": { + "enablePurgeProtection": false + }, "networkAcls": { "ipRules": [ "104.43.16.94" @@ -604,9 +674,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc01pub001' +param name = 'dpawu1pu002' // Non-required parameters param advancedOptions = { + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -637,13 +710,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc02priv001' + name: 'dpawu2pr002' // Non-required parameters advancedOptions: { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } virtualNetwork: { subnetNamePrivateLink: '' } @@ -672,7 +748,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc02priv001" + "value": "dpawu2pr002" }, // Non-required parameters "advancedOptions": { @@ -681,6 +757,9 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "subnetNameBackend": "", "subnetNameFrontend": "" }, + "keyVault": { + "enablePurgeProtection": false + }, "virtualNetwork": { "subnetNamePrivateLink": "" } @@ -713,13 +792,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc02priv001' +param name = 'dpawu2pr002' // Non-required parameters param advancedOptions = { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } virtualNetwork: { subnetNamePrivateLink: '' } @@ -749,13 +831,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc02pub001' + name: 'dpawu2pu002' // Non-required parameters advancedOptions: { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -789,7 +874,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc02pub001" + "value": "dpawu2pu002" }, // Non-required parameters "advancedOptions": { @@ -798,6 +883,9 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "subnetNameBackend": "", "subnetNameFrontend": "" }, + "keyVault": { + "enablePurgeProtection": false + }, "networkAcls": { "ipRules": [ "104.43.16.94" @@ -835,13 +923,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc02pub001' +param name = 'dpawu2pu002' // Non-required parameters param advancedOptions = { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } networkAcls: { ipRules: [ '104.43.16.94' @@ -876,13 +967,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc03priv001' + name: 'dpawu3pr002' // Non-required parameters advancedOptions: { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } virtualNetwork: { subnetNamePrivateLink: '' } @@ -913,7 +1007,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc03priv001" + "value": "dpawu3pr002" }, // Non-required parameters "advancedOptions": { @@ -922,6 +1016,9 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "subnetNameBackend": "", "subnetNameFrontend": "" }, + "keyVault": { + "enablePurgeProtection": false + }, "virtualNetwork": { "subnetNamePrivateLink": "" } @@ -960,13 +1057,16 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc03priv001' +param name = 'dpawu3pr002' // Non-required parameters param advancedOptions = { databricks: { subnetNameBackend: '' subnetNameFrontend: '' } + keyVault: { + enablePurgeProtection: false + } virtualNetwork: { subnetNamePrivateLink: '' } @@ -998,7 +1098,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawuc03pub001' + name: 'dpawu3p002' // Non-required parameters advancedOptions: { databricks: { @@ -1040,7 +1140,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawuc03pub001" + "value": "dpawu3p002" }, // Non-required parameters "advancedOptions": { @@ -1092,7 +1192,7 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawuc03pub001' +param name = 'dpawu3p002' // Non-required parameters param advancedOptions = { databricks: { @@ -1135,12 +1235,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor name: 'privateAnalyticalWorkspaceDeployment' params: { // Required parameters - name: 'dpawwaf001' + name: 'dpawwaf002' // Non-required parameters advancedOptions: { keyVault: { createMode: 'default' - enablePurgeProtection: true + enablePurgeProtection: false enableSoftDelete: true sku: 'standard' softDeleteRetentionInDays: 90 @@ -1176,14 +1276,14 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor "parameters": { // Required parameters "name": { - "value": "dpawwaf001" + "value": "dpawwaf002" }, // Non-required parameters "advancedOptions": { "value": { "keyVault": { "createMode": "default", - "enablePurgeProtection": true, + "enablePurgeProtection": false, "enableSoftDelete": true, "sku": "standard", "softDeleteRetentionInDays": 90 @@ -1225,12 +1325,12 @@ module privateAnalyticalWorkspace 'br/public:avm/ptn/data/private-analytical-wor using 'br/public:avm/ptn/data/private-analytical-workspace:' // Required parameters -param name = 'dpawwaf001' +param name = 'dpawwaf002' // Non-required parameters param advancedOptions = { keyVault: { createMode: 'default' - enablePurgeProtection: true + enablePurgeProtection: false enableSoftDelete: true sku: 'standard' softDeleteRetentionInDays: 90 @@ -1339,43 +1439,57 @@ This parameter allows you to specify additional settings for Azure Key Vault if | Parameter | Type | Description | | :-- | :-- | :-- | -| [`createMode`](#parameter-advancedoptionskeyvaultcreatemode) | string | The vault's create mode to indicate whether the vault need to be recovered or not. - 'recover' or 'default'. The dafult value is: 'default'. | -| [`enablePurgeProtection`](#parameter-advancedoptionskeyvaultenablepurgeprotection) | bool | Provide 'true' to enable Key Vault's purge protection feature. The dafult value is: 'true'. | -| [`enableSoftDelete`](#parameter-advancedoptionskeyvaultenablesoftdelete) | bool | Switch to enable/disable Key Vault's soft delete feature. The dafult value is: 'true'. | -| [`sku`](#parameter-advancedoptionskeyvaultsku) | string | Specifies the SKU for the vault. - 'premium' or 'standard'. The dafult value is: 'premium'. | -| [`softDeleteRetentionInDays`](#parameter-advancedoptionskeyvaultsoftdeleteretentionindays) | int | Soft delete data retention days. It accepts >=7 and <=90. The dafult value is: '90'. | +| [`createMode`](#parameter-advancedoptionskeyvaultcreatemode) | string | The vault's create mode to indicate whether the vault need to be recovered or not. The default value is: 'default'. | +| [`enablePurgeProtection`](#parameter-advancedoptionskeyvaultenablepurgeprotection) | bool | Provide 'true' to enable Key Vault's purge protection feature. The default value is: 'true'. | +| [`enableSoftDelete`](#parameter-advancedoptionskeyvaultenablesoftdelete) | bool | Switch to enable/disable Key Vault's soft delete feature. The default value is: 'true'. | +| [`sku`](#parameter-advancedoptionskeyvaultsku) | string | Specifies the SKU for the vault. The default value is: 'premium'. | +| [`softDeleteRetentionInDays`](#parameter-advancedoptionskeyvaultsoftdeleteretentionindays) | int | Soft delete data retention days. It accepts >=7 and <=90. The default value is: '90'. | ### Parameter: `advancedOptions.keyVault.createMode` -The vault's create mode to indicate whether the vault need to be recovered or not. - 'recover' or 'default'. The dafult value is: 'default'. +The vault's create mode to indicate whether the vault need to be recovered or not. The default value is: 'default'. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'default' + 'recover' + ] + ``` ### Parameter: `advancedOptions.keyVault.enablePurgeProtection` -Provide 'true' to enable Key Vault's purge protection feature. The dafult value is: 'true'. +Provide 'true' to enable Key Vault's purge protection feature. The default value is: 'true'. - Required: No - Type: bool ### Parameter: `advancedOptions.keyVault.enableSoftDelete` -Switch to enable/disable Key Vault's soft delete feature. The dafult value is: 'true'. +Switch to enable/disable Key Vault's soft delete feature. The default value is: 'true'. - Required: No - Type: bool ### Parameter: `advancedOptions.keyVault.sku` -Specifies the SKU for the vault. - 'premium' or 'standard'. The dafult value is: 'premium'. +Specifies the SKU for the vault. The default value is: 'premium'. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'premium' + 'standard' + ] + ``` ### Parameter: `advancedOptions.keyVault.softDeleteRetentionInDays` -Soft delete data retention days. It accepts >=7 and <=90. The dafult value is: '90'. +Soft delete data retention days. It accepts >=7 and <=90. The default value is: '90'. - Required: No - Type: int @@ -1391,19 +1505,19 @@ This parameter allows you to specify additional settings for Azure Log Analytics | Parameter | Type | Description | | :-- | :-- | :-- | -| [`dailyQuotaGb`](#parameter-advancedoptionsloganalyticsworkspacedailyquotagb) | int | The workspace daily quota for ingestion. The dafult value is: '-1' (not limited). | -| [`dataRetention`](#parameter-advancedoptionsloganalyticsworkspacedataretention) | int | Number of days data will be retained for. The dafult value is: '365'. | +| [`dailyQuotaGb`](#parameter-advancedoptionsloganalyticsworkspacedailyquotagb) | int | The workspace daily quota for ingestion. The default value is: '-1' (not limited). | +| [`dataRetention`](#parameter-advancedoptionsloganalyticsworkspacedataretention) | int | Number of days data will be retained for. The default value is: '365'. | ### Parameter: `advancedOptions.logAnalyticsWorkspace.dailyQuotaGb` -The workspace daily quota for ingestion. The dafult value is: '-1' (not limited). +The workspace daily quota for ingestion. The default value is: '-1' (not limited). - Required: No - Type: int ### Parameter: `advancedOptions.logAnalyticsWorkspace.dataRetention` -Number of days data will be retained for. The dafult value is: '365'. +Number of days data will be retained for. The default value is: '365'. - Required: No - Type: int @@ -1602,13 +1716,15 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/databricks/access-connector:0.2.0` | Remote reference | -| `br/public:avm/res/databricks/workspace:0.6.0` | Remote reference | -| `br/public:avm/res/key-vault/vault:0.7.0` | Remote reference | -| `br/public:avm/res/network/network-security-group:0.4.0` | Remote reference | +| `br/public:avm/res/databricks/access-connector:0.3.0` | Remote reference | +| `br/public:avm/res/databricks/workspace:0.8.5` | Remote reference | +| `br/public:avm/res/key-vault/vault:0.9.0` | Remote reference | +| `br/public:avm/res/network/network-security-group:0.5.0` | Remote reference | | `br/public:avm/res/network/private-dns-zone:0.5.0` | Remote reference | -| `br/public:avm/res/network/virtual-network:0.2.0` | Remote reference | -| `br/public:avm/res/operational-insights/workspace:0.5.0` | Remote reference | +| `br/public:avm/res/network/private-dns-zone:0.6.0` | Remote reference | +| `br/public:avm/res/network/virtual-network:0.5.0` | Remote reference | +| `br/public:avm/res/operational-insights/workspace:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Notes diff --git a/avm/ptn/data/private-analytical-workspace/main.bicep b/avm/ptn/data/private-analytical-workspace/main.bicep index aa3d8d5f05..a5cf9954a5 100644 --- a/avm/ptn/data/private-analytical-workspace/main.bicep +++ b/avm/ptn/data/private-analytical-workspace/main.bicep @@ -8,8 +8,9 @@ param name string @description('Optional. Location for all Resources in the solution.') param location string = resourceGroup().location +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings for all Resources in the solution.') -param lock lockType +param lock lockType? @description('Optional. Tags for all Resources in the solution.') param tags object? @@ -30,7 +31,7 @@ param logAnalyticsWorkspaceResourceId string? param keyVaultResourceId string? @description('Optional. Array of users or groups who are in charge of the solution.') -param solutionAdministrators userGroupRoleAssignmentType? +param solutionAdministrators userGroupRoleAssignmentType[]? @description('Optional. Additional options that can affect some components of the solution and how they are configured.') param advancedOptions advancedOptionsType? @@ -272,28 +273,14 @@ var subnets = concat( name: subnetNameDbwFrontend addressPrefix: subnetDbwFrontendDefaultAddressPrefix networkSecurityGroupResourceId: nsgDbwFrontend.outputs.resourceId - delegations: [ - { - name: 'Microsoft.Databricks/workspaces' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] + delegation: 'Microsoft.Databricks/workspaces' } { // a container subnet (sometimes called the private subnet) name: subnetNameDbwBackend addressPrefix: subnetDbwBackendDefaultAddressPrefix networkSecurityGroupResourceId: nsgDbwBackend.outputs.resourceId - delegations: [ - { - name: 'Microsoft.Databricks/workspaces' - properties: { - serviceName: 'Microsoft.Databricks/workspaces' - } - } - ] + delegation: 'Microsoft.Databricks/workspaces' } ] : [] @@ -365,8 +352,8 @@ resource kvExisting 'Microsoft.KeyVault/vaults@2023-07-01' existing = if (!creat ) } -module vnet 'br/public:avm/res/network/virtual-network:0.2.0' = if (createNewVNET) { - name: vnetName +module vnet 'br/public:avm/res/network/virtual-network:0.5.0' = if (createNewVNET) { + name: '${uniqueString(deployment().name, location)}-vnet-${vnetName}' params: { // Required parameters addressPrefixes: [ @@ -393,15 +380,15 @@ module vnet 'br/public:avm/res/network/virtual-network:0.2.0' = if (createNewVNE dnsServers: [] enableTelemetry: enableTelemetry location: location - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock subnets: subnets tags: tags } } -module nsgPrivateLink 'br/public:avm/res/network/network-security-group:0.4.0' = if (createNewVNET) { - name: nsgNamePrivateLink +module nsgPrivateLink 'br/public:avm/res/network/network-security-group:0.5.0' = if (createNewVNET) { + name: '${uniqueString(deployment().name, location)}-nsg-${nsgNamePrivateLink}' params: { // Required parameters name: nsgNamePrivateLink @@ -419,15 +406,15 @@ module nsgPrivateLink 'br/public:avm/res/network/network-security-group:0.4.0' = ] enableTelemetry: enableTelemetry location: location - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags securityRules: nsgRulesPrivateLink } } -module nsgDbwFrontend 'br/public:avm/res/network/network-security-group:0.4.0' = if (createNewVNET && enableDatabricks) { - name: nsgNameDbwFrontend +module nsgDbwFrontend 'br/public:avm/res/network/network-security-group:0.5.0' = if (createNewVNET && enableDatabricks) { + name: '${uniqueString(deployment().name, location)}-nsg-${nsgNameDbwFrontend}' params: { // Required parameters name: nsgNameDbwFrontend @@ -445,15 +432,15 @@ module nsgDbwFrontend 'br/public:avm/res/network/network-security-group:0.4.0' = ] enableTelemetry: enableTelemetry location: location - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags securityRules: nsgRulesDbw } } -module nsgDbwBackend 'br/public:avm/res/network/network-security-group:0.4.0' = if (createNewVNET && enableDatabricks) { - name: nsgNameDbwBackend +module nsgDbwBackend 'br/public:avm/res/network/network-security-group:0.5.0' = if (createNewVNET && enableDatabricks) { + name: '${uniqueString(deployment().name, location)}-nsg-${nsgNameDbwBackend}' params: { // Required parameters name: nsgNameDbwBackend @@ -471,7 +458,7 @@ module nsgDbwBackend 'br/public:avm/res/network/network-security-group:0.4.0' = ] enableTelemetry: enableTelemetry location: location - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags securityRules: nsgRulesDbw @@ -479,14 +466,14 @@ module nsgDbwBackend 'br/public:avm/res/network/network-security-group:0.4.0' = } module dnsZoneSaBlob 'br/public:avm/res/network/private-dns-zone:0.5.0' = if (createNewVNET && enableDatabricks) { - name: privateDnsZoneNameSaBlob + name: '${uniqueString(deployment().name, location)}-zone-${privateDnsZoneNameSaBlob}' params: { // Required parameters name: privateDnsZoneNameSaBlob // Non-required parameters enableTelemetry: enableTelemetry location: 'global' - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags virtualNetworkLinks: [ @@ -498,8 +485,8 @@ module dnsZoneSaBlob 'br/public:avm/res/network/private-dns-zone:0.5.0' = if (cr } } -module log 'br/public:avm/res/operational-insights/workspace:0.5.0' = if (createNewLog) { - name: logName +module log 'br/public:avm/res/operational-insights/workspace:0.7.1' = if (createNewLog) { + name: '${uniqueString(deployment().name, location)}-law-${logName}' params: { // Required parameters name: logName @@ -509,15 +496,15 @@ module log 'br/public:avm/res/operational-insights/workspace:0.5.0' = if (create diagnosticSettings: [] enableTelemetry: enableTelemetry location: location - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock skuName: 'PerGB2018' tags: tags } } -module kv 'br/public:avm/res/key-vault/vault:0.7.0' = if (createNewKV) { - name: kvName +module kv 'br/public:avm/res/key-vault/vault:0.9.0' = if (createNewKV) { + name: '${uniqueString(deployment().name, location)}-vault-${kvName}' params: { // Required parameters name: kvName @@ -562,7 +549,15 @@ module kv 'br/public:avm/res/key-vault/vault:0.7.0' = if (createNewKV) { name: '${name}-kv-pep' location: location subnetResourceId: vnetCfg.subnetResourceIdPrivateLink - privateDnsZoneResourceIds: createNewVNET ? [dnsZoneKv.outputs.resourceId] : [] + privateDnsZoneGroup: createNewVNET + ? { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: dnsZoneKv.outputs.resourceId + } + ] + } + : null tags: tags enableTelemetry: enableTelemetry lock: lock @@ -577,15 +572,15 @@ module kv 'br/public:avm/res/key-vault/vault:0.7.0' = if (createNewKV) { } } -module dnsZoneKv 'br/public:avm/res/network/private-dns-zone:0.5.0' = if (createNewVNET && createNewKV) { - name: privateDnsZoneNameKv +module dnsZoneKv 'br/public:avm/res/network/private-dns-zone:0.6.0' = if (createNewVNET && createNewKV) { + name: '${uniqueString(deployment().name, location)}-zone-${privateDnsZoneNameKv}' params: { // Required parameters name: privateDnsZoneNameKv // Non-required parameters enableTelemetry: enableTelemetry location: 'global' - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags virtualNetworkLinks: [ @@ -597,8 +592,8 @@ module dnsZoneKv 'br/public:avm/res/network/private-dns-zone:0.5.0' = if (create } } -module accessConnector 'br/public:avm/res/databricks/access-connector:0.2.0' = if (enableDatabricks) { - name: dbwAccessConnectorName +module accessConnector 'br/public:avm/res/databricks/access-connector:0.3.0' = if (enableDatabricks) { + name: '${uniqueString(deployment().name, location)}-connector-${dbwAccessConnectorName}' params: { // Required parameters name: dbwAccessConnectorName @@ -609,13 +604,13 @@ module accessConnector 'br/public:avm/res/databricks/access-connector:0.2.0' = i managedIdentities: { systemAssigned: true } - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] tags: tags } } -module dbw 'br/public:avm/res/databricks/workspace:0.6.0' = if (enableDatabricks) { - name: dbwName +module dbw 'br/public:avm/res/databricks/workspace:0.8.5' = if (enableDatabricks) { + name: '${uniqueString(deployment().name, location)}-workspace-${dbwName}' params: { // Required parameters name: dbwName @@ -649,22 +644,38 @@ module dbw 'br/public:avm/res/databricks/workspace:0.6.0' = if (enableDatabricks location: location service: 'databricks_ui_api' subnetResourceId: vnetCfg.subnetResourceIdPrivateLink - privateDnsZoneResourceIds: createNewVNET ? [dnsZoneDbw.outputs.resourceId] : [] + privateDnsZoneGroup: createNewVNET + ? { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: dnsZoneDbw.outputs.resourceId + } + ] + } + : null tags: tags enableTelemetry: enableTelemetry lock: lock - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] } { name: '${name}-dbw-auth-pep' location: location service: 'browser_authentication' subnetResourceId: vnetCfg.subnetResourceIdPrivateLink - privateDnsZoneResourceIds: createNewVNET ? [dnsZoneDbw.outputs.resourceId] : [] + privateDnsZoneGroup: createNewVNET + ? { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: dnsZoneDbw.outputs.resourceId + } + ] + } + : null tags: tags enableTelemetry: enableTelemetry lock: lock - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] } ] privateStorageAccount: 'Enabled' @@ -675,7 +686,7 @@ module dbw 'br/public:avm/res/databricks/workspace:0.6.0' = if (enableDatabricks // which means that your workspace data plane does not need network security group rules // to connect to the Azure Databricks control plane. Otherwise, select All Rules. requiredNsgRules: empty(dbwIpRules) ? 'NoAzureDatabricksRules' : 'AllRules' // In some environments with 'NoAzureDatabricksRules' cluster cannot be created - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] skuName: 'premium' // We need premium to use VNET injection, Private Connectivity (Requires Premium Plan) storageAccountName: null // TODO add existing one (maybe with PEP) - https://learn.microsoft.com/en-us/azure/databricks/security/network/storage/firewall-support storageAccountPrivateEndpoints: [ @@ -684,26 +695,34 @@ module dbw 'br/public:avm/res/databricks/workspace:0.6.0' = if (enableDatabricks location: location service: 'blob' subnetResourceId: vnetCfg.subnetResourceIdPrivateLink - privateDnsZoneResourceIds: createNewVNET ? [dnsZoneSaBlob.outputs.resourceId] : [] + privateDnsZoneGroup: createNewVNET + ? { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: dnsZoneSaBlob.outputs.resourceId + } + ] + } + : null tags: tags enableTelemetry: enableTelemetry lock: lock - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] } ] tags: tags } } -module dnsZoneDbw 'br/public:avm/res/network/private-dns-zone:0.5.0' = if (createNewVNET && enableDatabricks) { - name: privateDnsZoneNameDbw +module dnsZoneDbw 'br/public:avm/res/network/private-dns-zone:0.6.0' = if (createNewVNET && enableDatabricks) { + name: '${uniqueString(deployment().name, location)}-zone-${privateDnsZoneNameDbw}' params: { // Required parameters name: privateDnsZoneNameDbw // Non-required parameters enableTelemetry: enableTelemetry location: 'global' - roleAssignments: empty(ownerRoleAssignments) ? [] : ownerRoleAssignments + roleAssignments: !empty(ownerRoleAssignments) ? ownerRoleAssignments : [] lock: lock tags: tags virtualNetworkLinks: [ @@ -783,15 +802,6 @@ output databricksResourceGroupName string = enableDatabricks ? dbw.outputs.resou // Definitions // // ================ // -@export() -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - @export() type userGroupRoleAssignmentType = { @description('Required. The principal ID of the principal (user/group) to assign the role to.') @@ -799,7 +809,7 @@ type userGroupRoleAssignmentType = { @description('Required. The principal type of the assigned principal ID.') principalType: ('Group' | 'User') -}[] +} @export() type networkAclsType = { @@ -815,31 +825,31 @@ type virtualNetworkType = { @export() type logAnalyticsWorkspaceType = { - @description('Optional. Number of days data will be retained for. The dafult value is: \'365\'.') + @description('Optional. Number of days data will be retained for. The default value is: \'365\'.') @minValue(0) @maxValue(730) dataRetention: int? - @description('Optional. The workspace daily quota for ingestion. The dafult value is: \'-1\' (not limited).') + @description('Optional. The workspace daily quota for ingestion. The default value is: \'-1\' (not limited).') @minValue(-1) dailyQuotaGb: int? } @export() type keyVaultType = { - @description('Optional. The vault\'s create mode to indicate whether the vault need to be recovered or not. - \'recover\' or \'default\'. The dafult value is: \'default\'.') - createMode: string? + @description('Optional. The vault\'s create mode to indicate whether the vault need to be recovered or not. The default value is: \'default\'.') + createMode: ('default' | 'recover')? - @description('Optional. Specifies the SKU for the vault. - \'premium\' or \'standard\'. The dafult value is: \'premium\'.') - sku: string? + @description('Optional. Specifies the SKU for the vault. The default value is: \'premium\'.') + sku: ('standard' | 'premium')? - @description('Optional. Switch to enable/disable Key Vault\'s soft delete feature. The dafult value is: \'true\'.') + @description('Optional. Switch to enable/disable Key Vault\'s soft delete feature. The default value is: \'true\'.') enableSoftDelete: bool? - @description('Optional. Soft delete data retention days. It accepts >=7 and <=90. The dafult value is: \'90\'.') + @description('Optional. Soft delete data retention days. It accepts >=7 and <=90. The default value is: \'90\'.') softDeleteRetentionInDays: int? - @description('Optional. Provide \'true\' to enable Key Vault\'s purge protection feature. The dafult value is: \'true\'.') + @description('Optional. Provide \'true\' to enable Key Vault\'s purge protection feature. The default value is: \'true\'.') enablePurgeProtection: bool? } diff --git a/avm/ptn/data/private-analytical-workspace/main.json b/avm/ptn/data/private-analytical-workspace/main.json index ae4fe32df4..78d6897ac2 100644 --- a/avm/ptn/data/private-analytical-workspace/main.json +++ b/avm/ptn/data/private-analytical-workspace/main.json @@ -5,62 +5,31 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "17435710338744006218" + "version": "0.30.23.60470", + "templateHash": "4437449109602171238" }, "name": "private-analytical-workspace", "description": "This pattern module enables you to use Azure services that are typical for data analytics solutions. The goal is to help data scientists establish an environment for data analysis simply. It is secure by default for enterprise use. Data scientists should not spend much time on how to build infrastructure solution. They should mainly concentrate on the data analytics components they require for the solution.", "owner": "Azure/module-maintainers" }, "definitions": { - "lockType": { + "userGroupRoleAssignmentType": { "type": "object", "properties": { - "name": { + "principalId": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Required. The principal ID of the principal (user/group) to assign the role to." } }, - "kind": { + "principalType": { "type": "string", "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" + "Group", + "User" ], - "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true, - "metadata": { - "__bicep_export!": true - } - }, - "userGroupRoleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Group", - "User" - ], - "metadata": { - "description": "Required. The principal type of the assigned principal ID." - } + "description": "Required. The principal type of the assigned principal ID." } } }, @@ -110,7 +79,7 @@ "minValue": 0, "maxValue": 730, "metadata": { - "description": "Optional. Number of days data will be retained for. The dafult value is: '365'." + "description": "Optional. Number of days data will be retained for. The default value is: '365'." } }, "dailyQuotaGb": { @@ -118,7 +87,7 @@ "nullable": true, "minValue": -1, "metadata": { - "description": "Optional. The workspace daily quota for ingestion. The dafult value is: '-1' (not limited)." + "description": "Optional. The workspace daily quota for ingestion. The default value is: '-1' (not limited)." } } }, @@ -131,37 +100,45 @@ "properties": { "createMode": { "type": "string", + "allowedValues": [ + "default", + "recover" + ], "nullable": true, "metadata": { - "description": "Optional. The vault's create mode to indicate whether the vault need to be recovered or not. - 'recover' or 'default'. The dafult value is: 'default'." + "description": "Optional. The vault's create mode to indicate whether the vault need to be recovered or not. The default value is: 'default'." } }, "sku": { "type": "string", + "allowedValues": [ + "premium", + "standard" + ], "nullable": true, "metadata": { - "description": "Optional. Specifies the SKU for the vault. - 'premium' or 'standard'. The dafult value is: 'premium'." + "description": "Optional. Specifies the SKU for the vault. The default value is: 'premium'." } }, "enableSoftDelete": { "type": "bool", "nullable": true, "metadata": { - "description": "Optional. Switch to enable/disable Key Vault's soft delete feature. The dafult value is: 'true'." + "description": "Optional. Switch to enable/disable Key Vault's soft delete feature. The default value is: 'true'." } }, "softDeleteRetentionInDays": { "type": "int", "nullable": true, "metadata": { - "description": "Optional. Soft delete data retention days. It accepts >=7 and <=90. The dafult value is: '90'." + "description": "Optional. Soft delete data retention days. It accepts >=7 and <=90. The default value is: '90'." } }, "enablePurgeProtection": { "type": "bool", "nullable": true, "metadata": { - "description": "Optional. Provide 'true' to enable Key Vault's purge protection feature. The dafult value is: 'true'." + "description": "Optional. Provide 'true' to enable Key Vault's purge protection feature. The default value is: 'true'." } } }, @@ -233,6 +210,36 @@ "metadata": { "__bicep_export!": 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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -251,6 +258,7 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings for all Resources in the solution." } @@ -298,7 +306,10 @@ } }, "solutionAdministrators": { - "$ref": "#/definitions/userGroupRoleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/userGroupRoleAssignmentType" + }, "nullable": true, "metadata": { "description": "Optional. Array of users or groups who are in charge of the solution." @@ -587,7 +598,7 @@ "condition": "[variables('createNewVNET')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('vnetName')]", + "name": "[format('{0}-vnet-{1}', uniqueString(deployment().name, parameters('location')), variables('vnetName'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -629,12 +640,12 @@ "location": { "value": "[parameters('location')]" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, "subnets": { - "value": "[concat(createArray(createObject('name', variables('subnetNamePrivateLink'), 'addressPrefix', variables('subnetPrivateLinkDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgPrivateLink').outputs.resourceId.value)), if(parameters('enableDatabricks'), createArray(createObject('name', variables('subnetNameDbwFrontend'), 'addressPrefix', variables('subnetDbwFrontendDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgDbwFrontend').outputs.resourceId.value, 'delegations', createArray(createObject('name', 'Microsoft.Databricks/workspaces', 'properties', createObject('serviceName', 'Microsoft.Databricks/workspaces')))), createObject('name', variables('subnetNameDbwBackend'), 'addressPrefix', variables('subnetDbwBackendDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgDbwBackend').outputs.resourceId.value, 'delegations', createArray(createObject('name', 'Microsoft.Databricks/workspaces', 'properties', createObject('serviceName', 'Microsoft.Databricks/workspaces'))))), createArray()))]" + "value": "[concat(createArray(createObject('name', variables('subnetNamePrivateLink'), 'addressPrefix', variables('subnetPrivateLinkDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgPrivateLink').outputs.resourceId.value)), if(parameters('enableDatabricks'), createArray(createObject('name', variables('subnetNameDbwFrontend'), 'addressPrefix', variables('subnetDbwFrontendDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgDbwFrontend').outputs.resourceId.value, 'delegation', 'Microsoft.Databricks/workspaces'), createObject('name', variables('subnetNameDbwBackend'), 'addressPrefix', variables('subnetDbwBackendDefaultAddressPrefix'), 'networkSecurityGroupResourceId', reference('nsgDbwBackend').outputs.resourceId.value, 'delegation', 'Microsoft.Databricks/workspaces')), createArray()))]" }, "tags": { "value": "[parameters('tags')]" @@ -647,231 +658,480 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "2754811334012865077" + "version": "0.30.23.60470", + "templateHash": "12023193036665775110" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", "owner": "Azure/module-maintainers" }, "definitions": { - "lockType": { + "peeringType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. The Name of VNET Peering resource. If not provided, default value will be peer-localVnetName-remoteVnetName." } }, - "kind": { + "remoteVirtualNetworkResourceId": { "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], + "metadata": { + "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID." + } + }, + "allowForwardedTraffic": { + "type": "bool", "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true." + } + }, + "allowGatewayTransit": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false." + } + }, + "allowVirtualNetworkAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true." + } + }, + "doNotVerifyRemoteGateways": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Do not verify the provisioning state of the remote gateway. Default is true." + } + }, + "useRemoteGateways": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false." + } + }, + "remotePeeringEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Deploy the outbound and the inbound peering." + } + }, + "remotePeeringName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the VNET Peering resource in the remove Virtual Network. If not provided, default value will be peer-remoteVnetName-localVnetName." + } + }, + "remotePeeringAllowForwardedTraffic": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true." + } + }, + "remotePeeringAllowGatewayTransit": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false." + } + }, + "remotePeeringAllowVirtualNetworkAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true." + } + }, + "remotePeeringDoNotVerifyRemoteGateways": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Do not verify the provisioning state of the remote gateway. Default is true." + } + }, + "remotePeeringUseRemoteGateways": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false." } } - }, - "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'." - } + "subnetType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The Name of the subnet resource." + } + }, + "addressPrefix": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The address prefix for the subnet. Required if `addressPrefixes` is empty." + } + }, + "addressPrefixes": { + "type": "array", + "items": { + "type": "string" }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } + "nullable": true, + "metadata": { + "description": "Conditional. List of address prefixes for the subnet. Required if `addressPrefix` is empty." + } + }, + "applicationGatewayIPConfigurations": { + "type": "array", + "items": { + "type": "object" }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } + "nullable": true, + "metadata": { + "description": "Optional. Application gateway IP configurations of virtual network resource." + } + }, + "delegation": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The delegation to enable on the subnet." + } + }, + "natGatewayResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the NAT Gateway to use for the subnet." + } + }, + "networkSecurityGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the network security group to assign to the subnet." + } + }, + "privateEndpointNetworkPolicies": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled", + "NetworkSecurityGroupEnabled", + "RouteTableEnabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. enable or disable apply network policies on private endpoint in the subnet." + } + }, + "privateLinkServiceNetworkPolicies": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. enable or disable apply network policies on private link service in the subnet." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "routeTableResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the route table to assign to the subnet." + } + }, + "serviceEndpointPolicies": { + "type": "array", + "items": { + "type": "object" }, - "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\"." - } + "nullable": true, + "metadata": { + "description": "Optional. An array of service endpoint policies." + } + }, + "serviceEndpoints": { + "type": "array", + "items": { + "type": "string" }, - "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, + "metadata": { + "description": "Optional. The service endpoints to enable on the subnet." + } + }, + "defaultOutboundAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Set this property to false to disable default outbound connectivity for all VMs in the subnet. This property can only be set at the time of subnet creation and cannot be updated for an existing subnet." + } + }, + "sharingScope": { + "type": "string", + "allowedValues": [ + "DelegatedServices", + "Tenant" + ], + "nullable": true, + "metadata": { + "description": "Optional. Set this property to Tenant to allow sharing subnet with other subscriptions in your AAD tenant. This property can only be set if defaultOutboundAccess is set to false, both properties can only be set if subnet is empty." } } - }, - "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`." - } + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + }, + "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + } + } + }, + "roleAssignmentType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + } + } } }, "parameters": { @@ -894,32 +1154,48 @@ "description": "Required. An Array of 1 or more IP Address Prefixes for the Virtual Network." } }, + "virtualNetworkBgpCommunity": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The BGP community associated with the virtual network." + } + }, "subnets": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/subnetType" + }, + "nullable": true, "metadata": { "description": "Optional. An Array of subnets to deploy to the Virtual Network." } }, "dnsServers": { "type": "array", - "defaultValue": [], + "items": { + "type": "string" + }, + "nullable": true, "metadata": { "description": "Optional. DNS Servers associated to the Virtual Network." } }, "ddosProtectionPlanResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Resource ID of the DDoS protection plan to assign the VNET to. If it's left blank, DDoS protection will not be configured. If it's provided, the VNET created by this template will be attached to the referenced DDoS protection plan. The DDoS protection plan can exist in the same or in a different subscription." } }, "peerings": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/peeringType" + }, + "nullable": true, "metadata": { - "description": "Optional. Virtual Network Peerings configurations." + "description": "Optional. Virtual Network Peering configurations." } }, "vnetEncryption": { @@ -949,19 +1225,28 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -979,6 +1264,13 @@ "metadata": { "description": "Optional. Enable/Disable usage telemetry for module." } + }, + "enableVmProtection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates if VM protection is enabled for all the subnets in the virtual network." + } } }, "variables": { @@ -994,7 +1286,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -1003,7 +1295,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.2.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1021,42 +1313,21 @@ }, "virtualNetwork": { "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-11-01", + "apiVersion": "2024-01-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "copy": [ - { - "name": "subnets", - "count": "[length(parameters('subnets'))]", - "input": { - "name": "[parameters('subnets')[copyIndex('subnets')].name]", - "properties": { - "addressPrefix": "[parameters('subnets')[copyIndex('subnets')].addressPrefix]", - "addressPrefixes": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'addressPrefixes'), parameters('subnets')[copyIndex('subnets')].addressPrefixes, createArray())]", - "applicationGatewayIPConfigurations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'applicationGatewayIPConfigurations'), parameters('subnets')[copyIndex('subnets')].applicationGatewayIPConfigurations, createArray())]", - "delegations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'delegations'), parameters('subnets')[copyIndex('subnets')].delegations, createArray())]", - "ipAllocations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'ipAllocations'), parameters('subnets')[copyIndex('subnets')].ipAllocations, createArray())]", - "natGateway": "[if(and(contains(parameters('subnets')[copyIndex('subnets')], 'natGatewayResourceId'), not(empty(parameters('subnets')[copyIndex('subnets')].natGatewayResourceId))), createObject('id', parameters('subnets')[copyIndex('subnets')].natGatewayResourceId), null())]", - "networkSecurityGroup": "[if(and(contains(parameters('subnets')[copyIndex('subnets')], 'networkSecurityGroupResourceId'), not(empty(parameters('subnets')[copyIndex('subnets')].networkSecurityGroupResourceId))), createObject('id', parameters('subnets')[copyIndex('subnets')].networkSecurityGroupResourceId), null())]", - "privateEndpointNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateEndpointNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateEndpointNetworkPolicies, null())]", - "privateLinkServiceNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateLinkServiceNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateLinkServiceNetworkPolicies, null())]", - "routeTable": "[if(and(contains(parameters('subnets')[copyIndex('subnets')], 'routeTableResourceId'), not(empty(parameters('subnets')[copyIndex('subnets')].routeTableResourceId))), createObject('id', parameters('subnets')[copyIndex('subnets')].routeTableResourceId), null())]", - "serviceEndpoints": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpoints'), parameters('subnets')[copyIndex('subnets')].serviceEndpoints, createArray())]", - "serviceEndpointPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpointPolicies'), parameters('subnets')[copyIndex('subnets')].serviceEndpointPolicies, createArray())]" - } - } - } - ], "addressSpace": { "addressPrefixes": "[parameters('addressPrefixes')]" }, + "bgpCommunities": "[if(not(empty(parameters('virtualNetworkBgpCommunity'))), createObject('virtualNetworkCommunity', parameters('virtualNetworkBgpCommunity')), null())]", "ddosProtectionPlan": "[if(not(empty(parameters('ddosProtectionPlanResourceId'))), createObject('id', parameters('ddosProtectionPlanResourceId')), null())]", "dhcpOptions": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', array(parameters('dnsServers'))), null())]", "enableDdosProtection": "[not(empty(parameters('ddosProtectionPlanResourceId')))]", "encryption": "[if(equals(parameters('vnetEncryption'), true()), createObject('enabled', parameters('vnetEncryption'), 'enforcement', parameters('vnetEncryptionEnforcement')), null())]", - "flowTimeoutInMinutes": "[if(not(equals(parameters('flowTimeoutInMinutes'), 0)), parameters('flowTimeoutInMinutes'), null())]" + "flowTimeoutInMinutes": "[if(not(equals(parameters('flowTimeoutInMinutes'), 0)), parameters('flowTimeoutInMinutes'), null())]", + "enableVmProtection": "[parameters('enableVmProtection')]" } }, "virtualNetwork_lock": { @@ -1139,7 +1410,7 @@ "virtualNetwork_subnets": { "copy": { "name": "virtualNetwork_subnets", - "count": "[length(parameters('subnets'))]", + "count": "[length(coalesce(parameters('subnets'), createArray()))]", "mode": "serial", "batchSize": 1 }, @@ -1156,23 +1427,50 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('subnets')[copyIndex()].name]" + "value": "[coalesce(parameters('subnets'), createArray())[copyIndex()].name]" }, "addressPrefix": { - "value": "[parameters('subnets')[copyIndex()].addressPrefix]" - }, - "addressPrefixes": "[if(contains(parameters('subnets')[copyIndex()], 'addressPrefixes'), createObject('value', parameters('subnets')[copyIndex()].addressPrefixes), createObject('value', createArray()))]", - "applicationGatewayIPConfigurations": "[if(contains(parameters('subnets')[copyIndex()], 'applicationGatewayIPConfigurations'), createObject('value', parameters('subnets')[copyIndex()].applicationGatewayIPConfigurations), createObject('value', createArray()))]", - "delegations": "[if(contains(parameters('subnets')[copyIndex()], 'delegations'), createObject('value', parameters('subnets')[copyIndex()].delegations), createObject('value', createArray()))]", - "ipAllocations": "[if(contains(parameters('subnets')[copyIndex()], 'ipAllocations'), createObject('value', parameters('subnets')[copyIndex()].ipAllocations), createObject('value', createArray()))]", - "natGatewayResourceId": "[if(contains(parameters('subnets')[copyIndex()], 'natGatewayResourceId'), createObject('value', parameters('subnets')[copyIndex()].natGatewayResourceId), createObject('value', ''))]", - "networkSecurityGroupResourceId": "[if(contains(parameters('subnets')[copyIndex()], 'networkSecurityGroupResourceId'), createObject('value', parameters('subnets')[copyIndex()].networkSecurityGroupResourceId), createObject('value', ''))]", - "privateEndpointNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex()], 'privateEndpointNetworkPolicies'), createObject('value', parameters('subnets')[copyIndex()].privateEndpointNetworkPolicies), createObject('value', ''))]", - "privateLinkServiceNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex()], 'privateLinkServiceNetworkPolicies'), createObject('value', parameters('subnets')[copyIndex()].privateLinkServiceNetworkPolicies), createObject('value', ''))]", - "roleAssignments": "[if(contains(parameters('subnets')[copyIndex()], 'roleAssignments'), createObject('value', parameters('subnets')[copyIndex()].roleAssignments), createObject('value', createArray()))]", - "routeTableResourceId": "[if(contains(parameters('subnets')[copyIndex()], 'routeTableResourceId'), createObject('value', parameters('subnets')[copyIndex()].routeTableResourceId), createObject('value', ''))]", - "serviceEndpointPolicies": "[if(contains(parameters('subnets')[copyIndex()], 'serviceEndpointPolicies'), createObject('value', parameters('subnets')[copyIndex()].serviceEndpointPolicies), createObject('value', createArray()))]", - "serviceEndpoints": "[if(contains(parameters('subnets')[copyIndex()], 'serviceEndpoints'), createObject('value', parameters('subnets')[copyIndex()].serviceEndpoints), createObject('value', createArray()))]" + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'addressPrefix')]" + }, + "addressPrefixes": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'addressPrefixes')]" + }, + "applicationGatewayIPConfigurations": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'applicationGatewayIPConfigurations')]" + }, + "delegation": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'delegation')]" + }, + "natGatewayResourceId": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'natGatewayResourceId')]" + }, + "networkSecurityGroupResourceId": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'networkSecurityGroupResourceId')]" + }, + "privateEndpointNetworkPolicies": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'privateEndpointNetworkPolicies')]" + }, + "privateLinkServiceNetworkPolicies": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'privateLinkServiceNetworkPolicies')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "routeTableResourceId": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'routeTableResourceId')]" + }, + "serviceEndpointPolicies": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'serviceEndpointPolicies')]" + }, + "serviceEndpoints": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'serviceEndpoints')]" + }, + "defaultOutboundAccess": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'defaultOutboundAccess')]" + }, + "sharingScope": { + "value": "[tryGet(coalesce(parameters('subnets'), createArray())[copyIndex()], 'sharingScope')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1181,8 +1479,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "17087074157977382192" + "version": "0.30.23.60470", + "templateHash": "6411714881793832751" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -1190,84 +1488,86 @@ }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + } + } } }, "parameters": { "name": { "type": "string", "metadata": { - "description": "Optional. The Name of the subnet resource." + "description": "Requird. The Name of the subnet resource." } }, "virtualNetworkName": { @@ -1278,88 +1578,106 @@ }, "addressPrefix": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The address prefix for the subnet." + "description": "Conditional. The address prefix for the subnet. Required if `addressPrefixes` is empty." } }, "networkSecurityGroupResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The resource ID of the network security group to assign to the subnet." } }, "routeTableResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The resource ID of the route table to assign to the subnet." } }, "serviceEndpoints": { "type": "array", + "items": { + "type": "string" + }, "defaultValue": [], "metadata": { "description": "Optional. The service endpoints to enable on the subnet." } }, - "delegations": { - "type": "array", - "defaultValue": [], + "delegation": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The delegations to enable on the subnet." + "description": "Optional. The delegation to enable on the subnet." } }, "natGatewayResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The resource ID of the NAT Gateway to use for the subnet." } }, "privateEndpointNetworkPolicies": { "type": "string", - "defaultValue": "", + "nullable": true, "allowedValues": [ "Disabled", "Enabled", - "" + "NetworkSecurityGroupEnabled", + "RouteTableEnabled" ], "metadata": { - "description": "Optional. enable or disable apply network policies on private endpoint in the subnet." + "description": "Optional. Enable or disable apply network policies on private endpoint in the subnet." } }, "privateLinkServiceNetworkPolicies": { "type": "string", - "defaultValue": "", + "nullable": true, "allowedValues": [ "Disabled", - "Enabled", - "" + "Enabled" ], "metadata": { - "description": "Optional. enable or disable apply network policies on private link service in the subnet." + "description": "Optional. Enable or disable apply network policies on private link service in the subnet." } }, "addressPrefixes": { "type": "array", - "defaultValue": [], + "items": { + "type": "string" + }, + "nullable": true, "metadata": { - "description": "Optional. List of address prefixes for the subnet." + "description": "Conditional. List of address prefixes for the subnet. Required if `addressPrefix` is empty." } }, - "applicationGatewayIPConfigurations": { - "type": "array", - "defaultValue": [], + "defaultOutboundAccess": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. Application gateway IP configurations of virtual network resource." + "description": "Optional. Set this property to false to disable default outbound connectivity for all VMs in the subnet. This property can only be set at the time of subnet creation and cannot be updated for an existing subnet." + } + }, + "sharingScope": { + "type": "string", + "allowedValues": [ + "DelegatedServices", + "Tenant" + ], + "nullable": true, + "metadata": { + "description": "Optional. Set this property to Tenant to allow sharing subnet with other subscriptions in your AAD tenant. This property can only be set if defaultOutboundAccess is set to false, both properties can only be set if subnet is empty." } }, - "ipAllocations": { + "applicationGatewayIPConfigurations": { "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. Array of IpAllocation which reference this subnet." + "description": "Optional. Application gateway IP configurations of virtual network resource." } }, "serviceEndpointPolicies": { @@ -1370,7 +1688,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -1389,7 +1711,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -1397,26 +1719,35 @@ "virtualNetwork": { "existing": true, "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-11-01", + "apiVersion": "2024-01-01", "name": "[parameters('virtualNetworkName')]" }, "subnet": { "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "2023-11-01", + "apiVersion": "2024-01-01", "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('name'))]", "properties": { + "copy": [ + { + "name": "serviceEndpoints", + "count": "[length(parameters('serviceEndpoints'))]", + "input": { + "service": "[parameters('serviceEndpoints')[copyIndex('serviceEndpoints')]]" + } + } + ], "addressPrefix": "[parameters('addressPrefix')]", + "addressPrefixes": "[parameters('addressPrefixes')]", "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]", "routeTable": "[if(not(empty(parameters('routeTableResourceId'))), createObject('id', parameters('routeTableResourceId')), null())]", "natGateway": "[if(not(empty(parameters('natGatewayResourceId'))), createObject('id', parameters('natGatewayResourceId')), null())]", - "serviceEndpoints": "[parameters('serviceEndpoints')]", - "delegations": "[parameters('delegations')]", - "privateEndpointNetworkPolicies": "[if(not(empty(parameters('privateEndpointNetworkPolicies'))), parameters('privateEndpointNetworkPolicies'), null())]", - "privateLinkServiceNetworkPolicies": "[if(not(empty(parameters('privateLinkServiceNetworkPolicies'))), parameters('privateLinkServiceNetworkPolicies'), null())]", - "addressPrefixes": "[parameters('addressPrefixes')]", + "delegations": "[if(not(empty(parameters('delegation'))), createArray(createObject('name', parameters('delegation'), 'properties', createObject('serviceName', parameters('delegation')))), createArray())]", + "privateEndpointNetworkPolicies": "[parameters('privateEndpointNetworkPolicies')]", + "privateLinkServiceNetworkPolicies": "[parameters('privateLinkServiceNetworkPolicies')]", "applicationGatewayIPConfigurations": "[parameters('applicationGatewayIPConfigurations')]", - "ipAllocations": "[parameters('ipAllocations')]", - "serviceEndpointPolicies": "[parameters('serviceEndpointPolicies')]" + "serviceEndpointPolicies": "[parameters('serviceEndpointPolicies')]", + "defaultOutboundAccess": "[parameters('defaultOutboundAccess')]", + "sharingScope": "[parameters('sharingScope')]" }, "dependsOn": [ "virtualNetwork" @@ -1467,19 +1798,19 @@ }, "value": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('name'))]" }, - "subnetAddressPrefix": { + "addressPrefix": { "type": "string", "metadata": { "description": "The address prefix for the subnet." }, - "value": "[reference('subnet').addressPrefix]" + "value": "[coalesce(tryGet(reference('subnet'), 'addressPrefix'), '')]" }, - "subnetAddressPrefixes": { + "addressPrefixes": { "type": "array", "metadata": { "description": "List of address prefixes for the subnet." }, - "value": "[if(not(empty(parameters('addressPrefixes'))), reference('subnet').addressPrefixes, createArray())]" + "value": "[coalesce(tryGet(reference('subnet'), 'addressPrefixes'), createArray())]" } } } @@ -1491,7 +1822,7 @@ "virtualNetwork_peering_local": { "copy": { "name": "virtualNetwork_peering_local", - "count": "[length(parameters('peerings'))]" + "count": "[length(coalesce(parameters('peerings'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -1505,15 +1836,27 @@ "localVnetName": { "value": "[parameters('name')]" }, - "remoteVirtualNetworkId": { - "value": "[parameters('peerings')[copyIndex()].remoteVirtualNetworkId]" + "remoteVirtualNetworkResourceId": { + "value": "[coalesce(parameters('peerings'), createArray())[copyIndex()].remoteVirtualNetworkResourceId]" + }, + "name": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'name')]" + }, + "allowForwardedTraffic": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'allowForwardedTraffic')]" }, - "name": "[if(contains(parameters('peerings')[copyIndex()], 'name'), createObject('value', parameters('peerings')[copyIndex()].name), createObject('value', format('{0}-{1}', parameters('name'), last(split(parameters('peerings')[copyIndex()].remoteVirtualNetworkId, '/')))))]", - "allowForwardedTraffic": "[if(contains(parameters('peerings')[copyIndex()], 'allowForwardedTraffic'), createObject('value', parameters('peerings')[copyIndex()].allowForwardedTraffic), createObject('value', true()))]", - "allowGatewayTransit": "[if(contains(parameters('peerings')[copyIndex()], 'allowGatewayTransit'), createObject('value', parameters('peerings')[copyIndex()].allowGatewayTransit), createObject('value', false()))]", - "allowVirtualNetworkAccess": "[if(contains(parameters('peerings')[copyIndex()], 'allowVirtualNetworkAccess'), createObject('value', parameters('peerings')[copyIndex()].allowVirtualNetworkAccess), createObject('value', true()))]", - "doNotVerifyRemoteGateways": "[if(contains(parameters('peerings')[copyIndex()], 'doNotVerifyRemoteGateways'), createObject('value', parameters('peerings')[copyIndex()].doNotVerifyRemoteGateways), createObject('value', true()))]", - "useRemoteGateways": "[if(contains(parameters('peerings')[copyIndex()], 'useRemoteGateways'), createObject('value', parameters('peerings')[copyIndex()].useRemoteGateways), createObject('value', false()))]" + "allowGatewayTransit": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'allowGatewayTransit')]" + }, + "allowVirtualNetworkAccess": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'allowVirtualNetworkAccess')]" + }, + "doNotVerifyRemoteGateways": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'doNotVerifyRemoteGateways')]" + }, + "useRemoteGateways": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'useRemoteGateways')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1521,8 +1864,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1725716682351191048" + "version": "0.30.23.60470", + "templateHash": "345394220621166229" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -1531,9 +1874,9 @@ "parameters": { "name": { "type": "string", - "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", + "defaultValue": "[format('peer-{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkResourceId'), '/')))]", "metadata": { - "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName." + "description": "Optional. The Name of VNET Peering resource. If not provided, default value will be localVnetName-remoteVnetName." } }, "localVnetName": { @@ -1542,7 +1885,7 @@ "description": "Conditional. The name of the parent Virtual Network to add the peering to. Required if the template is used in a standalone deployment." } }, - "remoteVirtualNetworkId": { + "remoteVirtualNetworkResourceId": { "type": "string", "metadata": { "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID." @@ -1587,7 +1930,7 @@ "resources": [ { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2023-11-01", + "apiVersion": "2024-01-01", "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", "properties": { "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", @@ -1596,7 +1939,7 @@ "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", "useRemoteGateways": "[parameters('useRemoteGateways')]", "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkId')]" + "id": "[parameters('remoteVirtualNetworkResourceId')]" } } } @@ -1627,20 +1970,21 @@ } }, "dependsOn": [ - "virtualNetwork" + "virtualNetwork", + "virtualNetwork_subnets" ] }, "virtualNetwork_peering_remote": { "copy": { "name": "virtualNetwork_peering_remote", - "count": "[length(parameters('peerings'))]" + "count": "[length(coalesce(parameters('peerings'), createArray()))]" }, - "condition": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringEnabled'), equals(parameters('peerings')[copyIndex()].remotePeeringEnabled, true()), false())]", + "condition": "[coalesce(tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringEnabled'), false())]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-virtualNetworkPeering-remote-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "subscriptionId": "[split(parameters('peerings')[copyIndex()].remoteVirtualNetworkId, '/')[2]]", - "resourceGroup": "[split(parameters('peerings')[copyIndex()].remoteVirtualNetworkId, '/')[4]]", + "subscriptionId": "[split(coalesce(parameters('peerings'), createArray())[copyIndex()].remoteVirtualNetworkResourceId, '/')[2]]", + "resourceGroup": "[split(coalesce(parameters('peerings'), createArray())[copyIndex()].remoteVirtualNetworkResourceId, '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1648,17 +1992,29 @@ "mode": "Incremental", "parameters": { "localVnetName": { - "value": "[last(split(parameters('peerings')[copyIndex()].remoteVirtualNetworkId, '/'))]" + "value": "[last(split(coalesce(parameters('peerings'), createArray())[copyIndex()].remoteVirtualNetworkResourceId, '/'))]" }, - "remoteVirtualNetworkId": { + "remoteVirtualNetworkResourceId": { "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" }, - "name": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringName'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringName), createObject('value', format('{0}-{1}', last(split(parameters('peerings')[copyIndex()].remoteVirtualNetworkId, '/')), parameters('name'))))]", - "allowForwardedTraffic": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringAllowForwardedTraffic'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringAllowForwardedTraffic), createObject('value', true()))]", - "allowGatewayTransit": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringAllowGatewayTransit'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringAllowGatewayTransit), createObject('value', false()))]", - "allowVirtualNetworkAccess": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringAllowVirtualNetworkAccess'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringAllowVirtualNetworkAccess), createObject('value', true()))]", - "doNotVerifyRemoteGateways": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringDoNotVerifyRemoteGateways'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringDoNotVerifyRemoteGateways), createObject('value', true()))]", - "useRemoteGateways": "[if(contains(parameters('peerings')[copyIndex()], 'remotePeeringUseRemoteGateways'), createObject('value', parameters('peerings')[copyIndex()].remotePeeringUseRemoteGateways), createObject('value', false()))]" + "name": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringName')]" + }, + "allowForwardedTraffic": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringAllowForwardedTraffic')]" + }, + "allowGatewayTransit": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringAllowGatewayTransit')]" + }, + "allowVirtualNetworkAccess": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringAllowVirtualNetworkAccess')]" + }, + "doNotVerifyRemoteGateways": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringDoNotVerifyRemoteGateways')]" + }, + "useRemoteGateways": { + "value": "[tryGet(coalesce(parameters('peerings'), createArray())[copyIndex()], 'remotePeeringUseRemoteGateways')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1666,8 +2022,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1725716682351191048" + "version": "0.30.23.60470", + "templateHash": "345394220621166229" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -1676,9 +2032,9 @@ "parameters": { "name": { "type": "string", - "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", + "defaultValue": "[format('peer-{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkResourceId'), '/')))]", "metadata": { - "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName." + "description": "Optional. The Name of VNET Peering resource. If not provided, default value will be localVnetName-remoteVnetName." } }, "localVnetName": { @@ -1687,7 +2043,7 @@ "description": "Conditional. The name of the parent Virtual Network to add the peering to. Required if the template is used in a standalone deployment." } }, - "remoteVirtualNetworkId": { + "remoteVirtualNetworkResourceId": { "type": "string", "metadata": { "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID." @@ -1732,7 +2088,7 @@ "resources": [ { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2023-11-01", + "apiVersion": "2024-01-01", "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", "properties": { "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", @@ -1741,7 +2097,7 @@ "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", "useRemoteGateways": "[parameters('useRemoteGateways')]", "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkId')]" + "id": "[parameters('remoteVirtualNetworkResourceId')]" } } } @@ -1772,7 +2128,8 @@ } }, "dependsOn": [ - "virtualNetwork" + "virtualNetwork", + "virtualNetwork_subnets" ] } }, @@ -1804,8 +2161,8 @@ "description": "The names of the deployed subnets." }, "copy": { - "count": "[length(parameters('subnets'))]", - "input": "[parameters('subnets')[copyIndex()].name]" + "count": "[length(coalesce(parameters('subnets'), createArray()))]", + "input": "[reference(format('virtualNetwork_subnets[{0}]', copyIndex())).outputs.name.value]" } }, "subnetResourceIds": { @@ -1814,8 +2171,8 @@ "description": "The resource IDs of the deployed subnets." }, "copy": { - "count": "[length(parameters('subnets'))]", - "input": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), parameters('subnets')[copyIndex()].name)]" + "count": "[length(coalesce(parameters('subnets'), createArray()))]", + "input": "[reference(format('virtualNetwork_subnets[{0}]', copyIndex())).outputs.resourceId.value]" } }, "location": { @@ -1823,7 +2180,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('virtualNetwork', '2023-11-01', 'full').location]" + "value": "[reference('virtualNetwork', '2024-01-01', 'full').location]" } } } @@ -1840,7 +2197,7 @@ "condition": "[variables('createNewVNET')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('nsgNamePrivateLink')]", + "name": "[format('{0}-nsg-{1}', uniqueString(deployment().name, parameters('location')), variables('nsgNamePrivateLink'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1869,7 +2226,7 @@ "location": { "value": "[parameters('location')]" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -1888,7 +2245,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "10358219678615978032" + "templateHash": "32550557190395602" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -2322,7 +2679,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -2331,7 +2688,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2493,7 +2850,7 @@ "condition": "[and(variables('createNewVNET'), parameters('enableDatabricks'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('nsgNameDbwFrontend')]", + "name": "[format('{0}-nsg-{1}', uniqueString(deployment().name, parameters('location')), variables('nsgNameDbwFrontend'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -2522,7 +2879,7 @@ "location": { "value": "[parameters('location')]" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -2541,7 +2898,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "10358219678615978032" + "templateHash": "32550557190395602" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -2975,7 +3332,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -2984,7 +3341,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3146,7 +3503,7 @@ "condition": "[and(variables('createNewVNET'), parameters('enableDatabricks'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('nsgNameDbwBackend')]", + "name": "[format('{0}-nsg-{1}', uniqueString(deployment().name, parameters('location')), variables('nsgNameDbwBackend'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -3175,7 +3532,7 @@ "location": { "value": "[parameters('location')]" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -3194,7 +3551,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "10358219678615978032" + "templateHash": "32550557190395602" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -3628,7 +3985,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -3637,7 +3994,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3799,7 +4156,7 @@ "condition": "[and(variables('createNewVNET'), parameters('enableDatabricks'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('privateDnsZoneNameSaBlob')]", + "name": "[format('{0}-zone-{1}', uniqueString(deployment().name, parameters('location')), variables('privateDnsZoneNameSaBlob'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -3815,7 +4172,7 @@ "location": { "value": "global" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -6861,7 +7218,7 @@ "condition": "[variables('createNewLog')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('logName')]", + "name": "[format('{0}-law-{1}', uniqueString(deployment().name, parameters('location')), variables('logName'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -6886,7 +7243,7 @@ "location": { "value": "[parameters('location')]" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -6904,8 +7261,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6423883681003873806" + "version": "0.30.23.60470", + "templateHash": "17849222501048122703" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace.", @@ -7114,6 +7471,13 @@ "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, @@ -7308,13 +7672,6 @@ "description": "Optional. The diagnostic settings of the service." } }, - "useDeployedWorkspaceForDiagnosticSettings": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Instead of using an external reference, use the deployed instance as the target for its diagnostic settings." - } - }, "forceCmkForQuery": { "type": "bool", "defaultValue": true, @@ -7367,7 +7724,7 @@ "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')]", + "Role Based Access Control Administrator": "[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')]" @@ -7378,7 +7735,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.operationalinsights-workspace.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.operationalinsights-workspace.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -7450,7 +7807,7 @@ } ], "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[if(parameters('useDeployedWorkspaceForDiagnosticSettings'), resourceId('Microsoft.OperationalInsights/workspaces', parameters('name')), tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId'))]", + "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')]", @@ -7530,8 +7887,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1745671120474305926" + "version": "0.30.23.60470", + "templateHash": "8028201980853199520" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", @@ -7674,8 +8031,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "12032441371027552374" + "version": "0.30.23.60470", + "templateHash": "1524032160953098939" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -7698,7 +8055,7 @@ "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." + "description": "Optional. 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": { @@ -7796,8 +8153,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "12623216644328477682" + "version": "0.30.23.60470", + "templateHash": "16040380910189891293" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", @@ -7919,8 +8276,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "7683333179440464721" + "version": "0.30.23.60470", + "templateHash": "7572266675487147820" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", @@ -8085,8 +8442,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5765609820817623497" + "version": "0.30.23.60470", + "templateHash": "8816832199581598050" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", @@ -8234,8 +8591,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13460038983765020046" + "version": "0.30.23.60470", + "templateHash": "10275938611959517944" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", @@ -8268,7 +8625,7 @@ "LinuxPerformanceCollection" ], "metadata": { - "description": "Required. The kind of the DataSource." + "description": "Optional. The kind of the DataSource." } }, "tags": { @@ -8465,8 +8822,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6905244456918791391" + "version": "0.30.23.60470", + "templateHash": "2417830359794202602" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", @@ -8633,7 +8990,7 @@ "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')]", + "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')]" } }, @@ -8930,7 +9287,7 @@ "condition": "[variables('createNewKV')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('kvName')]", + "name": "[format('{0}-vault-{1}', uniqueString(deployment().name, parameters('location')), variables('kvName'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -9004,7 +9361,7 @@ "name": "[format('{0}-kv-pep', parameters('name'))]", "location": "[parameters('location')]", "subnetResourceId": "[createObject('resourceId', if(variables('createNewVNET'), reference('vnet').outputs.resourceId.value, extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))))), 'name', if(variables('createNewVNET'), reference('vnet').outputs.name.value, if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), 'location', if(variables('createNewVNET'), reference('vnet').outputs.location.value, reference('vnetExisting', '2023-11-01', 'full').location), 'resourceGroupName', if(variables('createNewVNET'), reference('vnet').outputs.resourceGroupName.value, split(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), '/')[4]), 'subnetResourceIdPrivateLink', if(variables('createNewVNET'), reference('vnet').outputs.subnetResourceIds.value[0], extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks/subnets', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'virtualNetwork'), 'subnetNamePrivateLink'), 'dummyName'))), 'subnetNameDbwFrontend', if(variables('createNewVNET'), variables('subnetNameDbwFrontend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameFrontend'), 'dummyName')), 'subnetNameDbwBackend', if(variables('createNewVNET'), variables('subnetNameDbwBackend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameBackend'), 'dummyName'))).subnetResourceIdPrivateLink]", - "privateDnsZoneResourceIds": "[if(variables('createNewVNET'), createArray(reference('dnsZoneKv').outputs.resourceId.value), createArray())]", + "privateDnsZoneGroup": "[if(variables('createNewVNET'), createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', reference('dnsZoneKv').outputs.resourceId.value))), null())]", "tags": "[parameters('tags')]", "enableTelemetry": "[parameters('enableTelemetry')]", "lock": "[parameters('lock')]", @@ -9030,7 +9387,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "2551361518348339794" + "templateHash": "10085839006881327962" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -9269,21 +9626,44 @@ "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" + "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 groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -10073,7 +10453,7 @@ "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')]", + "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')]" } }, @@ -10082,7 +10462,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.keyvault-vault.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.keyvault-vault.{0}.{1}', replace('0.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -10469,13 +10849,13 @@ "value": "[parameters('name')]" }, "attributesEnabled": { - "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributesEnabled')]" + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'enabled')]" }, "attributesExp": { - "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributesExp')]" + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'exp')]" }, "attributesNbf": { - "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributesNbf')]" + "value": "[tryGet(tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'attributes'), 'nbf')]" }, "contentType": { "value": "[tryGet(coalesce(parameters('secrets'), createArray())[copyIndex()], 'contentType')]" @@ -10495,7 +10875,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "4990258423482296566" + "templateHash": "114626909766354577" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", @@ -10654,7 +11034,7 @@ "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')]", + "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')]" } }, @@ -10756,13 +11136,13 @@ "value": "[parameters('name')]" }, "attributesEnabled": { - "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributesEnabled')]" + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'enabled')]" }, "attributesExp": { - "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributesExp')]" + "value": "[tryGet(tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'attributes'), 'exp')]" }, "attributesNbf": { - "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], '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": { @@ -10793,7 +11173,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "10436564794447478489" + "templateHash": "14269695922191217406" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", @@ -11003,7 +11383,7 @@ "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')]", + "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')]" } }, @@ -11120,11 +11500,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -11152,19 +11529,47 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4120048060064073955" + "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": { @@ -11268,13 +11673,13 @@ "groupId": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "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." + "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": { @@ -11308,8 +11713,11 @@ "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." + "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": { @@ -11349,8 +11757,11 @@ "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." + "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": { @@ -11398,6 +11809,29 @@ } }, "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": { @@ -11433,18 +11867,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -11500,6 +11927,13 @@ } }, "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')]", @@ -11517,8 +11951,8 @@ "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))]", + "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": { @@ -11536,7 +11970,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -11577,27 +12011,27 @@ "privateEndpoint_roleAssignments": { "copy": { "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), 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)]", + "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": "[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')]" + "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')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -11608,28 +12042,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "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.25.53.49325", - "templateHash": "11244630631275470040" + "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", @@ -11637,12 +12095,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "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": { @@ -11656,27 +12117,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -11734,14 +12204,28 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + "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(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" + "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), ''), ''))]" } } } @@ -11786,6 +12270,22 @@ "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]" + } + } } } } @@ -11802,7 +12302,7 @@ "condition": "[and(variables('createNewVNET'), variables('createNewKV'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('privateDnsZoneNameKv')]", + "name": "[format('{0}-zone-{1}', uniqueString(deployment().name, parameters('location')), variables('privateDnsZoneNameKv'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -11818,7 +12318,7 @@ "location": { "value": "global" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -11842,7 +12342,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "17411368014038876941" + "templateHash": "5518185016108244461" }, "name": "Private DNS Zones", "description": "This module deploys a Private DNS zone.", @@ -12583,7 +13083,7 @@ "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')]" + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" } }, "resources": { @@ -12591,7 +13091,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privatednszone.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privatednszone.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -12691,7 +13191,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "11343565859504250241" + "templateHash": "1641889417618452692" }, "name": "Private DNS Zone A record", "description": "This module deploys a Private DNS Zone A record.", @@ -12827,7 +13327,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -12944,7 +13444,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "3700934406905797316" + "templateHash": "17163414995652446126" }, "name": "Private DNS Zone AAAA record", "description": "This module deploys a Private DNS Zone AAAA record.", @@ -13080,7 +13580,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -13197,7 +13697,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "12929118683431932277" + "templateHash": "2493714129104385633" }, "name": "Private DNS Zone CNAME record", "description": "This module deploys a Private DNS Zone CNAME record.", @@ -13333,7 +13833,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -13450,7 +13950,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "14178508926823177155" + "templateHash": "10928449924272756679" }, "name": "Private DNS Zone MX record", "description": "This module deploys a Private DNS Zone MX record.", @@ -13586,7 +14086,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -13703,7 +14203,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8082128465097964607" + "templateHash": "13191587152357386110" }, "name": "Private DNS Zone PTR record", "description": "This module deploys a Private DNS Zone PTR record.", @@ -13839,7 +14339,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -13956,7 +14456,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "6755707328778392735" + "templateHash": "12872700379964561295" }, "name": "Private DNS Zone SOA record", "description": "This module deploys a Private DNS Zone SOA record.", @@ -14092,7 +14592,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -14209,7 +14709,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "662436323695062210" + "templateHash": "12918383495773487180" }, "name": "Private DNS Zone SRV record", "description": "This module deploys a Private DNS Zone SRV record.", @@ -14345,7 +14845,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -14462,7 +14962,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "356727884506799436" + "templateHash": "128006490354221158" }, "name": "Private DNS Zone TXT record", "description": "This module deploys a Private DNS Zone TXT record.", @@ -14598,7 +15098,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -14864,7 +15364,7 @@ "condition": "[parameters('enableDatabricks')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('dbwAccessConnectorName')]", + "name": "[format('{0}-connector-{1}', uniqueString(deployment().name, parameters('location')), variables('dbwAccessConnectorName'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -14888,7 +15388,7 @@ "systemAssigned": true } }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "tags": { "value": "[parameters('tags')]" } @@ -14901,7 +15401,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "6033667819597442355" + "templateHash": "14471774374628354564" }, "name": "Azure Databricks Access Connectors", "description": "This module deploys an Azure Databricks Access Connector.", @@ -15091,7 +15591,7 @@ "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')]", + "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')]" } }, @@ -15100,7 +15600,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.databricks-accessconnector.{0}.{1}', replace('0.2.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.databricks-accessconnector.{0}.{1}', replace('0.3.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -15206,7 +15706,7 @@ "condition": "[parameters('enableDatabricks')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('dbwName')]", + "name": "[format('{0}-workspace-{1}', uniqueString(deployment().name, parameters('location')), variables('dbwName'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -15262,22 +15762,22 @@ "location": "[parameters('location')]", "service": "databricks_ui_api", "subnetResourceId": "[createObject('resourceId', if(variables('createNewVNET'), reference('vnet').outputs.resourceId.value, extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))))), 'name', if(variables('createNewVNET'), reference('vnet').outputs.name.value, if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), 'location', if(variables('createNewVNET'), reference('vnet').outputs.location.value, reference('vnetExisting', '2023-11-01', 'full').location), 'resourceGroupName', if(variables('createNewVNET'), reference('vnet').outputs.resourceGroupName.value, split(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), '/')[4]), 'subnetResourceIdPrivateLink', if(variables('createNewVNET'), reference('vnet').outputs.subnetResourceIds.value[0], extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks/subnets', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'virtualNetwork'), 'subnetNamePrivateLink'), 'dummyName'))), 'subnetNameDbwFrontend', if(variables('createNewVNET'), variables('subnetNameDbwFrontend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameFrontend'), 'dummyName')), 'subnetNameDbwBackend', if(variables('createNewVNET'), variables('subnetNameDbwBackend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameBackend'), 'dummyName'))).subnetResourceIdPrivateLink]", - "privateDnsZoneResourceIds": "[if(variables('createNewVNET'), createArray(reference('dnsZoneDbw').outputs.resourceId.value), createArray())]", + "privateDnsZoneGroup": "[if(variables('createNewVNET'), createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', reference('dnsZoneDbw').outputs.resourceId.value))), null())]", "tags": "[parameters('tags')]", "enableTelemetry": "[parameters('enableTelemetry')]", "lock": "[parameters('lock')]", - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createArray(), variables('ownerRoleAssignments'))]" + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), variables('ownerRoleAssignments'), createArray())]" }, { "name": "[format('{0}-dbw-auth-pep', parameters('name'))]", "location": "[parameters('location')]", "service": "browser_authentication", "subnetResourceId": "[createObject('resourceId', if(variables('createNewVNET'), reference('vnet').outputs.resourceId.value, extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))))), 'name', if(variables('createNewVNET'), reference('vnet').outputs.name.value, if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), 'location', if(variables('createNewVNET'), reference('vnet').outputs.location.value, reference('vnetExisting', '2023-11-01', 'full').location), 'resourceGroupName', if(variables('createNewVNET'), reference('vnet').outputs.resourceGroupName.value, split(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), '/')[4]), 'subnetResourceIdPrivateLink', if(variables('createNewVNET'), reference('vnet').outputs.subnetResourceIds.value[0], extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks/subnets', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'virtualNetwork'), 'subnetNamePrivateLink'), 'dummyName'))), 'subnetNameDbwFrontend', if(variables('createNewVNET'), variables('subnetNameDbwFrontend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameFrontend'), 'dummyName')), 'subnetNameDbwBackend', if(variables('createNewVNET'), variables('subnetNameDbwBackend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameBackend'), 'dummyName'))).subnetResourceIdPrivateLink]", - "privateDnsZoneResourceIds": "[if(variables('createNewVNET'), createArray(reference('dnsZoneDbw').outputs.resourceId.value), createArray())]", + "privateDnsZoneGroup": "[if(variables('createNewVNET'), createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', reference('dnsZoneDbw').outputs.resourceId.value))), null())]", "tags": "[parameters('tags')]", "enableTelemetry": "[parameters('enableTelemetry')]", "lock": "[parameters('lock')]", - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createArray(), variables('ownerRoleAssignments'))]" + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), variables('ownerRoleAssignments'), createArray())]" } ] }, @@ -15286,7 +15786,7 @@ }, "publicNetworkAccess": "[if(empty(variables('dbwIpRules')), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]", "requiredNsgRules": "[if(empty(variables('dbwIpRules')), createObject('value', 'NoAzureDatabricksRules'), createObject('value', 'AllRules'))]", - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "skuName": { "value": "premium" }, @@ -15300,11 +15800,11 @@ "location": "[parameters('location')]", "service": "blob", "subnetResourceId": "[createObject('resourceId', if(variables('createNewVNET'), reference('vnet').outputs.resourceId.value, extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))))), 'name', if(variables('createNewVNET'), reference('vnet').outputs.name.value, if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), 'location', if(variables('createNewVNET'), reference('vnet').outputs.location.value, reference('vnetExisting', '2023-11-01', 'full').location), 'resourceGroupName', if(variables('createNewVNET'), reference('vnet').outputs.resourceGroupName.value, split(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/')))), '/')[4]), 'subnetResourceIdPrivateLink', if(variables('createNewVNET'), reference('vnet').outputs.subnetResourceIds.value[0], extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', if(variables('createNewVNET'), subscription().id, split(parameters('virtualNetworkResourceId'), '/')[2]), if(variables('createNewVNET'), resourceGroup().id, split(parameters('virtualNetworkResourceId'), '/')[4])), 'Microsoft.Network/virtualNetworks/subnets', if(variables('createNewVNET'), 'dummyName', last(split(parameters('virtualNetworkResourceId'), '/'))), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'virtualNetwork'), 'subnetNamePrivateLink'), 'dummyName'))), 'subnetNameDbwFrontend', if(variables('createNewVNET'), variables('subnetNameDbwFrontend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameFrontend'), 'dummyName')), 'subnetNameDbwBackend', if(variables('createNewVNET'), variables('subnetNameDbwBackend'), coalesce(tryGet(tryGet(parameters('advancedOptions'), 'databricks'), 'subnetNameBackend'), 'dummyName'))).subnetResourceIdPrivateLink]", - "privateDnsZoneResourceIds": "[if(variables('createNewVNET'), createArray(reference('dnsZoneSaBlob').outputs.resourceId.value), createArray())]", + "privateDnsZoneGroup": "[if(variables('createNewVNET'), createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', reference('dnsZoneSaBlob').outputs.resourceId.value))), null())]", "tags": "[parameters('tags')]", "enableTelemetry": "[parameters('enableTelemetry')]", "lock": "[parameters('lock')]", - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createArray(), variables('ownerRoleAssignments'))]" + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), variables('ownerRoleAssignments'), createArray())]" } ] }, @@ -15319,8 +15819,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "402312165701369561" + "version": "0.30.23.60470", + "templateHash": "5134701226569732145" }, "name": "Azure Databricks Workspaces", "description": "This module deploys an Azure Databricks Workspace.", @@ -15390,21 +15890,44 @@ "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" + "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 groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -15431,7 +15954,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, "ipAddresses": { @@ -15786,6 +16309,21 @@ } }, "nullable": true + }, + "defaultCatalogType": { + "type": "object", + "properties": { + "initialType": { + "type": "string", + "allowedValues": [ + "HiveMetastore", + "UnityCatalog" + ], + "metadata": { + "description": "Required. Choose between HiveMetastore or UnityCatalog." + } + } + } } }, "parameters": { @@ -16015,6 +16553,56 @@ "metadata": { "description": "Conditional. The resource ID of the associated access connector for private access to the managed workspace storage account. Required if privateStorageAccount is enabled." } + }, + "defaultCatalog": { + "$ref": "#/definitions/defaultCatalogType", + "nullable": true, + "metadata": { + "description": "Optional. The default catalog configuration for the Databricks workspace." + } + }, + "automaticClusterUpdate": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Enabled", + "Disabled", + "" + ], + "metadata": { + "description": "Optional. The value for enabling automatic cluster updates in enhanced security compliance." + } + }, + "complianceStandards": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The compliance standards array for the security profile. Should be a list of compliance standards like \"HIPAA\", \"NONE\" or \"PCI_DSS\"." + } + }, + "complianceSecurityProfileValue": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Enabled", + "Disabled", + "" + ], + "metadata": { + "description": "Optional. The value to Enable or Disable for the compliance security profile." + } + }, + "enhancedSecurityMonitoring": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Enabled", + "Disabled", + "" + ], + "metadata": { + "description": "Optional. The value for enabling or configuring enhanced security monitoring." + } } }, "variables": { @@ -16029,7 +16617,7 @@ "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')]", + "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')]" } }, @@ -16062,7 +16650,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.databricks-workspace.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.databricks-workspace.{0}.{1}', replace('0.8.5', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -16105,7 +16693,7 @@ "sku": { "name": "[parameters('skuName')]" }, - "properties": "[union(createObject('managedResourceGroupId', if(not(empty(parameters('managedResourceGroupResourceId'))), parameters('managedResourceGroupResourceId'), format('{0}/resourceGroups/rg-{1}-managed', subscription().id, parameters('name'))), 'parameters', union(createObject('enableNoPublicIp', createObject('value', parameters('disablePublicIp')), 'prepareEncryption', createObject('value', parameters('prepareEncryption')), 'vnetAddressPrefix', createObject('value', parameters('vnetAddressPrefix')), 'requireInfrastructureEncryption', createObject('value', parameters('requireInfrastructureEncryption'))), if(not(empty(parameters('customVirtualNetworkResourceId'))), createObject('customVirtualNetworkId', createObject('value', parameters('customVirtualNetworkResourceId'))), createObject()), if(not(empty(parameters('amlWorkspaceResourceId'))), createObject('amlWorkspaceId', createObject('value', parameters('amlWorkspaceResourceId'))), createObject()), if(not(empty(parameters('customPrivateSubnetName'))), createObject('customPrivateSubnetName', createObject('value', parameters('customPrivateSubnetName'))), createObject()), if(not(empty(parameters('customPublicSubnetName'))), createObject('customPublicSubnetName', createObject('value', parameters('customPublicSubnetName'))), createObject()), if(not(empty(parameters('loadBalancerBackendPoolName'))), createObject('loadBalancerBackendPoolName', createObject('value', parameters('loadBalancerBackendPoolName'))), createObject()), if(not(empty(parameters('loadBalancerResourceId'))), createObject('loadBalancerId', createObject('value', parameters('loadBalancerResourceId'))), createObject()), if(not(empty(parameters('natGatewayName'))), createObject('natGatewayName', createObject('value', parameters('natGatewayName'))), createObject()), if(not(empty(parameters('publicIpName'))), createObject('publicIpName', createObject('value', parameters('publicIpName'))), createObject()), if(not(empty(parameters('storageAccountName'))), createObject('storageAccountName', createObject('value', parameters('storageAccountName'))), createObject()), if(not(empty(parameters('storageAccountSkuName'))), createObject('storageAccountSkuName', createObject('value', parameters('storageAccountSkuName'))), createObject())), 'publicNetworkAccess', parameters('publicNetworkAccess'), 'requiredNsgRules', parameters('requiredNsgRules'), 'encryption', if(or(not(empty(parameters('customerManagedKey'))), not(empty(parameters('customerManagedKeyManagedDisk')))), createObject('entities', createObject('managedServices', if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.Keyvault', 'keyVaultProperties', createObject('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()), 'managedDisk', if(not(empty(parameters('customerManagedKeyManagedDisk'))), createObject('keySource', 'Microsoft.Keyvault', 'keyVaultProperties', createObject('keyVaultUri', reference('cMKManagedDiskKeyVault').vaultUri, 'keyName', parameters('customerManagedKeyManagedDisk').keyName, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'keyVersion'), ''))), parameters('customerManagedKeyManagedDisk').keyVersion, last(split(reference('cMKManagedDiskKeyVault::cMKKey').keyUriWithVersion, '/')))), 'rotationToLatestKeyVersionEnabled', coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'rotationToLatestKeyVersionEnabled'), true())), null()))), null())), if(not(empty(parameters('privateStorageAccount'))), createObject('defaultStorageFirewall', parameters('privateStorageAccount'), 'accessConnector', createObject('id', parameters('accessConnectorResourceId'), 'identityType', 'SystemAssigned')), createObject()))]", + "properties": "[shallowMerge(createArray(createObject('managedResourceGroupId', if(not(empty(parameters('managedResourceGroupResourceId'))), parameters('managedResourceGroupResourceId'), format('{0}/resourceGroups/rg-{1}-managed', subscription().id, parameters('name'))), 'parameters', shallowMerge(createArray(createObject('enableNoPublicIp', createObject('value', parameters('disablePublicIp')), 'prepareEncryption', createObject('value', parameters('prepareEncryption')), 'vnetAddressPrefix', createObject('value', parameters('vnetAddressPrefix')), 'requireInfrastructureEncryption', createObject('value', parameters('requireInfrastructureEncryption'))), if(not(empty(parameters('customVirtualNetworkResourceId'))), createObject('customVirtualNetworkId', createObject('value', parameters('customVirtualNetworkResourceId'))), createObject()), if(not(empty(parameters('amlWorkspaceResourceId'))), createObject('amlWorkspaceId', createObject('value', parameters('amlWorkspaceResourceId'))), createObject()), if(not(empty(parameters('customPrivateSubnetName'))), createObject('customPrivateSubnetName', createObject('value', parameters('customPrivateSubnetName'))), createObject()), if(not(empty(parameters('customPublicSubnetName'))), createObject('customPublicSubnetName', createObject('value', parameters('customPublicSubnetName'))), createObject()), if(not(empty(parameters('loadBalancerBackendPoolName'))), createObject('loadBalancerBackendPoolName', createObject('value', parameters('loadBalancerBackendPoolName'))), createObject()), if(not(empty(parameters('loadBalancerResourceId'))), createObject('loadBalancerId', createObject('value', parameters('loadBalancerResourceId'))), createObject()), if(not(empty(parameters('natGatewayName'))), createObject('natGatewayName', createObject('value', parameters('natGatewayName'))), createObject()), if(not(empty(parameters('publicIpName'))), createObject('publicIpName', createObject('value', parameters('publicIpName'))), createObject()), if(not(empty(parameters('storageAccountName'))), createObject('storageAccountName', createObject('value', parameters('storageAccountName'))), createObject()), if(not(empty(parameters('storageAccountSkuName'))), createObject('storageAccountSkuName', createObject('value', parameters('storageAccountSkuName'))), createObject()))), 'publicNetworkAccess', parameters('publicNetworkAccess'), 'requiredNsgRules', parameters('requiredNsgRules'), 'encryption', if(or(not(empty(parameters('customerManagedKey'))), not(empty(parameters('customerManagedKeyManagedDisk')))), createObject('entities', createObject('managedServices', if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.Keyvault', 'keyVaultProperties', createObject('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()), 'managedDisk', if(not(empty(parameters('customerManagedKeyManagedDisk'))), createObject('keySource', 'Microsoft.Keyvault', 'keyVaultProperties', createObject('keyVaultUri', reference('cMKManagedDiskKeyVault').vaultUri, 'keyName', parameters('customerManagedKeyManagedDisk').keyName, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'keyVersion'), ''))), parameters('customerManagedKeyManagedDisk').keyVersion, last(split(reference('cMKManagedDiskKeyVault::cMKKey').keyUriWithVersion, '/')))), 'rotationToLatestKeyVersionEnabled', coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'rotationToLatestKeyVersionEnabled'), true())), null()))), null())), if(not(empty(parameters('privateStorageAccount'))), createObject('defaultStorageFirewall', parameters('privateStorageAccount'), 'accessConnector', createObject('id', parameters('accessConnectorResourceId'), 'identityType', 'SystemAssigned')), createObject()), if(not(empty(parameters('defaultCatalog'))), createObject('defaultCatalog', createObject('initialName', '', 'initialType', tryGet(parameters('defaultCatalog'), 'initialType'))), createObject()), if(or(or(not(empty(parameters('automaticClusterUpdate'))), not(empty(parameters('complianceStandards')))), not(empty(parameters('enhancedSecurityMonitoring')))), createObject('enhancedSecurityCompliance', createObject('automaticClusterUpdate', createObject('value', parameters('automaticClusterUpdate')), 'complianceSecurityProfile', createObject('complianceStandards', parameters('complianceStandards'), 'value', parameters('complianceSecurityProfileValue')), 'enhancedSecurityMonitoring', createObject('value', parameters('enhancedSecurityMonitoring')))), createObject())))]", "dependsOn": [ "cMKKeyVault", "cMKManagedDiskKeyVault" @@ -16213,11 +16801,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -16246,13 +16831,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "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": { @@ -16504,6 +17110,29 @@ } }, "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": { @@ -16539,18 +17168,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -16631,7 +17253,7 @@ "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))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -16710,7 +17332,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -16721,28 +17343,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "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": "15263454436186512874" + "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", @@ -16750,12 +17396,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "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": { @@ -16769,27 +17418,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "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('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -16856,6 +17514,13 @@ }, "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": { @@ -16870,9 +17535,9 @@ "workspace" ] }, - "storageAccount_privateEndpoints": { + "storageAccount_storageAccountPrivateEndpoints": { "copy": { - "name": "storageAccount_privateEndpoints", + "name": "storageAccount_storageAccountPrivateEndpoints", "count": "[length(coalesce(parameters('storageAccountPrivateEndpoints'), createArray()))]", "mode": "serial", "batchSize": 1 @@ -16905,11 +17570,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -16938,13 +17600,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "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": { @@ -17196,6 +17879,29 @@ } }, "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": { @@ -17231,18 +17937,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -17323,7 +18022,7 @@ "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))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -17402,7 +18101,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -17413,28 +18112,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "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": "15263454436186512874" + "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", @@ -17442,12 +18165,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "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": { @@ -17461,27 +18187,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "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('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -17548,6 +18283,13 @@ }, "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": { @@ -17637,13 +18379,32 @@ "privateEndpoints": { "type": "array", "metadata": { - "description": "The private endpoints for the Databricks Workspace." + "description": "The private endpoints of the Databricks Workspace." }, "copy": { "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", "input": { "name": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", - "resourceId": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]" + "resourceId": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + }, + "storagePrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the Databricks Workspace Storage." + }, + "copy": { + "count": "[length(if(and(not(empty(parameters('storageAccountPrivateEndpoints'))), equals(parameters('privateStorageAccount'), 'Enabled')), array(parameters('storageAccountPrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" } } } @@ -17664,7 +18425,7 @@ "condition": "[and(variables('createNewVNET'), parameters('enableDatabricks'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[variables('privateDnsZoneNameDbw')]", + "name": "[format('{0}-zone-{1}', uniqueString(deployment().name, parameters('location')), variables('privateDnsZoneNameDbw'))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -17680,7 +18441,7 @@ "location": { "value": "global" }, - "roleAssignments": "[if(empty(variables('ownerRoleAssignments')), createObject('value', createArray()), createObject('value', variables('ownerRoleAssignments')))]", + "roleAssignments": "[if(not(empty(variables('ownerRoleAssignments'))), createObject('value', variables('ownerRoleAssignments')), createObject('value', createArray()))]", "lock": { "value": "[parameters('lock')]" }, @@ -17704,7 +18465,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "17411368014038876941" + "templateHash": "5518185016108244461" }, "name": "Private DNS Zones", "description": "This module deploys a Private DNS zone.", @@ -18445,7 +19206,7 @@ "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')]" + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" } }, "resources": { @@ -18453,7 +19214,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privatednszone.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privatednszone.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -18553,7 +19314,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "11343565859504250241" + "templateHash": "1641889417618452692" }, "name": "Private DNS Zone A record", "description": "This module deploys a Private DNS Zone A record.", @@ -18689,7 +19450,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -18806,7 +19567,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "3700934406905797316" + "templateHash": "17163414995652446126" }, "name": "Private DNS Zone AAAA record", "description": "This module deploys a Private DNS Zone AAAA record.", @@ -18942,7 +19703,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -19059,7 +19820,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "12929118683431932277" + "templateHash": "2493714129104385633" }, "name": "Private DNS Zone CNAME record", "description": "This module deploys a Private DNS Zone CNAME record.", @@ -19195,7 +19956,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -19312,7 +20073,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "14178508926823177155" + "templateHash": "10928449924272756679" }, "name": "Private DNS Zone MX record", "description": "This module deploys a Private DNS Zone MX record.", @@ -19448,7 +20209,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -19565,7 +20326,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8082128465097964607" + "templateHash": "13191587152357386110" }, "name": "Private DNS Zone PTR record", "description": "This module deploys a Private DNS Zone PTR record.", @@ -19701,7 +20462,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -19818,7 +20579,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "6755707328778392735" + "templateHash": "12872700379964561295" }, "name": "Private DNS Zone SOA record", "description": "This module deploys a Private DNS Zone SOA record.", @@ -19954,7 +20715,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -20071,7 +20832,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "662436323695062210" + "templateHash": "12918383495773487180" }, "name": "Private DNS Zone SRV record", "description": "This module deploys a Private DNS Zone SRV record.", @@ -20207,7 +20968,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, @@ -20324,7 +21085,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "356727884506799436" + "templateHash": "128006490354221158" }, "name": "Private DNS Zone TXT record", "description": "This module deploys a Private DNS Zone TXT record.", @@ -20460,7 +21221,7 @@ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", "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')]", + "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')]" } }, diff --git a/avm/ptn/data/private-analytical-workspace/tests/common.tests.ps1 b/avm/ptn/data/private-analytical-workspace/tests/common.tests.ps1 index 403df09473..024d98b5e7 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/common.tests.ps1 +++ b/avm/ptn/data/private-analytical-workspace/tests/common.tests.ps1 @@ -87,10 +87,10 @@ function Test-VerifySubnet($Subnet, $SubnetName, $SubnetAddressPrefix, $NumberOf $Subnet.AddressPrefix[0] | Should -Be $SubnetAddressPrefix $Subnet.NetworkSecurityGroup.Count | Should -Be $NumberOfSecurityGroups - if ( $NumberOfPrivateEndpoints -eq $null ) { $Subnet.PrivateEndpoints | Should -BeNullOrEmpty } + if ( $null -eq $NumberOfPrivateEndpoints ) { $Subnet.PrivateEndpoints | Should -BeNullOrEmpty } else { $Subnet.PrivateEndpoints.Count | Should -Be $NumberOfPrivateEndpoints } - if ( $NumberOfIpConfigurations -eq $null ) { $Subnet.IpConfigurations | Should -BeNullOrEmpty } + if ( $null -eq $NumberOfIpConfigurations ) { $Subnet.IpConfigurations | Should -BeNullOrEmpty } else { $Subnet.IpConfigurations.Count | Should -Be $NumberOfIpConfigurations } $Subnet.ServiceAssociationLinks | Should -BeNullOrEmpty @@ -98,7 +98,7 @@ function Test-VerifySubnet($Subnet, $SubnetName, $SubnetAddressPrefix, $NumberOf $Subnet.ServiceEndpoints | Should -BeNullOrEmpty $Subnet.ServiceEndpointPolicies | Should -BeNullOrEmpty - if ( $DelegationServiceName -eq $null ) { $Subnet.Delegations | Should -BeNullOrEmpty } + if ( $null -eq $DelegationServiceName ) { $Subnet.Delegations | Should -BeNullOrEmpty } else { $Subnet.Delegations.Count | Should -Be 1 $Subnet.Delegations[0].ProvisioningState | Should -Be 'Succeeded' @@ -157,7 +157,7 @@ function Test-VerifyPrivateEndpoint($Name, $ResourceGroupName, $Tags, $SubnetNam $pep.NetworkInterfaces.Count | Should -Be 1 $pep.PrivateLinkServiceConnections.ProvisioningState | Should -Be 'Succeeded' - if ( $ServiceId -eq $null ) { + if ( $null -eq $ServiceId ) { # For some services I have no Id - but must be no empty $pep.PrivateLinkServiceConnections.PrivateLinkServiceId | Should -Not -BeNullOrEmpty } else { @@ -177,7 +177,7 @@ function Test-VerifyPrivateEndpoint($Name, $ResourceGroupName, $Tags, $SubnetNam } function Test-VerifyLogAnalyticsWorkspace($LogAnalyticsWorkspaceResourceGroupName, $LogAnalyticsWorkspaceName, $Tags, $Sku, $RetentionInDays, $DailyQuotaGb) { - $log = Get-AzOperationalInsightsWorkspace -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -name $LogAnalyticsWorkspaceName + $log = Get-AzOperationalInsightsWorkspace -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -Name $LogAnalyticsWorkspaceName $log | Should -Not -BeNullOrEmpty $log.ProvisioningState | Should -Be 'Succeeded' $log.Sku | Should -Be $Sku @@ -213,12 +213,12 @@ function Test-VerifyKeyVault($KeyVaultResourceGroupName, $KeyVaultName, $Tags, $ $kv.EnableRbacAuthorization | Should -Be $true $kv.EnableSoftDelete | Should -Be $EnableSoftDelete $kv.SoftDeleteRetentionInDays | Should -Be $RetentionInDays - $kv.EnablePurgeProtection | Should -Be $true + $kv.EnablePurgeProtection | Should -BeIn @($false, $null) $kv.PublicNetworkAccess | Should -Be $PublicNetworkAccess $kv.AccessPolicies | Should -BeNullOrEmpty $kv.NetworkAcls.DefaultAction | Should -Be 'Deny' $kv.NetworkAcls.Bypass | Should -Be 'None' - if ( $IpAddressRanges -eq $null ) { $kv.NetworkAcls.IpAddressRanges | Should -BeNullOrEmpty } + if ( $null -eq $IpAddressRanges ) { $kv.NetworkAcls.IpAddressRanges | Should -BeNullOrEmpty } else { $kv.NetworkAcls.IpAddressRanges.Count | Should -Be $IpAddressRanges.Count diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/defaults/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/defaults/main.test.bicep index 7294cf0921..c44e8f45f2 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/defaults/main.test.bicep @@ -42,7 +42,12 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' + advancedOptions: { + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } + } } } ] diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/max/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/max/main.test.bicep index 2ed8f5a925..399caddfc5 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/max/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/max/main.test.bicep @@ -42,7 +42,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' location: enforcedLocation tags: { Owner: 'Contoso MAX Team' @@ -57,7 +57,7 @@ module testDeployment '../../../main.bicep' = [ sku: 'standard' enableSoftDelete: false softDeleteRetentionInDays: 7 - enablePurgeProtection: true + enablePurgeProtection: false // For the purposes of the test, we disable purge protection } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/min-priv/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/min-priv/main.test.bicep index 6fa222de9e..0a2f6c69ed 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/min-priv/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/min-priv/main.test.bicep @@ -42,12 +42,17 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' } enableDatabricks: false + advancedOptions: { + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } + } } } ] diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/min-pub/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/min-pub/main.test.bicep index f39b800312..228a47f1ce 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/min-pub/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/min-pub/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawminpub' +param serviceShort string = 'dpawminpu' @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_#' @@ -42,7 +42,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' @@ -50,6 +50,9 @@ module testDeployment '../../../main.bicep' = [ enableDatabricks: false advancedOptions: { networkAcls: { ipRules: ['104.43.16.94'] } + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-priv/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-priv/main.test.bicep index b4bcb77b27..bdb5e3342e 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-priv/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-priv/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc01priv' +param serviceShort string = 'dpawu1pr' @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_#' @@ -42,11 +42,16 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' } + advancedOptions: { + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } + } enableDatabricks: true } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-pub/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-pub/main.test.bicep index ec65507b8a..2e1618b23c 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-pub/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc01-pub/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc01pub' +param serviceShort string = 'dpawu1pu' @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_#' @@ -42,7 +42,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' @@ -50,6 +50,9 @@ module testDeployment '../../../main.bicep' = [ enableDatabricks: true advancedOptions: { networkAcls: { ipRules: ['104.43.16.94'] } + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-priv/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-priv/main.test.bicep index 3e0b702e8f..b86e618ce3 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-priv/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-priv/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc02priv' +param serviceShort string = 'dpawu2pr' @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_#' @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' @@ -66,6 +66,9 @@ module testDeployment '../../../main.bicep' = [ subnetNameFrontend: last(split(nestedDependencies.outputs.subnetResourceIds[1], '/')) subnetNameBackend: last(split(nestedDependencies.outputs.subnetResourceIds[2], '/')) } + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-pub/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-pub/main.test.bicep index 14d147df4d..0de5fdd4b8 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-pub/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc02-pub/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc02pub' +param serviceShort string = 'dpawu2pu' @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_#' @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' @@ -67,6 +67,9 @@ module testDeployment '../../../main.bicep' = [ subnetNameFrontend: last(split(nestedDependencies.outputs.subnetResourceIds[1], '/')) subnetNameBackend: last(split(nestedDependencies.outputs.subnetResourceIds[2], '/')) } + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-priv/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-priv/main.test.bicep index 6a2dae197b..cd51b030f5 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-priv/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-priv/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc03priv' +param serviceShort string = 'dpawu3pr' @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_#' @@ -53,7 +53,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' @@ -70,6 +70,9 @@ module testDeployment '../../../main.bicep' = [ subnetNameFrontend: last(split(nestedDependencies.outputs.subnetResourceIds[1], '/')) subnetNameBackend: last(split(nestedDependencies.outputs.subnetResourceIds[2], '/')) } + keyVault: { + enablePurgeProtection: false // For the purposes of the test, we disable purge protection + } } } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/dependencies.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/dependencies.bicep index b6b77e32b1..05038a4969 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/dependencies.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/dependencies.bicep @@ -237,6 +237,7 @@ module kv 'br/public:avm/res/key-vault/vault:0.7.0' = { name: keyVaultName // Non-required parameters location: location + enablePurgeProtection: false // For the purposes of the test, we disable purge protection } } diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/main.test.bicep index 2c154ddca6..f9f64f7716 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/uc03-pub/main.test.bicep @@ -16,7 +16,7 @@ param resourceGroupName string = 'dep-${namePrefix}-data-privateanalyticalworksp var enforcedLocation = 'northeurope' @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 = 'dpawuc03pub' +param serviceShort string = 'dpawu3p' @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_#' @@ -39,7 +39,7 @@ module nestedDependencies 'dependencies.bicep' = { location: enforcedLocation virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-1' } } @@ -53,7 +53,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' tags: { Owner: 'Contoso' CostCenter: '123-456-789' diff --git a/avm/ptn/data/private-analytical-workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/ptn/data/private-analytical-workspace/tests/e2e/waf-aligned/main.test.bicep index a2d221f635..358e84c2f8 100644 --- a/avm/ptn/data/private-analytical-workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/ptn/data/private-analytical-workspace/tests/e2e/waf-aligned/main.test.bicep @@ -42,7 +42,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' + name: '${namePrefix}${serviceShort}002' location: enforcedLocation tags: { 'hidden-title': 'This is visible in the resource name' @@ -58,7 +58,7 @@ module testDeployment '../../../main.bicep' = [ sku: 'standard' enableSoftDelete: true softDeleteRetentionInDays: 90 - enablePurgeProtection: true + enablePurgeProtection: false // For the purposes of the test, we disable purge protection } } } diff --git a/avm/ptn/deployment-script/import-image-to-acr/README.md b/avm/ptn/deployment-script/import-image-to-acr/README.md index 0e878635e3..82e34a64bd 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/README.md +++ b/avm/ptn/deployment-script/import-image-to-acr/README.md @@ -393,13 +393,13 @@ The managed identity definition for this resource. Required if `assignRbacRole` | Parameter | Type | Description | | :-- | :-- | :-- | -| [`userAssignedResourcesIds`](#parameter-managedidentitiesuserassignedresourcesids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | -### Parameter: `managedIdentities.userAssignedResourcesIds` +### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. -- Required: Yes +- Required: No - Type: array ### Parameter: `managedIdentityName` @@ -497,6 +497,7 @@ The password for the source registry. Required if the source registry is private - Required: No - Type: securestring - Default: `''` +- Example: `keyVault.getSecret("keyVaultSecretName")` ### Parameter: `sourceRegistryUsername` @@ -549,7 +550,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/resources/deployment-script:0.4.0` | Remote reference | +| `br/public:avm/res/resources/deployment-script:0.5.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Notes diff --git a/avm/ptn/deployment-script/import-image-to-acr/main.bicep b/avm/ptn/deployment-script/import-image-to-acr/main.bicep index e6c532e567..9ae53ae653 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/main.bicep +++ b/avm/ptn/deployment-script/import-image-to-acr/main.bicep @@ -20,8 +20,9 @@ param runOnce bool = false @description('Optional. If set, the `Contributor` role will be granted to the managed identity (passed by the `managedIdentities` parameter or create with the name specified in parameter `managedIdentityName`), which is needed to import images into the Azure Container Registry. Defaults to `true`.') param assignRbacRole bool = true +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Conditional. The managed identity definition for this resource. Required if `assignRbacRole` is `true` and `managedIdentityName` is `null`.') -param managedIdentities managedIdentitiesType? +param managedIdentities managedIdentityOnlyUserAssignedType? @description('Conditional. Name of the Managed Identity resource to create. Required if `assignRbacRole` is `true` and `managedIdentities` is `null`. Defaults to `id-ContainerRegistryImport`.') param managedIdentityName string? @@ -41,6 +42,7 @@ param sourceRegistryUsername string = '' @description('Optional. The password for the source registry. Required if the source registry is private, or to logon to the public docker registry.') @secure() +@metadata({ example: 'keyVault.getSecret("keyVaultSecretName")' }) param sourceRegistryPassword string = '' @description('Optional. The new image name in the ACR. You can use this to import a publically available image with a custom name for later updating from e.g., your build pipeline.') @@ -87,7 +89,7 @@ param tags object? // Variables // // ============== // -var useExistingManagedIdentity = length(managedIdentities.?userAssignedResourcesIds ?? []) > 0 +var useExistingManagedIdentity = length(managedIdentities.?userAssignedResourceIds ?? []) > 0 // ============== // // Resources // @@ -118,7 +120,7 @@ resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { // needed to "convert" resourceIds to principalId resource existingManagedIdentities 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = [ - for resourceId in (managedIdentities.?userAssignedResourcesIds ?? []): if (assignRbacRole) { + for resourceId in (managedIdentities.?userAssignedResourceIds ?? []): if (assignRbacRole) { name: last(split(resourceId, '/')) scope: resourceGroup(split(resourceId, '/')[2], split(resourceId, '/')[4]) // get the resource group from the managed identity, as it could be in another resource group } @@ -132,7 +134,7 @@ resource newManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@20 // assign the Contributor role to the managed identity (new or existing) to import images into the ACR resource acrRoleAssignmentExistingManagedIdentities 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ - for i in range(0, length(assignRbacRole ? (managedIdentities.?userAssignedResourcesIds ?? []) : [])): if (useExistingManagedIdentity && assignRbacRole) { + for i in range(0, length(assignRbacRole ? (managedIdentities.?userAssignedResourceIds ?? []) : [])): if (useExistingManagedIdentity && assignRbacRole) { name: guid('roleAssignment-acr-${existingManagedIdentities[i].name}') scope: acr properties: { @@ -158,7 +160,7 @@ resource acrRoleAssignmentNewManagedIdentity 'Microsoft.Authorization/roleAssign } } -module imageImport 'br/public:avm/res/resources/deployment-script:0.4.0' = { +module imageImport 'br/public:avm/res/resources/deployment-script:0.5.0' = { name: name ?? 'ACR-Import-${last(split(replace(image,':','-'),'/'))}' scope: resourceGroup() params: { @@ -167,7 +169,7 @@ module imageImport 'br/public:avm/res/resources/deployment-script:0.4.0' = { tags: tags managedIdentities: useExistingManagedIdentity ? managedIdentities - : { userAssignedResourcesIds: [newManagedIdentity.id] } + : { userAssignedResourceIds: [newManagedIdentity.id] } kind: 'AzureCLI' runOnce: runOnce azCliVersion: '2.63.0' // available tags are listed here: https://mcr.microsoft.com/v2/azure-cli/tags/list @@ -248,8 +250,3 @@ type importedImageType = { @description('Required. The image name in the Azure Container Registry.') acrHostedImage: string } - -type managedIdentitiesType = { - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourcesIds: string[] -} diff --git a/avm/ptn/deployment-script/import-image-to-acr/main.json b/avm/ptn/deployment-script/import-image-to-acr/main.json index 6bfe24d5cd..72f37ed58c 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/main.json +++ b/avm/ptn/deployment-script/import-image-to-acr/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "17375159703541878382" + "version": "0.30.23.60470", + "templateHash": "11351051395125066237" }, "name": "import-image-to-acr", "description": "This modules deployes an image to an Azure Container Registry.", @@ -30,18 +30,25 @@ } } }, - "managedIdentitiesType": { + "managedIdentityOnlyUserAssignedType": { "type": "object", "properties": { - "userAssignedResourcesIds": { + "userAssignedResourceIds": { "type": "array", "items": { "type": "string" }, + "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } + }, + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } } } }, @@ -87,7 +94,7 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", "nullable": true, "metadata": { "description": "Conditional. The managed identity definition for this resource. Required if `assignRbacRole` is `true` and `managedIdentityName` is `null`." @@ -122,6 +129,7 @@ "type": "securestring", "defaultValue": "", "metadata": { + "example": "keyVault.getSecret(\"keyVaultSecretName\")", "description": "Optional. The password for the source registry. Required if the source registry is private, or to logon to the public docker registry." } }, @@ -193,7 +201,7 @@ } }, "variables": { - "useExistingManagedIdentity": "[greater(length(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray())), 0)]" + "useExistingManagedIdentity": "[greater(length(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray())), 0)]" }, "resources": { "avmTelemetry": { @@ -225,15 +233,15 @@ "existingManagedIdentities": { "copy": { "name": "existingManagedIdentities", - "count": "[length(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()))]" + "count": "[length(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()))]" }, "condition": "[parameters('assignRbacRole')]", "existing": true, "type": "Microsoft.ManagedIdentity/userAssignedIdentities", "apiVersion": "2023-01-31", - "subscriptionId": "[split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray())[copyIndex()], '/')[2]]", - "resourceGroup": "[split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray())[copyIndex()], '/')[4]]", - "name": "[last(split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray())[copyIndex()], '/'))]" + "subscriptionId": "[split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray())[copyIndex()], '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray())[copyIndex()], '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray())[copyIndex()], '/'))]" }, "newManagedIdentity": { "condition": "[and(not(variables('useExistingManagedIdentity')), parameters('assignRbacRole'))]", @@ -246,22 +254,22 @@ "acrRoleAssignmentExistingManagedIdentities": { "copy": { "name": "acrRoleAssignmentExistingManagedIdentities", - "count": "[length(range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), createArray()))))]" + "count": "[length(range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), createArray()))))]" }, "condition": "[and(variables('useExistingManagedIdentity'), parameters('assignRbacRole'))]", "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('acrName'))]", - "name": "[guid(format('roleAssignment-acr-{0}', last(split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray())[range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), createArray())))[copyIndex()]], '/'))))]", + "name": "[guid(format('roleAssignment-acr-{0}', last(split(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray())[range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), createArray())))[copyIndex()]], '/'))))]", "properties": { - "principalId": "[reference(format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), createArray())))[copyIndex()])).principalId]", + "principalId": "[reference(format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), createArray())))[copyIndex()])).principalId]", "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "principalType": "ServicePrincipal" }, "dependsOn": [ "acr", - "[format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), createArray())))[copyIndex()])]", - "[format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), createArray())))[copyIndex()])]" + "[format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), createArray())))[copyIndex()])]", + "[format('existingManagedIdentities[{0}]', range(0, length(if(parameters('assignRbacRole'), coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), createArray())))[copyIndex()])]" ] }, "acrRoleAssignmentNewManagedIdentity": { @@ -299,7 +307,7 @@ "tags": { "value": "[parameters('tags')]" }, - "managedIdentities": "[if(variables('useExistingManagedIdentity'), createObject('value', parameters('managedIdentities')), createObject('value', createObject('userAssignedResourcesIds', createArray(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', coalesce(parameters('managedIdentityName'), 'id-ContainerRegistryImport'))))))]", + "managedIdentities": "[if(variables('useExistingManagedIdentity'), createObject('value', parameters('managedIdentities')), createObject('value', createObject('userAssignedResourceIds', createArray(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', coalesce(parameters('managedIdentityName'), 'id-ContainerRegistryImport'))))))]", "kind": { "value": "AzureCLI" }, @@ -378,14 +386,39 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5978422939896103340" + "version": "0.30.23.60470", + "templateHash": "16722602669876377866" }, "name": "Deployment Scripts", "description": "This module deploys Deployment Scripts.", "owner": "Azure/module-maintainers" }, "definitions": { + "environmentVariableType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the environment variable." + } + }, + "secureValue": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Conditional. The value of the secure environment variable. Required if `value` is null." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The value of the environment variable. Required if `secureValue` is null." + } + } + } + }, "lockType": { "type": "object", "properties": { @@ -409,119 +442,107 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "managedIdentitiesType": { + "managedIdentityOnlyUserAssignedType": { "type": "object", "properties": { - "userAssignedResourcesIds": { + "userAssignedResourceIds": { "type": "array", "items": { "type": "string" }, + "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } }, - "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." - } - } + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } - }, - "nullable": true + } }, - "environmentVariableType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the environment variable." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "secureValue": { - "type": "securestring", + "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": "Required. The value of the secure environment variable." + "description": "Optional. The principal type of the assigned principal ID." } }, - "value": { + "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": "Required. The value of the environment variable." + "description": "Optional. The Resource Id of the delegated managed identity resource." } } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } } } }, @@ -551,7 +572,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } @@ -681,12 +703,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -725,15 +752,15 @@ "containerGroupName": "[parameters('containerGroupName')]", "subnetIds": "[if(not(empty(coalesce(variables('subnetIds'), createArray()))), variables('subnetIds'), null())]" }, - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), 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(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null()), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" + "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(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null()), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" }, "resources": { "storageAccount": { "condition": "[not(empty(parameters('storageAccountResourceId')))]", "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-04-01", + "apiVersion": "2023-05-01", "subscriptionId": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '//'), '/')[2]]", "resourceGroup": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '////'), '/')[4]]", "name": "[last(split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), 'dummyAccount'), '/'))]" @@ -742,7 +769,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.resources-deploymentscript.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.resources-deploymentscript.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { diff --git a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/dependencies.bicep b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/dependencies.bicep index f68b4451d5..5b6e20b8c1 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/dependencies.bicep +++ b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/dependencies.bicep @@ -18,7 +18,7 @@ param keyVaultName string var ipRange = '10.0.0.0' -module identity 'br/public:avm/res/managed-identity/user-assigned-identity:0.2.1' = { +module identity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = { name: managedIdentityName params: { name: managedIdentityName @@ -63,7 +63,7 @@ resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' = { } } -module dnsZoneContainerRegistry 'br/public:avm/res/network/private-dns-zone:0.2.5' = { +module dnsZoneContainerRegistry 'br/public:avm/res/network/private-dns-zone:0.6.0' = { name: '${uniqueString(deployment().name, location)}-dnsZone-ACR' params: { name: 'privatelink.azurecr.io' @@ -77,7 +77,7 @@ module dnsZoneContainerRegistry 'br/public:avm/res/network/private-dns-zone:0.2. } } -module storage 'br/public:avm/res/storage/storage-account:0.9.0' = { +module storage 'br/public:avm/res/storage/storage-account:0.9.1' = { name: '${uniqueString(resourceGroup().name, location)}-storage' params: { name: storageAccountName @@ -155,7 +155,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = { } // the container registry to upload the image into -module acr 'br/public:avm/res/container-registry/registry:0.2.0' = { +module acr 'br/public:avm/res/container-registry/registry:0.6.0' = { name: '${uniqueString(resourceGroup().name, location)}-acr' params: { name: acrName @@ -172,10 +172,12 @@ module acr 'br/public:avm/res/container-registry/registry:0.2.0' = { subnetResourceId: vnet::subnet_privateendpoints.id customNetworkInterfaceName: '${uniqueString(resourceGroup().name, location)}-pe-ContainerRegistry-nic' location: location - privateDnsZoneGroupName: 'default' - privateDnsZoneResourceIds: [ - dnsZoneContainerRegistry.outputs.resourceId - ] + privateDnsZoneGroup: { + name: 'default' + privateDnsZoneGroupConfigs: [ + { privateDnsZoneResourceId: dnsZoneContainerRegistry.outputs.resourceId } + ] + } isManualConnection: false service: 'registry' } diff --git a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/main.test.bicep b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/main.test.bicep index 8cd3fd3db1..5bcd7b3eb4 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/main.test.bicep +++ b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/max/main.test.bicep @@ -72,7 +72,7 @@ module testDeployment '../../../main.bicep' = [ newImageName: 'application/your-image-name:tag' cleanupPreference: 'OnExpiration' assignRbacRole: true - managedIdentities: { userAssignedResourcesIds: [dependencies.outputs.managedIdentityResourceId] } + managedIdentities: { userAssignedResourceIds: [dependencies.outputs.managedIdentityResourceId] } overwriteExistingImage: true storageAccountResourceId: dependencies.outputs.storageAccountResourceId subnetResourceIds: [dependencies.outputs.deploymentScriptSubnetResourceId] diff --git a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/dependencies.bicep b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/dependencies.bicep index 545c0c6fcc..1048ff244d 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/dependencies.bicep @@ -7,7 +7,7 @@ param managedIdentityName string @description('Required. The name of the Azure Container Registry.') param acrName string -module identity 'br/public:avm/res/managed-identity/user-assigned-identity:0.2.1' = { +module identity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = { name: managedIdentityName params: { name: managedIdentityName @@ -16,7 +16,7 @@ module identity 'br/public:avm/res/managed-identity/user-assigned-identity:0.2.1 } // the container registry to upload the image into -module acr 'br/public:avm/res/container-registry/registry:0.2.0' = { +module acr 'br/public:avm/res/container-registry/registry:0.6.0' = { name: '${uniqueString(resourceGroup().name, location)}-acr' params: { name: acrName diff --git a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/main.test.bicep b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/main.test.bicep index b9dc712fab..5189921d0c 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/ptn/deployment-script/import-image-to-acr/tests/e2e/waf-aligned/main.test.bicep @@ -55,7 +55,7 @@ module testDeployment '../../../main.bicep' = [ acrName: dependencies.outputs.acrName image: 'mcr.microsoft.com/k8se/quickstart-jobs:latest' overwriteExistingImage: true - managedIdentities: { userAssignedResourcesIds: [dependencies.outputs.managedIdentityResourceId] } + managedIdentities: { userAssignedResourceIds: [dependencies.outputs.managedIdentityResourceId] } } } ] diff --git a/avm/ptn/deployment-script/import-image-to-acr/version.json b/avm/ptn/deployment-script/import-image-to-acr/version.json index 17dd49a0b9..aa34c4d0f5 100644 --- a/avm/ptn/deployment-script/import-image-to-acr/version.json +++ b/avm/ptn/deployment-script/import-image-to-acr/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/ptn/lz/sub-vending/README.md b/avm/ptn/lz/sub-vending/README.md index 76930aff30..d7a98d231b 100644 --- a/avm/ptn/lz/sub-vending/README.md +++ b/avm/ptn/lz/sub-vending/README.md @@ -796,7 +796,7 @@ param virtualNetworkResourceGroupName = '' | [`roleAssignments`](#parameter-roleassignments) | array | Supply an array of objects containing the details of the role assignments to create.

Each object must contain the following `keys`:

  • `principalId` = The Object ID of the User, Group, SPN, Managed Identity to assign the RBAC role too.
  • `definition` = The Name of one of the pre-defined built-In RBAC Roles or a Resource ID of a Built-in or custom RBAC Role Definition as follows:

    - You can only provide the RBAC role name of the pre-defined roles (Contributor, Owner, Reader, Role Based Access Control Administrator (Preview), and User Access Administrator). We only provide those roles as they are the most common ones to assign to a new subscription, also to reduce the template size and complexity in case we define each and every Built-in RBAC role.

    - You can provide the Resource ID of a Built-in or custom RBAC Role Definition

    - e.g. `/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`

  • `relativeScope` = 2 options can be provided for input value:

    1. `''` *(empty string)* = Make RBAC Role Assignment to Subscription scope

    2. `'/resourceGroups/'` = Make RBAC Role Assignment to specified Resource Group.

    | | [`subscriptionAliasEnabled`](#parameter-subscriptionaliasenabled) | bool | Whether to create a new Subscription using the Subscription Alias resource. If `false`, supply an existing Subscription''s ID in the parameter named `existingSubscriptionId` instead to deploy resources to an existing Subscription. | | [`subscriptionAliasName`](#parameter-subscriptionaliasname) | string | The name of the Subscription Alias, that will be created by this module.

    The string must be comprised of `a-z`, `A-Z`, `0-9`, `-`, `_` and ` ` (space). The maximum length is 63 characters.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    | -| [`subscriptionBillingScope`](#parameter-subscriptionbillingscope) | string | The Billing Scope for the new Subscription alias, that will be created by this module.

    A valid Billing Scope starts with `/providers/Microsoft.Billing/billingAccounts/` and is case sensitive.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    | +| [`subscriptionBillingScope`](#parameter-subscriptionbillingscope) | string | The Billing Scope for the new Subscription alias, that will be created by this module.

    A valid Billing Scope looks like `/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName}` and is case sensitive.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    | | [`subscriptionDisplayName`](#parameter-subscriptiondisplayname) | string | The name of the subscription alias. The string must be comprised of a-z, A-Z, 0-9, - and _. The maximum length is 63 characters.

    The string must be comprised of `a-z`, `A-Z`, `0-9`, `-`, `_` and ` ` (space). The maximum length is 63 characters.

    > The value for this parameter and the parameter named `subscriptionAliasName` are usually set to the same value for simplicity. But they can be different if required for a reason.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    | | [`subscriptionManagementGroupAssociationEnabled`](#parameter-subscriptionmanagementgroupassociationenabled) | bool | Whether to move the Subscription to the specified Management Group supplied in the parameter `subscriptionManagementGroupId`.

    | | [`subscriptionManagementGroupId`](#parameter-subscriptionmanagementgroupid) | string | The destination Management Group ID for the new Subscription that will be created by this module (or the existing one provided in the parameter `existingSubscriptionId`).

    **IMPORTANT:** Do not supply the display name of the Management Group. The Management Group ID forms part of the Azure Resource ID. e.g., `/providers/Microsoft.Management/managementGroups/{managementGroupId}`.

    | @@ -983,7 +983,6 @@ An object of resource providers and resource providers features to register. If 'Microsoft.Sql': [] 'Microsoft.Storage': [] 'Microsoft.StreamAnalytics': [] - 'Microsoft.TimeSeriesInsights': [] 'Microsoft.Web': [] } ``` @@ -1003,6 +1002,23 @@ Supply an array of objects containing the details of the role assignments to cre - Required: No - Type: array - Default: `[]` +- Example: + ```Bicep + [ + { + // Contributor role assignment at subscription scope + principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + definition: '/Contributor' + relativeScope: '' + } + { + // Owner role assignment at resource group scope + principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + definition: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' + relativeScope: '/resourceGroups/{resourceGroupName}' + } + ] + ``` **Required parameters** @@ -1099,7 +1115,7 @@ The name of the Subscription Alias, that will be created by this module.

    Th ### Parameter: `subscriptionBillingScope` -The Billing Scope for the new Subscription alias, that will be created by this module.

    A valid Billing Scope starts with `/providers/Microsoft.Billing/billingAccounts/` and is case sensitive.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    +The Billing Scope for the new Subscription alias, that will be created by this module.

    A valid Billing Scope looks like `/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName}` and is case sensitive.

    > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.

    - Required: No - Type: string diff --git a/avm/ptn/lz/sub-vending/main.bicep b/avm/ptn/lz/sub-vending/main.bicep index 832fabd70e..0511f295b5 100644 --- a/avm/ptn/lz/sub-vending/main.bicep +++ b/avm/ptn/lz/sub-vending/main.bicep @@ -40,7 +40,7 @@ param subscriptionAliasName string = '' @description('''Optional. The Billing Scope for the new Subscription alias, that will be created by this module. -A valid Billing Scope starts with `/providers/Microsoft.Billing/billingAccounts/` and is case sensitive. +A valid Billing Scope looks like `/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName}` and is case sensitive. > **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**. ''') @@ -200,6 +200,24 @@ Each object must contain the following `keys`: 1. `''` *(empty string)* = Make RBAC Role Assignment to Subscription scope 2. `'/resourceGroups/'` = Make RBAC Role Assignment to specified Resource Group. ''') +@metadata({ + example: ''' + [ + { + // Contributor role assignment at subscription scope + principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + definition: '/Contributor' + relativeScope: '' + } + { + // Owner role assignment at resource group scope + principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + definition: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' + relativeScope: '/resourceGroups/{resourceGroupName}' + } + ] + ''' +}) param roleAssignments roleAssignmentType = [] @description('Optional. Enable/Disable usage telemetry for module.') @@ -297,7 +315,6 @@ param resourceProviders object = { 'Microsoft.Sql': [] 'Microsoft.Storage': [] 'Microsoft.StreamAnalytics': [] - 'Microsoft.TimeSeriesInsights': [] 'Microsoft.Web': [] } diff --git a/avm/ptn/lz/sub-vending/main.json b/avm/ptn/lz/sub-vending/main.json index 730e310ed9..3411c86bc6 100644 --- a/avm/ptn/lz/sub-vending/main.json +++ b/avm/ptn/lz/sub-vending/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15876773286910776098" + "version": "0.31.34.60546", + "templateHash": "5769743851515501504" }, "name": "Sub-vending", "description": "This module deploys a subscription to accelerate deployment of landing zones. For more information on how to use it, please visit this [Wiki](https://github.com/Azure/bicep-lz-vending/wiki).", @@ -257,7 +257,7 @@ "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. The Billing Scope for the new Subscription alias, that will be created by this module.\n\nA valid Billing Scope starts with `/providers/Microsoft.Billing/billingAccounts/` and is case sensitive.\n\n> **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.\n" + "description": "Optional. The Billing Scope for the new Subscription alias, that will be created by this module.\n\nA valid Billing Scope looks like `/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName}` and is case sensitive.\n\n> **Not required when providing an existing Subscription ID via the parameter `existingSubscriptionId`**.\n" } }, "subscriptionWorkload": { @@ -456,6 +456,7 @@ "$ref": "#/definitions/roleAssignmentType", "defaultValue": [], "metadata": { + "example": " [\n {\n // Contributor role assignment at subscription scope\n principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'\n definition: '/Contributor'\n relativeScope: ''\n }\n {\n // Owner role assignment at resource group scope\n principalId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'\n definition: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635'\n relativeScope: '/resourceGroups/{resourceGroupName}'\n }\n ]\n ", "description": "Optional. Supply an array of objects containing the details of the role assignments to create.\n\nEach object must contain the following `keys`:\n- `principalId` = The Object ID of the User, Group, SPN, Managed Identity to assign the RBAC role too.\n- `definition` = The Name of one of the pre-defined built-In RBAC Roles or a Resource ID of a Built-in or custom RBAC Role Definition as follows:\n - You can only provide the RBAC role name of the pre-defined roles (Contributor, Owner, Reader, Role Based Access Control Administrator (Preview), and User Access Administrator). We only provide those roles as they are the most common ones to assign to a new subscription, also to reduce the template size and complexity in case we define each and every Built-in RBAC role.\n - You can provide the Resource ID of a Built-in or custom RBAC Role Definition\n - e.g. `/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`\n- `relativeScope` = 2 options can be provided for input value:\n 1. `''` *(empty string)* = Make RBAC Role Assignment to Subscription scope\n 2. `'/resourceGroups/'` = Make RBAC Role Assignment to specified Resource Group.\n" } }, @@ -589,7 +590,6 @@ "Microsoft.Sql": [], "Microsoft.Storage": [], "Microsoft.StreamAnalytics": [], - "Microsoft.TimeSeriesInsights": [], "Microsoft.Web": [] }, "metadata": { @@ -670,8 +670,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1611270751895734589" + "version": "0.31.34.60546", + "templateHash": "3457070988046201960" } }, "parameters": { @@ -881,8 +881,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17058377789394467622" + "version": "0.31.34.60546", + "templateHash": "15704136472131684900" }, "name": "`/subResourcesWrapper/deploy.bicep` Parameters", "description": "This module is used by the [`bicep-lz-vending`](https://aka.ms/sub-vending/bicep) module to help orchestrate the deployment", @@ -1474,7 +1474,6 @@ "Microsoft.Sql": [], "Microsoft.Storage": [], "Microsoft.StreamAnalytics": [], - "Microsoft.TimeSeriesInsights": [], "Microsoft.Web": [] }, "metadata": { @@ -1589,8 +1588,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15074465703139369012" + "version": "0.31.34.60546", + "templateHash": "17907165258968798055" } }, "parameters": { @@ -1650,8 +1649,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15410141635305926698" + "version": "0.31.34.60546", + "templateHash": "3960537387423914398" } }, "parameters": { @@ -1710,8 +1709,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5472979603320584709" + "version": "0.31.34.60546", + "templateHash": "4908789287090218941" } }, "parameters": { @@ -1766,8 +1765,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11343593259864722989" + "version": "0.31.34.60546", + "templateHash": "12493928637555451452" } }, "parameters": { @@ -1844,8 +1843,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13884963778440627255" + "version": "0.31.34.60546", + "templateHash": "12602325500495654095" } }, "parameters": { @@ -1899,8 +1898,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4428652978548820109" + "version": "0.31.34.60546", + "templateHash": "7409476431103411951" } }, "parameters": { @@ -2479,8 +2478,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15410141635305926698" + "version": "0.31.34.60546", + "templateHash": "3960537387423914398" } }, "parameters": { @@ -2539,8 +2538,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5472979603320584709" + "version": "0.31.34.60546", + "templateHash": "4908789287090218941" } }, "parameters": { @@ -2595,8 +2594,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11343593259864722989" + "version": "0.31.34.60546", + "templateHash": "12493928637555451452" } }, "parameters": { @@ -2673,8 +2672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13884963778440627255" + "version": "0.31.34.60546", + "templateHash": "12602325500495654095" } }, "parameters": { @@ -2728,8 +2727,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4428652978548820109" + "version": "0.31.34.60546", + "templateHash": "7409476431103411951" } }, "parameters": { @@ -4425,8 +4424,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15250207882926040999" + "version": "0.31.34.60546", + "templateHash": "11117025288711367178" } }, "parameters": { @@ -7551,6 +7550,9 @@ }, "subscriptionId": { "value": "[parameters('subscriptionId')]" + }, + "principalType": { + "value": "ServicePrincipal" } }, "template": { @@ -8248,6 +8250,9 @@ }, "resourceGroupName": { "value": "[parameters('deploymentScriptResourceGroupName')]" + }, + "principalType": { + "value": "ServicePrincipal" } }, "template": { diff --git a/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep b/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep index 5e16e204d6..068205a588 100644 --- a/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep +++ b/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep @@ -178,7 +178,6 @@ param resourceProviders object = { 'Microsoft.Sql': [] 'Microsoft.Storage': [] 'Microsoft.StreamAnalytics': [] - 'Microsoft.TimeSeriesInsights': [] 'Microsoft.Web': [] } @@ -575,6 +574,7 @@ module createRoleAssignmentsDeploymentScript 'br/public:avm/ptn/authorization/ro principalId: !empty(resourceProviders) ? createManagedIdentityForDeploymentScript.outputs.principalId : '' roleDefinitionIdOrName: 'Contributor' subscriptionId: subscriptionId + principalType: 'ServicePrincipal' } } @@ -586,6 +586,7 @@ module createRoleAssignmentsDeploymentScriptStorageAccount 'br/public:avm/ptn/au roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/69566ab7-960f-475b-8e7c-b3118f30c6bd' subscriptionId: subscriptionId resourceGroupName: deploymentScriptResourceGroupName + principalType: 'ServicePrincipal' } } diff --git a/avm/ptn/network/hub-networking/README.md b/avm/ptn/network/hub-networking/README.md index 9385bebd8c..e702471bb4 100644 --- a/avm/ptn/network/hub-networking/README.md +++ b/avm/ptn/network/hub-networking/README.md @@ -18,15 +18,15 @@ This module is designed to simplify the creation of multi-region hub networks in | `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.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/azureFirewalls` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/azureFirewalls) | +| `Microsoft.Network/azureFirewalls` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/azureFirewalls) | | `Microsoft.Network/bastionHosts` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/bastionHosts) | | `Microsoft.Network/publicIPAddresses` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-09-01/publicIPAddresses) | | `Microsoft.Network/routeTables` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/routeTables) | -| `Microsoft.Network/routeTables/routes` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/routeTables/routes) | -| `Microsoft.Network/virtualNetworks` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks) | -| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/subnets) | +| `Microsoft.Network/routeTables/routes` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/routeTables/routes) | +| `Microsoft.Network/virtualNetworks` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks) | +| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/subnets) | | `Microsoft.Network/virtualNetworks/subnets` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualNetworks/subnets) | -| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/virtualNetworkPeerings) | +| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/virtualNetworkPeerings) | ## Usage examples diff --git a/avm/ptn/network/private-link-private-dns-zones/README.md b/avm/ptn/network/private-link-private-dns-zones/README.md index 6fe8264487..8686381c3f 100644 --- a/avm/ptn/network/private-link-private-dns-zones/README.md +++ b/avm/ptn/network/private-link-private-dns-zones/README.md @@ -331,11 +331,9 @@ An array of Private Link Private DNS Zones to create. Each item must be a valid - Default: ```Bicep [ - '{regionCode}.privatelink.backup.windowsazure.com' '{regionName}.data.privatelink.azurecr.io' - '{regionName}.privatelink.batch.azure.com' - '{regionName}.service.privatelink.batch.azure.com' 'privatelink-global.wvd.microsoft.com' + 'privatelink.{regionCode}.backup.windowsazure.com' 'privatelink.{regionName}.azmk8s.io' 'privatelink.{regionName}.kusto.windows.net' 'privatelink.adf.azure.com' @@ -357,6 +355,7 @@ An array of Private Link Private DNS Zones to create. Each item must be a valid 'privatelink.azureiotcentral.com' 'privatelink.azurestaticapps.net' 'privatelink.azurewebsites.net' + 'privatelink.batch.azure.com' 'privatelink.blob.core.windows.net' 'privatelink.cassandra.cosmos.azure.com' 'privatelink.cognitiveservices.azure.com' @@ -440,6 +439,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-dns-zone:0.6.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/ptn/network/private-link-private-dns-zones/main.bicep b/avm/ptn/network/private-link-private-dns-zones/main.bicep index 95595e05ab..7786799de6 100644 --- a/avm/ptn/network/private-link-private-dns-zones/main.bicep +++ b/avm/ptn/network/private-link-private-dns-zones/main.bicep @@ -63,8 +63,7 @@ param privateLinkPrivateDnsZones array = [ 'privatelink.pbidedicated.windows.net' 'privatelink.tip1.powerquery.microsoft.com' 'privatelink.azuredatabricks.net' - '{regionName}.privatelink.batch.azure.com' - '{regionName}.service.privatelink.batch.azure.com' + 'privatelink.batch.azure.com' 'privatelink-global.wvd.microsoft.com' 'privatelink.wvd.microsoft.com' 'privatelink.{regionName}.azmk8s.io' @@ -99,7 +98,7 @@ param privateLinkPrivateDnsZones array = [ 'privatelink.digitaltwins.azure.net' 'privatelink.media.azure.net' 'privatelink.azure-automation.net' - '{regionCode}.privatelink.backup.windowsazure.com' + 'privatelink.{regionCode}.backup.windowsazure.com' 'privatelink.siterecovery.windowsazure.com' 'privatelink.monitor.azure.com' 'privatelink.oms.opinsights.azure.com' diff --git a/avm/ptn/network/private-link-private-dns-zones/main.json b/avm/ptn/network/private-link-private-dns-zones/main.json index eb2a087b14..e18a8049bf 100644 --- a/avm/ptn/network/private-link-private-dns-zones/main.json +++ b/avm/ptn/network/private-link-private-dns-zones/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "17544740987961555702" + "templateHash": "6071389975562170906" }, "name": "avm/ptn/network/private-link-private-dns-zones", "description": "Private Link Private DNS Zones", @@ -91,8 +91,7 @@ "privatelink.pbidedicated.windows.net", "privatelink.tip1.powerquery.microsoft.com", "privatelink.azuredatabricks.net", - "{regionName}.privatelink.batch.azure.com", - "{regionName}.service.privatelink.batch.azure.com", + "privatelink.batch.azure.com", "privatelink-global.wvd.microsoft.com", "privatelink.wvd.microsoft.com", "privatelink.{regionName}.azmk8s.io", @@ -126,7 +125,7 @@ "privatelink.digitaltwins.azure.net", "privatelink.media.azure.net", "privatelink.azure-automation.net", - "{regionCode}.privatelink.backup.windowsazure.com", + "privatelink.{regionCode}.backup.windowsazure.com", "privatelink.siterecovery.windowsazure.com", "privatelink.monitor.azure.com", "privatelink.oms.opinsights.azure.com", diff --git a/avm/res/analysis-services/server/README.md b/avm/res/analysis-services/server/README.md index 746d2e0701..c6cbf5f1e7 100644 --- a/avm/res/analysis-services/server/README.md +++ b/avm/res/analysis-services/server/README.md @@ -13,6 +13,7 @@ This module deploys an Analysis Services Server. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -615,7 +616,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -725,7 +726,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -951,6 +952,14 @@ Tags of the resource. | `resourceGroupName` | string | The resource group the analysis service was deployed into. | | `resourceId` | string | The resource ID of the analysis service. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/analysis-services/server/main.bicep b/avm/res/analysis-services/server/main.bicep index a308a8afc3..f37233e165 100644 --- a/avm/res/analysis-services/server/main.bicep +++ b/avm/res/analysis-services/server/main.bicep @@ -26,14 +26,17 @@ param firewallSettings object = { @description('Optional. Location for all Resources.') param location string = resourceGroup().location +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -165,85 +168,3 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = server.location - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? diff --git a/avm/res/analysis-services/server/main.json b/avm/res/analysis-services/server/main.json index 73e2047e7f..e43d0f41be 100644 --- a/avm/res/analysis-services/server/main.json +++ b/avm/res/analysis-services/server/main.json @@ -5,14 +5,136 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13383500180025970135" + "version": "0.30.23.60470", + "templateHash": "783447731005535223" }, "name": "Analysis Services Servers", "description": "This module deploys an Analysis Services Server.", "owner": "Azure/module-maintainers" }, "definitions": { + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, "lockType": { "type": "object", "properties": { @@ -36,200 +158,87 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, "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." - } + "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." } - } - }, - "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." - } + }, + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -277,19 +286,28 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } diff --git a/avm/res/api-management/service/README.md b/avm/res/api-management/service/README.md index 42c1636201..f53359c277 100644 --- a/avm/res/api-management/service/README.md +++ b/avm/res/api-management/service/README.md @@ -2431,7 +2431,7 @@ A list of availability zones denoting where the resource needs to come from. Onl ## Notes -The latest version of this module only includes supported versions of the API Management resource. All unsupported versions of API Management have been removed from the related parameters. See the [API Management stv1 platform retirement](!https://learn.microsoft.com/en-us/azure/api-management/breaking-changes/stv1-platform-retirement-august-2024) article for more details. +The latest version of this module only includes supported versions of the API Management resource. All unsupported versions of API Management have been removed from the related parameters. See the [API Management stv1 platform retirement](https://learn.microsoft.com/en-us/azure/api-management/breaking-changes/stv1-platform-retirement-august-2024) article for more details. ### Parameter Usage: `apiManagementServicePolicy` diff --git a/avm/res/api-management/service/api-version-set/main.json b/avm/res/api-management/service/api-version-set/main.json index 061641030c..5578690d60 100644 --- a/avm/res/api-management/service/api-version-set/main.json +++ b/avm/res/api-management/service/api-version-set/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2492486199367242598" + "version": "0.31.34.60546", + "templateHash": "4169716301128870956" }, "name": "API Management Service API Version Sets", "description": "This module deploys an API Management Service API Version Set.", diff --git a/avm/res/api-management/service/api/diagnostics/main.json b/avm/res/api-management/service/api/diagnostics/main.json index 6db7e0f400..f38a7d145b 100644 --- a/avm/res/api-management/service/api/diagnostics/main.json +++ b/avm/res/api-management/service/api/diagnostics/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2531959928497745895" + "version": "0.31.34.60546", + "templateHash": "5353729184860596208" }, "name": "API Management Service APIs Diagnostics.", "description": "This module deploys an API Management Service API Diagnostics.", diff --git a/avm/res/api-management/service/api/main.json b/avm/res/api-management/service/api/main.json index a87b3409db..32a0de7df8 100644 --- a/avm/res/api-management/service/api/main.json +++ b/avm/res/api-management/service/api/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17036957862982683599" + "version": "0.31.34.60546", + "templateHash": "79502668979653596" }, "name": "API Management Service APIs", "description": "This module deploys an API Management Service API.", @@ -245,10 +245,7 @@ "type": "[parameters('type')]", "value": "[parameters('value')]", "wsdlSelector": "[coalesce(parameters('wsdlSelector'), createObject())]" - }, - "dependsOn": [ - "service" - ] + } }, "policy": { "copy": { @@ -283,8 +280,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5643177447182050438" + "version": "0.31.34.60546", + "templateHash": "7084313641171504315" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", @@ -430,8 +427,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2531959928497745895" + "version": "0.31.34.60546", + "templateHash": "5353729184860596208" }, "name": "API Management Service APIs Diagnostics.", "description": "This module deploys an API Management Service API Diagnostics.", diff --git a/avm/res/api-management/service/api/policy/main.json b/avm/res/api-management/service/api/policy/main.json index af5ae11307..f65064267e 100644 --- a/avm/res/api-management/service/api/policy/main.json +++ b/avm/res/api-management/service/api/policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5643177447182050438" + "version": "0.31.34.60546", + "templateHash": "7084313641171504315" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", diff --git a/avm/res/api-management/service/authorization-server/main.json b/avm/res/api-management/service/authorization-server/main.json index 50d0897a93..41509bb54c 100644 --- a/avm/res/api-management/service/authorization-server/main.json +++ b/avm/res/api-management/service/authorization-server/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17927787726774417819" + "version": "0.31.34.60546", + "templateHash": "7143680740173420481" }, "name": "API Management Service Authorization Servers", "description": "This module deploys an API Management Service Authorization Server.", diff --git a/avm/res/api-management/service/backend/main.json b/avm/res/api-management/service/backend/main.json index c3ae5f49b2..f6757a8df6 100644 --- a/avm/res/api-management/service/backend/main.json +++ b/avm/res/api-management/service/backend/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14706757128951530017" + "version": "0.31.34.60546", + "templateHash": "8388368953433969607" }, "name": "API Management Service Backends", "description": "This module deploys an API Management Service Backend.", @@ -114,10 +114,7 @@ "tls": "[parameters('tls')]", "url": "[parameters('url')]", "protocol": "[parameters('protocol')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/api-management/service/cache/main.json b/avm/res/api-management/service/cache/main.json index 285f53b0fb..1e9937f722 100644 --- a/avm/res/api-management/service/cache/main.json +++ b/avm/res/api-management/service/cache/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2750555671183513052" + "version": "0.31.34.60546", + "templateHash": "11909687365337883274" }, "name": "API Management Service Caches", "description": "This module deploys an API Management Service Cache.", @@ -68,10 +68,7 @@ "connectionString": "[parameters('connectionString')]", "useFromLocation": "[parameters('useFromLocation')]", "resourceId": "[parameters('resourceId')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/api-management/service/identity-provider/main.json b/avm/res/api-management/service/identity-provider/main.json index 6768ba8a3e..293b1b230a 100644 --- a/avm/res/api-management/service/identity-provider/main.json +++ b/avm/res/api-management/service/identity-provider/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1342690797398622979" + "version": "0.31.34.60546", + "templateHash": "11902978823059118045" }, "name": "API Management Service Identity Providers", "description": "This module deploys an API Management Service Identity Provider.", @@ -141,10 +141,7 @@ "clientId": "[parameters('clientId')]", "clientLibrary": "[parameters('clientLibrary')]", "clientSecret": "[parameters('clientSecret')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/api-management/service/loggers/README.md b/avm/res/api-management/service/logger/README.md similarity index 92% rename from avm/res/api-management/service/loggers/README.md rename to avm/res/api-management/service/logger/README.md index c0fabec510..769f788fe5 100644 --- a/avm/res/api-management/service/loggers/README.md +++ b/avm/res/api-management/service/logger/README.md @@ -20,8 +20,8 @@ This module deploys an API Management Service Logger. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`loggerType`](#parameter-loggertype) | string | Logger type. | | [`name`](#parameter-name) | string | Resource Name. | +| [`type`](#parameter-type) | string | Logger type. | **Conditional parameters** @@ -35,10 +35,17 @@ This module deploys an API Management Service Logger. | Parameter | Type | Description | | :-- | :-- | :-- | +| [`description`](#parameter-description) | string | Logger description. | | [`isBuffered`](#parameter-isbuffered) | bool | Whether records are buffered in the logger before publishing. | -| [`loggerDescription`](#parameter-loggerdescription) | string | Logger description. | -### Parameter: `loggerType` +### Parameter: `name` + +Resource Name. + +- Required: Yes +- Type: string + +### Parameter: `type` Logger type. @@ -53,13 +60,6 @@ Logger type. ] ``` -### Parameter: `name` - -Resource Name. - -- Required: Yes -- Type: string - ### Parameter: `apiManagementServiceName` The name of the parent API Management service. Required if the template is used in a standalone deployment. @@ -81,6 +81,14 @@ Required if loggerType = applicationInsights or azureEventHub. Azure Resource Id - Required: Yes - Type: string +### Parameter: `description` + +Logger description. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `isBuffered` Whether records are buffered in the logger before publishing. @@ -89,13 +97,6 @@ Whether records are buffered in the logger before publishing. - Type: bool - Default: `True` -### Parameter: `loggerDescription` - -Logger description. - -- Required: Yes -- Type: string - ## Outputs | Output | Type | Description | diff --git a/avm/res/api-management/service/logger/main.bicep b/avm/res/api-management/service/logger/main.bicep new file mode 100644 index 0000000000..0397eb4c99 --- /dev/null +++ b/avm/res/api-management/service/logger/main.bicep @@ -0,0 +1,55 @@ +metadata name = 'API Management Service Loggers' +metadata description = 'This module deploys an API Management Service Logger.' +metadata owner = 'Azure/module-maintainers' + +@sys.description('Conditional. The name of the parent API Management service. Required if the template is used in a standalone deployment.') +param apiManagementServiceName string + +@sys.description('Required. Resource Name.') +param name string + +@sys.description('Optional. Logger description.') +param description string = '' + +@sys.description('Optional. Whether records are buffered in the logger before publishing.') +param isBuffered bool = true + +@sys.description('Required. Logger type.') +@allowed([ + 'applicationInsights' + 'azureEventHub' + 'azureMonitor' +]) +param type string + +@sys.description('Conditional. Required if loggerType = applicationInsights or azureEventHub. Azure Resource Id of a log target (either Azure Event Hub resource or Azure Application Insights resource).') +param targetResourceId string + +@secure() +@sys.description('Conditional. Required if loggerType = applicationInsights or azureEventHub. The name and SendRule connection string of the event hub for azureEventHub logger. Instrumentation key for applicationInsights logger.') +param credentials object + +resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = { + name: apiManagementServiceName +} + +resource loggers 'Microsoft.ApiManagement/service/loggers@2022-08-01' = { + name: name + parent: service + properties: { + credentials: credentials + description: description + isBuffered: isBuffered + loggerType: type + resourceId: targetResourceId + } +} + +@sys.description('The resource ID of the logger.') +output resourceId string = loggers.id + +@sys.description('The name of the logger.') +output name string = loggers.name + +@sys.description('The resource group the named value was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/api-management/service/loggers/main.json b/avm/res/api-management/service/logger/main.json similarity index 92% rename from avm/res/api-management/service/loggers/main.json rename to avm/res/api-management/service/logger/main.json index 7d3305a3cd..cce73b9b5c 100644 --- a/avm/res/api-management/service/loggers/main.json +++ b/avm/res/api-management/service/logger/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12834599511984803283" + "version": "0.31.34.60546", + "templateHash": "11518344218995825129" }, "name": "API Management Service Loggers", "description": "This module deploys an API Management Service Logger.", @@ -24,8 +24,9 @@ "description": "Required. Resource Name." } }, - "loggerDescription": { + "description": { "type": "string", + "defaultValue": "", "metadata": { "description": "Optional. Logger description." } @@ -37,7 +38,7 @@ "description": "Optional. Whether records are buffered in the logger before publishing." } }, - "loggerType": { + "type": { "type": "string", "allowedValues": [ "applicationInsights", @@ -68,9 +69,9 @@ "name": "[format('{0}/{1}', parameters('apiManagementServiceName'), parameters('name'))]", "properties": { "credentials": "[parameters('credentials')]", - "description": "[parameters('loggerDescription')]", + "description": "[parameters('description')]", "isBuffered": "[parameters('isBuffered')]", - "loggerType": "[parameters('loggerType')]", + "loggerType": "[parameters('type')]", "resourceId": "[parameters('targetResourceId')]" } } diff --git a/avm/res/api-management/service/loggers/main.bicep b/avm/res/api-management/service/loggers/main.bicep deleted file mode 100644 index 6f7d1af8fb..0000000000 --- a/avm/res/api-management/service/loggers/main.bicep +++ /dev/null @@ -1,55 +0,0 @@ -metadata name = 'API Management Service Loggers' -metadata description = 'This module deploys an API Management Service Logger.' -metadata owner = 'Azure/module-maintainers' - -@description('Conditional. The name of the parent API Management service. Required if the template is used in a standalone deployment.') -param apiManagementServiceName string - -@description('Required. Resource Name.') -param name string - -@description('Optional. Logger description.') -param loggerDescription string - -@description('Optional. Whether records are buffered in the logger before publishing.') -param isBuffered bool = true - -@description('Required. Logger type.') -@allowed([ - 'applicationInsights' - 'azureEventHub' - 'azureMonitor' -]) -param loggerType string - -@description('Conditional. Required if loggerType = applicationInsights or azureEventHub. Azure Resource Id of a log target (either Azure Event Hub resource or Azure Application Insights resource).') -param targetResourceId string - -@secure() -@description('Conditional. Required if loggerType = applicationInsights or azureEventHub. The name and SendRule connection string of the event hub for azureEventHub logger. Instrumentation key for applicationInsights logger.') -param credentials object - -resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = { - name: apiManagementServiceName -} - -resource loggers 'Microsoft.ApiManagement/service/loggers@2022-08-01' = { - name: name - parent: service - properties: { - credentials: credentials - description: loggerDescription - isBuffered: isBuffered - loggerType: loggerType - resourceId: targetResourceId - } -} - -@description('The resource ID of the logger.') -output resourceId string = loggers.id - -@description('The name of the logger.') -output name string = loggers.name - -@description('The resource group the named value was deployed into.') -output resourceGroupName string = resourceGroup().name diff --git a/avm/res/api-management/service/main.bicep b/avm/res/api-management/service/main.bicep index 37a49b86c0..cc18535d18 100644 --- a/avm/res/api-management/service/main.bicep +++ b/avm/res/api-management/service/main.bicep @@ -409,16 +409,16 @@ module service_identityProviders 'identity-provider/main.bicep' = [ } ] -module service_loggers 'loggers/main.bicep' = [ +module service_loggers 'logger/main.bicep' = [ for (logger, index) in loggers: { name: '${uniqueString(deployment().name, location)}-Apim-Logger-${index}' params: { name: logger.name apiManagementServiceName: service.name credentials: logger.?credentials ?? {} - isBuffered: logger.?isBuffered ?? true - loggerDescription: logger.?loggerDescription ?? '' - loggerType: logger.?loggerType ?? 'azureMonitor' + isBuffered: logger.?isBuffered + description: logger.?loggerDescription + type: logger.?loggerType ?? 'azureMonitor' targetResourceId: logger.?targetResourceId ?? '' } dependsOn: [ diff --git a/avm/res/api-management/service/main.json b/avm/res/api-management/service/main.json index fc42a71966..82b4b88203 100644 --- a/avm/res/api-management/service/main.json +++ b/avm/res/api-management/service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7676062632439815762" + "version": "0.31.34.60546", + "templateHash": "5338224658105001512" }, "name": "API Management Services", "description": "This module deploys an API Management Service. The default deployment is set to use a Premium SKU to align with Microsoft WAF-aligned best practices. In most cases, non-prod deployments should use a lower-tier SKU.", @@ -791,8 +791,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17036957862982683599" + "version": "0.31.34.60546", + "templateHash": "79502668979653596" }, "name": "API Management Service APIs", "description": "This module deploys an API Management Service API.", @@ -1031,10 +1031,7 @@ "type": "[parameters('type')]", "value": "[parameters('value')]", "wsdlSelector": "[coalesce(parameters('wsdlSelector'), createObject())]" - }, - "dependsOn": [ - "service" - ] + } }, "policy": { "copy": { @@ -1069,8 +1066,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5643177447182050438" + "version": "0.31.34.60546", + "templateHash": "7084313641171504315" }, "name": "API Management Service APIs Policies", "description": "This module deploys an API Management Service API Policy.", @@ -1216,8 +1213,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2531959928497745895" + "version": "0.31.34.60546", + "templateHash": "5353729184860596208" }, "name": "API Management Service APIs Diagnostics.", "description": "This module deploys an API Management Service API Diagnostics.", @@ -1444,8 +1441,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2492486199367242598" + "version": "0.31.34.60546", + "templateHash": "4169716301128870956" }, "name": "API Management Service API Version Sets", "description": "This module deploys an API Management Service API Version Set.", @@ -1585,8 +1582,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17927787726774417819" + "version": "0.31.34.60546", + "templateHash": "7143680740173420481" }, "name": "API Management Service Authorization Servers", "description": "This module deploys an API Management Service Authorization Server.", @@ -1835,8 +1832,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14706757128951530017" + "version": "0.31.34.60546", + "templateHash": "8388368953433969607" }, "name": "API Management Service Backends", "description": "This module deploys an API Management Service Backend.", @@ -1944,10 +1941,7 @@ "tls": "[parameters('tls')]", "url": "[parameters('url')]", "protocol": "[parameters('protocol')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { @@ -2019,8 +2013,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2750555671183513052" + "version": "0.31.34.60546", + "templateHash": "11909687365337883274" }, "name": "API Management Service Caches", "description": "This module deploys an API Management Service Cache.", @@ -2082,10 +2076,7 @@ "connectionString": "[parameters('connectionString')]", "useFromLocation": "[parameters('useFromLocation')]", "resourceId": "[parameters('resourceId')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { @@ -2177,8 +2168,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2531959928497745895" + "version": "0.31.34.60546", + "templateHash": "5353729184860596208" }, "name": "API Management Service APIs Diagnostics.", "description": "This module deploys an API Management Service API Diagnostics.", @@ -2407,8 +2398,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1342690797398622979" + "version": "0.31.34.60546", + "templateHash": "11902978823059118045" }, "name": "API Management Service Identity Providers", "description": "This module deploys an API Management Service Identity Provider.", @@ -2543,10 +2534,7 @@ "clientId": "[parameters('clientId')]", "clientLibrary": "[parameters('clientLibrary')]", "clientSecret": "[parameters('clientSecret')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { @@ -2602,12 +2590,12 @@ "value": "[coalesce(tryGet(parameters('loggers')[copyIndex()], 'credentials'), createObject())]" }, "isBuffered": { - "value": "[coalesce(tryGet(parameters('loggers')[copyIndex()], 'isBuffered'), true())]" + "value": "[tryGet(parameters('loggers')[copyIndex()], 'isBuffered')]" }, - "loggerDescription": { - "value": "[coalesce(tryGet(parameters('loggers')[copyIndex()], 'loggerDescription'), '')]" + "description": { + "value": "[tryGet(parameters('loggers')[copyIndex()], 'loggerDescription')]" }, - "loggerType": { + "type": { "value": "[coalesce(tryGet(parameters('loggers')[copyIndex()], 'loggerType'), 'azureMonitor')]" }, "targetResourceId": { @@ -2620,8 +2608,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12834599511984803283" + "version": "0.31.34.60546", + "templateHash": "11518344218995825129" }, "name": "API Management Service Loggers", "description": "This module deploys an API Management Service Logger.", @@ -2640,8 +2628,9 @@ "description": "Required. Resource Name." } }, - "loggerDescription": { + "description": { "type": "string", + "defaultValue": "", "metadata": { "description": "Optional. Logger description." } @@ -2653,7 +2642,7 @@ "description": "Optional. Whether records are buffered in the logger before publishing." } }, - "loggerType": { + "type": { "type": "string", "allowedValues": [ "applicationInsights", @@ -2684,9 +2673,9 @@ "name": "[format('{0}/{1}', parameters('apiManagementServiceName'), parameters('name'))]", "properties": { "credentials": "[parameters('credentials')]", - "description": "[parameters('loggerDescription')]", + "description": "[parameters('description')]", "isBuffered": "[parameters('isBuffered')]", - "loggerType": "[parameters('loggerType')]", + "loggerType": "[parameters('type')]", "resourceId": "[parameters('targetResourceId')]" } } @@ -2764,8 +2753,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10162843567606353040" + "version": "0.31.34.60546", + "templateHash": "5493266151487858395" }, "name": "API Management Service Named Values", "description": "This module deploys an API Management Service Named Value.", @@ -2839,10 +2828,7 @@ "displayName": "[parameters('displayName')]", "value": "[if(variables('keyVaultEmpty'), parameters('value'), null())]", "keyVault": "[if(not(variables('keyVaultEmpty')), parameters('keyVault'), null())]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { @@ -2905,8 +2891,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14869704072680236257" + "version": "0.31.34.60546", + "templateHash": "9587521329160400551" }, "name": "API Management Service Portal Settings", "description": "This module deploys an API Management Service Portal Setting.", @@ -3004,8 +2990,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9395795206748286282" + "version": "0.31.34.60546", + "templateHash": "957115286202001780" }, "name": "API Management Service Policies", "description": "This module deploys an API Management Service Policy.", @@ -3139,8 +3125,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8029364311033748838" + "version": "0.31.34.60546", + "templateHash": "3551579457056086397" }, "name": "API Management Service Products", "description": "This module deploys an API Management Service Product.", @@ -3268,8 +3254,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "602104798329438871" + "version": "0.31.34.60546", + "templateHash": "11213919899113582129" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", @@ -3358,8 +3344,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5238408376918932137" + "version": "0.31.34.60546", + "templateHash": "10245602090275457578" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", @@ -3518,8 +3504,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16082435269276611452" + "version": "0.31.34.60546", + "templateHash": "17857709197993310769" }, "name": "API Management Service Subscriptions", "description": "This module deploys an API Management Service Subscription.", @@ -3607,10 +3593,7 @@ "secondaryKey": "[parameters('secondaryKey')]", "state": "[parameters('state')]", "allowTracing": "[parameters('allowTracing')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/api-management/service/named-value/main.json b/avm/res/api-management/service/named-value/main.json index b182535671..7e25a3a988 100644 --- a/avm/res/api-management/service/named-value/main.json +++ b/avm/res/api-management/service/named-value/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10162843567606353040" + "version": "0.31.34.60546", + "templateHash": "5493266151487858395" }, "name": "API Management Service Named Values", "description": "This module deploys an API Management Service Named Value.", @@ -80,10 +80,7 @@ "displayName": "[parameters('displayName')]", "value": "[if(variables('keyVaultEmpty'), parameters('value'), null())]", "keyVault": "[if(not(variables('keyVaultEmpty')), parameters('keyVault'), null())]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/api-management/service/policy/main.json b/avm/res/api-management/service/policy/main.json index dd3c7eab82..d4d4505da4 100644 --- a/avm/res/api-management/service/policy/main.json +++ b/avm/res/api-management/service/policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9395795206748286282" + "version": "0.31.34.60546", + "templateHash": "957115286202001780" }, "name": "API Management Service Policies", "description": "This module deploys an API Management Service Policy.", diff --git a/avm/res/api-management/service/portalsetting/main.json b/avm/res/api-management/service/portalsetting/main.json index d68c8ed791..505ef1bb18 100644 --- a/avm/res/api-management/service/portalsetting/main.json +++ b/avm/res/api-management/service/portalsetting/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14869704072680236257" + "version": "0.31.34.60546", + "templateHash": "9587521329160400551" }, "name": "API Management Service Portal Settings", "description": "This module deploys an API Management Service Portal Setting.", diff --git a/avm/res/api-management/service/product/api/main.json b/avm/res/api-management/service/product/api/main.json index 5603f9f789..f959bf4191 100644 --- a/avm/res/api-management/service/product/api/main.json +++ b/avm/res/api-management/service/product/api/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "602104798329438871" + "version": "0.31.34.60546", + "templateHash": "11213919899113582129" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", diff --git a/avm/res/api-management/service/product/group/main.json b/avm/res/api-management/service/product/group/main.json index 28d5460152..0dcdd2026c 100644 --- a/avm/res/api-management/service/product/group/main.json +++ b/avm/res/api-management/service/product/group/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5238408376918932137" + "version": "0.31.34.60546", + "templateHash": "10245602090275457578" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", diff --git a/avm/res/api-management/service/product/main.json b/avm/res/api-management/service/product/main.json index 892a25de5c..aa02572e7d 100644 --- a/avm/res/api-management/service/product/main.json +++ b/avm/res/api-management/service/product/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8029364311033748838" + "version": "0.31.34.60546", + "templateHash": "3551579457056086397" }, "name": "API Management Service Products", "description": "This module deploys an API Management Service Product.", @@ -133,8 +133,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "602104798329438871" + "version": "0.31.34.60546", + "templateHash": "11213919899113582129" }, "name": "API Management Service Products APIs", "description": "This module deploys an API Management Service Product API.", @@ -223,8 +223,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5238408376918932137" + "version": "0.31.34.60546", + "templateHash": "10245602090275457578" }, "name": "API Management Service Products Groups", "description": "This module deploys an API Management Service Product Group.", diff --git a/avm/res/api-management/service/subscription/main.json b/avm/res/api-management/service/subscription/main.json index 6abc772cc3..2c53fdfa76 100644 --- a/avm/res/api-management/service/subscription/main.json +++ b/avm/res/api-management/service/subscription/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16082435269276611452" + "version": "0.31.34.60546", + "templateHash": "17857709197993310769" }, "name": "API Management Service Subscriptions", "description": "This module deploys an API Management Service Subscription.", @@ -94,10 +94,7 @@ "secondaryKey": "[parameters('secondaryKey')]", "state": "[parameters('state')]", "allowTracing": "[parameters('allowTracing')]" - }, - "dependsOn": [ - "service" - ] + } } }, "outputs": { diff --git a/avm/res/app-configuration/configuration-store/key-value/main.json b/avm/res/app-configuration/configuration-store/key-value/main.json index 58dc82fcea..4dca71c4cb 100644 --- a/avm/res/app-configuration/configuration-store/key-value/main.json +++ b/avm/res/app-configuration/configuration-store/key-value/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "11258786733278014615" + "version": "0.30.23.60470", + "templateHash": "7176115037834080970" }, "name": "App Configuration Stores Key Values", "description": "This module deploys an App Configuration Store Key Value.", diff --git a/avm/res/app-configuration/configuration-store/main.bicep b/avm/res/app-configuration/configuration-store/main.bicep index 6c404d734e..5092c71d32 100644 --- a/avm/res/app-configuration/configuration-store/main.bicep +++ b/avm/res/app-configuration/configuration-store/main.bicep @@ -209,7 +209,7 @@ module configurationStore_keyValues 'key-value/main.bicep' = [ } ] -module configurationStore_replicas 'replicas/main.bicep' = [ +module configurationStore_replicas 'replica/main.bicep' = [ for (replicaLocation, index) in (replicaLocations ?? []): { name: '${uniqueString(deployment().name, location)}-AppConfig-Replicas-${index}' params: { diff --git a/avm/res/app-configuration/configuration-store/replicas/README.md b/avm/res/app-configuration/configuration-store/replica/README.md similarity index 100% rename from avm/res/app-configuration/configuration-store/replicas/README.md rename to avm/res/app-configuration/configuration-store/replica/README.md diff --git a/avm/res/app-configuration/configuration-store/replicas/main.bicep b/avm/res/app-configuration/configuration-store/replica/main.bicep similarity index 100% rename from avm/res/app-configuration/configuration-store/replicas/main.bicep rename to avm/res/app-configuration/configuration-store/replica/main.bicep diff --git a/avm/res/app-configuration/configuration-store/replicas/main.json b/avm/res/app-configuration/configuration-store/replica/main.json similarity index 100% rename from avm/res/app-configuration/configuration-store/replicas/main.json rename to avm/res/app-configuration/configuration-store/replica/main.json diff --git a/avm/res/automation/automation-account/README.md b/avm/res/automation/automation-account/README.md index 6bae91ba88..25662fa93d 100644 --- a/avm/res/automation/automation-account/README.md +++ b/avm/res/automation/automation-account/README.md @@ -246,9 +246,11 @@ module automationAccount 'br/public:avm/res/automation/automation-account:' + plan: { + product: 'OMSGallery/Updates' + publisher: 'Microsoft' + } } ] jobSchedules: [ @@ -507,9 +509,11 @@ module automationAccount 'br/public:avm/res/automation/automation-account:", + "plan": { + "product": "OMSGallery/Updates", + "publisher": "Microsoft" + } } ] }, @@ -784,9 +788,11 @@ param diagnosticSettings = [ param disableLocalAuth = true param gallerySolutions = [ { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' + name: '' + plan: { + product: 'OMSGallery/Updates' + publisher: 'Microsoft' + } } ] param jobSchedules = [ @@ -1025,9 +1031,10 @@ module automationAccount 'br/public:avm/res/automation/automation-account:' + plan: { + product: 'OMSGallery/Updates' + } } ] jobSchedules: [ @@ -1235,9 +1242,10 @@ module automationAccount 'br/public:avm/res/automation/automation-account:", + "plan": { + "product": "OMSGallery/Updates" + } } ] }, @@ -1461,9 +1469,10 @@ param diagnosticSettings = [ param disableLocalAuth = true param gallerySolutions = [ { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' + name: '' + plan: { + product: 'OMSGallery/Updates' + } } ] param jobSchedules = [ @@ -1946,7 +1955,61 @@ List of gallerySolutions to be created in the linked log analytics workspace. - Required: No - Type: array -- Default: `[]` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsname) | string | Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. | +| [`plan`](#parameter-gallerysolutionsplan) | object | Plan for solution object supported by the OperationsManagement resource provider. | + +### Parameter: `gallerySolutions.name` + +Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan` + +Plan for solution object supported by the OperationsManagement resource provider. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`product`](#parameter-gallerysolutionsplanproduct) | string | The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsplanname) | string | Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. | +| [`publisher`](#parameter-gallerysolutionsplanpublisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. | + +### Parameter: `gallerySolutions.plan.product` + +The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan.name` + +Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. + +- Required: No +- Type: string + +### Parameter: `gallerySolutions.plan.publisher` + +The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. + +- Required: No +- Type: string ### Parameter: `jobSchedules` @@ -2110,15 +2173,13 @@ Custom DNS configurations. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | | [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | -### Parameter: `privateEndpoints.customDnsConfigs.fqdn` - -Fqdn that resolves to private endpoint IP address. +**Optional parameters** -- Required: No -- Type: string +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | FQDN that resolves to private endpoint IP address. | ### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` @@ -2127,6 +2188,13 @@ A list of private IP addresses of the private endpoint. - Required: Yes - Type: array +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +FQDN that resolves to private endpoint IP address. + +- Required: No +- Type: string + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. @@ -2645,7 +2713,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | -| `br/public:avm/res/operations-management/solution:0.1.3` | Remote reference | +| `br/public:avm/res/operations-management/solution:0.3.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/automation/automation-account/main.bicep b/avm/res/automation/automation-account/main.bicep index e4ad3c8d84..cc0a1569af 100644 --- a/avm/res/automation/automation-account/main.bicep +++ b/avm/res/automation/automation-account/main.bicep @@ -15,7 +15,7 @@ param location string = resourceGroup().location ]) param skuName string = 'Basic' -import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The customer managed key definition.') param customerManagedKey customerManagedKeyType? @@ -41,7 +41,7 @@ param variables array = [] param linkedWorkspaceResourceId string = '' @description('Optional. List of gallerySolutions to be created in the linked log analytics workspace.') -param gallerySolutions array = [] +param gallerySolutions gallerySolutionType[]? @description('Optional. List of softwareUpdateConfigurations to be created in the automation account.') param softwareUpdateConfigurations array = [] @@ -57,23 +57,23 @@ param publicNetworkAccess string = '' @description('Optional. Disable local authentication profile used within the resource.') param disableLocalAuth bool = true -import { privateEndpointMultiServiceType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { privateEndpointMultiServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') param privateEndpoints privateEndpointMultiServiceType[]? -import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingFullType[]? -import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentityAllType? -import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') param lock lockType? -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? @@ -323,15 +323,14 @@ module automationAccount_linkedService 'modules/linked-service.bicep' = if (!emp ) } -module automationAccount_solutions 'br/public:avm/res/operations-management/solution:0.1.3' = [ - for (gallerySolution, index) in gallerySolutions: if (!empty(linkedWorkspaceResourceId)) { +module automationAccount_solutions 'br/public:avm/res/operations-management/solution:0.3.0' = [ + for (gallerySolution, index) in gallerySolutions ?? []: if (!empty(linkedWorkspaceResourceId)) { name: '${uniqueString(deployment().name, location)}-AutoAccount-Solution-${index}' params: { name: gallerySolution.name location: location logAnalyticsWorkspaceName: last(split(linkedWorkspaceResourceId, '/'))! - product: gallerySolution.?product - publisher: gallerySolution.?publisher + plan: gallerySolution.plan enableTelemetry: enableTelemetry } // This is to support solution to law in different subscription and resource group than the automation account. @@ -550,3 +549,17 @@ type credentialType = { @sys.description('Optional. Description of the credential.') description: string? } + +import { solutionPlanType } from 'br/public:avm/res/operations-management/solution:0.3.0' + +@export() +type gallerySolutionType = { + @description('''Required. Name of the solution. + For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`. + For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`. + The solution type is case-sensitive.''') + name: string + + @description('Required. Plan for solution object supported by the OperationsManagement resource provider.') + plan: solutionPlanType +} diff --git a/avm/res/automation/automation-account/main.json b/avm/res/automation/automation-account/main.json index cf1dcffca2..648ea43ae5 100644 --- a/avm/res/automation/automation-account/main.json +++ b/avm/res/automation/automation-account/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "17012028979997047683" + "templateHash": "5140090215914688680" }, "name": "Automation Accounts", "description": "This module deploys an Azure Automation Account.", @@ -46,6 +46,26 @@ "__bicep_export!": true } }, + "gallerySolutionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { @@ -53,7 +73,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, "ipAddresses": { @@ -68,7 +88,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -110,7 +130,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -151,7 +171,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -188,7 +208,7 @@ "metadata": { "description": "An AVM-aligned type for a customer-managed key.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -310,7 +330,7 @@ "metadata": { "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -340,7 +360,7 @@ "metadata": { "description": "An AVM-aligned type for a lock.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -368,7 +388,7 @@ "metadata": { "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -509,7 +529,7 @@ "metadata": { "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can NOT be assumed (i.e., for services that have more than one subresource, like Storage Account with Blob (blob, table, queue, file, ...).", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -584,7 +604,37 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/res/operations-management/solution:0.3.0" } } } @@ -675,7 +725,10 @@ }, "gallerySolutions": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/gallerySolutionType" + }, + "nullable": true, "metadata": { "description": "Optional. List of gallerySolutions to be created in the linked log analytics workspace." } @@ -1993,7 +2046,7 @@ "automationAccount_solutions": { "copy": { "name": "automationAccount_solutions", - "count": "[length(parameters('gallerySolutions'))]" + "count": "[length(coalesce(parameters('gallerySolutions'), createArray()))]" }, "condition": "[not(empty(parameters('linkedWorkspaceResourceId')))]", "type": "Microsoft.Resources/deployments", @@ -2008,7 +2061,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('gallerySolutions')[copyIndex()].name]" + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].name]" }, "location": { "value": "[parameters('location')]" @@ -2016,11 +2069,8 @@ "logAnalyticsWorkspaceName": { "value": "[last(split(parameters('linkedWorkspaceResourceId'), '/'))]" }, - "product": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'product')]" - }, - "publisher": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'publisher')]" + "plan": { + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].plan]" }, "enableTelemetry": { "value": "[parameters('enableTelemetry')]" @@ -2028,22 +2078,59 @@ }, "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": "15740268121966556319" + "version": "0.30.23.60470", + "templateHash": "1867653058254938383" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", "owner": "Azure/module-maintainers" }, + "definitions": { + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "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})`." + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } }, "logAnalyticsWorkspaceName": { @@ -2059,20 +2146,6 @@ "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, @@ -2081,16 +2154,12 @@ } } }, - "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": [ - { + "resources": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.1.3', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.3.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2106,36 +2175,45 @@ } } }, - { + "logAnalyticsWorkspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "solution": { "type": "Microsoft.OperationsManagement/solutions", "apiVersion": "2015-11-01-preview", - "name": "[variables('solutionName')]", + "name": "[parameters('name')]", "location": "[parameters('location')]", "properties": { "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" }, "plan": { - "name": "[variables('solutionName')]", + "name": "[coalesce(tryGet(parameters('plan'), 'name'), parameters('name'))]", "promotionCode": "", - "product": "[variables('solutionProduct')]", - "publisher": "[parameters('publisher')]" - } + "product": "[parameters('plan').product]", + "publisher": "[coalesce(tryGet(parameters('plan'), 'publisher'), 'Microsoft')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the deployed solution." }, - "value": "[variables('solutionName')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed solution." }, - "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + "value": "[resourceId('Microsoft.OperationsManagement/solutions', parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -2149,7 +2227,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + "value": "[reference('solution', '2015-11-01-preview', 'full').location]" } } } diff --git a/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep index a3dfb495d2..afcdf60468 100644 --- a/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/max/main.test.bicep @@ -76,9 +76,11 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'Updates(${last(split(diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId, '/'))})' + plan: { + product: 'OMSGallery/Updates' + publisher: 'Microsoft' + } } ] jobSchedules: [ diff --git a/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep index 355d2a8e53..4ee50b8f61 100644 --- a/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/automation/automation-account/tests/e2e/waf-aligned/main.test.bicep @@ -76,9 +76,10 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'Updates' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'Updates(${last(split(diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId, '/'))})' + plan: { + product: 'OMSGallery/Updates' + } } ] jobSchedules: [ diff --git a/avm/res/automation/automation-account/version.json b/avm/res/automation/automation-account/version.json index b8b30a0125..a830c3d961 100644 --- a/avm/res/automation/automation-account/version.json +++ b/avm/res/automation/automation-account/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.9", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.10", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/cdn/profile/README.md b/avm/res/cdn/profile/README.md index cdbbe70b4d..1a43a43d99 100644 --- a/avm/res/cdn/profile/README.md +++ b/avm/res/cdn/profile/README.md @@ -1211,6 +1211,250 @@ Array of origin group objects. Required if the afdEndpoints is specified. - Type: array - Default: `[]` +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`loadBalancingSettings`](#parameter-origingroupsloadbalancingsettings) | object | Load balancing settings for a backend pool. | +| [`name`](#parameter-origingroupsname) | string | The name of the origin group. | +| [`origins`](#parameter-origingroupsorigins) | array | The list of origins within the origin group. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`healthProbeSettings`](#parameter-origingroupshealthprobesettings) | object | Health probe settings to the origin that is used to determine the health of the origin. | +| [`sessionAffinityState`](#parameter-origingroupssessionaffinitystate) | string | Whether to allow session affinity on this host. | +| [`trafficRestorationTimeToHealedOrNewEndpointsInMinutes`](#parameter-origingroupstrafficrestorationtimetohealedornewendpointsinminutes) | int | Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins. | + +### Parameter: `originGroups.loadBalancingSettings` + +Load balancing settings for a backend pool. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`additionalLatencyInMilliseconds`](#parameter-origingroupsloadbalancingsettingsadditionallatencyinmilliseconds) | int | Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000. | +| [`sampleSize`](#parameter-origingroupsloadbalancingsettingssamplesize) | int | Number of samples to consider for load balancing decisions. | +| [`successfulSamplesRequired`](#parameter-origingroupsloadbalancingsettingssuccessfulsamplesrequired) | int | Number of samples within the sample window that must be successful to mark the backend as healthy. | + +### Parameter: `originGroups.loadBalancingSettings.additionalLatencyInMilliseconds` + +Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000. + +- Required: Yes +- Type: int + +### Parameter: `originGroups.loadBalancingSettings.sampleSize` + +Number of samples to consider for load balancing decisions. + +- Required: Yes +- Type: int + +### Parameter: `originGroups.loadBalancingSettings.successfulSamplesRequired` + +Number of samples within the sample window that must be successful to mark the backend as healthy. + +- Required: Yes +- Type: int + +### Parameter: `originGroups.name` + +The name of the origin group. + +- Required: Yes +- Type: string + +### Parameter: `originGroups.origins` + +The list of origins within the origin group. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`hostName`](#parameter-origingroupsoriginshostname) | string | The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint. | +| [`name`](#parameter-origingroupsoriginsname) | string | The name of the origion. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabledState`](#parameter-origingroupsoriginsenabledstate) | string | Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool. | +| [`enforceCertificateNameCheck`](#parameter-origingroupsoriginsenforcecertificatenamecheck) | bool | Whether to enable certificate name check at origin level. | +| [`httpPort`](#parameter-origingroupsoriginshttpport) | int | The value of the HTTP port. Must be between 1 and 65535. | +| [`httpsPort`](#parameter-origingroupsoriginshttpsport) | int | The value of the HTTPS port. Must be between 1 and 65535. | +| [`originHostHeader`](#parameter-origingroupsoriginsoriginhostheader) | string | The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint. | +| [`priority`](#parameter-origingroupsoriginspriority) | int | Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5. | +| [`sharedPrivateLinkResource`](#parameter-origingroupsoriginssharedprivatelinkresource) | object | The properties of the private link resource for private origin. | +| [`weight`](#parameter-origingroupsoriginsweight) | int | Weight of the origin in given origin group for load balancing. Must be between 1 and 1000. | + +### Parameter: `originGroups.origins.hostName` + +The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint. + +- Required: Yes +- Type: string + +### Parameter: `originGroups.origins.name` + +The name of the origion. + +- Required: Yes +- Type: string + +### Parameter: `originGroups.origins.enabledState` + +Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `originGroups.origins.enforceCertificateNameCheck` + +Whether to enable certificate name check at origin level. + +- Required: No +- Type: bool + +### Parameter: `originGroups.origins.httpPort` + +The value of the HTTP port. Must be between 1 and 65535. + +- Required: No +- Type: int + +### Parameter: `originGroups.origins.httpsPort` + +The value of the HTTPS port. Must be between 1 and 65535. + +- Required: No +- Type: int + +### Parameter: `originGroups.origins.originHostHeader` + +The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint. + +- Required: No +- Type: string + +### Parameter: `originGroups.origins.priority` + +Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5. + +- Required: No +- Type: int + +### Parameter: `originGroups.origins.sharedPrivateLinkResource` + +The properties of the private link resource for private origin. + +- Required: No +- Type: object + +### Parameter: `originGroups.origins.weight` + +Weight of the origin in given origin group for load balancing. Must be between 1 and 1000. + +- Required: No +- Type: int + +### Parameter: `originGroups.healthProbeSettings` + +Health probe settings to the origin that is used to determine the health of the origin. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`probeIntervalInSeconds`](#parameter-origingroupshealthprobesettingsprobeintervalinseconds) | int | The number of seconds between health probes.Default is 240sec. | +| [`probePath`](#parameter-origingroupshealthprobesettingsprobepath) | string | The path relative to the origin that is used to determine the health of the origin. | +| [`probeProtocol`](#parameter-origingroupshealthprobesettingsprobeprotocol) | string | Protocol to use for health probe. | +| [`probeRequestType`](#parameter-origingroupshealthprobesettingsproberequesttype) | string | The request type to probe. | + +### Parameter: `originGroups.healthProbeSettings.probeIntervalInSeconds` + +The number of seconds between health probes.Default is 240sec. + +- Required: No +- Type: int + +### Parameter: `originGroups.healthProbeSettings.probePath` + +The path relative to the origin that is used to determine the health of the origin. + +- Required: No +- Type: string + +### Parameter: `originGroups.healthProbeSettings.probeProtocol` + +Protocol to use for health probe. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Http' + 'Https' + 'NotSet' + ] + ``` + +### Parameter: `originGroups.healthProbeSettings.probeRequestType` + +The request type to probe. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'GET' + 'HEAD' + 'NotSet' + ] + ``` + +### Parameter: `originGroups.sessionAffinityState` + +Whether to allow session affinity on this host. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `originGroups.trafficRestorationTimeToHealedOrNewEndpointsInMinutes` + +Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins. + +- Required: No +- Type: int + ### Parameter: `afdEndpoints` Array of AFD endpoint objects. @@ -1219,6 +1463,271 @@ Array of AFD endpoint objects. - Type: array - Default: `[]` +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-afdendpointsname) | string | The name of the AFD Endpoint. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoGeneratedDomainNameLabelScope`](#parameter-afdendpointsautogenerateddomainnamelabelscope) | string | The scope of the auto-generated domain name label. | +| [`enabledState`](#parameter-afdendpointsenabledstate) | string | The state of the AFD Endpoint. | +| [`routes`](#parameter-afdendpointsroutes) | array | The list of routes for this AFD Endpoint. | +| [`tags`](#parameter-afdendpointstags) | object | The tags for the AFD Endpoint. | + +### Parameter: `afdEndpoints.name` + +The name of the AFD Endpoint. + +- Required: Yes +- Type: string + +### Parameter: `afdEndpoints.autoGeneratedDomainNameLabelScope` + +The scope of the auto-generated domain name label. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'NoReuse' + 'ResourceGroupReuse' + 'SubscriptionReuse' + 'TenantReuse' + ] + ``` + +### Parameter: `afdEndpoints.enabledState` + +The state of the AFD Endpoint. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `afdEndpoints.routes` + +The list of routes for this AFD Endpoint. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-afdendpointsroutesname) | string | The name of the route. | +| [`originGroupName`](#parameter-afdendpointsroutesorigingroupname) | string | The name of the origin group. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`cacheConfiguration`](#parameter-afdendpointsroutescacheconfiguration) | object | The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object. | +| [`customDomainNames`](#parameter-afdendpointsroutescustomdomainnames) | array | The names of the custom domains. | +| [`enabledState`](#parameter-afdendpointsroutesenabledstate) | string | Whether to enable use of this rule. | +| [`forwardingProtocol`](#parameter-afdendpointsroutesforwardingprotocol) | string | The protocol this rule will use when forwarding traffic to backends. | +| [`httpsRedirect`](#parameter-afdendpointsrouteshttpsredirect) | string | Whether to automatically redirect HTTP traffic to HTTPS traffic. | +| [`linkToDefaultDomain`](#parameter-afdendpointsrouteslinktodefaultdomain) | string | Whether this route will be linked to the default endpoint domain. | +| [`originPath`](#parameter-afdendpointsroutesoriginpath) | string | A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath. | +| [`patternsToMatch`](#parameter-afdendpointsroutespatternstomatch) | array | The route patterns of the rule. | +| [`ruleSets`](#parameter-afdendpointsroutesrulesets) | array | The rule sets of the rule. | +| [`supportedProtocols`](#parameter-afdendpointsroutessupportedprotocols) | array | The supported protocols of the rule. | + +### Parameter: `afdEndpoints.routes.name` + +The name of the route. + +- Required: Yes +- Type: string + +### Parameter: `afdEndpoints.routes.originGroupName` + +The name of the origin group. + +- Required: Yes +- Type: string + +### Parameter: `afdEndpoints.routes.cacheConfiguration` + +The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`compressionSettings`](#parameter-afdendpointsroutescacheconfigurationcompressionsettings) | object | Compression settings. | +| [`queryParameters`](#parameter-afdendpointsroutescacheconfigurationqueryparameters) | string | Query parameters to include or exclude (comma separated). | +| [`queryStringCachingBehavior`](#parameter-afdendpointsroutescacheconfigurationquerystringcachingbehavior) | string | Defines how Frontdoor caches requests that include query strings. | + +### Parameter: `afdEndpoints.routes.cacheConfiguration.compressionSettings` + +Compression settings. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`contentTypesToCompress`](#parameter-afdendpointsroutescacheconfigurationcompressionsettingscontenttypestocompress) | array | List of content types on which compression applies. The value should be a valid MIME type. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`iscontentTypeToCompressAll`](#parameter-afdendpointsroutescacheconfigurationcompressionsettingsiscontenttypetocompressall) | bool | Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB. | + +### Parameter: `afdEndpoints.routes.cacheConfiguration.compressionSettings.contentTypesToCompress` + +List of content types on which compression applies. The value should be a valid MIME type. + +- Required: Yes +- Type: array + +### Parameter: `afdEndpoints.routes.cacheConfiguration.compressionSettings.iscontentTypeToCompressAll` + +Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB. + +- Required: No +- Type: bool + +### Parameter: `afdEndpoints.routes.cacheConfiguration.queryParameters` + +Query parameters to include or exclude (comma separated). + +- Required: Yes +- Type: string + +### Parameter: `afdEndpoints.routes.cacheConfiguration.queryStringCachingBehavior` + +Defines how Frontdoor caches requests that include query strings. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'IgnoreQueryString' + 'IgnoreSpecifiedQueryStrings' + 'IncludeSpecifiedQueryStrings' + 'UseQueryString' + ] + ``` + +### Parameter: `afdEndpoints.routes.customDomainNames` + +The names of the custom domains. + +- Required: No +- Type: array + +### Parameter: `afdEndpoints.routes.enabledState` + +Whether to enable use of this rule. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `afdEndpoints.routes.forwardingProtocol` + +The protocol this rule will use when forwarding traffic to backends. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'HttpOnly' + 'HttpsOnly' + 'MatchRequest' + ] + ``` + +### Parameter: `afdEndpoints.routes.httpsRedirect` + +Whether to automatically redirect HTTP traffic to HTTPS traffic. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `afdEndpoints.routes.linkToDefaultDomain` + +Whether this route will be linked to the default endpoint domain. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `afdEndpoints.routes.originPath` + +A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath. + +- Required: No +- Type: string + +### Parameter: `afdEndpoints.routes.patternsToMatch` + +The route patterns of the rule. + +- Required: No +- Type: array + +### Parameter: `afdEndpoints.routes.ruleSets` + +The rule sets of the rule. + +- Required: No +- Type: array + +### Parameter: `afdEndpoints.routes.supportedProtocols` + +The supported protocols of the rule. + +- Required: No +- Type: array + +### Parameter: `afdEndpoints.tags` + +The tags for the AFD Endpoint. + +- Required: No +- Type: object + ### Parameter: `customDomains` Array of custom domain objects. @@ -1227,6 +1736,95 @@ Array of custom domain objects. - Type: array - Default: `[]` +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`certificateType`](#parameter-customdomainscertificatetype) | string | The type of the certificate. | +| [`hostName`](#parameter-customdomainshostname) | string | The host name of the custom domain. | +| [`name`](#parameter-customdomainsname) | string | The name of the custom domain. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`azureDnsZoneResourceId`](#parameter-customdomainsazurednszoneresourceid) | string | The resource ID of the Azure DNS zone. | +| [`extendedProperties`](#parameter-customdomainsextendedproperties) | object | Extended properties. | +| [`minimumTlsVersion`](#parameter-customdomainsminimumtlsversion) | string | The minimum TLS version. | +| [`preValidatedCustomDomainResourceId`](#parameter-customdomainsprevalidatedcustomdomainresourceid) | string | The resource ID of the pre-validated custom domain. | +| [`secretName`](#parameter-customdomainssecretname) | string | The name of the secret. | + +### Parameter: `customDomains.certificateType` + +The type of the certificate. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AzureFirstPartyManagedCertificate' + 'CustomerCertificate' + 'ManagedCertificate' + ] + ``` + +### Parameter: `customDomains.hostName` + +The host name of the custom domain. + +- Required: Yes +- Type: string + +### Parameter: `customDomains.name` + +The name of the custom domain. + +- Required: Yes +- Type: string + +### Parameter: `customDomains.azureDnsZoneResourceId` + +The resource ID of the Azure DNS zone. + +- Required: No +- Type: string + +### Parameter: `customDomains.extendedProperties` + +Extended properties. + +- Required: No +- Type: object + +### Parameter: `customDomains.minimumTlsVersion` + +The minimum TLS version. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'TLS10' + 'TLS12' + ] + ``` + +### Parameter: `customDomains.preValidatedCustomDomainResourceId` + +The resource ID of the pre-validated custom domain. + +- Required: No +- Type: string + +### Parameter: `customDomains.secretName` + +The name of the secret. + +- Required: No +- Type: string + ### Parameter: `enableTelemetry` Enable/Disable usage telemetry for module. @@ -1444,6 +2042,89 @@ Array of rule set objects. - Type: array - Default: `[]` +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-rulesetsname) | string | Name of the rule set. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rules`](#parameter-rulesetsrules) | array | Array of rules. | + +### Parameter: `ruleSets.name` + +Name of the rule set. + +- Required: Yes +- Type: string + +### Parameter: `ruleSets.rules` + +Array of rules. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-rulesetsrulesname) | string | The name of the rule. | +| [`order`](#parameter-rulesetsrulesorder) | int | The order in which the rules are applied for the endpoint. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`actions`](#parameter-rulesetsrulesactions) | array | A list of actions that are executed when all the conditions of a rule are satisfied.. | +| [`conditions`](#parameter-rulesetsrulesconditions) | array | A list of conditions that must be matched for the actions to be executed. | +| [`matchProcessingBehavior`](#parameter-rulesetsrulesmatchprocessingbehavior) | string | If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue. | + +### Parameter: `ruleSets.rules.name` + +The name of the rule. + +- Required: Yes +- Type: string + +### Parameter: `ruleSets.rules.order` + +The order in which the rules are applied for the endpoint. + +- Required: Yes +- Type: int + +### Parameter: `ruleSets.rules.actions` + +A list of actions that are executed when all the conditions of a rule are satisfied.. + +- Required: No +- Type: array + +### Parameter: `ruleSets.rules.conditions` + +A list of conditions that must be matched for the actions to be executed. + +- Required: No +- Type: array + +### Parameter: `ruleSets.rules.matchProcessingBehavior` + +If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Continue' + 'Stop' + ] + ``` + ### Parameter: `secrets` Array of secret objects. diff --git a/avm/res/cdn/profile/afdEndpoint/README.md b/avm/res/cdn/profile/afdEndpoint/README.md index 910c0df19c..49f50fa42a 100644 --- a/avm/res/cdn/profile/afdEndpoint/README.md +++ b/avm/res/cdn/profile/afdEndpoint/README.md @@ -100,6 +100,205 @@ The list of routes for this AFD Endpoint. - Required: No - Type: array +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-routesname) | string | The name of the route. | +| [`originGroupName`](#parameter-routesorigingroupname) | string | The name of the origin group. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`cacheConfiguration`](#parameter-routescacheconfiguration) | object | The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object. | +| [`customDomainNames`](#parameter-routescustomdomainnames) | array | The names of the custom domains. | +| [`enabledState`](#parameter-routesenabledstate) | string | Whether to enable use of this rule. | +| [`forwardingProtocol`](#parameter-routesforwardingprotocol) | string | The protocol this rule will use when forwarding traffic to backends. | +| [`httpsRedirect`](#parameter-routeshttpsredirect) | string | Whether to automatically redirect HTTP traffic to HTTPS traffic. | +| [`linkToDefaultDomain`](#parameter-routeslinktodefaultdomain) | string | Whether this route will be linked to the default endpoint domain. | +| [`originPath`](#parameter-routesoriginpath) | string | A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath. | +| [`patternsToMatch`](#parameter-routespatternstomatch) | array | The route patterns of the rule. | +| [`ruleSets`](#parameter-routesrulesets) | array | The rule sets of the rule. | +| [`supportedProtocols`](#parameter-routessupportedprotocols) | array | The supported protocols of the rule. | + +### Parameter: `routes.name` + +The name of the route. + +- Required: Yes +- Type: string + +### Parameter: `routes.originGroupName` + +The name of the origin group. + +- Required: Yes +- Type: string + +### Parameter: `routes.cacheConfiguration` + +The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`compressionSettings`](#parameter-routescacheconfigurationcompressionsettings) | object | Compression settings. | +| [`queryParameters`](#parameter-routescacheconfigurationqueryparameters) | string | Query parameters to include or exclude (comma separated). | +| [`queryStringCachingBehavior`](#parameter-routescacheconfigurationquerystringcachingbehavior) | string | Defines how Frontdoor caches requests that include query strings. | + +### Parameter: `routes.cacheConfiguration.compressionSettings` + +Compression settings. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`contentTypesToCompress`](#parameter-routescacheconfigurationcompressionsettingscontenttypestocompress) | array | List of content types on which compression applies. The value should be a valid MIME type. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`iscontentTypeToCompressAll`](#parameter-routescacheconfigurationcompressionsettingsiscontenttypetocompressall) | bool | Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB. | + +### Parameter: `routes.cacheConfiguration.compressionSettings.contentTypesToCompress` + +List of content types on which compression applies. The value should be a valid MIME type. + +- Required: Yes +- Type: array + +### Parameter: `routes.cacheConfiguration.compressionSettings.iscontentTypeToCompressAll` + +Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB. + +- Required: No +- Type: bool + +### Parameter: `routes.cacheConfiguration.queryParameters` + +Query parameters to include or exclude (comma separated). + +- Required: Yes +- Type: string + +### Parameter: `routes.cacheConfiguration.queryStringCachingBehavior` + +Defines how Frontdoor caches requests that include query strings. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'IgnoreQueryString' + 'IgnoreSpecifiedQueryStrings' + 'IncludeSpecifiedQueryStrings' + 'UseQueryString' + ] + ``` + +### Parameter: `routes.customDomainNames` + +The names of the custom domains. + +- Required: No +- Type: array + +### Parameter: `routes.enabledState` + +Whether to enable use of this rule. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `routes.forwardingProtocol` + +The protocol this rule will use when forwarding traffic to backends. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'HttpOnly' + 'HttpsOnly' + 'MatchRequest' + ] + ``` + +### Parameter: `routes.httpsRedirect` + +Whether to automatically redirect HTTP traffic to HTTPS traffic. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `routes.linkToDefaultDomain` + +Whether this route will be linked to the default endpoint domain. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `routes.originPath` + +A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath. + +- Required: No +- Type: string + +### Parameter: `routes.patternsToMatch` + +The route patterns of the rule. + +- Required: No +- Type: array + +### Parameter: `routes.ruleSets` + +The rule sets of the rule. + +- Required: No +- Type: array + +### Parameter: `routes.supportedProtocols` + +The supported protocols of the rule. + +- Required: No +- Type: array + ### Parameter: `tags` The tags of the AFD Endpoint. diff --git a/avm/res/cdn/profile/afdEndpoint/main.bicep b/avm/res/cdn/profile/afdEndpoint/main.bicep index a280fcf07f..84644ab9ff 100644 --- a/avm/res/cdn/profile/afdEndpoint/main.bicep +++ b/avm/res/cdn/profile/afdEndpoint/main.bicep @@ -31,7 +31,7 @@ param autoGeneratedDomainNameLabelScope string = 'TenantReuse' param enabledState string = 'Enabled' @description('Optional. The list of routes for this AFD Endpoint.') -param routes array? +param routes routeType[]? resource profile 'Microsoft.Cdn/profiles@2023-05-01' existing = { name: profileName @@ -84,3 +84,27 @@ output location string = afdEndpoint.location @description('The list of routes assigned to the AFD endpoint.') output routes array = routes ?? [] + +// =============== // +// Definitions // +// =============== // + +import { routeType } from './route/main.bicep' + +@export() +type afdEndpointType = { + @description('Required. The name of the AFD Endpoint.') + name: string + + @description('Optional. The list of routes for this AFD Endpoint.') + routes: routeType[]? + + @description('Optional. The tags for the AFD Endpoint.') + tags: object? + + @description('Optional. The scope of the auto-generated domain name label.') + autoGeneratedDomainNameLabelScope: 'NoReuse' | 'ResourceGroupReuse' | 'SubscriptionReuse' | 'TenantReuse' | null + + @description('Optional. The state of the AFD Endpoint.') + enabledState: 'Enabled' | 'Disabled' | null +} diff --git a/avm/res/cdn/profile/afdEndpoint/main.json b/avm/res/cdn/profile/afdEndpoint/main.json index 7cfef24e3f..866c19c60f 100644 --- a/avm/res/cdn/profile/afdEndpoint/main.json +++ b/avm/res/cdn/profile/afdEndpoint/main.json @@ -5,13 +5,237 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "792735746278824384" + "version": "0.31.34.60546", + "templateHash": "16899001110062450573" }, "name": "CDN Profiles AFD Endpoints", "description": "This module deploys a CDN Profile AFD Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "afdEndpointType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the AFD Endpoint." + } + }, + "routes": { + "type": "array", + "items": { + "$ref": "#/definitions/routeType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of routes for this AFD Endpoint." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The tags for the AFD Endpoint." + } + }, + "autoGeneratedDomainNameLabelScope": { + "type": "string", + "allowedValues": [ + "NoReuse", + "ResourceGroupReuse", + "SubscriptionReuse", + "TenantReuse" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scope of the auto-generated domain name label." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. The state of the AFD Endpoint." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_1.afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "route/main.bicep" + } + } + }, + "routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/_1.afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "route/main.bicep" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -65,6 +289,9 @@ }, "routes": { "type": "array", + "items": { + "$ref": "#/definitions/routeType" + }, "nullable": true, "metadata": { "description": "Optional. The list of routes for this AFD Endpoint." @@ -87,10 +314,7 @@ "properties": { "autoGeneratedDomainNameLabelScope": "[parameters('autoGeneratedDomainNameLabelScope')]", "enabledState": "[parameters('enabledState')]" - }, - "dependsOn": [ - "profile" - ] + } }, "afdEndpoint_routes": { "copy": { @@ -156,13 +380,175 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1034122698174669197" + "version": "0.31.34.60546", + "templateHash": "15873678240851060540" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", "owner": "Azure/module-maintainers" }, + "definitions": { + "routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + } + } + }, "parameters": { "name": { "type": "string", @@ -288,10 +674,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/afdEndpoints", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]" }, "profile::customDomains": { "copy": { @@ -301,19 +684,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/customDomains", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]" }, "profile::originGroup": { "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile::ruleSet": { "copy": { @@ -323,10 +700,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]" }, "profile": { "existing": true, @@ -366,10 +740,7 @@ "originPath": "[parameters('originPath')]", "patternsToMatch": "[parameters('patternsToMatch')]", "supportedProtocols": "[parameters('supportedProtocols')]" - }, - "dependsOn": [ - "profile::afdEndpoint" - ] + } } }, "outputs": { @@ -398,8 +769,7 @@ } }, "dependsOn": [ - "afdEndpoint", - "profile" + "afdEndpoint" ] } }, diff --git a/avm/res/cdn/profile/afdEndpoint/route/main.bicep b/avm/res/cdn/profile/afdEndpoint/route/main.bicep index 36bfd40c15..265bd43405 100644 --- a/avm/res/cdn/profile/afdEndpoint/route/main.bicep +++ b/avm/res/cdn/profile/afdEndpoint/route/main.bicep @@ -122,3 +122,66 @@ output resourceId string = route.id @description('The name of the resource group the route was created in.') output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // + +@export() +type routeType = { + @description('Required. The name of the route.') + name: string + + @description('Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object.') + cacheConfiguration: afdRoutecacheConfigurationType? + + @description('Optional. The names of the custom domains.') + customDomainNames: string[]? + + @description('Optional. Whether to enable use of this rule.') + enabledState: 'Enabled' | 'Disabled' | null + + @description('Optional. The protocol this rule will use when forwarding traffic to backends.') + forwardingProtocol: 'HttpOnly' | 'HttpsOnly' | 'MatchRequest' | null + + @description('Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic.') + httpsRedirect: 'Enabled' | 'Disabled' | null + + @description('Optional. Whether this route will be linked to the default endpoint domain.') + linkToDefaultDomain: 'Enabled' | 'Disabled' | null + + @description('Required. The name of the origin group.') + originGroupName: string + + @description('Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath.') + originPath: string? + + @description('Optional. The route patterns of the rule.') + patternsToMatch: array? + + @description('Optional. The rule sets of the rule.') + ruleSets: object[]? + + @description('Optional. The supported protocols of the rule.') + supportedProtocols: array? +} + +type afdRoutecacheConfigurationType = { + @description('Required. Compression settings.') + compressionSettings: { + @description('Required. List of content types on which compression applies. The value should be a valid MIME type.') + contentTypesToCompress: string[] + + @description('Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won\'t be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB.') + iscontentTypeToCompressAll: bool? + } + @description('Required. Query parameters to include or exclude (comma separated).') + queryParameters: string + + @description('Required. Defines how Frontdoor caches requests that include query strings.') + queryStringCachingBehavior: + | 'IgnoreQueryString' + | 'IgnoreSpecifiedQueryStrings' + | 'IncludeSpecifiedQueryStrings' + | 'UseQueryString' +} diff --git a/avm/res/cdn/profile/afdEndpoint/route/main.json b/avm/res/cdn/profile/afdEndpoint/route/main.json index 852e97f10c..eae2b5bfce 100644 --- a/avm/res/cdn/profile/afdEndpoint/route/main.json +++ b/avm/res/cdn/profile/afdEndpoint/route/main.json @@ -5,13 +5,175 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1034122698174669197" + "version": "0.31.34.60546", + "templateHash": "15873678240851060540" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", "owner": "Azure/module-maintainers" }, + "definitions": { + "routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + } + } + }, "parameters": { "name": { "type": "string", @@ -137,10 +299,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/afdEndpoints", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]" }, "profile::customDomains": { "copy": { @@ -150,19 +309,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/customDomains", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]" }, "profile::originGroup": { "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile::ruleSet": { "copy": { @@ -172,10 +325,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]" }, "profile": { "existing": true, @@ -215,10 +365,7 @@ "originPath": "[parameters('originPath')]", "patternsToMatch": "[parameters('patternsToMatch')]", "supportedProtocols": "[parameters('supportedProtocols')]" - }, - "dependsOn": [ - "profile::afdEndpoint" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/customdomain/README.md b/avm/res/cdn/profile/customdomain/README.md index 39077a14be..37e9d735de 100644 --- a/avm/res/cdn/profile/customdomain/README.md +++ b/avm/res/cdn/profile/customdomain/README.md @@ -49,6 +49,7 @@ The type of the certificate used for secure delivery. - Allowed: ```Bicep [ + 'AzureFirstPartyManagedCertificate' 'CustomerCertificate' 'ManagedCertificate' ] diff --git a/avm/res/cdn/profile/customdomain/main.bicep b/avm/res/cdn/profile/customdomain/main.bicep index a0a4f4477f..efe67a0569 100644 --- a/avm/res/cdn/profile/customdomain/main.bicep +++ b/avm/res/cdn/profile/customdomain/main.bicep @@ -21,6 +21,7 @@ param extendedProperties object = {} param preValidatedCustomDomainResourceId string = '' @allowed([ + 'AzureFirstPartyManagedCertificate' 'CustomerCertificate' 'ManagedCertificate' ]) @@ -40,10 +41,9 @@ param secretName string = '' resource profile 'Microsoft.Cdn/profiles@2023-05-01' existing = { name: profileName - resource secrect 'secrets@2023-05-01' existing = - if (!empty(secretName)) { - name: secretName - } + resource secrect 'secrets@2023-05-01' existing = if (!empty(secretName)) { + name: secretName + } } resource customDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = { @@ -82,3 +82,33 @@ output resourceId string = customDomain.id @description('The name of the resource group the custom domain was created in.') output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // +@export() +type customDomainType = { + @description('Required. The name of the custom domain.') + name: string + + @description('Required. The host name of the custom domain.') + hostName: string + + @description('Required. The type of the certificate.') + certificateType: 'AzureFirstPartyManagedCertificate' | 'CustomerCertificate' | 'ManagedCertificate' + + @description('Optional. The resource ID of the Azure DNS zone.') + azureDnsZoneResourceId: string? + + @description('Optional. The resource ID of the pre-validated custom domain.') + preValidatedCustomDomainResourceId: string? + + @description('Optional. The name of the secret.') + secretName: string? + + @description('Optional. The minimum TLS version.') + minimumTlsVersion: 'TLS10' | 'TLS12' | null + + @description('Optional. Extended properties.') + extendedProperties: object? +} diff --git a/avm/res/cdn/profile/customdomain/main.json b/avm/res/cdn/profile/customdomain/main.json index e45727e4ad..b88c221734 100644 --- a/avm/res/cdn/profile/customdomain/main.json +++ b/avm/res/cdn/profile/customdomain/main.json @@ -1,16 +1,89 @@ { "$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.30.23.60470", - "templateHash": "16955838730426729961" + "version": "0.31.34.60546", + "templateHash": "10387694873442665915" }, "name": "CDN Profiles Custom Domains", "description": "This module deploys a CDN Profile Custom Domains.", "owner": "Azure/module-maintainers" }, + "definitions": { + "customDomainType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the custom domain." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The host name of the custom domain." + } + }, + "certificateType": { + "type": "string", + "allowedValues": [ + "AzureFirstPartyManagedCertificate", + "CustomerCertificate", + "ManagedCertificate" + ], + "metadata": { + "description": "Required. The type of the certificate." + } + }, + "azureDnsZoneResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Azure DNS zone." + } + }, + "preValidatedCustomDomainResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the pre-validated custom domain." + } + }, + "secretName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the secret." + } + }, + "minimumTlsVersion": { + "type": "string", + "allowedValues": [ + "TLS10", + "TLS12" + ], + "nullable": true, + "metadata": { + "description": "Optional. The minimum TLS version." + } + }, + "extendedProperties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Extended properties." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -54,6 +127,7 @@ "certificateType": { "type": "string", "allowedValues": [ + "AzureFirstPartyManagedCertificate", "CustomerCertificate", "ManagedCertificate" ], @@ -80,8 +154,21 @@ } } }, - "resources": [ - { + "resources": { + "profile::secrect": { + "condition": "[not(empty(parameters('secretName')))]", + "existing": true, + "type": "Microsoft.Cdn/profiles/secrets", + "apiVersion": "2023-05-01", + "name": "[format('{0}/{1}', parameters('profileName'), parameters('secretName'))]" + }, + "profile": { + "existing": true, + "type": "Microsoft.Cdn/profiles", + "apiVersion": "2023-05-01", + "name": "[parameters('profileName')]" + }, + "customDomain": { "type": "Microsoft.Cdn/profiles/customDomains", "apiVersion": "2023-05-01", "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", @@ -97,7 +184,7 @@ } } } - ], + }, "outputs": { "name": { "type": "string", diff --git a/avm/res/cdn/profile/endpoint/main.json b/avm/res/cdn/profile/endpoint/main.json index 273dbe9fce..ca9c1a9478 100644 --- a/avm/res/cdn/profile/endpoint/main.json +++ b/avm/res/cdn/profile/endpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3460565146034921053" + "version": "0.31.34.60546", + "templateHash": "5709530270456479127" }, "name": "CDN Profiles Endpoints", "description": "This module deploys a CDN Profile Endpoint.", @@ -59,10 +59,7 @@ "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", "location": "[parameters('location')]", "properties": "[parameters('properties')]", - "tags": "[parameters('tags')]", - "dependsOn": [ - "profile" - ] + "tags": "[parameters('tags')]" }, "endpoint_origins": { "copy": { @@ -125,8 +122,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4151069688274070352" + "version": "0.31.34.60546", + "templateHash": "12416203553821456162" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", @@ -233,19 +230,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/endpoints", "apiVersion": "2021-06-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]" }, "origin": { "type": "Microsoft.Cdn/profiles/endpoints/origins", "apiVersion": "2021-06-01", "name": "[format('{0}/{1}/{2}', parameters('profileName'), parameters('endpointName'), parameters('name'))]", - "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]", - "dependsOn": [ - "endpoint" - ] + "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]" } }, "outputs": { @@ -281,8 +272,7 @@ } }, "dependsOn": [ - "endpoint", - "profile" + "endpoint" ] } }, diff --git a/avm/res/cdn/profile/endpoint/origin/main.json b/avm/res/cdn/profile/endpoint/origin/main.json index f4c079ff44..e71c4745c1 100644 --- a/avm/res/cdn/profile/endpoint/origin/main.json +++ b/avm/res/cdn/profile/endpoint/origin/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4151069688274070352" + "version": "0.31.34.60546", + "templateHash": "12416203553821456162" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", @@ -113,19 +113,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/endpoints", "apiVersion": "2021-06-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]" }, "origin": { "type": "Microsoft.Cdn/profiles/endpoints/origins", "apiVersion": "2021-06-01", "name": "[format('{0}/{1}/{2}', parameters('profileName'), parameters('endpointName'), parameters('name'))]", - "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]", - "dependsOn": [ - "endpoint" - ] + "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]" } }, "outputs": { diff --git a/avm/res/cdn/profile/main.bicep b/avm/res/cdn/profile/main.bicep index 2c30c0c2e2..ae15d9234b 100644 --- a/avm/res/cdn/profile/main.bicep +++ b/avm/res/cdn/profile/main.bicep @@ -38,16 +38,16 @@ param endpointProperties object? param secrets array = [] @description('Optional. Array of custom domain objects.') -param customDomains array = [] +param customDomains customDomainType[] = [] @description('Conditional. Array of origin group objects. Required if the afdEndpoints is specified.') -param originGroups array = [] +param originGroups originGroupType[] = [] @description('Optional. Array of rule set objects.') -param ruleSets array = [] +param ruleSets ruleSetType[] = [] @description('Optional. Array of AFD endpoint objects.') -param afdEndpoints array = [] +param afdEndpoints afdEndpointType[] = [] @description('Optional. Array of Security Policy objects (see https://learn.microsoft.com/en-us/azure/templates/microsoft.cdn/profiles/securitypolicies for details).') param securityPolicies securityPolicyType = [] @@ -320,6 +320,14 @@ output systemAssignedMIPrincipalId string = profile.?identity.?principalId ?? '' // Definitions // // =============== // +import { afdEndpointType } from 'afdEndpoint/main.bicep' +import { customDomainType } from 'customdomain/main.bicep' +import { originGroupType } from 'origingroup/main.bicep' +import { originType } from 'origingroup//origin/main.bicep' +import { associationsType } from 'securityPolicies/main.bicep' +import { ruleSetType } from 'ruleset/main.bicep' +import { ruleType } from 'ruleset/rule/main.bicep' + type managedIdentitiesType = { @description('Optional. Enables system assigned managed identity on the resource.') systemAssigned: bool? @@ -328,7 +336,7 @@ type managedIdentitiesType = { userAssignedResourceIds: string[]? }? -import { associationsType } from 'securityPolicies/main.bicep' +@export() type securityPolicyType = { @description('Required. Name of the security policy.') name: string diff --git a/avm/res/cdn/profile/main.json b/avm/res/cdn/profile/main.json index ff95fa664e..1d5952c679 100644 --- a/avm/res/cdn/profile/main.json +++ b/avm/res/cdn/profile/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17027452417371199673" + "version": "0.31.34.60546", + "templateHash": "10761375864597089825" }, "name": "CDN Profiles", "description": "This module deploys a CDN Profile.", @@ -60,6 +60,9 @@ } } } + }, + "metadata": { + "__bicep_export!": true } }, "lockType": { @@ -160,6 +163,388 @@ }, "nullable": true }, + "_1.afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "afdEndpoint/route/main.bicep" + } + } + }, + "_1.routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/_1.afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "afdEndpoint/route/main.bicep" + } + } + }, + "_2.healthProbeSettingsType": { + "type": "object", + "properties": { + "probePath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The path relative to the origin that is used to determine the health of the origin." + } + }, + "probeProtocol": { + "type": "string", + "allowedValues": [ + "Http", + "Https", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. Protocol to use for health probe." + } + }, + "probeRequestType": { + "type": "string", + "allowedValues": [ + "GET", + "HEAD", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. The request type to probe." + } + }, + "probeIntervalInSeconds": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of seconds between health probes.Default is 240sec." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origingroup/main.bicep" + } + } + }, + "_2.loadBalancingSettingsType": { + "type": "object", + "properties": { + "additionalLatencyInMilliseconds": { + "type": "int", + "metadata": { + "description": "Required. Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000." + } + }, + "sampleSize": { + "type": "int", + "metadata": { + "description": "Required. Number of samples to consider for load balancing decisions." + } + }, + "successfulSamplesRequired": { + "type": "int", + "metadata": { + "description": "Required. Number of samples within the sample window that must be successful to mark the backend as healthy." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origingroup/main.bicep" + } + } + }, + "_3.originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origingroup/origin/main.bicep" + } + } + }, + "afdEndpointType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the AFD Endpoint." + } + }, + "routes": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.routeType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of routes for this AFD Endpoint." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The tags for the AFD Endpoint." + } + }, + "autoGeneratedDomainNameLabelScope": { + "type": "string", + "allowedValues": [ + "NoReuse", + "ResourceGroupReuse", + "SubscriptionReuse", + "TenantReuse" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scope of the auto-generated domain name label." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. The state of the AFD Endpoint." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "afdEndpoint/main.bicep" + } + } + }, "associationsType": { "type": "array", "items": { @@ -195,7 +580,290 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "securityPolicies/main.bicep" + "sourceTemplate": "securityPolicies/main.bicep" + } + } + }, + "customDomainType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the custom domain." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The host name of the custom domain." + } + }, + "certificateType": { + "type": "string", + "allowedValues": [ + "AzureFirstPartyManagedCertificate", + "CustomerCertificate", + "ManagedCertificate" + ], + "metadata": { + "description": "Required. The type of the certificate." + } + }, + "azureDnsZoneResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Azure DNS zone." + } + }, + "preValidatedCustomDomainResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the pre-validated custom domain." + } + }, + "secretName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the secret." + } + }, + "minimumTlsVersion": { + "type": "string", + "allowedValues": [ + "TLS10", + "TLS12" + ], + "nullable": true, + "metadata": { + "description": "Optional. The minimum TLS version." + } + }, + "extendedProperties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Extended properties." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "customdomain/main.bicep" + } + } + }, + "originGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "loadBalancingSettings": { + "$ref": "#/definitions/_2.loadBalancingSettingsType", + "metadata": { + "description": "Required. Load balancing settings for a backend pool." + } + }, + "healthProbeSettings": { + "$ref": "#/definitions/_2.healthProbeSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. Health probe settings to the origin that is used to determine the health of the origin." + } + }, + "sessionAffinityState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to allow session affinity on this host." + } + }, + "trafficRestorationTimeToHealedOrNewEndpointsInMinutes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins." + } + }, + "origins": { + "type": "array", + "items": { + "$ref": "#/definitions/_3.originType" + }, + "metadata": { + "description": "Required. The list of origins within the origin group." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origingroup/main.bicep" + } + } + }, + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origingroup//origin/main.bicep" + } + } + }, + "ruleSetType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the rule set." + } + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of rules." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "ruleset/main.bicep" + } + } + }, + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "ruleset/rule/main.bicep" } } } @@ -264,6 +932,9 @@ }, "customDomains": { "type": "array", + "items": { + "$ref": "#/definitions/customDomainType" + }, "defaultValue": [], "metadata": { "description": "Optional. Array of custom domain objects." @@ -271,6 +942,9 @@ }, "originGroups": { "type": "array", + "items": { + "$ref": "#/definitions/originGroupType" + }, "defaultValue": [], "metadata": { "description": "Conditional. Array of origin group objects. Required if the afdEndpoints is specified." @@ -278,6 +952,9 @@ }, "ruleSets": { "type": "array", + "items": { + "$ref": "#/definitions/ruleSetType" + }, "defaultValue": [], "metadata": { "description": "Optional. Array of rule set objects." @@ -285,6 +962,9 @@ }, "afdEndpoints": { "type": "array", + "items": { + "$ref": "#/definitions/afdEndpointType" + }, "defaultValue": [], "metadata": { "description": "Optional. Array of AFD endpoint objects." @@ -454,8 +1134,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3460565146034921053" + "version": "0.31.34.60546", + "templateHash": "5709530270456479127" }, "name": "CDN Profiles Endpoints", "description": "This module deploys a CDN Profile Endpoint.", @@ -508,10 +1188,7 @@ "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", "location": "[parameters('location')]", "properties": "[parameters('properties')]", - "tags": "[parameters('tags')]", - "dependsOn": [ - "profile" - ] + "tags": "[parameters('tags')]" }, "endpoint_origins": { "copy": { @@ -574,8 +1251,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4151069688274070352" + "version": "0.31.34.60546", + "templateHash": "12416203553821456162" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin.", @@ -682,19 +1359,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/endpoints", "apiVersion": "2021-06-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('endpointName'))]" }, "origin": { "type": "Microsoft.Cdn/profiles/endpoints/origins", "apiVersion": "2021-06-01", "name": "[format('{0}/{1}/{2}', parameters('profileName'), parameters('endpointName'), parameters('name'))]", - "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]", - "dependsOn": [ - "endpoint" - ] + "properties": "[union(createObject('hostName', parameters('hostName'), 'httpPort', parameters('httpPort'), 'enabled', parameters('enabled'), 'httpsPort', parameters('httpsPort')), if(or(greater(parameters('priority'), 0), greater(parameters('weight'), 0)), createObject('priority', parameters('priority'), 'weight', parameters('weight')), createObject()), if(and(not(empty(parameters('privateLinkAlias'))), not(empty(parameters('privateLinkLocation')))), createObject('privateLinkAlias', parameters('privateLinkAlias'), 'privateLinkLocation', parameters('privateLinkLocation')), createObject()), if(not(empty(parameters('privateLinkResourceId'))), createObject('privateLinkResourceId', parameters('privateLinkResourceId')), createObject()), if(not(empty(parameters('originHostHeader'))), createObject('originHostHeader', parameters('originHostHeader')), createObject()))]" } }, "outputs": { @@ -730,8 +1401,7 @@ } }, "dependsOn": [ - "endpoint", - "profile" + "endpoint" ] } }, @@ -827,8 +1497,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9127977884501208410" + "version": "0.31.34.60546", + "templateHash": "135211401759640973" }, "name": "CDN Profiles Secret", "description": "This module deploys a CDN Profile Secret.", @@ -972,17 +1642,90 @@ }, "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.30.23.60470", - "templateHash": "16955838730426729961" + "version": "0.31.34.60546", + "templateHash": "10387694873442665915" }, "name": "CDN Profiles Custom Domains", "description": "This module deploys a CDN Profile Custom Domains.", "owner": "Azure/module-maintainers" }, + "definitions": { + "customDomainType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the custom domain." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The host name of the custom domain." + } + }, + "certificateType": { + "type": "string", + "allowedValues": [ + "AzureFirstPartyManagedCertificate", + "CustomerCertificate", + "ManagedCertificate" + ], + "metadata": { + "description": "Required. The type of the certificate." + } + }, + "azureDnsZoneResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Azure DNS zone." + } + }, + "preValidatedCustomDomainResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the pre-validated custom domain." + } + }, + "secretName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the secret." + } + }, + "minimumTlsVersion": { + "type": "string", + "allowedValues": [ + "TLS10", + "TLS12" + ], + "nullable": true, + "metadata": { + "description": "Optional. The minimum TLS version." + } + }, + "extendedProperties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Extended properties." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -1026,6 +1769,7 @@ "certificateType": { "type": "string", "allowedValues": [ + "AzureFirstPartyManagedCertificate", "CustomerCertificate", "ManagedCertificate" ], @@ -1052,8 +1796,21 @@ } } }, - "resources": [ - { + "resources": { + "profile::secrect": { + "condition": "[not(empty(parameters('secretName')))]", + "existing": true, + "type": "Microsoft.Cdn/profiles/secrets", + "apiVersion": "2023-05-01", + "name": "[format('{0}/{1}', parameters('profileName'), parameters('secretName'))]" + }, + "profile": { + "existing": true, + "type": "Microsoft.Cdn/profiles", + "apiVersion": "2023-05-01", + "name": "[parameters('profileName')]" + }, + "customDomain": { "type": "Microsoft.Cdn/profiles/customDomains", "apiVersion": "2023-05-01", "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", @@ -1069,7 +1826,7 @@ } } } - ], + }, "outputs": { "name": { "type": "string", @@ -1143,13 +1900,223 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16948516107556143812" + "version": "0.31.34.60546", + "templateHash": "15886213526918072525" }, "name": "CDN Profiles Origin Group", "description": "This module deploys a CDN Profile Origin Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "originGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "loadBalancingSettings": { + "$ref": "#/definitions/loadBalancingSettingsType", + "metadata": { + "description": "Required. Load balancing settings for a backend pool." + } + }, + "healthProbeSettings": { + "$ref": "#/definitions/healthProbeSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. Health probe settings to the origin that is used to determine the health of the origin." + } + }, + "sessionAffinityState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to allow session affinity on this host." + } + }, + "trafficRestorationTimeToHealedOrNewEndpointsInMinutes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins." + } + }, + "origins": { + "type": "array", + "items": { + "$ref": "#/definitions/originType" + }, + "metadata": { + "description": "Required. The list of origins within the origin group." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "loadBalancingSettingsType": { + "type": "object", + "properties": { + "additionalLatencyInMilliseconds": { + "type": "int", + "metadata": { + "description": "Required. Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000." + } + }, + "sampleSize": { + "type": "int", + "metadata": { + "description": "Required. Number of samples to consider for load balancing decisions." + } + }, + "successfulSamplesRequired": { + "type": "int", + "metadata": { + "description": "Required. Number of samples within the sample window that must be successful to mark the backend as healthy." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "healthProbeSettingsType": { + "type": "object", + "properties": { + "probePath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The path relative to the origin that is used to determine the health of the origin." + } + }, + "probeProtocol": { + "type": "string", + "allowedValues": [ + "Http", + "Https", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. Protocol to use for health probe." + } + }, + "probeRequestType": { + "type": "string", + "allowedValues": [ + "GET", + "HEAD", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. The request type to probe." + } + }, + "probeIntervalInSeconds": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of seconds between health probes.Default is 240sec." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origin/main.bicep" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -1217,10 +2184,7 @@ "loadBalancingSettings": "[parameters('loadBalancingSettings')]", "sessionAffinityState": "[parameters('sessionAffinityState')]", "trafficRestorationTimeToHealedOrNewEndpointsInMinutes": "[parameters('trafficRestorationTimeToHealedOrNewEndpointsInMinutes')]" - }, - "dependsOn": [ - "profile" - ] + } }, "originGroup_origins": { "copy": { @@ -1280,13 +2244,95 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4669077701065465911" + "version": "0.31.34.60546", + "templateHash": "3615112055594041997" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", "owner": "Azure/module-maintainers" }, + "definitions": { + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -1378,10 +2424,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile": { "existing": true, @@ -1403,10 +2446,7 @@ "priority": "[parameters('priority')]", "sharedPrivateLinkResource": "[parameters('sharedPrivateLinkResource')]", "weight": "[parameters('weight')]" - }, - "dependsOn": [ - "profile::originGroup" - ] + } } }, "outputs": { @@ -1506,12 +2546,85 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11520922481694023973" + "version": "0.31.34.60546", + "templateHash": "4753233857701337613" + }, + "name": "CDN Profiles Rule Sets", + "description": "This module deploys a CDN Profile rule set.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "ruleSetType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the rule set." + } + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of rules." + } + } + }, + "metadata": { + "__bicep_export!": true + } }, - "name": "CDN Profiles Rule Sets", - "description": "This module deploys a CDN Profile rule set.", - "owner": "Azure/module-maintainers" + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "rule/main.bicep" + } + } + } }, "parameters": { "name": { @@ -1528,6 +2641,9 @@ }, "rules": { "type": "array", + "items": { + "$ref": "#/definitions/ruleType" + }, "nullable": true, "metadata": { "description": "Optinal. The rules to apply to the rule set." @@ -1544,10 +2660,7 @@ "ruleSet": { "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]" }, "ruleSet_rules": { "copy": { @@ -1592,13 +2705,60 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8818585542646204223" + "version": "0.31.34.60546", + "templateHash": "11756620080021514486" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", "owner": "Azure/module-maintainers" }, + "definitions": { + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -1655,10 +2815,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]" }, "profile": { "existing": true, @@ -1675,10 +2832,7 @@ "actions": "[parameters('actions')]", "conditions": "[parameters('conditions')]", "matchProcessingBehavior": "[parameters('matchProcessingBehavior')]" - }, - "dependsOn": [ - "profile::ruleSet" - ] + } } }, "outputs": { @@ -1780,13 +2934,237 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "792735746278824384" + "version": "0.31.34.60546", + "templateHash": "16899001110062450573" }, "name": "CDN Profiles AFD Endpoints", "description": "This module deploys a CDN Profile AFD Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "afdEndpointType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the AFD Endpoint." + } + }, + "routes": { + "type": "array", + "items": { + "$ref": "#/definitions/routeType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of routes for this AFD Endpoint." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The tags for the AFD Endpoint." + } + }, + "autoGeneratedDomainNameLabelScope": { + "type": "string", + "allowedValues": [ + "NoReuse", + "ResourceGroupReuse", + "SubscriptionReuse", + "TenantReuse" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scope of the auto-generated domain name label." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. The state of the AFD Endpoint." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_1.afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "route/main.bicep" + } + } + }, + "routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/_1.afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "route/main.bicep" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -1840,6 +3218,9 @@ }, "routes": { "type": "array", + "items": { + "$ref": "#/definitions/routeType" + }, "nullable": true, "metadata": { "description": "Optional. The list of routes for this AFD Endpoint." @@ -1862,10 +3243,7 @@ "properties": { "autoGeneratedDomainNameLabelScope": "[parameters('autoGeneratedDomainNameLabelScope')]", "enabledState": "[parameters('enabledState')]" - }, - "dependsOn": [ - "profile" - ] + } }, "afdEndpoint_routes": { "copy": { @@ -1931,13 +3309,175 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1034122698174669197" + "version": "0.31.34.60546", + "templateHash": "15873678240851060540" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route.", "owner": "Azure/module-maintainers" }, + "definitions": { + "routeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the route." + } + }, + "cacheConfiguration": { + "$ref": "#/definitions/afdRoutecacheConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object." + } + }, + "customDomainNames": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The names of the custom domains." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable use of this rule." + } + }, + "forwardingProtocol": { + "type": "string", + "allowedValues": [ + "HttpOnly", + "HttpsOnly", + "MatchRequest" + ], + "nullable": true, + "metadata": { + "description": "Optional. The protocol this rule will use when forwarding traffic to backends." + } + }, + "httpsRedirect": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to automatically redirect HTTP traffic to HTTPS traffic." + } + }, + "linkToDefaultDomain": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether this route will be linked to the default endpoint domain." + } + }, + "originGroupName": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "originPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath." + } + }, + "patternsToMatch": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The route patterns of the rule." + } + }, + "ruleSets": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. The rule sets of the rule." + } + }, + "supportedProtocols": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The supported protocols of the rule." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "afdRoutecacheConfigurationType": { + "type": "object", + "properties": { + "compressionSettings": { + "type": "object", + "properties": { + "contentTypesToCompress": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. List of content types on which compression applies. The value should be a valid MIME type." + } + }, + "iscontentTypeToCompressAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether content compression is enabled on AzureFrontDoor. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on AzureFrontDoor when requested content is smaller than 1 byte or larger than 1 MB." + } + } + }, + "metadata": { + "description": "Required. Compression settings." + } + }, + "queryParameters": { + "type": "string", + "metadata": { + "description": "Required. Query parameters to include or exclude (comma separated)." + } + }, + "queryStringCachingBehavior": { + "type": "string", + "allowedValues": [ + "IgnoreQueryString", + "IgnoreSpecifiedQueryStrings", + "IncludeSpecifiedQueryStrings", + "UseQueryString" + ], + "metadata": { + "description": "Required. Defines how Frontdoor caches requests that include query strings." + } + } + } + } + }, "parameters": { "name": { "type": "string", @@ -2063,10 +3603,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/afdEndpoints", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('afdEndpointName'))]" }, "profile::customDomains": { "copy": { @@ -2076,19 +3613,13 @@ "existing": true, "type": "Microsoft.Cdn/profiles/customDomains", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), coalesce(parameters('customDomainNames'), createArray())[copyIndex()])]" }, "profile::originGroup": { "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile::ruleSet": { "copy": { @@ -2098,10 +3629,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSets')[copyIndex()].name)]" }, "profile": { "existing": true, @@ -2141,10 +3669,7 @@ "originPath": "[parameters('originPath')]", "patternsToMatch": "[parameters('patternsToMatch')]", "supportedProtocols": "[parameters('supportedProtocols')]" - }, - "dependsOn": [ - "profile::afdEndpoint" - ] + } } }, "outputs": { @@ -2173,8 +3698,7 @@ } }, "dependsOn": [ - "afdEndpoint", - "profile" + "afdEndpoint" ] } }, @@ -2258,8 +3782,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11561080659040848436" + "version": "0.31.34.60546", + "templateHash": "3914917842985483427" }, "name": "CDN Profiles Security Policy", "description": "This module deploys a CDN Profile Security Policy.", @@ -2349,10 +3873,7 @@ }, "associations": "[parameters('associations')]" } - }, - "dependsOn": [ - "profile" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/origingroup/main.bicep b/avm/res/cdn/profile/origingroup/main.bicep index 258f75686f..f404a050eb 100644 --- a/avm/res/cdn/profile/origingroup/main.bicep +++ b/avm/res/cdn/profile/origingroup/main.bicep @@ -73,3 +73,56 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = profile.location + +// =============== // +// Definitions // +// =============== // + +import { originType } from './origin/main.bicep' +@export() +type originGroupType = { + @description('Required. The name of the origin group.') + name: string + + @description('Required. Load balancing settings for a backend pool.') + loadBalancingSettings: loadBalancingSettingsType + + @description('Optional. Health probe settings to the origin that is used to determine the health of the origin.') + healthProbeSettings: healthProbeSettingsType? + + @description('Optional. Whether to allow session affinity on this host.') + sessionAffinityState: 'Enabled' | 'Disabled' | null + + @description('Optional. Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins.') + trafficRestorationTimeToHealedOrNewEndpointsInMinutes: int? + + @description('Required. The list of origins within the origin group.') + origins: originType[] +} + +@export() +type loadBalancingSettingsType = { + @description('Required. Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000.') + additionalLatencyInMilliseconds: int + + @description('Required. Number of samples to consider for load balancing decisions.') + sampleSize: int + + @description('Required. Number of samples within the sample window that must be successful to mark the backend as healthy.') + successfulSamplesRequired: int +} + +@export() +type healthProbeSettingsType = { + @description('Optional. The path relative to the origin that is used to determine the health of the origin.') + probePath: string? + + @description('Optional. Protocol to use for health probe.') + probeProtocol: 'Http' | 'Https' | 'NotSet' | null + + @description('Optional. The request type to probe.') + probeRequestType: 'GET' | 'HEAD' | 'NotSet' | null + + @description('Optional. The number of seconds between health probes.Default is 240sec.') + probeIntervalInSeconds: int? +} diff --git a/avm/res/cdn/profile/origingroup/main.json b/avm/res/cdn/profile/origingroup/main.json index af9a692a27..7dd74caff6 100644 --- a/avm/res/cdn/profile/origingroup/main.json +++ b/avm/res/cdn/profile/origingroup/main.json @@ -5,13 +5,223 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16948516107556143812" + "version": "0.31.34.60546", + "templateHash": "15886213526918072525" }, "name": "CDN Profiles Origin Group", "description": "This module deploys a CDN Profile Origin Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "originGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origin group." + } + }, + "loadBalancingSettings": { + "$ref": "#/definitions/loadBalancingSettingsType", + "metadata": { + "description": "Required. Load balancing settings for a backend pool." + } + }, + "healthProbeSettings": { + "$ref": "#/definitions/healthProbeSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. Health probe settings to the origin that is used to determine the health of the origin." + } + }, + "sessionAffinityState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to allow session affinity on this host." + } + }, + "trafficRestorationTimeToHealedOrNewEndpointsInMinutes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Time in minutes to shift the traffic to the endpoint gradually when an unhealthy endpoint comes healthy or a new endpoint is added. Default is 10 mins." + } + }, + "origins": { + "type": "array", + "items": { + "$ref": "#/definitions/originType" + }, + "metadata": { + "description": "Required. The list of origins within the origin group." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "loadBalancingSettingsType": { + "type": "object", + "properties": { + "additionalLatencyInMilliseconds": { + "type": "int", + "metadata": { + "description": "Required. Additional latency in milliseconds for probes to the backend. Must be between 0 and 1000." + } + }, + "sampleSize": { + "type": "int", + "metadata": { + "description": "Required. Number of samples to consider for load balancing decisions." + } + }, + "successfulSamplesRequired": { + "type": "int", + "metadata": { + "description": "Required. Number of samples within the sample window that must be successful to mark the backend as healthy." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "healthProbeSettingsType": { + "type": "object", + "properties": { + "probePath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The path relative to the origin that is used to determine the health of the origin." + } + }, + "probeProtocol": { + "type": "string", + "allowedValues": [ + "Http", + "Https", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. Protocol to use for health probe." + } + }, + "probeRequestType": { + "type": "string", + "allowedValues": [ + "GET", + "HEAD", + "NotSet" + ], + "nullable": true, + "metadata": { + "description": "Optional. The request type to probe." + } + }, + "probeIntervalInSeconds": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of seconds between health probes.Default is 240sec." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "origin/main.bicep" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -79,10 +289,7 @@ "loadBalancingSettings": "[parameters('loadBalancingSettings')]", "sessionAffinityState": "[parameters('sessionAffinityState')]", "trafficRestorationTimeToHealedOrNewEndpointsInMinutes": "[parameters('trafficRestorationTimeToHealedOrNewEndpointsInMinutes')]" - }, - "dependsOn": [ - "profile" - ] + } }, "originGroup_origins": { "copy": { @@ -142,13 +349,95 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4669077701065465911" + "version": "0.31.34.60546", + "templateHash": "3615112055594041997" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", "owner": "Azure/module-maintainers" }, + "definitions": { + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -240,10 +529,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile": { "existing": true, @@ -265,10 +551,7 @@ "priority": "[parameters('priority')]", "sharedPrivateLinkResource": "[parameters('sharedPrivateLinkResource')]", "weight": "[parameters('weight')]" - }, - "dependsOn": [ - "profile::originGroup" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/origingroup/origin/main.bicep b/avm/res/cdn/profile/origingroup/origin/main.bicep index ccf7a62aa1..166e2b43ac 100644 --- a/avm/res/cdn/profile/origingroup/origin/main.bicep +++ b/avm/res/cdn/profile/origingroup/origin/main.bicep @@ -74,3 +74,40 @@ output resourceId string = origin.id @description('The name of the resource group the origin was created in.') output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // + +@export() +type originType = { + @description('Required. The name of the origion.') + name: string + + @description('Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint.') + hostName: string + + @description('Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool.') + enabledState: 'Enabled' | 'Disabled' | null + + @description('Optional. Whether to enable certificate name check at origin level.') + enforceCertificateNameCheck: bool? + + @description('Optional. The value of the HTTP port. Must be between 1 and 65535.') + httpPort: int? + + @description('Optional. The value of the HTTPS port. Must be between 1 and 65535.') + httpsPort: int? + + @description('Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint.') + originHostHeader: string? + + @description('Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5.') + priority: int? + + @description('Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000.') + weight: int? + + @description('Optional. The properties of the private link resource for private origin.') + sharedPrivateLinkResource: object? +} diff --git a/avm/res/cdn/profile/origingroup/origin/main.json b/avm/res/cdn/profile/origingroup/origin/main.json index 8ee5bf04df..6488e9907f 100644 --- a/avm/res/cdn/profile/origingroup/origin/main.json +++ b/avm/res/cdn/profile/origingroup/origin/main.json @@ -5,13 +5,95 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4669077701065465911" + "version": "0.31.34.60546", + "templateHash": "3615112055594041997" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin.", "owner": "Azure/module-maintainers" }, + "definitions": { + "originType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the origion." + } + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Required. The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.This should be unique across all origins in an endpoint." + } + }, + "enabledState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool." + } + }, + "enforceCertificateNameCheck": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable certificate name check at origin level." + } + }, + "httpPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTP port. Must be between 1 and 65535." + } + }, + "httpsPort": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The value of the HTTPS port. Must be between 1 and 65535." + } + }, + "originHostHeader": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure Front Door origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default. This overrides the host header defined at Endpoint." + } + }, + "priority": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Priority of origin in given origin group for load balancing. Higher priorities will not be used for load balancing if any lower priority origin is healthy.Must be between 1 and 5." + } + }, + "weight": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Weight of the origin in given origin group for load balancing. Must be between 1 and 1000." + } + }, + "sharedPrivateLinkResource": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the private link resource for private origin." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -103,10 +185,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/originGroups", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('originGroupName'))]" }, "profile": { "existing": true, @@ -128,10 +207,7 @@ "priority": "[parameters('priority')]", "sharedPrivateLinkResource": "[parameters('sharedPrivateLinkResource')]", "weight": "[parameters('weight')]" - }, - "dependsOn": [ - "profile::originGroup" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/ruleset/main.bicep b/avm/res/cdn/profile/ruleset/main.bicep index 9d96381236..dbaf29f99c 100644 --- a/avm/res/cdn/profile/ruleset/main.bicep +++ b/avm/res/cdn/profile/ruleset/main.bicep @@ -9,7 +9,7 @@ param name string param profileName string @description('Optinal. The rules to apply to the rule set.') -param rules array? +param rules ruleType[]? resource profile 'Microsoft.Cdn/profiles@2023-05-01' existing = { name: profileName @@ -35,6 +35,17 @@ module ruleSet_rules 'rule/main.bicep' = [ } ] +import { ruleType } from './rule/main.bicep' + +@export() +type ruleSetType = { + @description('Required. Name of the rule set.') + name: string + + @description('Optional. Array of rules.') + rules: ruleType[]? +} + @description('The name of the rule set.') output name string = ruleSet.name diff --git a/avm/res/cdn/profile/ruleset/main.json b/avm/res/cdn/profile/ruleset/main.json index 2d040690b5..cffc63c7ee 100644 --- a/avm/res/cdn/profile/ruleset/main.json +++ b/avm/res/cdn/profile/ruleset/main.json @@ -5,13 +5,86 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11520922481694023973" + "version": "0.31.34.60546", + "templateHash": "4753233857701337613" }, "name": "CDN Profiles Rule Sets", "description": "This module deploys a CDN Profile rule set.", "owner": "Azure/module-maintainers" }, + "definitions": { + "ruleSetType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the rule set." + } + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of rules." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "rule/main.bicep" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -27,6 +100,9 @@ }, "rules": { "type": "array", + "items": { + "$ref": "#/definitions/ruleType" + }, "nullable": true, "metadata": { "description": "Optinal. The rules to apply to the rule set." @@ -43,10 +119,7 @@ "ruleSet": { "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('name'))]" }, "ruleSet_rules": { "copy": { @@ -91,13 +164,60 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8818585542646204223" + "version": "0.31.34.60546", + "templateHash": "11756620080021514486" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", "owner": "Azure/module-maintainers" }, + "definitions": { + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -154,10 +274,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]" }, "profile": { "existing": true, @@ -174,10 +291,7 @@ "actions": "[parameters('actions')]", "conditions": "[parameters('conditions')]", "matchProcessingBehavior": "[parameters('matchProcessingBehavior')]" - }, - "dependsOn": [ - "profile::ruleSet" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/ruleset/rule/main.bicep b/avm/res/cdn/profile/ruleset/rule/main.bicep index 7851860264..2f172c93ce 100644 --- a/avm/res/cdn/profile/ruleset/rule/main.bicep +++ b/avm/res/cdn/profile/ruleset/rule/main.bicep @@ -54,3 +54,21 @@ output resourceId string = rule.id @description('The name of the resource group the custom domain was created in.') output resourceGroupName string = resourceGroup().name + +@export() +type ruleType = { + @description('Required. The name of the rule.') + name: string + + @description('Required. The order in which the rules are applied for the endpoint.') + order: int + + @description('Optional. A list of actions that are executed when all the conditions of a rule are satisfied..') + actions: array? + + @description('Optional. A list of conditions that must be matched for the actions to be executed.') + conditions: array? + + @description('Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue.') + matchProcessingBehavior: 'Continue' | 'Stop' | null +} diff --git a/avm/res/cdn/profile/ruleset/rule/main.json b/avm/res/cdn/profile/ruleset/rule/main.json index 98e0f0fef8..465bed9ee5 100644 --- a/avm/res/cdn/profile/ruleset/rule/main.json +++ b/avm/res/cdn/profile/ruleset/rule/main.json @@ -5,13 +5,60 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8818585542646204223" + "version": "0.31.34.60546", + "templateHash": "11756620080021514486" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule.", "owner": "Azure/module-maintainers" }, + "definitions": { + "ruleType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the rule." + } + }, + "order": { + "type": "int", + "metadata": { + "description": "Required. The order in which the rules are applied for the endpoint." + } + }, + "actions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of actions that are executed when all the conditions of a rule are satisfied.." + } + }, + "conditions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of conditions that must be matched for the actions to be executed." + } + }, + "matchProcessingBehavior": { + "type": "string", + "allowedValues": [ + "Continue", + "Stop" + ], + "nullable": true, + "metadata": { + "description": "Optional. If this rule is a match should the rules engine continue running the remaining rules or stop. If not present, defaults to Continue." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", @@ -68,10 +115,7 @@ "existing": true, "type": "Microsoft.Cdn/profiles/ruleSets", "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]", - "dependsOn": [ - "profile" - ] + "name": "[format('{0}/{1}', parameters('profileName'), parameters('ruleSetName'))]" }, "profile": { "existing": true, @@ -88,10 +132,7 @@ "actions": "[parameters('actions')]", "conditions": "[parameters('conditions')]", "matchProcessingBehavior": "[parameters('matchProcessingBehavior')]" - }, - "dependsOn": [ - "profile::ruleSet" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/secret/main.json b/avm/res/cdn/profile/secret/main.json index 77dc6a600b..4c2f0abd3c 100644 --- a/avm/res/cdn/profile/secret/main.json +++ b/avm/res/cdn/profile/secret/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9127977884501208410" + "version": "0.31.34.60546", + "templateHash": "135211401759640973" }, "name": "CDN Profiles Secret", "description": "This module deploys a CDN Profile Secret.", diff --git a/avm/res/cdn/profile/securityPolicies/main.json b/avm/res/cdn/profile/securityPolicies/main.json index be06e14c99..e94a644cf3 100644 --- a/avm/res/cdn/profile/securityPolicies/main.json +++ b/avm/res/cdn/profile/securityPolicies/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11561080659040848436" + "version": "0.31.34.60546", + "templateHash": "3914917842985483427" }, "name": "CDN Profiles Security Policy", "description": "This module deploys a CDN Profile Security Policy.", @@ -96,10 +96,7 @@ }, "associations": "[parameters('associations')]" } - }, - "dependsOn": [ - "profile" - ] + } } }, "outputs": { diff --git a/avm/res/cdn/profile/version.json b/avm/res/cdn/profile/version.json index 35040975ae..0f81d22abc 100644 --- a/avm/res/cdn/profile/version.json +++ b/avm/res/cdn/profile/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", + "version": "0.8", "pathFilters": [ "./main.json" ] -} +} \ No newline at end of file diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 16a4e92bf0..3fd239938e 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -19,6 +19,7 @@ This module deploys a Virtual Machine with one or multiple NICs and optionally o | `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.Automanage/configurationProfileAssignments` | [2022-05-04](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Compute/disks` | [2024-03-02](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2024-03-02/disks) | | `Microsoft.Compute/virtualMachines` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2024-07-01/virtualMachines) | | `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | | `Microsoft.DevTestLab/schedules` | [2018-09-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DevTestLab/2018-09-15/schedules) | @@ -47,8 +48,9 @@ The following section provides usage examples for the module, which were used to - [Using a host pool to register the VM](#example-7-using-a-host-pool-to-register-the-vm) - [Using large parameter set for Windows](#example-8-using-large-parameter-set-for-windows) - [Deploy a VM with nVidia graphic card](#example-9-deploy-a-vm-with-nvidia-graphic-card) -- [Using disk encryption set for the VM.](#example-10-using-disk-encryption-set-for-the-vm) -- [Adding the VM to a VMSS.](#example-11-adding-the-vm-to-a-vmss) +- [Deploying Windows VM with premium SSDv2 data disk](#example-10-deploying-windows-vm-with-premium-ssdv2-data-disk) +- [Using disk encryption set for the VM.](#example-11-using-disk-encryption-set-for-the-vm) +- [Adding the VM to a VMSS.](#example-12-adding-the-vm-to-a-vmss) ### Example 1: _Using automanage for the VM._ @@ -4152,7 +4154,209 @@ param location = ''

    -### Example 10: _Using disk encryption set for the VM._ +### Example 10: _Deploying Windows VM with premium SSDv2 data disk_ + +This instance deploys the module with premium SSDv2 data disk. + + +

    + +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: 'virtualMachineDeployment' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + name: 'cvmwinssdv2' + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + caching: 'ReadWrite' + diskSizeGB: 128 + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_D2s_v3' + zone: 1 + // Non-required parameters + adminPassword: '' + dataDisks: [ + { + caching: 'None' + diskIOPSReadWrite: 3000 + diskMBpsReadWrite: 125 + diskSizeGB: 1024 + managedDisk: { + storageAccountType: 'PremiumV2_LRS' + } + } + ] + location: '' + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } + }, + "name": { + "value": "cvmwinssdv2" + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "caching": "ReadWrite", + "diskSizeGB": 128, + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_D2s_v3" + }, + "zone": { + "value": 1 + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "dataDisks": { + "value": [ + { + "caching": "None", + "diskIOPSReadWrite": 3000, + "diskMBpsReadWrite": 125, + "diskSizeGB": 1024, + "managedDisk": { + "storageAccountType": "PremiumV2_LRS" + } + } + ] + }, + "location": { + "value": "" + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/compute/virtual-machine:' + +// Required parameters +param adminUsername = 'localAdminUser' +param imageReference = { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' +} +param name = 'cvmwinssdv2' +param nicConfigurations = [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } +] +param osDisk = { + caching: 'ReadWrite' + diskSizeGB: 128 + managedDisk: { + storageAccountType: 'Premium_LRS' + } +} +param osType = 'Windows' +param vmSize = 'Standard_D2s_v3' +param zone = 1 +// Non-required parameters +param adminPassword = '' +param dataDisks = [ + { + caching: 'None' + diskIOPSReadWrite: 3000 + diskMBpsReadWrite: 125 + diskSizeGB: 1024 + managedDisk: { + storageAccountType: 'PremiumV2_LRS' + } + } +] +param location = '' +``` + +
    +

    + +### Example 11: _Using disk encryption set for the VM._ This instance deploys the module with disk enryption set. @@ -4360,7 +4564,7 @@ param location = ''

    -### Example 11: _Adding the VM to a VMSS._ +### Example 12: _Adding the VM to a VMSS._ This instance deploys the module with the minimum set of required parameters and adds it to a VMSS. @@ -4613,6 +4817,7 @@ param virtualMachineScaleSetResourceId = '' | [`tags`](#parameter-tags) | object | Tags of the resource. | | [`timeZone`](#parameter-timezone) | string | Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. | | [`ultraSSDEnabled`](#parameter-ultrassdenabled) | bool | The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. | +| [`userData`](#parameter-userdata) | string | UserData for the VM, which must be base-64 encoded. Customer should not pass any secrets in here. | | [`virtualMachineScaleSetResourceId`](#parameter-virtualmachinescalesetresourceid) | string | Resource ID of a virtual machine scale set, where the VM should be added. | | [`vTpmEnabled`](#parameter-vtpmenabled) | bool | Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | | [`winRM`](#parameter-winrm) | array | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | @@ -4958,6 +5163,8 @@ Specifies the data disks. For security reasons, it is recommended to specify Dis | [`caching`](#parameter-datadiskscaching) | string | Specifies the caching requirements. | | [`createOption`](#parameter-datadiskscreateoption) | string | Specifies how the virtual machine should be created. | | [`deleteOption`](#parameter-datadisksdeleteoption) | string | Specifies whether data disk should be deleted or detached upon VM deletion. | +| [`diskIOPSReadWrite`](#parameter-datadisksdiskiopsreadwrite) | int | The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes. | +| [`diskMBpsReadWrite`](#parameter-datadisksdiskmbpsreadwrite) | int | The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10. | | [`lun`](#parameter-datadiskslun) | int | Specifies the logical unit number of the data disk. | | [`name`](#parameter-datadisksname) | string | The disk name. | @@ -4986,6 +5193,7 @@ The managed disk parameters. | Parameter | Type | Description | | :-- | :-- | :-- | | [`diskEncryptionSetResourceId`](#parameter-datadisksmanageddiskdiskencryptionsetresourceid) | string | Specifies the customer managed disk encryption set resource id for the managed disk. | +| [`id`](#parameter-datadisksmanageddiskid) | string | Specifies the customer managed disk id for the managed disk. | ### Parameter: `dataDisks.managedDisk.storageAccountType` @@ -5013,6 +5221,13 @@ Specifies the customer managed disk encryption set resource id for the managed d - Required: No - Type: string +### Parameter: `dataDisks.managedDisk.id` + +Specifies the customer managed disk id for the managed disk. + +- Required: No +- Type: string + ### Parameter: `dataDisks.caching` Specifies the caching requirements. @@ -5057,6 +5272,20 @@ Specifies whether data disk should be deleted or detached upon VM deletion. ] ``` +### Parameter: `dataDisks.diskIOPSReadWrite` + +The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes. + +- Required: No +- Type: int + +### Parameter: `dataDisks.diskMBpsReadWrite` + +The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10. + +- Required: No +- Type: int + ### Parameter: `dataDisks.lun` Specifies the logical unit number of the data disk. @@ -5695,6 +5924,14 @@ The flag that enables or disables a capability to have one or more managed data - Type: bool - Default: `False` +### Parameter: `userData` + +UserData for the VM, which must be base-64 encoded. Customer should not pass any secrets in here. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `virtualMachineScaleSetResourceId` Resource ID of a virtual machine scale set, where the VM should be added. diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index 702433c26d..e42039bdd8 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "10657605324993327332" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -121,10 +121,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index d9f22a1b23..27c7365be7 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -51,6 +51,9 @@ param adminUsername string @secure() param adminPassword string = '' +@description('Optional. UserData for the VM, which must be base-64 encoded. Customer should not pass any secrets in here.') +param userData string = '' + @description('Optional. Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format.') param customData string = '' @@ -497,6 +500,25 @@ module vm_nic 'modules/nic-configuration.bicep' = [ } ] +resource managedDataDisks 'Microsoft.Compute/disks@2024-03-02' = [ + for (dataDisk, index) in dataDisks ?? []: { + location: location + name: dataDisk.?name ?? '${name}-disk-data-${padLeft((index + 1), 2, '0')}' + sku: { + name: dataDisk.managedDisk.storageAccountType + } + properties: { + diskSizeGB: dataDisk.diskSizeGB + creationData: { + createOption: dataDisk.?createoption ?? 'Empty' + } + diskIOPSReadWrite: dataDisk.?diskIOPSReadWrite + diskMBpsReadWrite: dataDisk.?diskMBpsReadWrite + } + zones: zone != 0 ? array(string(zone)) : null + } +] + resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = { name: name location: location @@ -538,11 +560,12 @@ resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = { lun: dataDisk.?lun ?? index name: dataDisk.?name ?? '${name}-disk-data-${padLeft((index + 1), 2, '0')}' diskSizeGB: dataDisk.diskSizeGB - createOption: dataDisk.?createoption ?? 'Empty' + createOption: (managedDataDisks[index].?id != null) ? 'Attach' : dataDisk.?createoption ?? 'Empty' deleteOption: dataDisk.?deleteOption ?? 'Delete' caching: dataDisk.?caching ?? 'ReadOnly' managedDisk: { storageAccountType: dataDisk.managedDisk.storageAccountType + id: managedDataDisks[index].?id diskEncryptionSet: { id: dataDisk.managedDisk.?diskEncryptionSetResourceId } @@ -620,6 +643,7 @@ resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = { } : null licenseType: !empty(licenseType) ? licenseType : null + userData: !empty(userData) ? base64(userData) : null } dependsOn: [ vm_nic @@ -1107,6 +1131,12 @@ type dataDisksType = { @description('Optional. Specifies the caching requirements.') caching: 'None' | 'ReadOnly' | 'ReadWrite'? + @description('Optional. The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes.') + diskIOPSReadWrite: int? + + @description('Optional. The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10.') + diskMBpsReadWrite: int? + @description('Required. The managed disk parameters.') managedDisk: { @description('Required. Specifies the storage account type for the managed disk.') @@ -1121,5 +1151,8 @@ type dataDisksType = { @description('Optional. Specifies the customer managed disk encryption set resource id for the managed disk.') diskEncryptionSetResourceId: string? + + @description('Optional. Specifies the customer managed disk id for the managed disk.') + id: string? } }[]? diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index de1432dd89..ee412188a1 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1443306495474212036" + "version": "0.31.34.60546", + "templateHash": "8773273774920281983" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -279,6 +279,20 @@ "description": "Optional. Specifies the caching requirements." } }, + "diskIOPSReadWrite": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of IOPS allowed for this disk; only settable for UltraSSD disks. One operation can transfer between 4k and 256k bytes." + } + }, + "diskMBpsReadWrite": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The bandwidth allowed for this disk; only settable for UltraSSD disks. MBps means millions of bytes per second - MB here uses the ISO notation, of powers of 10." + } + }, "managedDisk": { "type": "object", "properties": { @@ -303,6 +317,13 @@ "metadata": { "description": "Optional. Specifies the customer managed disk encryption set resource id for the managed disk." } + }, + "id": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the customer managed disk id for the managed disk." + } } }, "metadata": { @@ -412,6 +433,13 @@ "description": "Optional. When specifying a Windows Virtual Machine, this value should be passed." } }, + "userData": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. UserData for the VM, which must be base-64 encoded. Customer should not pass any secrets in here." + } + }, "customData": { "type": "string", "defaultValue": "", @@ -973,6 +1001,28 @@ } } }, + "managedDataDisks": { + "copy": { + "name": "managedDataDisks", + "count": "[length(coalesce(parameters('dataDisks'), createArray()))]" + }, + "type": "Microsoft.Compute/disks", + "apiVersion": "2024-03-02", + "name": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex()], 'name'), format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex(), 1), 2, '0')))]", + "location": "[parameters('location')]", + "sku": { + "name": "[coalesce(parameters('dataDisks'), createArray())[copyIndex()].managedDisk.storageAccountType]" + }, + "properties": { + "diskSizeGB": "[coalesce(parameters('dataDisks'), createArray())[copyIndex()].diskSizeGB]", + "creationData": { + "createOption": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex()], 'createoption'), 'Empty')]" + }, + "diskIOPSReadWrite": "[tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex()], 'diskIOPSReadWrite')]", + "diskMBpsReadWrite": "[tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex()], 'diskMBpsReadWrite')]" + }, + "zones": "[if(not(equals(parameters('zone'), 0)), array(string(parameters('zone'))), null())]" + }, "vm": { "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2024-07-01", @@ -1000,11 +1050,12 @@ "lun": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'lun'), copyIndex('dataDisks'))]", "name": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'name'), format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0')))]", "diskSizeGB": "[coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')].diskSizeGB]", - "createOption": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'createoption'), 'Empty')]", + "createOption": "[if(not(equals(resourceId('Microsoft.Compute/disks', coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'name'), format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0')))), null())), 'Attach', coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'createoption'), 'Empty'))]", "deleteOption": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'deleteOption'), 'Delete')]", "caching": "[coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'caching'), 'ReadOnly')]", "managedDisk": { "storageAccountType": "[coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')].managedDisk.storageAccountType]", + "id": "[resourceId('Microsoft.Compute/disks', coalesce(tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')], 'name'), format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0'))))]", "diskEncryptionSet": { "id": "[tryGet(coalesce(parameters('dataDisks'), createArray())[copyIndex('dataDisks')].managedDisk, 'diskEncryptionSetResourceId')]" } @@ -1069,9 +1120,11 @@ "evictionPolicy": "[if(parameters('enableEvictionPolicy'), 'Deallocate', null())]", "billingProfile": "[if(and(not(empty(parameters('priority'))), not(empty(parameters('maxPriceForLowPriorityVm')))), createObject('maxPrice', json(parameters('maxPriceForLowPriorityVm'))), null())]", "host": "[if(not(empty(parameters('dedicatedHostId'))), createObject('id', parameters('dedicatedHostId')), null())]", - "licenseType": "[if(not(empty(parameters('licenseType'))), parameters('licenseType'), null())]" + "licenseType": "[if(not(empty(parameters('licenseType'))), parameters('licenseType'), null())]", + "userData": "[if(not(empty(parameters('userData'))), base64(parameters('userData')), null())]" }, "dependsOn": [ + "managedDataDisks", "vm_nic" ] }, @@ -1251,8 +1304,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "191716886366421622" + "version": "0.31.34.60546", + "templateHash": "4400762038950491974" } }, "definitions": { @@ -2855,8 +2908,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2971,10 +3024,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -3070,8 +3120,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3186,10 +3236,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -3281,8 +3328,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3397,10 +3444,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -3487,8 +3531,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3603,10 +3647,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -3698,8 +3739,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3814,10 +3855,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -3904,8 +3942,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4020,10 +4058,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -4118,8 +4153,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4234,10 +4269,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -4336,8 +4368,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4452,10 +4484,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -4548,8 +4577,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4664,10 +4693,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -4756,8 +4782,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4872,10 +4898,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -4973,8 +4996,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -5089,10 +5112,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -5186,8 +5206,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "1742015474710386242" + "version": "0.31.34.60546", + "templateHash": "1194243367873711347" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -5302,10 +5322,7 @@ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] + } } }, "outputs": { @@ -5385,8 +5402,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.3.12046", - "templateHash": "18427642917647797213" + "version": "0.31.34.60546", + "templateHash": "7575343013066166436" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/dependencies.bicep new file mode 100644 index 0000000000..68972ec7ec --- /dev/null +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/dependencies.bicep @@ -0,0 +1,30 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/main.test.bicep new file mode 100644 index 0000000000..d2e547f0cc --- /dev/null +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.SSDv2/main.test.bicep @@ -0,0 +1,101 @@ +targetScope = 'subscription' + +metadata name = 'Deploying Windows VM with premium SSDv2 data disk' +metadata description = 'This instance deploys the module with premium SSDv2 data disk.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${serviceShort}-rg' + +// Capacity constraints for VM type +#disable-next-line no-hardcoded-location +var enforcedLocation = 'uksouth' + +@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 = 'cvmwinssdv2' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@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: enforcedLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, enforcedLocation)}-nestedDependencies' + params: { + location: enforcedLocation + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}' + params: { + location: enforcedLocation + name: '${namePrefix}${serviceShort}' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + zone: 1 + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: 128 + caching: 'ReadWrite' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + dataDisks: [ + { + diskSizeGB: 1024 + caching: 'None' + managedDisk: { + storageAccountType: 'PremiumV2_LRS' + } + diskIOPSReadWrite: 3000 + diskMBpsReadWrite: 125 + } + ] + osType: 'Windows' + vmSize: 'Standard_D2s_v3' + adminPassword: password + } + } +] diff --git a/avm/res/compute/virtual-machine/version.json b/avm/res/compute/virtual-machine/version.json index 9a9a06e897..a830c3d961 100644 --- a/avm/res/compute/virtual-machine/version.json +++ b/avm/res/compute/virtual-machine/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.8", + "version": "0.10", "pathFilters": [ "./main.json" ] diff --git a/avm/res/container-service/managed-cluster/README.md b/avm/res/container-service/managed-cluster/README.md index 8fc9f67ba1..8ff9e062da 100644 --- a/avm/res/container-service/managed-cluster/README.md +++ b/avm/res/container-service/managed-cluster/README.md @@ -35,9 +35,10 @@ The following section provides usage examples for the module, which were used to - [Using only defaults and use AKS Automatic mode](#example-1-using-only-defaults-and-use-aks-automatic-mode) - [Using Azure CNI Network Plugin.](#example-2-using-azure-cni-network-plugin) - [Using only defaults](#example-3-using-only-defaults) -- [Using Kubenet Network Plugin.](#example-4-using-kubenet-network-plugin) -- [Using Private Cluster.](#example-5-using-private-cluster) -- [WAF-aligned](#example-6-waf-aligned) +- [Using Istio Service Mesh add-on](#example-4-using-istio-service-mesh-add-on) +- [Using Kubenet Network Plugin.](#example-5-using-kubenet-network-plugin) +- [Using Private Cluster.](#example-6-using-private-cluster) +- [WAF-aligned](#example-7-waf-aligned) ### Example 1: _Using only defaults and use AKS Automatic mode_ @@ -1203,7 +1204,162 @@ param managedIdentities = {

    -### Example 4: _Using Kubenet Network Plugin._ +### Example 4: _Using Istio Service Mesh add-on_ + +This instance deploys the module with Istio Service Mesh add-on and plug a Certificate Authority from Key Vault. + + +

    + +via Bicep module + +```bicep +module managedCluster 'br/public:avm/res/container-service/managed-cluster:' = { + name: 'managedClusterDeployment' + params: { + // Required parameters + name: 'csist001' + primaryAgentPoolProfiles: [ + { + count: 3 + mode: 'System' + name: 'systempool' + vmSize: 'Standard_DS2_v2' + } + ] + // Non-required parameters + enableKeyvaultSecretsProvider: true + enableSecretRotation: true + istioServiceMeshCertificateAuthority: { + certChainObjectName: '' + certObjectName: '' + keyObjectName: '' + keyVaultResourceId: '' + rootCertObjectName: '' + } + istioServiceMeshEnabled: true + istioServiceMeshInternalIngressGatewayEnabled: true + istioServiceMeshRevisions: [ + 'asm-1-22' + ] + location: '' + managedIdentities: { + systemAssigned: true + } + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "csist001" + }, + "primaryAgentPoolProfiles": { + "value": [ + { + "count": 3, + "mode": "System", + "name": "systempool", + "vmSize": "Standard_DS2_v2" + } + ] + }, + // Non-required parameters + "enableKeyvaultSecretsProvider": { + "value": true + }, + "enableSecretRotation": { + "value": true + }, + "istioServiceMeshCertificateAuthority": { + "value": { + "certChainObjectName": "", + "certObjectName": "", + "keyObjectName": "", + "keyVaultResourceId": "", + "rootCertObjectName": "" + } + }, + "istioServiceMeshEnabled": { + "value": true + }, + "istioServiceMeshInternalIngressGatewayEnabled": { + "value": true + }, + "istioServiceMeshRevisions": { + "value": [ + "asm-1-22" + ] + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "systemAssigned": true + } + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/container-service/managed-cluster:' + +// Required parameters +param name = 'csist001' +param primaryAgentPoolProfiles = [ + { + count: 3 + mode: 'System' + name: 'systempool' + vmSize: 'Standard_DS2_v2' + } +] +// Non-required parameters +param enableKeyvaultSecretsProvider = true +param enableSecretRotation = true +param istioServiceMeshCertificateAuthority = { + certChainObjectName: '' + certObjectName: '' + keyObjectName: '' + keyVaultResourceId: '' + rootCertObjectName: '' +} +param istioServiceMeshEnabled = true +param istioServiceMeshInternalIngressGatewayEnabled = true +param istioServiceMeshRevisions = [ + 'asm-1-22' +] +param location = '' +param managedIdentities = { + systemAssigned: true +} +``` + +
    +

    + +### Example 5: _Using Kubenet Network Plugin._ This instance deploys the module with Kubenet network plugin . @@ -1602,7 +1758,7 @@ param tags = {

    -### Example 5: _Using Private Cluster._ +### Example 6: _Using Private Cluster._ This instance deploys the module with a private cluster instance. @@ -1912,7 +2068,7 @@ param skuTier = 'Standard'

    -### Example 6: _WAF-aligned_ +### Example 7: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Well-Architected Framework. @@ -2552,6 +2708,11 @@ param tags = { | [`identityProfile`](#parameter-identityprofile) | object | Identities associated with the cluster. | | [`imageCleanerIntervalHours`](#parameter-imagecleanerintervalhours) | int | The interval in hours Image Cleaner will run. The maximum value is three months. | | [`ingressApplicationGatewayEnabled`](#parameter-ingressapplicationgatewayenabled) | bool | Specifies whether the ingressApplicationGateway (AGIC) add-on is enabled or not. | +| [`istioServiceMeshCertificateAuthority`](#parameter-istioservicemeshcertificateauthority) | object | The Istio Certificate Authority definition. | +| [`istioServiceMeshEnabled`](#parameter-istioservicemeshenabled) | bool | Specifies whether the Istio ServiceMesh add-on is enabled or not. | +| [`istioServiceMeshExternalIngressGatewayEnabled`](#parameter-istioservicemeshexternalingressgatewayenabled) | bool | Specifies whether the External Istio Ingress Gateway is enabled or not. | +| [`istioServiceMeshInternalIngressGatewayEnabled`](#parameter-istioservicemeshinternalingressgatewayenabled) | bool | Specifies whether the Internal Istio Ingress Gateway is enabled or not. | +| [`istioServiceMeshRevisions`](#parameter-istioservicemeshrevisions) | array | The list of revisions of the Istio control plane. When an upgrade is not in progress, this holds one value. When canary upgrade is in progress, this can only hold two consecutive values. | | [`kedaAddon`](#parameter-kedaaddon) | bool | Enables Kubernetes Event-driven Autoscaling (KEDA). | | [`kubeDashboardEnabled`](#parameter-kubedashboardenabled) | bool | Specifies whether the kubeDashboard add-on is enabled or not. | | [`kubernetesVersion`](#parameter-kubernetesversion) | string | Version of Kubernetes specified when creating the managed cluster. | @@ -4173,6 +4334,89 @@ Specifies whether the ingressApplicationGateway (AGIC) add-on is enabled or not. - Type: bool - Default: `False` +### Parameter: `istioServiceMeshCertificateAuthority` + +The Istio Certificate Authority definition. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`certChainObjectName`](#parameter-istioservicemeshcertificateauthoritycertchainobjectname) | string | The Certificate chain object name in Azure Key Vault. | +| [`certObjectName`](#parameter-istioservicemeshcertificateauthoritycertobjectname) | string | The Intermediate certificate object name in Azure Key Vault. | +| [`keyObjectName`](#parameter-istioservicemeshcertificateauthoritykeyobjectname) | string | The Intermediate certificate private key object name in Azure Key Vault. | +| [`keyVaultResourceId`](#parameter-istioservicemeshcertificateauthoritykeyvaultresourceid) | string | The resource ID of a key vault to reference a Certificate Authority from. | +| [`rootCertObjectName`](#parameter-istioservicemeshcertificateauthorityrootcertobjectname) | string | Root certificate object name in Azure Key Vault. | + +### Parameter: `istioServiceMeshCertificateAuthority.certChainObjectName` + +The Certificate chain object name in Azure Key Vault. + +- Required: Yes +- Type: string + +### Parameter: `istioServiceMeshCertificateAuthority.certObjectName` + +The Intermediate certificate object name in Azure Key Vault. + +- Required: Yes +- Type: string + +### Parameter: `istioServiceMeshCertificateAuthority.keyObjectName` + +The Intermediate certificate private key object name in Azure Key Vault. + +- Required: Yes +- Type: string + +### Parameter: `istioServiceMeshCertificateAuthority.keyVaultResourceId` + +The resource ID of a key vault to reference a Certificate Authority from. + +- Required: Yes +- Type: string + +### Parameter: `istioServiceMeshCertificateAuthority.rootCertObjectName` + +Root certificate object name in Azure Key Vault. + +- Required: Yes +- Type: string + +### Parameter: `istioServiceMeshEnabled` + +Specifies whether the Istio ServiceMesh add-on is enabled or not. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `istioServiceMeshExternalIngressGatewayEnabled` + +Specifies whether the External Istio Ingress Gateway is enabled or not. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `istioServiceMeshInternalIngressGatewayEnabled` + +Specifies whether the Internal Istio Ingress Gateway is enabled or not. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `istioServiceMeshRevisions` + +The list of revisions of the Istio control plane. When an upgrade is not in progress, this holds one value. When canary upgrade is in progress, this can only hold two consecutive values. + +- Required: No +- Type: array + ### Parameter: `kedaAddon` Enables Kubernetes Event-driven Autoscaling (KEDA). @@ -4401,6 +4645,7 @@ Specifies the network policy used for building Kubernetes network. - calico or a [ 'azure' 'calico' + 'cilium' ] ``` diff --git a/avm/res/container-service/managed-cluster/agent-pool/main.json b/avm/res/container-service/managed-cluster/agent-pool/main.json index 65a21588ad..11965a3fab 100644 --- a/avm/res/container-service/managed-cluster/agent-pool/main.json +++ b/avm/res/container-service/managed-cluster/agent-pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13856766172443517827" + "version": "0.31.34.60546", + "templateHash": "13504241837980660061" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool.", @@ -355,10 +355,7 @@ "vmSize": "[parameters('vmSize')]", "vnetSubnetID": "[parameters('vnetSubnetResourceId')]", "workloadRuntime": "[parameters('workloadRuntime')]" - }, - "dependsOn": [ - "managedCluster" - ] + } } }, "outputs": { diff --git a/avm/res/container-service/managed-cluster/main.bicep b/avm/res/container-service/managed-cluster/main.bicep index 4cd9c21330..3aecff5f78 100644 --- a/avm/res/container-service/managed-cluster/main.bicep +++ b/avm/res/container-service/managed-cluster/main.bicep @@ -38,6 +38,7 @@ param networkPluginMode string? @allowed([ 'azure' 'calico' + 'cilium' ]) param networkPolicy string? @@ -405,6 +406,21 @@ param metricLabelsAllowlist string = '' @description('Optional. A comma-separated list of Kubernetes cluster metrics annotations.') param metricAnnotationsAllowList string = '' +@description('Optional. Specifies whether the Istio ServiceMesh add-on is enabled or not.') +param istioServiceMeshEnabled bool = false + +@description('Optional. The list of revisions of the Istio control plane. When an upgrade is not in progress, this holds one value. When canary upgrade is in progress, this can only hold two consecutive values.') +param istioServiceMeshRevisions array? + +@description('Optional. Specifies whether the Internal Istio Ingress Gateway is enabled or not.') +param istioServiceMeshInternalIngressGatewayEnabled bool = false + +@description('Optional. Specifies whether the External Istio Ingress Gateway is enabled or not.') +param istioServiceMeshExternalIngressGatewayEnabled bool = false + +@description('Optional. The Istio Certificate Authority definition.') +param istioServiceMeshCertificateAuthority istioServiceMeshCertificateAuthorityType + // =========== // // Variables // // =========== // @@ -705,8 +721,8 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2024-03-02-p networkProfile: { networkDataplane: networkDataplane networkPlugin: networkPlugin - networkPluginMode: networkPluginMode - networkPolicy: networkPolicy + networkPluginMode: networkDataplane == 'cilium' ? 'overlay' : networkPluginMode + networkPolicy: networkDataplane == 'cilium' ? 'cilium' : networkPolicy podCidr: podCidr serviceCidr: serviceCidr dnsServiceIP: dnsServiceIP @@ -826,6 +842,37 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2024-03-02-p } } supportPlan: supportPlan + serviceMeshProfile: istioServiceMeshEnabled + ? { + istio: { + revisions: !empty(istioServiceMeshRevisions) ? istioServiceMeshRevisions : null + components: { + ingressGateways: [ + { + enabled: istioServiceMeshInternalIngressGatewayEnabled + mode: 'Internal' + } + { + enabled: istioServiceMeshExternalIngressGatewayEnabled + mode: 'External' + } + ] + } + certificateAuthority: !empty(istioServiceMeshCertificateAuthority) + ? { + plugin: { + certChainObjectName: istioServiceMeshCertificateAuthority.?certChainObjectName + certObjectName: istioServiceMeshCertificateAuthority.?certObjectName + keyObjectName: istioServiceMeshCertificateAuthority.?keyObjectName + keyVaultId: istioServiceMeshCertificateAuthority.?keyVaultResourceId + rootCertObjectName: istioServiceMeshCertificateAuthority.?rootCertObjectName + } + } + : null + } + mode: 'Istio' + } + : null } } @@ -1291,4 +1338,21 @@ type maintenanceConfigurationType = { @description('Required. Maintenance window for the maintenance configuration.') maintenanceWindow: object -} +}? + +type istioServiceMeshCertificateAuthorityType = { + @description('Required. The resource ID of a key vault to reference a Certificate Authority from.') + keyVaultResourceId: string + + @description('Required. The Certificate chain object name in Azure Key Vault.') + certChainObjectName: string + + @description('Required. The Intermediate certificate object name in Azure Key Vault.') + certObjectName: string + + @description('Required. The Intermediate certificate private key object name in Azure Key Vault.') + keyObjectName: string + + @description('Required. Root certificate object name in Azure Key Vault.') + rootCertObjectName: string +}? diff --git a/avm/res/container-service/managed-cluster/main.json b/avm/res/container-service/managed-cluster/main.json index 314963ebd2..3f20739576 100644 --- a/avm/res/container-service/managed-cluster/main.json +++ b/avm/res/container-service/managed-cluster/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17374623663141250391" + "version": "0.31.34.60546", + "templateHash": "178765084464759811" }, "name": "Azure Kubernetes Service (AKS) Managed Clusters", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster.", @@ -705,9 +705,46 @@ } } }, + "nullable": true, "metadata": { "__bicep_export!": true } + }, + "istioServiceMeshCertificateAuthorityType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a Certificate Authority from." + } + }, + "certChainObjectName": { + "type": "string", + "metadata": { + "description": "Required. The Certificate chain object name in Azure Key Vault." + } + }, + "certObjectName": { + "type": "string", + "metadata": { + "description": "Required. The Intermediate certificate object name in Azure Key Vault." + } + }, + "keyObjectName": { + "type": "string", + "metadata": { + "description": "Required. The Intermediate certificate private key object name in Azure Key Vault." + } + }, + "rootCertObjectName": { + "type": "string", + "metadata": { + "description": "Required. Root certificate object name in Azure Key Vault." + } + } + }, + "nullable": true } }, "parameters": { @@ -775,7 +812,8 @@ "nullable": true, "allowedValues": [ "azure", - "calico" + "calico", + "cilium" ], "metadata": { "description": "Optional. Specifies the network policy used for building Kubernetes network. - calico or azure." @@ -1564,6 +1602,40 @@ "metadata": { "description": "Optional. A comma-separated list of Kubernetes cluster metrics annotations." } + }, + "istioServiceMeshEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the Istio ServiceMesh add-on is enabled or not." + } + }, + "istioServiceMeshRevisions": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of revisions of the Istio control plane. When an upgrade is not in progress, this holds one value. When canary upgrade is in progress, this can only hold two consecutive values." + } + }, + "istioServiceMeshInternalIngressGatewayEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the Internal Istio Ingress Gateway is enabled or not." + } + }, + "istioServiceMeshExternalIngressGatewayEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the External Istio Ingress Gateway is enabled or not." + } + }, + "istioServiceMeshCertificateAuthority": { + "$ref": "#/definitions/istioServiceMeshCertificateAuthorityType", + "metadata": { + "description": "Optional. The Istio Certificate Authority definition." + } } }, "variables": { @@ -1606,10 +1678,7 @@ "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" - ] + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]" }, "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", @@ -1720,8 +1789,8 @@ "networkProfile": { "networkDataplane": "[parameters('networkDataplane')]", "networkPlugin": "[parameters('networkPlugin')]", - "networkPluginMode": "[parameters('networkPluginMode')]", - "networkPolicy": "[parameters('networkPolicy')]", + "networkPluginMode": "[if(equals(parameters('networkDataplane'), 'cilium'), 'overlay', parameters('networkPluginMode'))]", + "networkPolicy": "[if(equals(parameters('networkDataplane'), 'cilium'), 'cilium', parameters('networkPolicy'))]", "podCidr": "[parameters('podCidr')]", "serviceCidr": "[parameters('serviceCidr')]", "dnsServiceIP": "[parameters('dnsServiceIP')]", @@ -1802,7 +1871,8 @@ "enabled": "[parameters('enableStorageProfileSnapshotController')]" } }, - "supportPlan": "[parameters('supportPlan')]" + "supportPlan": "[parameters('supportPlan')]", + "serviceMeshProfile": "[if(parameters('istioServiceMeshEnabled'), createObject('istio', createObject('revisions', if(not(empty(parameters('istioServiceMeshRevisions'))), parameters('istioServiceMeshRevisions'), null()), 'components', createObject('ingressGateways', createArray(createObject('enabled', parameters('istioServiceMeshInternalIngressGatewayEnabled'), 'mode', 'Internal'), createObject('enabled', parameters('istioServiceMeshExternalIngressGatewayEnabled'), 'mode', 'External'))), 'certificateAuthority', if(not(empty(parameters('istioServiceMeshCertificateAuthority'))), createObject('plugin', createObject('certChainObjectName', tryGet(parameters('istioServiceMeshCertificateAuthority'), 'certChainObjectName'), 'certObjectName', tryGet(parameters('istioServiceMeshCertificateAuthority'), 'certObjectName'), 'keyObjectName', tryGet(parameters('istioServiceMeshCertificateAuthority'), 'keyObjectName'), 'keyVaultId', tryGet(parameters('istioServiceMeshCertificateAuthority'), 'keyVaultResourceId'), 'rootCertObjectName', tryGet(parameters('istioServiceMeshCertificateAuthority'), 'rootCertObjectName'))), null())), 'mode', 'Istio'), null())]" } }, "managedCluster_lock": { @@ -1935,8 +2005,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14041521425406296021" + "version": "0.31.34.60546", + "templateHash": "3191846535289543816" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations.", @@ -2132,8 +2202,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "9210340338669366768" + "version": "0.31.34.60546", + "templateHash": "13504241837980660061" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool.", @@ -2482,10 +2552,7 @@ "vmSize": "[parameters('vmSize')]", "vnetSubnetID": "[parameters('vnetSubnetResourceId')]", "workloadRuntime": "[parameters('workloadRuntime')]" - }, - "dependsOn": [ - "managedCluster" - ] + } } }, "outputs": { diff --git a/avm/res/container-service/managed-cluster/maintenance-configurations/main.json b/avm/res/container-service/managed-cluster/maintenance-configurations/main.json index 22e9300b85..64b5e4c229 100644 --- a/avm/res/container-service/managed-cluster/maintenance-configurations/main.json +++ b/avm/res/container-service/managed-cluster/maintenance-configurations/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2505380725266419010" + "version": "0.31.34.60546", + "templateHash": "3191846535289543816" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations.", diff --git a/avm/res/container-service/managed-cluster/tests/e2e/istio/dependencies.bicep b/avm/res/container-service/managed-cluster/tests/e2e/istio/dependencies.bicep new file mode 100644 index 0000000000..ff0496b6e1 --- /dev/null +++ b/avm/res/container-service/managed-cluster/tests/e2e/istio/dependencies.bicep @@ -0,0 +1,96 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the organization to which the Root Certificate is issued. It helps identify the legal entity that owns the root certificate') +param rootOrganization string + +@description('Required. The name of the organization to which the Certificate Authority is issued. It helps identify the legal entity that owns the certificate authority') +param caOrganization string + +@description('Required. The subject distinguished name is the name of the user of the certificate authority. The distinguished name for the certificate is a textual representation of the subject or issuer of the certificate') +param caSubjectName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Deployment Script to create for the Certificate generation.') +param cacertDeploymentScriptName string + +@description('Optional. Do not provide a value. Used to force the deployment script to rerun on every redeployment.') +param utcValue string = utcNow() + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: null + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${managedIdentity.name}-KeyVault-Admin-RoleAssignment') + scope: keyVault + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '00482a5a-887f-4fb3-b363-3b7fe8e74483' + ) // Key Vault Administrator + principalType: 'ServicePrincipal' + } +} + +resource cacertDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: cacertDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '11.0' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + arguments: ' -KeyVaultName "${keyVault.name}" -RootOrganization "${rootOrganization}" -CAOrganization "${caOrganization}" -CertSubjectName "${caSubjectName}"' + scriptContent: loadTextContent('scripts/Set-CertificateAuthorityInKeyVault.ps1') + } +} + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the root certificate secret.') +output rootCertSecretName string = cacertDeploymentScript.properties.outputs.rootCertSecretName + +@description('The name of the certiticate authority key secret.') +output caKeySecretName string = cacertDeploymentScript.properties.outputs.caKeySecretName + +@description('The name of the certificate authority cert secret.') +output caCertSecretName string = cacertDeploymentScript.properties.outputs.caCertSecretName + +@description('The name of the certificate chain secret.') +output certChainSecretName string = cacertDeploymentScript.properties.outputs.certChainSecretName + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/res/container-service/managed-cluster/tests/e2e/istio/main.rbac.bicep b/avm/res/container-service/managed-cluster/tests/e2e/istio/main.rbac.bicep new file mode 100644 index 0000000000..56a1220b2f --- /dev/null +++ b/avm/res/container-service/managed-cluster/tests/e2e/istio/main.rbac.bicep @@ -0,0 +1,22 @@ +@description('The resource ID of the Key Vault.') +param keyVaultResourceId string + +@description('The principal ID of the managed identity.') +param principalId string + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { + name: last(split(keyVaultResourceId, '/')) +} + +resource secretPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + scope: keyVault + name: guid('msi-${principalId}-KeyVault-Secret-User-RoleAssignment') + properties: { + principalId: principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4633458b-17de-408a-b874-0445c86b69e6' + ) // Key Vault Secrets User + principalType: 'ServicePrincipal' + } +} diff --git a/avm/res/container-service/managed-cluster/tests/e2e/istio/main.test.bicep b/avm/res/container-service/managed-cluster/tests/e2e/istio/main.test.bicep new file mode 100644 index 0000000000..9753edb426 --- /dev/null +++ b/avm/res/container-service/managed-cluster/tests/e2e/istio/main.test.bicep @@ -0,0 +1,91 @@ +targetScope = 'subscription' + +metadata name = 'Using Istio Service Mesh add-on' +metadata description = 'This instance deploys the module with Istio Service Mesh add-on and plug a Certificate Authority from Key Vault.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-containerservice.managedclusters-${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 = 'csist' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + rootOrganization: 'Istio' + caOrganization: 'Istio' + caSubjectName: 'istiod.aks-istio.system.svc' + cacertDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + managedIdentities: { + systemAssigned: true + } + primaryAgentPoolProfiles: [ + { + name: 'systempool' + count: 3 + vmSize: 'Standard_DS2_v2' + mode: 'System' + } + ] + istioServiceMeshEnabled: true + istioServiceMeshInternalIngressGatewayEnabled: true + istioServiceMeshRevisions: [ + 'asm-1-22' + ] + istioServiceMeshCertificateAuthority: { + certChainObjectName: nestedDependencies.outputs.certChainSecretName + certObjectName: nestedDependencies.outputs.caCertSecretName + keyObjectName: nestedDependencies.outputs.caKeySecretName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + rootCertObjectName: nestedDependencies.outputs.rootCertSecretName + } + enableKeyvaultSecretsProvider: true + enableSecretRotation: true + } + } +] + +module secretPermissions 'main.rbac.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-rbac' + params: { + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + principalId: testDeployment[0].outputs.keyvaultIdentityObjectId + } +} diff --git a/avm/res/container-service/managed-cluster/tests/e2e/istio/scripts/Set-CertificateAuthorityInKeyVault.ps1 b/avm/res/container-service/managed-cluster/tests/e2e/istio/scripts/Set-CertificateAuthorityInKeyVault.ps1 new file mode 100644 index 0000000000..d61d7c8933 --- /dev/null +++ b/avm/res/container-service/managed-cluster/tests/e2e/istio/scripts/Set-CertificateAuthorityInKeyVault.ps1 @@ -0,0 +1,168 @@ +<# +.SYNOPSIS +Generate a new Certificate Authority and store it as secret in the given Key Vault. + +.DESCRIPTION +Generate a new Certificate Authority and store it as secret in the given Key Vault. + +.PARAMETER KeyVaultName +Mandatory. The name of the Key Vault to add a new certificate to, or fetch the secret reference it from + +.PARAMETER RootOrganization +Mandatory. The name of the organization to which the Root Certificate is issued. It helps identify the legal entity that owns the root certificate + +.PARAMETER CAOrganization +Mandatory. The name of the organization to which the Certificate Authority is issued. It helps identify the legal entity that owns the certificate authority + +.PARAMETER CertSubjectName +Mandatory. The subject distinguished name is the name of the user of the certificate authority. The distinguished name for the certificate is a textual representation of the subject or issuer of the certificate + +.EXAMPLE +./Set-CertificateAuthorityInKeyVault.ps1 -KeyVaultName 'myVault' -RootOrganization 'Istio' -CAOrganization 'Istio' -CertSubjectName 'istiod.aks-istio-system.com' + +Generate a Certificate Authority and store it in the Key Vault 'myVault' with the provided organizations and subject name +#> +param( + [Parameter(Mandatory = $true)] + [string] $KeyVaultName, + + [Parameter(Mandatory = $true)] + [string] $RootOrganization, + + [Parameter(Mandatory = $true)] + [string] $CAOrganization, + + [Parameter(Mandatory = $true)] + [string] $CertSubjectName +) + +$rootKeyFile = 'root-key.pem' +$rootKeySize = 4096 + +Write-Verbose ('Generating root key [{0}]' -f $rootKeyFile) -Verbose + +openssl genrsa -out $rootKeyFile $rootKeySize + +$rootKeyContent = Get-Content -Path $rootKeyFile -Raw +$rootKeyContentSecureString = ConvertTo-SecureString -String $rootKeyContent -AsPlainText -Force +$rootKeySecretName = 'root-key' +Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $rootKeySecretName -SecretValue $rootKeyContentSecureString + +$rootConfFile = 'root-ca.conf' +$rootCommonName = 'Root CA' +$rootConfContent = @" +[ req ] +encrypt_key = no +prompt = no +utf8 = yes +default_md = sha256 +default_bits = $($rootKeySize) +req_extensions = req_ext +x509_extensions = req_ext +distinguished_name = req_dn +[ req_ext ] +subjectKeyIdentifier = hash +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign +[ req_dn ] +O = $($RootOrganization) +CN = $($rootCommonName) +"@ + +Write-Verbose ('Generating openssl config file [{0}]' -f $rootConfFile) -Verbose + +$rootConfContent | Set-Content -Path $rootConfFile + +$rootCertCSRFile = 'root-cert.csr' + +Write-Verbose ('Generating certificate signing request [{0}]' -f $rootCertCSRFile) -Verbose + +openssl req -sha256 -new -key $rootKeyFile -config $rootConfFile -out $rootCertCSRFile + +$rootCertFile = 'root-cert.pem' +$rootCertDays = 3650 + +Write-Verbose ('Generating root cert [{0}]' -f $rootCertFile) -Verbose + +openssl x509 -req -sha256 -days $rootCertDays -signkey $rootKeyFile -extensions req_ext -extfile $rootConfFile -in $rootCertCSRFile -out $rootCertFile + +$rootCertContent = Get-Content -Path $rootCertFile -Raw +$rootCertContentSecureString = ConvertTo-SecureString -String $rootCertContent -AsPlainText -Force +$rootCertSecretName = 'root-cert' +Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $rootCertSecretName -SecretValue $rootCertContentSecureString + +$caKeyFile = 'ca-key.pem' +$caKeySize = '4096' + +Write-Verbose ('Generating ca key [{0}]' -f $caKeyFile) -Verbose + +openssl genrsa -out $caKeyFile $caKeySize + +$caKeyContent = Get-Content -Path $caKeyFile -Raw +$caKeyContentSecureString = ConvertTo-SecureString -String $caKeyContent -AsPlainText -Force +$caKeySecretName = 'ca-key' +Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $caKeySecretName -SecretValue $caKeyContentSecureString + +$caConfFile = 'ca.conf' +$caCommonName = 'Intermediate CA' +$caConfLocation = Split-Path -Leaf (Get-Location) +$caConfContent = @" +[ req ] +encrypt_key = no +prompt = no +utf8 = yes +default_md = sha256 +default_bits = $($caKeySize) +req_extensions = req_ext +x509_extensions = req_ext +distinguished_name = req_dn +[ req_ext ] +subjectKeyIdentifier = hash +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign +subjectAltName=@san +[ san ] +DNS.1 = $($CertSubjectName) +[ req_dn ] +O = $($CAOrganization) +CN = $($caCommonName) +L = $($caConfLocation) +"@ + +Write-Verbose ('Generating openssl config file [{0}]' -f $caConfFile) -Verbose + +$caConfContent | Set-Content -Path $caConfFile + +$caCertCSRFile = 'ca-cert.csr' + +Write-Verbose ('Generating certificate signing request [{0}]' -f $caCertCSRFile) -Verbose + +openssl req -sha256 -new -key $caKeyFile -config $caConfFile -out $caCertCSRFile + +$caCertFile = 'ca-cert.pem' +$caCertDays = 3650 + +Write-Verbose ('Generating ca cert [{0}]' -f $caCertFile) -Verbose + +openssl x509 -req -sha256 -days $caCertDays -CA $rootCertFile -CAkey $rootKeyFile -CAcreateserial -extensions req_ext -extfile $caConfFile -in $caCertCSRFile -out $caCertFile + +$caCertContent = Get-Content -Path $caCertFile -Raw +$caCertContentSecureString = ConvertTo-SecureString -String $caCertContent -AsPlainText -Force +$caCertSecretName = 'ca-cert' +Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $caCertSecretName -SecretValue $caCertContentSecureString + +Write-Verbose 'Generating cert chain' -Verbose + +$certChainContent = $caCertContent + $rootCertContent +$certChainContentSecureString = ConvertTo-SecureString -String $certChainContent -AsPlainText -Force +$certChainSecretName = 'cert-chain' +Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $certChainSecretName -SecretValue $certChainContentSecureString + +# Write into Deployment Script output stream +$DeploymentScriptOutputs = @{ + rootKeySecretName = $rootKeySecretName + rootCertSecretName = $rootCertSecretName + caKeySecretName = $caKeySecretName + caCertSecretName = $caCertSecretName + certChainSecretName = $certChainSecretName +} diff --git a/avm/res/container-service/managed-cluster/version.json b/avm/res/container-service/managed-cluster/version.json index 13669e6601..41fc8c654f 100644 --- a/avm/res/container-service/managed-cluster/version.json +++ b/avm/res/container-service/managed-cluster/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", + "version": "0.5", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +} diff --git a/avm/res/db-for-postgre-sql/flexible-server/README.md b/avm/res/db-for-postgre-sql/flexible-server/README.md index 7bf8dcca6f..141436be5f 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/README.md +++ b/avm/res/db-for-postgre-sql/flexible-server/README.md @@ -147,7 +147,7 @@ module flexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:' // Required parameters -param name = 'dfpsfse001' +param name = 'dfpfmax001' param skuName = 'Standard_D2s_v3' param tier = 'GeneralPurpose' // Non-required parameters @@ -1317,7 +1317,7 @@ param tags = { | Parameter | Type | Description | | :-- | :-- | :-- | -| [`administratorLogin`](#parameter-administratorlogin) | string | The administrator login name of a server. Can only be specified when the PostgreSQL server is being created. | +| [`administratorLogin`](#parameter-administratorlogin) | string | The administrator login name for the server. Can only be specified when the PostgreSQL server is being created. | | [`administratorLoginPassword`](#parameter-administratorloginpassword) | securestring | The administrator login password. | | [`administrators`](#parameter-administrators) | array | The Azure AD administrators when AAD authentication enabled. | | [`availabilityZone`](#parameter-availabilityzone) | string | Availability zone information of the server. Default will have no preference set. | @@ -1410,7 +1410,7 @@ Required if 'createMode' is set to 'PointInTimeRestore'. ### Parameter: `administratorLogin` -The administrator login name of a server. Can only be specified when the PostgreSQL server is being created. +The administrator login name for the server. Can only be specified when the PostgreSQL server is being created. - Required: No - Type: string @@ -1867,15 +1867,13 @@ Custom DNS configurations. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | | [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | -### Parameter: `privateEndpoints.customDnsConfigs.fqdn` - -Fqdn that resolves to private endpoint IP address. +**Optional parameters** -- Required: No -- Type: string +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | FQDN that resolves to private endpoint IP address. | ### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` @@ -1884,6 +1882,13 @@ A list of private IP addresses of the private endpoint. - Required: Yes - Type: array +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +FQDN that resolves to private endpoint IP address. + +- Required: No +- Type: string + ### Parameter: `privateEndpoints.customNetworkInterfaceName` The custom name of the network interface attached to the Private Endpoint. @@ -2390,6 +2395,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.8.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json index 0f162e6039..83f8bcd344 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17167767529180811297" + "version": "0.31.34.60546", + "templateHash": "16481538210870485841" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json index 8b481b2d1c..4026bdbe02 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11184980891224869481" + "version": "0.31.34.60546", + "templateHash": "4744350024962623928" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", @@ -54,10 +54,7 @@ "properties": { "source": "[if(not(empty(parameters('source'))), parameters('source'), null())]", "value": "[if(not(empty(parameters('value'))), parameters('value'), null())]" - }, - "dependsOn": [ - "flexibleServer" - ] + } } }, "outputs": { diff --git a/avm/res/db-for-postgre-sql/flexible-server/database/main.json b/avm/res/db-for-postgre-sql/flexible-server/database/main.json index 5e56f5d9e0..3009f6fc24 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/database/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/database/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8538777017463575324" + "version": "0.31.34.60546", + "templateHash": "5925943942284222024" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", @@ -54,10 +54,7 @@ "properties": { "collation": "[if(not(empty(parameters('collation'))), parameters('collation'), null())]", "charset": "[if(not(empty(parameters('charset'))), parameters('charset'), null())]" - }, - "dependsOn": [ - "flexibleServer" - ] + } } }, "outputs": { diff --git a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json index 64a06fc7c2..4db73ef457 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3950185975907365475" + "version": "0.31.34.60546", + "templateHash": "9983440066171652627" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.bicep b/avm/res/db-for-postgre-sql/flexible-server/main.bicep index 51f50cc917..b0488e73f0 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/main.bicep @@ -5,7 +5,7 @@ metadata owner = 'Azure/module-maintainers' @description('Required. The name of the PostgreSQL flexible server.') param name string -@description('Optional. The administrator login name of a server. Can only be specified when the PostgreSQL server is being created.') +@description('Optional. The administrator login name for the server. Can only be specified when the PostgreSQL server is being created.') param administratorLogin string? @description('Optional. The administrator login password.') @@ -98,11 +98,11 @@ param highAvailability string = 'ZoneRedundant' @description('Optional. The mode to create a new PostgreSQL server.') param createMode string = 'Default' -import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Conditional. The managed identity definition for this resource. Required if \'cMKKeyName\' is not empty.') param managedIdentities managedIdentityOnlyUserAssignedType? -import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The customer managed key definition.') param customerManagedKey customerManagedKeyType? @@ -135,11 +135,11 @@ param databases array = [] @description('Optional. The configurations to create in the server.') param configurations array = [] -import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') param lock lockType? -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? @@ -149,11 +149,11 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingFullType[]? -import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. Used when the desired connectivy mode is \'Public Access\' and \'delegatedSubnetResourceId\' is NOT used.') param privateEndpoints privateEndpointSingleServiceType[]? diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.json b/avm/res/db-for-postgre-sql/flexible-server/main.json index d6b690368e..5df3bdd416 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4674728695659998649" + "version": "0.31.34.60546", + "templateHash": "13236500116916645585" }, "name": "DBforPostgreSQL Flexible Servers", "description": "This module deploys a DBforPostgreSQL Flexible Server.", @@ -20,7 +20,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, "ipAddresses": { @@ -35,7 +35,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -77,7 +77,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -118,7 +118,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -155,7 +155,7 @@ "metadata": { "description": "An AVM-aligned type for a customer-managed key.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -277,7 +277,7 @@ "metadata": { "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -307,7 +307,7 @@ "metadata": { "description": "An AVM-aligned type for a lock.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -328,7 +328,7 @@ "metadata": { "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -470,7 +470,7 @@ "metadata": { "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -545,7 +545,7 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -561,7 +561,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The administrator login name of a server. Can only be specified when the PostgreSQL server is being created." + "description": "Optional. The administrator login name for the server. Can only be specified when the PostgreSQL server is being created." } }, "administratorLoginPassword": { @@ -856,10 +856,7 @@ "apiVersion": "2023-07-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" - ] + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]" }, "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", @@ -937,11 +934,7 @@ "storageSizeGB": "[parameters('storageSizeGB')]" }, "version": "[parameters('version')]" - }, - "dependsOn": [ - "cMKKeyVault", - "cMKUserAssignedIdentity" - ] + } }, "flexibleServer_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", @@ -1054,8 +1047,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8538777017463575324" + "version": "0.31.34.60546", + "templateHash": "5925943942284222024" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", @@ -1103,10 +1096,7 @@ "properties": { "collation": "[if(not(empty(parameters('collation'))), parameters('collation'), null())]", "charset": "[if(not(empty(parameters('charset'))), parameters('charset'), null())]" - }, - "dependsOn": [ - "flexibleServer" - ] + } } }, "outputs": { @@ -1171,8 +1161,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3950185975907365475" + "version": "0.31.34.60546", + "templateHash": "9983440066171652627" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", @@ -1281,8 +1271,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11184980891224869481" + "version": "0.31.34.60546", + "templateHash": "4744350024962623928" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", @@ -1330,10 +1320,7 @@ "properties": { "source": "[if(not(empty(parameters('source'))), parameters('source'), null())]", "value": "[if(not(empty(parameters('value'))), parameters('value'), null())]" - }, - "dependsOn": [ - "flexibleServer" - ] + } } }, "outputs": { @@ -1402,8 +1389,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17167767529180811297" + "version": "0.31.34.60546", + "templateHash": "16481538210870485841" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/max/main.test.bicep b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/max/main.test.bicep index a9fd13c4ba..9013b6e853 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/max/main.test.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/max/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-dbforpostgresql.flexibleserv 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 = 'dfpsfse' +param serviceShort string = 'dfpfmax' @description('Generated. Used as a basis for unique resource names.') param baseTime string = utcNow('u') diff --git a/avm/res/db-for-postgre-sql/flexible-server/version.json b/avm/res/db-for-postgre-sql/flexible-server/version.json index a8eda31021..9ed3662aba 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/version.json +++ b/avm/res/db-for-postgre-sql/flexible-server/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +} diff --git a/avm/res/dev-ops-infrastructure/pool/README.md b/avm/res/dev-ops-infrastructure/pool/README.md index 9896670d02..9b7d40e881 100644 --- a/avm/res/dev-ops-infrastructure/pool/README.md +++ b/avm/res/dev-ops-infrastructure/pool/README.md @@ -17,7 +17,7 @@ This module deploys the Managed DevOps Pool resource. | :-- | :-- | | `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.DevOpsInfrastructure/pools` | [2024-04-04-preview](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.DevOpsInfrastructure/pools` | [2024-10-19](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DevOpsInfrastructure/2024-10-19/pools) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | ## Usage examples @@ -182,26 +182,24 @@ module pool 'br/public:avm/res/dev-ops-infrastructure/pool:' = { agentProfile: { kind: 'Stateless' resourcePredictions: { - daysData: [ - { - '09:00:00': 1 - '17:00:00': 0 + daysData: { + friday: { + endAgentCount: 0 + endTime: '17:00:00' + startAgentCount: 1 + startTime: '09:00:00' } - {} - {} - {} - { - '09:00:00': 1 - '17:00:00': 0 + monday: { + endAgentCount: 0 + endTime: '17:00:00' + startAgentCount: 1 + startTime: '09:00:00' } - {} - {} - ] - timeZone: 'Central Europe Standard Time' + } + timeZone: 'UTC' } resourcePredictionsProfile: { - kind: 'Automatic' - predictionPreference: 'Balanced' + kind: 'Manual' } } concurrency: 1 @@ -293,26 +291,24 @@ module pool 'br/public:avm/res/dev-ops-infrastructure/pool:' = { "value": { "kind": "Stateless", "resourcePredictions": { - "daysData": [ - { - "09:00:00": 1, - "17:00:00": 0 - }, - {}, - {}, - {}, - { - "09:00:00": 1, - "17:00:00": 0 + "daysData": { + "friday": { + "endAgentCount": 0, + "endTime": "17:00:00", + "startAgentCount": 1, + "startTime": "09:00:00" }, - {}, - {} - ], - "timeZone": "Central Europe Standard Time" + "monday": { + "endAgentCount": 0, + "endTime": "17:00:00", + "startAgentCount": 1, + "startTime": "09:00:00" + } + }, + "timeZone": "UTC" }, "resourcePredictionsProfile": { - "kind": "Automatic", - "predictionPreference": "Balanced" + "kind": "Manual" } } }, @@ -426,26 +422,24 @@ using 'br/public:avm/res/dev-ops-infrastructure/pool:' param agentProfile = { kind: 'Stateless' resourcePredictions: { - daysData: [ - { - '09:00:00': 1 - '17:00:00': 0 + daysData: { + friday: { + endAgentCount: 0 + endTime: '17:00:00' + startAgentCount: 1 + startTime: '09:00:00' } - {} - {} - {} - { - '09:00:00': 1 - '17:00:00': 0 + monday: { + endAgentCount: 0 + endTime: '17:00:00' + startAgentCount: 1 + startTime: '09:00:00' } - {} - {} - ] - timeZone: 'Central Europe Standard Time' + } + timeZone: 'UTC' } resourcePredictionsProfile: { - kind: 'Automatic' - predictionPreference: 'Balanced' + kind: 'Manual' } } param concurrency = 1 @@ -537,24 +531,6 @@ module pool 'br/public:avm/res/dev-ops-infrastructure/pool:' = { // Required parameters agentProfile: { kind: 'Stateless' - resourcePredictions: { - daysData: [ - { - '09:00:00': 1 - '17:00:00': 0 - } - {} - {} - {} - { - '09:00:00': 1 - '17:00:00': 0 - } - {} - {} - ] - timeZone: 'Central Europe Standard Time' - } resourcePredictionsProfile: { kind: 'Automatic' predictionPreference: 'Balanced' @@ -607,24 +583,6 @@ module pool 'br/public:avm/res/dev-ops-infrastructure/pool:' = { "agentProfile": { "value": { "kind": "Stateless", - "resourcePredictions": { - "daysData": [ - { - "09:00:00": 1, - "17:00:00": 0 - }, - {}, - {}, - {}, - { - "09:00:00": 1, - "17:00:00": 0 - }, - {}, - {} - ], - "timeZone": "Central Europe Standard Time" - }, "resourcePredictionsProfile": { "kind": "Automatic", "predictionPreference": "Balanced" @@ -691,24 +649,6 @@ using 'br/public:avm/res/dev-ops-infrastructure/pool:' // Required parameters param agentProfile = { kind: 'Stateless' - resourcePredictions: { - daysData: [ - { - '09:00:00': 1 - '17:00:00': 0 - } - {} - {} - {} - { - '09:00:00': 1 - '17:00:00': 0 - } - {} - {} - ] - timeZone: 'Central Europe Standard Time' - } resourcePredictionsProfile: { kind: 'Automatic' predictionPreference: 'Balanced' diff --git a/avm/res/dev-ops-infrastructure/pool/main.bicep b/avm/res/dev-ops-infrastructure/pool/main.bicep index 358dd0abf5..8dbaad49b5 100644 --- a/avm/res/dev-ops-infrastructure/pool/main.bicep +++ b/avm/res/dev-ops-infrastructure/pool/main.bicep @@ -114,6 +114,19 @@ var identity = !empty(managedIdentities) } : null +var formattedDaysData = !empty(agentProfile.?resourcePredictions.?daysData) + ? map( + ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + day => + contains(agentProfile.resourcePredictions.daysData, day) + ? { + '${agentProfile.resourcePredictions.daysData[day].startTime}': agentProfile.resourcePredictions.daysData[day].startAgentCount + '${agentProfile.resourcePredictions.daysData[day].endTime}': agentProfile.resourcePredictions.daysData[day].endAgentCount + } + : {} + ) + : null + #disable-next-line no-deployments-resources resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { name: '46d3xbcp.res.devopsinfrastructure-pool.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' @@ -133,13 +146,36 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -resource managedDevOpsPool 'Microsoft.DevOpsInfrastructure/pools@2024-04-04-preview' = { +resource managedDevOpsPool 'Microsoft.DevOpsInfrastructure/pools@2024-10-19' = { name: name location: location tags: tags identity: identity properties: { - agentProfile: agentProfile + // agentProfile: agentProfile + agentProfile: agentProfile.kind == 'Stateful' + ? { + kind: 'Stateful' + maxAgentLifetime: agentProfile.maxAgentLifetime + gracePeriodTimeSpan: agentProfile.gracePeriodTimeSpan + resourcePredictions: !empty(agentProfile.?resourcePredictions) + ? { + timeZone: agentProfile.?resourcePredictions.timeZone + daysData: formattedDaysData + } + : null + resourcePredictionsProfile: agentProfile.?resourcePredictionsProfile + } + : { + kind: 'Stateless' + resourcePredictions: !empty(agentProfile.?resourcePredictions) + ? { + timeZone: agentProfile.?resourcePredictions.timeZone + daysData: formattedDaysData + } + : null + resourcePredictionsProfile: agentProfile.?resourcePredictionsProfile + } devCenterProjectResourceId: devCenterProjectResourceId fabricProfile: { sku: { @@ -363,7 +399,13 @@ type agentStatefulType = { gracePeriodTimeSpan: string @description('Optional. Defines pool buffer/stand-by agents.') - resourcePredictions: object? + resourcePredictions: { + @description('Required. The time zone in which the daysData is provided. To see the list of available time zones, see: https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones?view=windows-11#time-zones or via PowerShell command `(Get-TimeZone -ListAvailable).StandardName`.') + timeZone: string + + @description('Optional. The number of agents needed at a specific time.') + daysData: daysDataType + }? @discriminator('kind') @description('Optional. Determines how the stand-by scheme should be provided.') @@ -381,26 +423,7 @@ type agentStatelessType = { timeZone: string @description('Optional. The number of agents needed at a specific time.') - @metadata({ - example: ''' - [ - { // Monday - '09:00': 5 - '22:00': 0 - } - {} // Tuesday - {} // Wednesday - {} // Thursday - { // Friday - '09:00': 5 - '22:00': 0 - } - {} // Saturday - {} // Sunday - ] - ''' - }) - daysData: object[]? + daysData: daysDataType }? @discriminator('kind') @@ -501,3 +524,42 @@ type managedIdentitiesType = { @description('Optional. The resource ID(s) to assign to the resource.') userAssignedResourceIds: string[]? }? + +@export() +type standbyAgentsConfigType = { + @description('Required. The time at which the agents are needed.') + startTime: string + + @description('Required. The time at which the agents are no longer needed.') + endTime: string + + @description('Required. The number of agents needed at the start time.') + startAgentCount: int + + @description('Required. The number of agents needed at the end time.') + endAgentCount: int +}? + +@export() +type daysDataType = { + @description('Optional. The number of agents needed at a specific time for Monday.') + monday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Tuesday.') + tuesday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Wednesday.') + wednesday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Thursday.') + thursday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Friday.') + friday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Saturday.') + saturday: standbyAgentsConfigType + + @description('Optional. The number of agents needed at a specific time for Sunday.') + sunday: standbyAgentsConfigType +}? diff --git a/avm/res/dev-ops-infrastructure/pool/main.json b/avm/res/dev-ops-infrastructure/pool/main.json index 05c3db9232..9607831b9e 100644 --- a/avm/res/dev-ops-infrastructure/pool/main.json +++ b/avm/res/dev-ops-infrastructure/pool/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14560645908978883645" + "version": "0.31.34.60546", + "templateHash": "14164073542984791131" }, "name": "Managed DevOps Pool", "description": "This module deploys the Managed DevOps Pool resource.", @@ -392,6 +392,20 @@ }, "resourcePredictions": { "type": "object", + "properties": { + "timeZone": { + "type": "string", + "metadata": { + "description": "Required. The time zone in which the daysData is provided. To see the list of available time zones, see: https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones?view=windows-11#time-zones or via PowerShell command `(Get-TimeZone -ListAvailable).StandardName`." + } + }, + "daysData": { + "$ref": "#/definitions/daysDataType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time." + } + } + }, "nullable": true, "metadata": { "description": "Optional. Defines pool buffer/stand-by agents." @@ -442,13 +456,8 @@ } }, "daysData": { - "type": "array", - "items": { - "type": "object" - }, - "nullable": true, + "$ref": "#/definitions/daysDataType", "metadata": { - "example": " [\n { // Monday\n '09:00': 5\n '22:00': 0\n }\n {} // Tuesday\n {} // Wednesday\n {} // Thursday\n { // Friday\n '09:00': 5\n '22:00': 0\n }\n {} // Saturday\n {} // Sunday\n ]\n ", "description": "Optional. The number of agents needed at a specific time." } } @@ -750,6 +759,90 @@ "metadata": { "__bicep_export!": true } + }, + "standbyAgentsConfigType": { + "type": "object", + "properties": { + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The time at which the agents are needed." + } + }, + "endTime": { + "type": "string", + "metadata": { + "description": "Required. The time at which the agents are no longer needed." + } + }, + "startAgentCount": { + "type": "int", + "metadata": { + "description": "Required. The number of agents needed at the start time." + } + }, + "endAgentCount": { + "type": "int", + "metadata": { + "description": "Required. The number of agents needed at the end time." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_export!": true + } + }, + "daysDataType": { + "type": "object", + "properties": { + "monday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Monday." + } + }, + "tuesday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Tuesday." + } + }, + "wednesday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Wednesday." + } + }, + "thursday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Thursday." + } + }, + "friday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Friday." + } + }, + "saturday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Saturday." + } + }, + "sunday": { + "$ref": "#/definitions/standbyAgentsConfigType", + "metadata": { + "description": "Optional. The number of agents needed at a specific time for Sunday." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_export!": true + } } }, "parameters": { @@ -889,7 +982,8 @@ "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" }, "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())]" + "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())]", + "formattedDaysData": "[if(not(empty(tryGet(tryGet(parameters('agentProfile'), 'resourcePredictions'), 'daysData'))), map(createArray('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'), lambda('day', if(contains(parameters('agentProfile').resourcePredictions.daysData, lambdaVariables('day')), createObject(format('{0}', parameters('agentProfile').resourcePredictions.daysData[lambdaVariables('day')].startTime), parameters('agentProfile').resourcePredictions.daysData[lambdaVariables('day')].startAgentCount, format('{0}', parameters('agentProfile').resourcePredictions.daysData[lambdaVariables('day')].endTime), parameters('agentProfile').resourcePredictions.daysData[lambdaVariables('day')].endAgentCount), createObject()))), null())]" }, "resources": { "avmTelemetry": { @@ -914,13 +1008,13 @@ }, "managedDevOpsPool": { "type": "Microsoft.DevOpsInfrastructure/pools", - "apiVersion": "2024-04-04-preview", + "apiVersion": "2024-10-19", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "identity": "[variables('identity')]", "properties": { - "agentProfile": "[parameters('agentProfile')]", + "agentProfile": "[if(equals(parameters('agentProfile').kind, 'Stateful'), createObject('kind', 'Stateful', 'maxAgentLifetime', parameters('agentProfile').maxAgentLifetime, 'gracePeriodTimeSpan', parameters('agentProfile').gracePeriodTimeSpan, 'resourcePredictions', if(not(empty(tryGet(parameters('agentProfile'), 'resourcePredictions'))), createObject('timeZone', tryGet(parameters('agentProfile'), 'resourcePredictions', 'timeZone'), 'daysData', variables('formattedDaysData')), null()), 'resourcePredictionsProfile', tryGet(parameters('agentProfile'), 'resourcePredictionsProfile')), createObject('kind', 'Stateless', 'resourcePredictions', if(not(empty(tryGet(parameters('agentProfile'), 'resourcePredictions'))), createObject('timeZone', tryGet(parameters('agentProfile'), 'resourcePredictions', 'timeZone'), 'daysData', variables('formattedDaysData')), null()), 'resourcePredictionsProfile', tryGet(parameters('agentProfile'), 'resourcePredictionsProfile')))]", "devCenterProjectResourceId": "[parameters('devCenterProjectResourceId')]", "fabricProfile": { "sku": { @@ -1041,7 +1135,7 @@ "metadata": { "description": "The location the Managed DevOps Pool resource was deployed into." }, - "value": "[reference('managedDevOpsPool', '2024-04-04-preview', 'full').location]" + "value": "[reference('managedDevOpsPool', '2024-10-19', 'full').location]" }, "systemAssignedMIPrincipalId": { "type": "string", @@ -1049,7 +1143,7 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[tryGet(tryGet(reference('managedDevOpsPool', '2024-04-04-preview', 'full'), 'identity'), 'principalId')]" + "value": "[tryGet(tryGet(reference('managedDevOpsPool', '2024-10-19', 'full'), 'identity'), 'principalId')]" } } } \ No newline at end of file diff --git a/avm/res/dev-ops-infrastructure/pool/tests/e2e/max/main.test.bicep b/avm/res/dev-ops-infrastructure/pool/tests/e2e/max/main.test.bicep index 09b40200e5..5a5ce51cb2 100644 --- a/avm/res/dev-ops-infrastructure/pool/tests/e2e/max/main.test.bicep +++ b/avm/res/dev-ops-infrastructure/pool/tests/e2e/max/main.test.bicep @@ -70,33 +70,24 @@ module testDeployment '../../../main.bicep' = [ agentProfile: { kind: 'Stateless' resourcePredictions: { - timeZone: 'Central Europe Standard Time' - daysData: [ - // Monday - { - '09:00:00': 1 - '17:00:00': 0 + timeZone: 'UTC' + daysData: { + monday: { + startTime: '09:00:00' + startAgentCount: 1 + endTime: '17:00:00' + endAgentCount: 0 } - // Tuesday - {} - // Wednesday - {} - // Thursday - {} - // Friday - { - '09:00:00': 1 - '17:00:00': 0 + friday: { + startTime: '09:00:00' + startAgentCount: 1 + endTime: '17:00:00' + endAgentCount: 0 } - // Saturday - {} - // Sunday - {} - ] + } } resourcePredictionsProfile: { - kind: 'Automatic' - predictionPreference: 'Balanced' + kind: 'Manual' } } concurrency: 1 diff --git a/avm/res/dev-ops-infrastructure/pool/tests/e2e/waf-aligned/main.test.bicep b/avm/res/dev-ops-infrastructure/pool/tests/e2e/waf-aligned/main.test.bicep index 20a04a3900..884f636192 100644 --- a/avm/res/dev-ops-infrastructure/pool/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/dev-ops-infrastructure/pool/tests/e2e/waf-aligned/main.test.bicep @@ -69,31 +69,6 @@ module testDeployment '../../../main.bicep' = [ location: enforcedLocation agentProfile: { kind: 'Stateless' - resourcePredictions: { - timeZone: 'Central Europe Standard Time' - daysData: [ - // Monday - { - '09:00:00': 1 - '17:00:00': 0 - } - // Tuesday - {} - // Wednesday - {} - // Thursday - {} - // Friday - { - '09:00:00': 1 - '17:00:00': 0 - } - // Saturday - {} - // Sunday - {} - ] - } resourcePredictionsProfile: { kind: 'Automatic' predictionPreference: 'Balanced' diff --git a/avm/res/dev-ops-infrastructure/pool/version.json b/avm/res/dev-ops-infrastructure/pool/version.json index 8def869ede..729ac87673 100644 --- a/avm/res/dev-ops-infrastructure/pool/version.json +++ b/avm/res/dev-ops-infrastructure/pool/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", + "version": "0.2", "pathFilters": [ "./main.json" ] -} +} \ No newline at end of file diff --git a/avm/res/fabric/capacity/README.md b/avm/res/fabric/capacity/README.md index d8f391e37b..a8975a4da6 100644 --- a/avm/res/fabric/capacity/README.md +++ b/avm/res/fabric/capacity/README.md @@ -8,12 +8,14 @@ This module deploys Fabric capacities, which provide the compute resources for a - [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` | [2016-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/locks) | | `Microsoft.Fabric/capacities` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates) | ## Usage examples @@ -25,7 +27,8 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/res/fabric/capacity:`. - [Using only defaults](#example-1-using-only-defaults) -- [WAF-aligned](#example-2-waf-aligned) +- [Using large parameter set.](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) ### Example 1: _Using only defaults_ @@ -102,7 +105,96 @@ param location = ''

    -### Example 2: _WAF-aligned_ +### Example 2: _Using large parameter set._ + +This instance deploys the module with most of its features enabled. + + +

    + +via Bicep module + +```bicep +module capacity 'br/public:avm/res/fabric/capacity:' = { + name: 'capacityDeployment' + params: { + // Required parameters + adminMembers: [ + '' + ] + name: 'fcmax001' + // Non-required parameters + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "adminMembers": { + "value": [ + "" + ] + }, + "name": { + "value": "fcmax001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/fabric/capacity:' + +// Required parameters +param adminMembers = [ + '' +] +param name = 'fcmax001' +// Non-required parameters +param location = '' +param lock = { + kind: 'CanNotDelete' + name: 'myCustomLockName' +} +``` + +
    +

    + +### Example 3: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -197,6 +289,7 @@ param skuName = 'F64' | :-- | :-- | :-- | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`skuName`](#parameter-skuname) | string | SKU tier of the Fabric resource. | | [`skuTier`](#parameter-skutier) | string | SKU name of the Fabric resource. | | [`tags`](#parameter-tags) | object | Tags of the resource. | @@ -231,6 +324,42 @@ Location for all resources. - Type: string - Default: `[resourceGroup().location]` +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + ### Parameter: `skuName` SKU tier of the Fabric resource. @@ -285,6 +414,14 @@ Tags of the resource. | `resourceGroupName` | string | The name of the resource group the module was deployed to. | | `resourceId` | string | The resource ID of the deployed Fabric resource. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/fabric/capacity/main.bicep b/avm/res/fabric/capacity/main.bicep index 65c6a7242d..c19347a9fe 100644 --- a/avm/res/fabric/capacity/main.bicep +++ b/avm/res/fabric/capacity/main.bicep @@ -34,6 +34,10 @@ param skuTier string = 'Fabric' @description('Required. List of admin members. Format: ["something@domain.com"].') param adminMembers array +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' +@description('Optional. The lock settings of the service.') +param lock lockType? + @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -75,6 +79,17 @@ resource fabricCapacity 'Microsoft.Fabric/capacities@2023-11-01' = { } } +resource fabricCapacity_lock 'Microsoft.Authorization/locks@2016-09-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' + ? 'Cannot delete resource or child resources.' + : 'Cannot delete or modify the resource or child resources.' + } + scope: fabricCapacity +} + // ============ // // Outputs // // ============ // diff --git a/avm/res/fabric/capacity/main.json b/avm/res/fabric/capacity/main.json index f90c00a5fc..ead274d019 100644 --- a/avm/res/fabric/capacity/main.json +++ b/avm/res/fabric/capacity/main.json @@ -6,12 +6,44 @@ "_generator": { "name": "bicep", "version": "0.30.3.12046", - "templateHash": "11718641793898572278" + "templateHash": "4050250114148213748" }, "name": "Fabric Capacities", "description": "This module deploys Fabric capacities, which provide the compute resources for all the experiences in Fabric.", "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + } + }, "parameters": { "name": { "type": "string", @@ -69,6 +101,13 @@ "description": "Required. List of admin members. Format: [\"something@domain.com\"]." } }, + "lock": { + "$ref": "#/definitions/lockType", + "nullable": true, + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, "enableTelemetry": { "type": "bool", "defaultValue": true, @@ -113,6 +152,20 @@ "members": "[parameters('adminMembers')]" } } + }, + "fabricCapacity_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2016-09-01", + "scope": "[format('Microsoft.Fabric/capacities/{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": [ + "fabricCapacity" + ] } }, "outputs": { diff --git a/avm/res/fabric/capacity/tests/e2e/max/main.test.bicep b/avm/res/fabric/capacity/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..bd31c44816 --- /dev/null +++ b/avm/res/fabric/capacity/tests/e2e/max/main.test.bicep @@ -0,0 +1,59 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set.' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-fabric-capacities-${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 = 'fcmax' + +@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_#' + +@description('Required. Email address used by resource. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-adminMembersSecret\'.') +@secure() +param adminMembersSecret string = '' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + adminMembers: [ + adminMembersSecret + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + } + } +] diff --git a/avm/res/health-bot/health-bot/README.md b/avm/res/health-bot/health-bot/README.md index 073a60ffba..4689cbc03d 100644 --- a/avm/res/health-bot/health-bot/README.md +++ b/avm/res/health-bot/health-bot/README.md @@ -13,6 +13,7 @@ This module deploys an Azure Health Bot. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -485,13 +486,13 @@ The managed identity definition for this resource. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. -- Required: Yes +- Required: No - Type: array ### Parameter: `roleAssignments` @@ -613,6 +614,14 @@ Tags of the resource. | `resourceGroupName` | string | The resource group the health bot was deployed into. | | `resourceId` | string | The resource ID of the health bot. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/health-bot/health-bot/main.bicep b/avm/res/health-bot/health-bot/main.bicep index 5eadd66157..68fdc1870f 100644 --- a/avm/res/health-bot/health-bot/main.bicep +++ b/avm/res/health-bot/health-bot/main.bicep @@ -13,17 +13,20 @@ param name string @description('Required. The name of the Azure Health Bot SKU.') param sku string +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityOnlyUserAssignedType? @description('Optional. Location for all resources.') param location string = resourceGroup().location +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -137,46 +140,3 @@ output resourceId string = healthBot.id @description('The location the resource was deployed into.') output location string = healthBot.location - -// =============== // -// Definitions // -// =============== // - -type managedIdentitiesType = { - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourceIds: string[] -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? diff --git a/avm/res/health-bot/health-bot/main.json b/avm/res/health-bot/health-bot/main.json index 6ee924eb9a..eb95f2d493 100644 --- a/avm/res/health-bot/health-bot/main.json +++ b/avm/res/health-bot/health-bot/main.json @@ -5,15 +5,45 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13204699140769654908" + "version": "0.30.23.60470", + "templateHash": "9706439680882910063" }, "name": "Azure Health Bots", "description": "This module deploys an Azure Health Bot.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "managedIdentityOnlyUserAssignedType": { "type": "object", "properties": { "userAssignedResourceIds": { @@ -21,110 +51,93 @@ "items": { "type": "string" }, + "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "lockType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "kind": { + "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": [ - "CanNotDelete", - "None", - "ReadOnly" + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" ], "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The principal type of the assigned principal ID." } - } - }, - "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." - } + }, + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -146,7 +159,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } @@ -160,12 +174,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } diff --git a/avm/res/healthcare-apis/workspace/README.md b/avm/res/healthcare-apis/workspace/README.md index 66c2b983fa..5210bf8332 100644 --- a/avm/res/healthcare-apis/workspace/README.md +++ b/avm/res/healthcare-apis/workspace/README.md @@ -13,6 +13,7 @@ This module deploys a Healthcare API Workspace. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -894,6 +895,14 @@ Tags of the resource. | `resourceGroupName` | string | The resource group where the workspace is deployed. | | `resourceId` | string | The resource ID of the health data services workspace. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | + ## Notes ### Parameter Usage: `iotconnectors` diff --git a/avm/res/healthcare-apis/workspace/main.bicep b/avm/res/healthcare-apis/workspace/main.bicep index 475e814f77..743b430d3a 100644 --- a/avm/res/healthcare-apis/workspace/main.bicep +++ b/avm/res/healthcare-apis/workspace/main.bicep @@ -10,11 +10,13 @@ param name string @description('Optional. Location for all resources.') param location string = resourceGroup().location +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @allowed([ 'Disabled' @@ -247,41 +249,3 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = workspace.location - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @sys.description('Optional. Specify the name of lock.') - name: string? - - @sys.description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @sys.description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @sys.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\'.') - roleDefinitionIdOrName: string - - @sys.description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @sys.description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @sys.description('Optional. The description of the role assignment.') - description: string? - - @sys.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".') - condition: string? - - @sys.description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @sys.description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? diff --git a/avm/res/healthcare-apis/workspace/main.json b/avm/res/healthcare-apis/workspace/main.json index eaee54c542..4361adabe7 100644 --- a/avm/res/healthcare-apis/workspace/main.json +++ b/avm/res/healthcare-apis/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "2224027190177398808" + "templateHash": "17701323057909267930" }, "name": "Healthcare API Workspaces", "description": "This module deploys a Healthcare API Workspace.", @@ -36,80 +36,87 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -130,12 +137,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } diff --git a/avm/res/insights/component/README.md b/avm/res/insights/component/README.md index 5d3c5bd464..6a7a088be3 100644 --- a/avm/res/insights/component/README.md +++ b/avm/res/insights/component/README.md @@ -8,6 +8,7 @@ This component deploys an Application Insights instance. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -514,7 +515,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -624,7 +625,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -689,7 +690,6 @@ Linked storage account resource ID. - Required: No - Type: string -- Default: `''` ### Parameter: `location` @@ -885,6 +885,14 @@ Tags of the resource. | `resourceGroupName` | string | The resource group the application insights component was deployed into. | | `resourceId` | string | The resource ID of the application insights component. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.3.0` | 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/res/insights/component/linkedStorageAccounts/main.json b/avm/res/insights/component/linkedStorageAccounts/main.json index a5d6e69bab..9bb22a6e89 100644 --- a/avm/res/insights/component/linkedStorageAccounts/main.json +++ b/avm/res/insights/component/linkedStorageAccounts/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "216781367921725873" + "version": "0.31.34.60546", + "templateHash": "16330852520711792816" }, "name": "Application Insights Linked Storage Account", "description": "This component deploys an Application Insights Linked Storage Account.", diff --git a/avm/res/insights/component/main.bicep b/avm/res/insights/component/main.bicep index a7a3c60dca..8b00736f3e 100644 --- a/avm/res/insights/component/main.bicep +++ b/avm/res/insights/component/main.bicep @@ -25,7 +25,7 @@ param disableLocalAuth bool = false param forceCustomerStorageForProfiler bool = false @description('Optional. Linked storage account resource ID.') -param linkedStorageAccountResourceId string = '' +param linkedStorageAccountResourceId string? @description('Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled.') @allowed([ @@ -66,8 +66,9 @@ param kind string = '' @description('Optional. Location for all Resources.') param location string = resourceGroup().location +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -75,8 +76,9 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -160,7 +162,7 @@ module linkedStorageAccount 'linkedStorageAccounts/main.bicep' = if (!empty(link name: '${uniqueString(deployment().name, location)}-appInsights-linkedStorageAccount' params: { appInsightsName: appInsights.name - storageAccountResourceId: linkedStorageAccountResourceId + storageAccountResourceId: linkedStorageAccountResourceId ?? '' } } @@ -229,77 +231,3 @@ output instrumentationKey string = appInsights.properties.InstrumentationKey @description('Application Insights Connection String.') output connectionString string = appInsights.properties.ConnectionString - -// =============== // -// Definitions // -// =============== // - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? diff --git a/avm/res/insights/component/main.json b/avm/res/insights/component/main.json index f7b9e3a933..210dd993f9 100644 --- a/avm/res/insights/component/main.json +++ b/avm/res/insights/component/main.json @@ -5,206 +5,210 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "707617228684994883" + "version": "0.31.34.60546", + "templateHash": "2627482903423190891" }, "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." - } + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the diagnostic setting." } - } - }, - "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`." - } + }, + "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." + } + }, + "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, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } + }, + "roleAssignmentType": { + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } } }, "parameters": { @@ -254,7 +258,7 @@ }, "linkedStorageAccountResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Linked storage account resource ID." } @@ -323,7 +327,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -343,7 +351,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -487,7 +499,7 @@ "value": "[parameters('name')]" }, "storageAccountResourceId": { - "value": "[parameters('linkedStorageAccountResourceId')]" + "value": "[coalesce(parameters('linkedStorageAccountResourceId'), '')]" } }, "template": { @@ -496,8 +508,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "216781367921725873" + "version": "0.31.34.60546", + "templateHash": "16330852520711792816" }, "name": "Application Insights Linked Storage Account", "description": "This component deploys an Application Insights Linked Storage Account.", diff --git a/avm/res/managed-services/registration-definition/main.bicep b/avm/res/managed-services/registration-definition/main.bicep index 5a25838cb1..6b8ee11127 100644 --- a/avm/res/managed-services/registration-definition/main.bicep +++ b/avm/res/managed-services/registration-definition/main.bicep @@ -96,6 +96,8 @@ output assignmentResourceId string = empty(resourceGroupName) // Definitions // // ================ // +@export() +@description('Authorization object describing the access Azure Active Directory principals in the managedBy tenant will receive on the delegated resource in the managed tenant.') type authorizationType = { @description('Conditional. The list of role definition ids which define all the permissions that the user in the authorization can assign to other principals. Required if the `roleDefinitionId` refers to the User Access Administrator Role.') delegatedRoleDefinitionIds: string[]? diff --git a/avm/res/managed-services/registration-definition/main.json b/avm/res/managed-services/registration-definition/main.json index d1e41f4df3..7176bf7ad8 100644 --- a/avm/res/managed-services/registration-definition/main.json +++ b/avm/res/managed-services/registration-definition/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "6598987839511353461" + "version": "0.30.23.60470", + "templateHash": "806800728084876706" }, "name": "Registration Definitions", "description": "This module deploys a `Registration Definition` and a `Registration Assignment` (often referred to as 'Lighthouse' or 'resource delegation') on a subscription or resource group scope.\nThis type of delegation is very similar to role assignments but here the principal that is assigned a role is in a remote/managing Azure Active Directory tenant.\nThe templates are run towards the tenant where the Azure resources you want to delegate access to are, providing 'authorizations' (aka. access delegation) to principals in a remote/managing tenant.", @@ -45,6 +45,10 @@ "description": "Required. The identifier of the Azure built-in role that defines the permissions that the Azure Active Directory principal will have on the projected scope." } } + }, + "metadata": { + "__bicep_export!": true, + "description": "Authorization object describing the access Azure Active Directory principals in the managedBy tenant will receive on the delegated resource in the managed tenant." } } }, @@ -175,8 +179,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "17889456379146479598" + "version": "0.30.23.60470", + "templateHash": "1358545064505499503" }, "name": "Registration Assignment", "description": "Create a registration assignment.", diff --git a/avm/res/network/azure-firewall/README.md b/avm/res/network/azure-firewall/README.md index 282958f330..2e71568439 100644 --- a/avm/res/network/azure-firewall/README.md +++ b/avm/res/network/azure-firewall/README.md @@ -18,7 +18,7 @@ This module deploys an Azure Firewall. | `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.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/azureFirewalls` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/azureFirewalls) | +| `Microsoft.Network/azureFirewalls` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/azureFirewalls) | | `Microsoft.Network/publicIPAddresses` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-09-01/publicIPAddresses) | ## Usage examples diff --git a/avm/res/network/front-door-web-application-firewall-policy/README.md b/avm/res/network/front-door-web-application-firewall-policy/README.md index 830c52b31e..45bfcccf86 100644 --- a/avm/res/network/front-door-web-application-firewall-policy/README.md +++ b/avm/res/network/front-door-web-application-firewall-policy/README.md @@ -16,7 +16,7 @@ This module deploys a Front Door Web Application Firewall (WAF) Policy. | :-- | :-- | | `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.Network/FrontDoorWebApplicationFirewallPolicies` | [2024-02-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/FrontDoorWebApplicationFirewallPolicies) | +| `Microsoft.Network/FrontDoorWebApplicationFirewallPolicies` | [2024-02-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-02-01/FrontDoorWebApplicationFirewallPolicies) | ## Usage examples diff --git a/avm/res/network/private-endpoint/README.md b/avm/res/network/private-endpoint/README.md index 540a6bef15..73417838cc 100644 --- a/avm/res/network/private-endpoint/README.md +++ b/avm/res/network/private-endpoint/README.md @@ -8,6 +8,7 @@ This module deploys a Private Endpoint. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -1278,6 +1279,14 @@ Tags to be applied on all resources/resource groups in this deployment. | `resourceGroupName` | string | The resource group the private endpoint was deployed into. | | `resourceId` | string | The resource ID of the private endpoint. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/network/public-ip-address/README.md b/avm/res/network/public-ip-address/README.md index 8ba95ec8ab..b392a84ddd 100644 --- a/avm/res/network/public-ip-address/README.md +++ b/avm/res/network/public-ip-address/README.md @@ -8,6 +8,7 @@ This module deploys a Public IP Address. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -122,6 +123,12 @@ module publicIpAddress 'br/public:avm/res/network/public-ip-address:' = } ] dnsSettings: '' + ipTags: [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } + ] location: '' lock: { kind: 'CanNotDelete' @@ -199,6 +206,14 @@ module publicIpAddress 'br/public:avm/res/network/public-ip-address:' = "dnsSettings": { "value": "" }, + "ipTags": { + "value": [ + { + "ipTagType": "RoutingPreference", + "tag": "Internet" + } + ] + }, "location": { "value": "" }, @@ -286,6 +301,12 @@ param diagnosticSettings = [ } ] param dnsSettings = '' +param ipTags = [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } +] param location = '' param lock = { kind: 'CanNotDelete' @@ -576,6 +597,7 @@ param zones = [ | [`dnsSettings`](#parameter-dnssettings) | object | The DNS settings of the public IP address. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`idleTimeoutInMinutes`](#parameter-idletimeoutinminutes) | int | The idle timeout of the public IP address. | +| [`ipTags`](#parameter-iptags) | array | The list of tags associated with the public IP address. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`publicIPAddressVersion`](#parameter-publicipaddressversion) | string | IP address version. | @@ -663,7 +685,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -773,7 +795,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -867,6 +889,34 @@ The idle timeout of the public IP address. - Type: int - Default: `4` +### Parameter: `ipTags` + +The list of tags associated with the public IP address. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ipTagType`](#parameter-iptagsiptagtype) | string | The IP tag type. | +| [`tag`](#parameter-iptagstag) | string | The IP tag. | + +### Parameter: `ipTags.ipTagType` + +The IP tag type. + +- Required: Yes +- Type: string + +### Parameter: `ipTags.tag` + +The IP tag. + +- Required: Yes +- Type: string + ### Parameter: `location` Location for all resources. @@ -1126,6 +1176,14 @@ A list of availability zones denoting the IP allocated for the resource needs to | `resourceGroupName` | string | The resource group the public IP address was deployed into. | | `resourceId` | string | The resource ID of the public IP address. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/network/public-ip-address/main.bicep b/avm/res/network/public-ip-address/main.bicep index 43a77d2454..923a8f1ccd 100644 --- a/avm/res/network/public-ip-address/main.bicep +++ b/avm/res/network/public-ip-address/main.bicep @@ -37,8 +37,12 @@ param publicIPAddressVersion string = 'IPv4' @description('Optional. The DNS settings of the public IP address.') param dnsSettings dnsSettingsType? +@description('Optional. The list of tags associated with the public IP address.') +param ipTags ipTagType[]? + +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @description('Optional. Name of a public IP address SKU.') @allowed([ @@ -60,8 +64,9 @@ param ddosSettings ddosSettingsType? @description('Optional. Location for all resources.') param location string = resourceGroup().location +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -72,8 +77,9 @@ param idleTimeoutInMinutes int = 4 @description('Optional. Tags of the resource.') param tags object? +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -159,7 +165,7 @@ resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = { } : null idleTimeoutInMinutes: idleTimeoutInMinutes - ipTags: null // Note: Requires feature 'Microsoft.Network/AllowBringYourOwnPublicIpAddress' to be registered on the subscription + ipTags: ipTags } } @@ -238,40 +244,7 @@ output location string = publicIpAddress.location // Definitions // // ================ // -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - +@export() type dnsSettingsType = { @description('Required. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system.') domainNameLabel: string @@ -286,6 +259,7 @@ type dnsSettingsType = { reverseFqdn: string? } +@export() type ddosSettingsType = { @description('Optional. The DDoS protection plan associated with the public IP address.') ddosProtectionPlan: { @@ -296,46 +270,11 @@ type ddosSettingsType = { protectionMode: 'Enabled' } -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? +@export() +type ipTagType = { + @description('Required. The IP tag type.') + ipTagType: string - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? + @description('Required. The IP tag.') + tag: string +} diff --git a/avm/res/network/public-ip-address/main.json b/avm/res/network/public-ip-address/main.json index 52d712a6d2..1052a87909 100644 --- a/avm/res/network/public-ip-address/main.json +++ b/avm/res/network/public-ip-address/main.json @@ -5,112 +5,14 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "7554660773280925072" + "version": "0.30.23.60470", + "templateHash": "11325859316909755285" }, "name": "Public IP Addresses", "description": "This module deploys a Public IP Address.", "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 - }, "dnsSettingsType": { "type": "object", "properties": { @@ -147,6 +49,9 @@ "description": "Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." } } + }, + "metadata": { + "__bicep_export!": true } }, "ddosSettingsType": { @@ -176,127 +81,257 @@ "description": "Required. The DDoS protection policy customizations." } } + }, + "metadata": { + "__bicep_export!": 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`." - } + "ipTagType": { + "type": "object", + "properties": { + "ipTagType": { + "type": "string", + "metadata": { + "description": "Required. The IP tag type." + } + }, + "tag": { + "type": "string", + "metadata": { + "description": "Required. The IP tag." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + }, + "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, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -361,8 +396,19 @@ "description": "Optional. The DNS settings of the public IP address." } }, + "ipTags": { + "type": "array", + "items": { + "$ref": "#/definitions/ipTagType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of tags associated with the public IP address." + } + }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } @@ -404,7 +450,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -431,7 +481,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -497,7 +551,7 @@ "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", "publicIPPrefix": "[if(not(empty(parameters('publicIpPrefixResourceId'))), createObject('id', parameters('publicIpPrefixResourceId')), null())]", "idleTimeoutInMinutes": "[parameters('idleTimeoutInMinutes')]", - "ipTags": null + "ipTags": "[parameters('ipTags')]" } }, "publicIpAddress_lock": { diff --git a/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep index daea40b73e..02aed1e048 100644 --- a/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/max/main.test.bicep @@ -71,6 +71,12 @@ module testDeployment '../../../main.bicep' = [ } dnsSettings: null ddosSettings: null + ipTags: [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } + ] publicIpPrefixResourceId: null publicIPAllocationMethod: 'Static' roleAssignments: [ diff --git a/avm/res/network/public-ip-address/version.json b/avm/res/network/public-ip-address/version.json index e42c3d9e5f..09c3664cec 100644 --- a/avm/res/network/public-ip-address/version.json +++ b/avm/res/network/public-ip-address/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.6", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.7", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/network/public-ip-prefix/README.md b/avm/res/network/public-ip-prefix/README.md index a61f1f8244..0b4c7cdd48 100644 --- a/avm/res/network/public-ip-prefix/README.md +++ b/avm/res/network/public-ip-prefix/README.md @@ -8,6 +8,7 @@ This module deploys a Public IP Prefix. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -16,7 +17,7 @@ This module deploys a Public IP Prefix. | :-- | :-- | | `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.Network/publicIPPrefixes` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-09-01/publicIPPrefixes) | +| `Microsoft.Network/publicIPPrefixes` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/publicIPPrefixes) | ## Usage examples @@ -27,8 +28,9 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/public-ip-prefix:`. - [Using only defaults](#example-1-using-only-defaults) -- [Using large parameter set](#example-2-using-large-parameter-set) -- [WAF-aligned](#example-3-waf-aligned) +- [IPv6 Public IP Prefix](#example-2-ipv6-public-ip-prefix) +- [Using large parameter set](#example-3-using-large-parameter-set) +- [WAF-aligned](#example-4-waf-aligned) ### Example 1: _Using only defaults_ @@ -99,7 +101,81 @@ param location = ''

    -### Example 2: _Using large parameter set_ +### Example 2: _IPv6 Public IP Prefix_ + +This instance deploys the module using the IPv6 version of the Public IP Prefix. + + +

    + +via Bicep module + +```bicep +module publicIpPrefix 'br/public:avm/res/network/public-ip-prefix:' = { + name: 'publicIpPrefixDeployment' + params: { + // Required parameters + name: 'npipip6001' + prefixLength: 127 + // Non-required parameters + location: '' + publicIPAddressVersion: 'IPv6' + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "npipip6001" + }, + "prefixLength": { + "value": 127 + }, + // Non-required parameters + "location": { + "value": "" + }, + "publicIPAddressVersion": { + "value": "IPv6" + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/network/public-ip-prefix:' + +// Required parameters +param name = 'npipip6001' +param prefixLength = 127 +// Non-required parameters +param location = '' +param publicIPAddressVersion = 'IPv6' +``` + +
    +

    + +### Example 3: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -116,6 +192,12 @@ module publicIpPrefix 'br/public:avm/res/network/public-ip-prefix:' = { name: 'npipmax001' prefixLength: 28 // Non-required parameters + ipTags: [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } + ] location: '' lock: { kind: 'CanNotDelete' @@ -173,6 +255,14 @@ module publicIpPrefix 'br/public:avm/res/network/public-ip-prefix:' = { "value": 28 }, // Non-required parameters + "ipTags": { + "value": [ + { + "ipTagType": "RoutingPreference", + "tag": "Internet" + } + ] + }, "location": { "value": "" }, @@ -234,6 +324,12 @@ using 'br/public:avm/res/network/public-ip-prefix:' param name = 'npipmax001' param prefixLength = 28 // Non-required parameters +param ipTags = [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } +] param location = '' param lock = { kind: 'CanNotDelete' @@ -272,7 +368,7 @@ param zones = [

    -### Example 3: _WAF-aligned_ +### Example 4: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -373,11 +469,14 @@ param tags = { | :-- | :-- | :-- | | [`customIPPrefix`](#parameter-customipprefix) | object | The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipTags`](#parameter-iptags) | array | The list of tags associated with the public IP prefix. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`publicIPAddressVersion`](#parameter-publicipaddressversion) | string | The public IP address version. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`tags`](#parameter-tags) | object | Tags of the resource. | -| [`zones`](#parameter-zones) | array | A list of availability zones denoting the IP allocated for the resource needs to come from. | +| [`tier`](#parameter-tier) | string | Tier of a public IP prefix SKU. If set to `Global`, the `zones` property must be empty. | +| [`zones`](#parameter-zones) | array | A list of availability zones denoting the IP allocated for the resource needs to come from. This is only applicable for regional public IP prefixes and must be empty for global public IP prefixes. | ### Parameter: `name` @@ -409,6 +508,34 @@ Enable/Disable usage telemetry for module. - Type: bool - Default: `True` +### Parameter: `ipTags` + +The list of tags associated with the public IP prefix. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ipTagType`](#parameter-iptagsiptagtype) | string | The IP tag type. | +| [`tag`](#parameter-iptagstag) | string | The IP tag. | + +### Parameter: `ipTags.ipTagType` + +The IP tag type. + +- Required: Yes +- Type: string + +### Parameter: `ipTags.tag` + +The IP tag. + +- Required: Yes +- Type: string + ### Parameter: `location` Location for all resources. @@ -453,6 +580,21 @@ Specify the name of lock. - Required: No - Type: string +### Parameter: `publicIPAddressVersion` + +The public IP address version. + +- Required: No +- Type: string +- Default: `'IPv4'` +- Allowed: + ```Bicep + [ + 'IPv4' + 'IPv6' + ] + ``` + ### Parameter: `roleAssignments` Array of role assignments to create. @@ -564,9 +706,24 @@ Tags of the resource. - Required: No - Type: object +### Parameter: `tier` + +Tier of a public IP prefix SKU. If set to `Global`, the `zones` property must be empty. + +- Required: No +- Type: string +- Default: `'Regional'` +- Allowed: + ```Bicep + [ + 'Global' + 'Regional' + ] + ``` + ### Parameter: `zones` -A list of availability zones denoting the IP allocated for the resource needs to come from. +A list of availability zones denoting the IP allocated for the resource needs to come from. This is only applicable for regional public IP prefixes and must be empty for global public IP prefixes. - Required: No - Type: array @@ -596,6 +753,14 @@ A list of availability zones denoting the IP allocated for the resource needs to | `resourceGroupName` | string | The resource group the public IP prefix was deployed into. | | `resourceId` | string | The resource ID of the public IP prefix. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/network/public-ip-prefix/main.bicep b/avm/res/network/public-ip-prefix/main.bicep index f53aaf8b6c..3eb63b2270 100644 --- a/avm/res/network/public-ip-prefix/main.bicep +++ b/avm/res/network/public-ip-prefix/main.bicep @@ -6,19 +6,35 @@ metadata owner = 'Azure/module-maintainers' @minLength(1) param name string +@description('Optional. Tier of a public IP prefix SKU. If set to `Global`, the `zones` property must be empty.') +@allowed([ + 'Global' + 'Regional' +]) +param tier string = 'Regional' + @description('Optional. Location for all resources.') param location string = resourceGroup().location @description('Required. Length of the Public IP Prefix.') @minValue(21) -@maxValue(31) +@maxValue(127) param prefixLength int +@description('Optional. The public IP address version.') +@allowed([ + 'IPv4' + 'IPv6' +]) +param publicIPAddressVersion string = 'IPv4' + +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -26,7 +42,10 @@ param tags object? @description('Optional. The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range.') param customIPPrefix object = {} -@description('Optional. A list of availability zones denoting the IP allocated for the resource needs to come from.') +@description('Optional. The list of tags associated with the public IP prefix.') +param ipTags ipTagType[]? + +@description('Optional. A list of availability zones denoting the IP allocated for the resource needs to come from. This is only applicable for regional public IP prefixes and must be empty for global public IP prefixes.') @allowed([ 1 2 @@ -89,18 +108,20 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -resource publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2023-09-01' = { +resource publicIpPrefix 'Microsoft.Network/publicIPPrefixes@2024-01-01' = { name: name location: location tags: tags sku: { name: 'Standard' + tier: tier } zones: map(zones, zone => string(zone)) properties: { customIPPrefix: !empty(customIPPrefix) ? customIPPrefix : null - publicIPAddressVersion: 'IPv4' + publicIPAddressVersion: publicIPAddressVersion prefixLength: prefixLength + ipTags: ipTags } } @@ -147,36 +168,11 @@ output location string = publicIpPrefix.location // Definitions // // =============== // -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? +@export() +type ipTagType = { + @description('Required. The IP tag type.') + ipTagType: string -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? + @description('Required. The IP tag.') + tag: string +} diff --git a/avm/res/network/public-ip-prefix/main.json b/avm/res/network/public-ip-prefix/main.json index 31a4295388..69abac3da9 100644 --- a/avm/res/network/public-ip-prefix/main.json +++ b/avm/res/network/public-ip-prefix/main.json @@ -6,13 +6,33 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "13346619343009869073" + "templateHash": "12984545577624848737" }, "name": "Public IP Prefixes", "description": "This module deploys a Public IP Prefix.", "owner": "Azure/module-maintainers" }, "definitions": { + "ipTagType": { + "type": "object", + "properties": { + "ipTagType": { + "type": "string", + "metadata": { + "description": "Required. The IP tag type." + } + }, + "tag": { + "type": "string", + "metadata": { + "description": "Required. The IP tag." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, "lockType": { "type": "object", "properties": { @@ -36,80 +56,87 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -120,6 +147,17 @@ "description": "Required. The name of the Public IP Prefix." } }, + "tier": { + "type": "string", + "defaultValue": "Regional", + "allowedValues": [ + "Global", + "Regional" + ], + "metadata": { + "description": "Optional. Tier of a public IP prefix SKU. If set to `Global`, the `zones` property must be empty." + } + }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -130,19 +168,35 @@ "prefixLength": { "type": "int", "minValue": 21, - "maxValue": 31, + "maxValue": 127, "metadata": { "description": "Required. Length of the Public IP Prefix." } }, + "publicIPAddressVersion": { + "type": "string", + "defaultValue": "IPv4", + "allowedValues": [ + "IPv4", + "IPv6" + ], + "metadata": { + "description": "Optional. The public IP address version." + } + }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -161,6 +215,16 @@ "description": "Optional. The custom IP address prefix that this prefix is associated with. A custom IP address prefix is a contiguous range of IP addresses owned by an external customer and provisioned into a subscription. When a custom IP prefix is in Provisioned, Commissioning, or Commissioned state, a linked public IP prefix can be created. Either as a subset of the custom IP prefix range or the entire range." } }, + "ipTags": { + "type": "array", + "items": { + "$ref": "#/definitions/ipTagType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of tags associated with the public IP prefix." + } + }, "zones": { "type": "array", "items": { @@ -177,7 +241,7 @@ 3 ], "metadata": { - "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from." + "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from. This is only applicable for regional public IP prefixes and must be empty for global public IP prefixes." } }, "enableTelemetry": { @@ -228,18 +292,20 @@ }, "publicIpPrefix": { "type": "Microsoft.Network/publicIPPrefixes", - "apiVersion": "2023-09-01", + "apiVersion": "2024-01-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "sku": { - "name": "Standard" + "name": "Standard", + "tier": "[parameters('tier')]" }, "zones": "[map(parameters('zones'), lambda('zone', string(lambdaVariables('zone'))))]", "properties": { "customIPPrefix": "[if(not(empty(parameters('customIPPrefix'))), parameters('customIPPrefix'), null())]", - "publicIPAddressVersion": "IPv4", - "prefixLength": "[parameters('prefixLength')]" + "publicIPAddressVersion": "[parameters('publicIPAddressVersion')]", + "prefixLength": "[parameters('prefixLength')]", + "ipTags": "[parameters('ipTags')]" } }, "publicIpPrefix_lock": { @@ -306,7 +372,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('publicIpPrefix', '2023-09-01', 'full').location]" + "value": "[reference('publicIpPrefix', '2024-01-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep index 271d5ed8ee..1c5839fb3c 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/defaults/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-prefix/tests/e2e/ipv6/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/ipv6/main.test.bicep new file mode 100644 index 0000000000..701807e263 --- /dev/null +++ b/avm/res/network/public-ip-prefix/tests/e2e/ipv6/main.test.bicep @@ -0,0 +1,50 @@ +targetScope = 'subscription' + +metadata name = 'IPv6 Public IP Prefix' +metadata description = 'This instance deploys the module using the IPv6 version of the Public IP Prefix.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.publicipprefixes-${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 = 'npipip6' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + prefixLength: 127 + publicIPAddressVersion: 'IPv6' + } + } +] diff --git a/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep index 9e3d908bcb..c9148cc77e 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/max/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } @@ -88,6 +88,12 @@ module testDeployment '../../../main.bicep' = [ 1 2 ] + ipTags: [ + { + ipTagType: 'RoutingPreference' + tag: 'Internet' + } + ] } } ] diff --git a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep index 469fe72abf..ce435763ad 100644 --- a/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/public-ip-prefix/tests/e2e/waf-aligned/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-prefix/version.json b/avm/res/network/public-ip-prefix/version.json index a8eda31021..21226dd43f 100644 --- a/avm/res/network/public-ip-prefix/version.json +++ b/avm/res/network/public-ip-prefix/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.6", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/network/virtual-hub/README.md b/avm/res/network/virtual-hub/README.md index 33a3d5861a..1f2cfbe4f6 100644 --- a/avm/res/network/virtual-hub/README.md +++ b/avm/res/network/virtual-hub/README.md @@ -18,7 +18,7 @@ If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integ | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Network/virtualHubs` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs) | | `Microsoft.Network/virtualHubs/hubRouteTables` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubRouteTables) | -| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualHubs/hubVirtualNetworkConnections) | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualHubs/hubVirtualNetworkConnections) | | `Microsoft.Network/virtualHubs/routingIntent` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs/routingIntent) | ## Usage examples diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md index 256ef324ed..e5a1aca8d3 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md @@ -12,7 +12,7 @@ This module deploys a Virtual Hub Virtual Network Connection. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualHubs/hubVirtualNetworkConnections) | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualHubs/hubVirtualNetworkConnections) | ## Parameters diff --git a/avm/res/network/virtual-network/README.md b/avm/res/network/virtual-network/README.md index 32e2524cd7..517b60738f 100644 --- a/avm/res/network/virtual-network/README.md +++ b/avm/res/network/virtual-network/README.md @@ -13,6 +13,7 @@ This module deploys a Virtual Network (vNet). - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -23,9 +24,9 @@ This module deploys a Virtual Network (vNet). | `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.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/virtualNetworks` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks) | -| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/subnets) | -| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/virtualNetworkPeerings) | +| `Microsoft.Network/virtualNetworks` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks) | +| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/subnets) | +| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/virtualNetworkPeerings) | ## Usage examples @@ -1924,6 +1925,14 @@ If the encrypted VNet allows VM that does not support encryption. Can only be us | `subnetNames` | array | The names of the deployed subnets. | | `subnetResourceIds` | array | The resource IDs of the deployed subnets. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | + ## Notes ### Considerations diff --git a/avm/res/network/virtual-network/main.bicep b/avm/res/network/virtual-network/main.bicep index 563c8e6263..e991462e1f 100644 --- a/avm/res/network/virtual-network/main.bicep +++ b/avm/res/network/virtual-network/main.bicep @@ -40,15 +40,15 @@ param vnetEncryptionEnforcement string = 'AllowUnencrypted' @description('Optional. The flow timeout in minutes for the Virtual Network, which is used to enable connection tracking for intra-VM flows. Possible values are between 4 and 30 minutes. Default value 0 will set the property to null.') param flowTimeoutInMinutes int = 0 -import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingFullType[]? -import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') param lock lockType? -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? diff --git a/avm/res/network/virtual-network/main.json b/avm/res/network/virtual-network/main.json index 452624b4f6..70188e91b4 100644 --- a/avm/res/network/virtual-network/main.json +++ b/avm/res/network/virtual-network/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "14315915542626804458" + "templateHash": "17189690206142535748" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", @@ -371,7 +371,7 @@ "metadata": { "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -401,7 +401,7 @@ "metadata": { "description": "An AVM-aligned type for a lock.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -476,7 +476,7 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -827,7 +827,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6411714881793832751" + "templateHash": "6385219422012602265" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -905,7 +905,7 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -914,7 +914,7 @@ "name": { "type": "string", "metadata": { - "description": "Requird. The Name of the subnet resource." + "description": "Required. The Name of the subnet resource." } }, "virtualNetworkName": { diff --git a/avm/res/network/virtual-network/subnet/README.md b/avm/res/network/virtual-network/subnet/README.md index b88a552dc0..9f36e460a2 100644 --- a/avm/res/network/virtual-network/subnet/README.md +++ b/avm/res/network/virtual-network/subnet/README.md @@ -14,10 +14,16 @@ This module deploys a Virtual Network Subnet. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/subnets) | +| `Microsoft.Network/virtualNetworks/subnets` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/subnets) | ## Parameters +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The Name of the subnet resource. | + **Conditional parameters** | Parameter | Type | Description | @@ -43,11 +49,12 @@ This module deploys a Virtual Network Subnet. | [`serviceEndpoints`](#parameter-serviceendpoints) | array | The service endpoints to enable on the subnet. | | [`sharingScope`](#parameter-sharingscope) | string | Set this property to Tenant to allow sharing subnet with other subscriptions in your AAD tenant. This property can only be set if defaultOutboundAccess is set to false, both properties can only be set if subnet is empty. | -**Requird parameters** +### Parameter: `name` -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`name`](#parameter-name) | string | The Name of the subnet resource. | +The Name of the subnet resource. + +- Required: Yes +- Type: string ### Parameter: `addressPrefix` @@ -277,13 +284,6 @@ Set this property to Tenant to allow sharing subnet with other subscriptions in ] ``` -### Parameter: `name` - -The Name of the subnet resource. - -- Required: Yes -- Type: string - ## Outputs | Output | Type | Description | diff --git a/avm/res/network/virtual-network/subnet/main.bicep b/avm/res/network/virtual-network/subnet/main.bicep index b862584f0f..069b8887ae 100644 --- a/avm/res/network/virtual-network/subnet/main.bicep +++ b/avm/res/network/virtual-network/subnet/main.bicep @@ -2,7 +2,7 @@ metadata name = 'Virtual Network Subnets' metadata description = 'This module deploys a Virtual Network Subnet.' metadata owner = 'Azure/module-maintainers' -@description('Requird. The Name of the subnet resource.') +@description('Required. The Name of the subnet resource.') param name string @description('Conditional. The name of the parent virtual network. Required if the template is used in a standalone deployment.') @@ -57,7 +57,7 @@ param applicationGatewayIPConfigurations array = [] @description('Optional. An array of service endpoint policies.') param serviceEndpointPolicies array = [] -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? diff --git a/avm/res/network/virtual-network/subnet/main.json b/avm/res/network/virtual-network/subnet/main.json index 7df77e1cdb..4fdc5bc155 100644 --- a/avm/res/network/virtual-network/subnet/main.json +++ b/avm/res/network/virtual-network/subnet/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6411714881793832751" + "templateHash": "6385219422012602265" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -84,7 +84,7 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -93,7 +93,7 @@ "name": { "type": "string", "metadata": { - "description": "Requird. The Name of the subnet resource." + "description": "Required. The Name of the subnet resource." } }, "virtualNetworkName": { diff --git a/avm/res/network/virtual-network/virtual-network-peering/README.md b/avm/res/network/virtual-network/virtual-network-peering/README.md index 5c61182dc1..ef10225be1 100644 --- a/avm/res/network/virtual-network/virtual-network-peering/README.md +++ b/avm/res/network/virtual-network/virtual-network-peering/README.md @@ -12,7 +12,7 @@ This module deploys a Virtual Network Peering. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks/virtualNetworkPeerings) | +| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/virtualNetworks/virtualNetworkPeerings) | ## Parameters diff --git a/avm/res/operational-insights/workspace/README.md b/avm/res/operational-insights/workspace/README.md index 40a8d48755..5e62e5614e 100644 --- a/avm/res/operational-insights/workspace/README.md +++ b/avm/res/operational-insights/workspace/README.md @@ -27,6 +27,7 @@ This module deploys a Log Analytics Workspace. | `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.SecurityInsights/onboardingStates` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.SecurityInsights/onboardingStates) | ## Usage examples @@ -199,9 +200,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwadv001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ @@ -507,9 +509,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwadv001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } } ] }, @@ -825,9 +828,10 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwadv001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] param linkedServices = [ @@ -1153,9 +1157,25 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwmax001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(oiwmax001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(oiwmax001)' + plan: { + name: 'SQLAuditing(oiwmax001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] linkedServices: [ @@ -1178,6 +1198,7 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = managedIdentities: { systemAssigned: true } + onboardWorkspaceToSentinel: true publicNetworkAccessForIngestion: 'Disabled' publicNetworkAccessForQuery: 'Disabled' roleAssignments: [ @@ -1455,9 +1476,25 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwmax001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } + }, + { + "name": "SecurityInsights(oiwmax001)", + "plan": { + "product": "OMSGallery/SecurityInsights", + "publisher": "Microsoft" + } + }, + { + "name": "SQLAuditing(oiwmax001)", + "plan": { + "name": "SQLAuditing(oiwmax001)", + "product": "SQLAuditing", + "publisher": "Microsoft" + } } ] }, @@ -1491,6 +1528,9 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "systemAssigned": true } }, + "onboardWorkspaceToSentinel": { + "value": true + }, "publicNetworkAccessForIngestion": { "value": "Disabled" }, @@ -1773,9 +1813,25 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwmax001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(oiwmax001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(oiwmax001)' + plan: { + name: 'SQLAuditing(oiwmax001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] param linkedServices = [ @@ -1798,6 +1854,7 @@ param lock = { param managedIdentities = { systemAssigned: true } +param onboardWorkspaceToSentinel = true param publicNetworkAccessForIngestion = 'Disabled' param publicNetworkAccessForQuery = 'Disabled' param roleAssignments = [ @@ -2062,9 +2119,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwwaf001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ @@ -2231,9 +2289,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwwaf001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } } ] }, @@ -2408,9 +2467,10 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwwaf001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] param linkedServices = [ @@ -2483,6 +2543,7 @@ param useResourcePermissions = true | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both. | +| [`onboardWorkspaceToSentinel`](#parameter-onboardworkspacetosentinel) | bool | Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions. | | [`publicNetworkAccessForIngestion`](#parameter-publicnetworkaccessforingestion) | string | The network access type for accessing Log Analytics ingestion. | | [`publicNetworkAccessForQuery`](#parameter-publicnetworkaccessforquery) | string | The network access type for accessing Log Analytics query. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | @@ -2717,7 +2778,61 @@ List of gallerySolutions to be created in the log analytics workspace. - Required: No - Type: array -- Default: `[]` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsname) | string | Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. | +| [`plan`](#parameter-gallerysolutionsplan) | object | Plan for solution object supported by the OperationsManagement resource provider. | + +### Parameter: `gallerySolutions.name` + +Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan` + +Plan for solution object supported by the OperationsManagement resource provider. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`product`](#parameter-gallerysolutionsplanproduct) | string | The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsplanname) | string | Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. | +| [`publisher`](#parameter-gallerysolutionsplanpublisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. | + +### Parameter: `gallerySolutions.plan.product` + +The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan.name` + +Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. + +- Required: No +- Type: string + +### Parameter: `gallerySolutions.plan.publisher` + +The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. + +- Required: No +- Type: string ### Parameter: `linkedServices` @@ -2783,7 +2898,7 @@ The managed identity definition for this resource. Only one type of identity is | Parameter | Type | Description | | :-- | :-- | :-- | | [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.systemAssigned` @@ -2794,11 +2909,19 @@ Enables system assigned managed identity on the resource. ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. - Required: No - Type: array +### Parameter: `onboardWorkspaceToSentinel` + +Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions. + +- Required: No +- Type: bool +- Default: `False` + ### Parameter: `publicNetworkAccessForIngestion` The network access type for accessing Log Analytics ingestion. @@ -3023,7 +3146,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/operations-management/solution:0.1.0` | Remote reference | +| `br/public:avm/res/operations-management/solution:0.3.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/operational-insights/workspace/data-export/main.json b/avm/res/operational-insights/workspace/data-export/main.json index baaf6389a0..50543665cd 100644 --- a/avm/res/operational-insights/workspace/data-export/main.json +++ b/avm/res/operational-insights/workspace/data-export/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8816832199581598050" + "version": "0.31.34.60546", + "templateHash": "6471227851268955186" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", diff --git a/avm/res/operational-insights/workspace/data-source/main.json b/avm/res/operational-insights/workspace/data-source/main.json index e559599820..632303522e 100644 --- a/avm/res/operational-insights/workspace/data-source/main.json +++ b/avm/res/operational-insights/workspace/data-source/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10275938611959517944" + "version": "0.31.34.60546", + "templateHash": "8463454444688288974" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", @@ -152,10 +152,7 @@ "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": { diff --git a/avm/res/operational-insights/workspace/linked-service/main.json b/avm/res/operational-insights/workspace/linked-service/main.json index 6bf582c2f8..9486a71e8c 100644 --- a/avm/res/operational-insights/workspace/linked-service/main.json +++ b/avm/res/operational-insights/workspace/linked-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1524032160953098939" + "version": "0.31.34.60546", + "templateHash": "13253888384545811424" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -62,10 +62,7 @@ "properties": { "resourceId": "[parameters('resourceId')]", "writeAccessResourceId": "[if(empty(parameters('writeAccessResourceId')), null(), parameters('writeAccessResourceId'))]" - }, - "dependsOn": [ - "workspace" - ] + } } }, "outputs": { diff --git a/avm/res/operational-insights/workspace/linked-storage-account/main.json b/avm/res/operational-insights/workspace/linked-storage-account/main.json index b3493c8095..01c473ad05 100644 --- a/avm/res/operational-insights/workspace/linked-storage-account/main.json +++ b/avm/res/operational-insights/workspace/linked-storage-account/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16040380910189891293" + "version": "0.31.34.60546", + "templateHash": "14472959311832661205" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", diff --git a/avm/res/operational-insights/workspace/main.bicep b/avm/res/operational-insights/workspace/main.bicep index b5be253202..22cfc7ffd3 100644 --- a/avm/res/operational-insights/workspace/main.bicep +++ b/avm/res/operational-insights/workspace/main.bicep @@ -48,7 +48,10 @@ param dataSources array = [] param tables array = [] @description('Optional. List of gallerySolutions to be created in the log analytics workspace.') -param gallerySolutions array = [] +param gallerySolutions gallerySolutionType[]? + +@description('Optional. Onboard the Log Analytics Workspace to Sentinel. Requires \'SecurityInsights\' solution to be in gallerySolutions.') +param onboardWorkspaceToSentinel bool = false @description('Optional. Number of days data will be retained for.') @minValue(0) @@ -73,23 +76,26 @@ param publicNetworkAccessForIngestion string = 'Enabled' ]) param publicNetworkAccessForQuery string = 'Enabled' +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? @description('Optional. Set to \'true\' to use resource or workspace permissions and \'false\' (or leave empty) to require workspace permissions.') param useResourcePermissions bool = false @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingType[]? @description('Optional. Indicates whether customer managed storage is mandatory for query management.') param forceCmkForQuery bool = true +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -342,20 +348,29 @@ module logAnalyticsWorkspace_tables 'table/main.bicep' = [ } ] -module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [ - for (gallerySolution, index) in gallerySolutions: if (!empty(gallerySolutions)) { +module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.3.0' = [ + for (gallerySolution, index) in gallerySolutions ?? []: if (!empty(gallerySolutions)) { name: '${uniqueString(deployment().name, location)}-LAW-Solution-${index}' params: { name: gallerySolution.name location: location logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - product: gallerySolution.?product - publisher: gallerySolution.?publisher + plan: gallerySolution.plan enableTelemetry: gallerySolution.?enableTelemetry ?? enableTelemetry } } ] +// Onboard the Log Analytics Workspace to Sentinel if SecurityInsights is in gallerySolutions and onboardWorkspaceToSentinel is set to true +resource logAnalyticsWorkspace_sentinelOnboarding 'Microsoft.SecurityInsights/onboardingStates@2024-03-01' = if (!empty(filter( + gallerySolutions ?? [], + item => startsWith(item.name, 'SecurityInsights') +)) && onboardWorkspaceToSentinel) { + name: 'default' + scope: logAnalyticsWorkspace + properties: {} +} + resource logAnalyticsWorkspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' properties: { @@ -409,48 +424,6 @@ output systemAssignedMIPrincipalId string = logAnalyticsWorkspace.?identity.?pri // 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.') - userAssignedResourceIds: string[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? @@ -496,4 +469,18 @@ type diagnosticSettingType = { @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') marketplacePartnerResourceId: string? -}[]? +} + +import { solutionPlanType } from 'br/public:avm/res/operations-management/solution:0.3.0' + +@export() +type gallerySolutionType = { + @description('''Required. Name of the solution. + For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`. + For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`. + The solution type is case-sensitive.''') + name: string + + @description('Required. Plan for solution object supported by the OperationsManagement resource provider.') + plan: solutionPlanType +} diff --git a/avm/res/operational-insights/workspace/main.json b/avm/res/operational-insights/workspace/main.json index f9386570de..5b7a4ae798 100644 --- a/avm/res/operational-insights/workspace/main.json +++ b/avm/res/operational-insights/workspace/main.json @@ -5,36 +5,156 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2112385645205183034" + "version": "0.31.34.60546", + "templateHash": "13803826230764856157" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "diagnosticSettingType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "name": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "Optional. The name of diagnostic setting." } }, - "userAssignedResourceIds": { + "logCategoriesAndGroups": { "type": "array", "items": { - "type": "string" + "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 resource ID(s) to assign to the resource." + "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." + } + } + } + }, + "gallerySolutionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "lockType": { "type": "object", @@ -59,207 +179,145 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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." - } + "managedIdentityAllType": { + "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" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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." - } + "roleAssignmentType": { + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/res/operations-management/solution:0.3.0" + } + } } }, "parameters": { @@ -353,11 +411,21 @@ }, "gallerySolutions": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/gallerySolutionType" + }, + "nullable": true, "metadata": { "description": "Optional. List of gallerySolutions to be created in the log analytics workspace." } }, + "onboardWorkspaceToSentinel": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions." + } + }, "dataRetention": { "type": "int", "defaultValue": 365, @@ -398,7 +466,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "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." } @@ -411,7 +480,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -425,12 +498,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -561,6 +639,17 @@ "logAnalyticsWorkspace" ] }, + "logAnalyticsWorkspace_sentinelOnboarding": { + "condition": "[and(not(empty(filter(coalesce(parameters('gallerySolutions'), createArray()), lambda('item', startsWith(lambdaVariables('item').name, 'SecurityInsights'))))), parameters('onboardWorkspaceToSentinel'))]", + "type": "Microsoft.SecurityInsights/onboardingStates", + "apiVersion": "2024-03-01", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", + "name": "default", + "properties": {}, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, "logAnalyticsWorkspace_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", @@ -631,8 +720,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8028201980853199520" + "version": "0.31.34.60546", + "templateHash": "4634762044709818669" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", @@ -705,11 +794,7 @@ "id": "[parameters('storageAccountResourceId')]", "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2022-09-01').keys[0].value]" } - }, - "dependsOn": [ - "storageAccount", - "workspace" - ] + } } }, "outputs": { @@ -775,8 +860,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1524032160953098939" + "version": "0.31.34.60546", + "templateHash": "13253888384545811424" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service.", @@ -832,10 +917,7 @@ "properties": { "resourceId": "[parameters('resourceId')]", "writeAccessResourceId": "[if(empty(parameters('writeAccessResourceId')), null(), parameters('writeAccessResourceId'))]" - }, - "dependsOn": [ - "workspace" - ] + } } }, "outputs": { @@ -897,8 +979,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16040380910189891293" + "version": "0.31.34.60546", + "templateHash": "14472959311832661205" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account.", @@ -1020,8 +1102,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7572266675487147820" + "version": "0.31.34.60546", + "templateHash": "1097692446107685243" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", @@ -1114,10 +1196,7 @@ "functionAlias": "[parameters('functionAlias')]", "functionParameters": "[parameters('functionParameters')]", "version": "[parameters('version')]" - }, - "dependsOn": [ - "workspace" - ] + } } }, "outputs": { @@ -1186,8 +1265,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8816832199581598050" + "version": "0.31.34.60546", + "templateHash": "6471227851268955186" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export.", @@ -1335,8 +1414,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10275938611959517944" + "version": "0.31.34.60546", + "templateHash": "8463454444688288974" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source.", @@ -1482,10 +1561,7 @@ "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": { @@ -1566,8 +1642,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2417830359794202602" + "version": "0.31.34.60546", + "templateHash": "7459975468074908308" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", @@ -1575,77 +1651,79 @@ }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -1712,7 +1790,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -1756,10 +1838,7 @@ "schema": "[parameters('schema')]", "searchResults": "[parameters('searchResults')]", "totalRetentionInDays": "[parameters('totalRetentionInDays')]" - }, - "dependsOn": [ - "workspace" - ] + } }, "table_roleAssignments": { "copy": { @@ -1816,7 +1895,7 @@ "logAnalyticsWorkspace_solutions": { "copy": { "name": "logAnalyticsWorkspace_solutions", - "count": "[length(parameters('gallerySolutions'))]" + "count": "[length(coalesce(parameters('gallerySolutions'), createArray()))]" }, "condition": "[not(empty(parameters('gallerySolutions')))]", "type": "Microsoft.Resources/deployments", @@ -1829,7 +1908,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('gallerySolutions')[copyIndex()].name]" + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].name]" }, "location": { "value": "[parameters('location')]" @@ -1837,34 +1916,68 @@ "logAnalyticsWorkspaceName": { "value": "[parameters('name')]" }, - "product": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'product')]" - }, - "publisher": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'publisher')]" + "plan": { + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].plan]" }, "enableTelemetry": { - "value": "[coalesce(tryGet(parameters('gallerySolutions')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + "value": "[coalesce(tryGet(coalesce(parameters('gallerySolutions'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "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.23.1.45101", - "templateHash": "18444780972506374592" + "version": "0.30.23.60470", + "templateHash": "1867653058254938383" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", "owner": "Azure/module-maintainers" }, + "definitions": { + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "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})`." + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } }, "logAnalyticsWorkspaceName": { @@ -1880,20 +1993,6 @@ "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, @@ -1902,16 +2001,12 @@ } } }, - "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": [ - { + "resources": { + "avmTelemetry": { "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))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.3.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1927,36 +2022,45 @@ } } }, - { + "logAnalyticsWorkspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "solution": { "type": "Microsoft.OperationsManagement/solutions", "apiVersion": "2015-11-01-preview", - "name": "[variables('solutionName')]", + "name": "[parameters('name')]", "location": "[parameters('location')]", "properties": { "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" }, "plan": { - "name": "[variables('solutionName')]", + "name": "[coalesce(tryGet(parameters('plan'), 'name'), parameters('name'))]", "promotionCode": "", - "product": "[variables('solutionProduct')]", - "publisher": "[parameters('publisher')]" - } + "product": "[parameters('plan').product]", + "publisher": "[coalesce(tryGet(parameters('plan'), 'publisher'), 'Microsoft')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the deployed solution." }, - "value": "[variables('solutionName')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed solution." }, - "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + "value": "[resourceId('Microsoft.OperationsManagement/solutions', parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -1970,7 +2074,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + "value": "[reference('solution', '2015-11-01-preview', 'full').location]" } } } diff --git a/avm/res/operational-insights/workspace/saved-search/main.json b/avm/res/operational-insights/workspace/saved-search/main.json index 40406ef502..94d7355386 100644 --- a/avm/res/operational-insights/workspace/saved-search/main.json +++ b/avm/res/operational-insights/workspace/saved-search/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7572266675487147820" + "version": "0.31.34.60546", + "templateHash": "1097692446107685243" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search.", @@ -99,10 +99,7 @@ "functionAlias": "[parameters('functionAlias')]", "functionParameters": "[parameters('functionParameters')]", "version": "[parameters('version')]" - }, - "dependsOn": [ - "workspace" - ] + } } }, "outputs": { diff --git a/avm/res/operational-insights/workspace/storage-insight-config/main.json b/avm/res/operational-insights/workspace/storage-insight-config/main.json index 39a0d3e3f5..58fde53976 100644 --- a/avm/res/operational-insights/workspace/storage-insight-config/main.json +++ b/avm/res/operational-insights/workspace/storage-insight-config/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8028201980853199520" + "version": "0.31.34.60546", + "templateHash": "4634762044709818669" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config.", @@ -79,11 +79,7 @@ "id": "[parameters('storageAccountResourceId')]", "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', last(split(parameters('storageAccountResourceId'), '/'))), '2022-09-01').keys[0].value]" } - }, - "dependsOn": [ - "storageAccount", - "workspace" - ] + } } }, "outputs": { diff --git a/avm/res/operational-insights/workspace/table/README.md b/avm/res/operational-insights/workspace/table/README.md index dc20f643c0..4418b50f3b 100644 --- a/avm/res/operational-insights/workspace/table/README.md +++ b/avm/res/operational-insights/workspace/table/README.md @@ -7,6 +7,7 @@ This module deploys a Log Analytics Workspace Table. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -224,3 +225,11 @@ The table total retention in days, between 4 and 2555. Setting this property to | `name` | string | The name of the table. | | `resourceGroupName` | string | The name of the resource group the table was created in. | | `resourceId` | string | The resource ID of the table. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/operational-insights/workspace/table/main.bicep b/avm/res/operational-insights/workspace/table/main.bicep index b38ff9210f..ad3323e998 100644 --- a/avm/res/operational-insights/workspace/table/main.bicep +++ b/avm/res/operational-insights/workspace/table/main.bicep @@ -38,8 +38,9 @@ param searchResults object = {} @maxValue(2555) param totalRetentionInDays int = -1 +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -135,29 +136,3 @@ output resourceGroupName string = resourceGroup().name // =============== // // Definitions // // =============== // - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? diff --git a/avm/res/operational-insights/workspace/table/main.json b/avm/res/operational-insights/workspace/table/main.json index 9c038008cd..25942c72b9 100644 --- a/avm/res/operational-insights/workspace/table/main.json +++ b/avm/res/operational-insights/workspace/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2417830359794202602" + "version": "0.31.34.60546", + "templateHash": "7459975468074908308" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", @@ -14,77 +14,79 @@ }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -151,7 +153,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -195,10 +201,7 @@ "schema": "[parameters('schema')]", "searchResults": "[parameters('searchResults')]", "totalRetentionInDays": "[parameters('totalRetentionInDays')]" - }, - "dependsOn": [ - "workspace" - ] + } }, "table_roleAssignments": { "copy": { diff --git a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep index 94d627e6a7..9fe570be9d 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep @@ -186,9 +186,10 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ diff --git a/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep index 4b277bc3f5..1c9fde140b 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep @@ -175,11 +175,28 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(${namePrefix}${serviceShort}001)' + plan: { + name: 'SQLAuditing(${namePrefix}${serviceShort}001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] + onboardWorkspaceToSentinel: true linkedServices: [ { name: 'Automation' diff --git a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep index 62e91d5492..9819017c8c 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -168,9 +168,10 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ diff --git a/avm/res/operational-insights/workspace/version.json b/avm/res/operational-insights/workspace/version.json index 7e1d3f4157..9a9a06e897 100644 --- a/avm/res/operational-insights/workspace/version.json +++ b/avm/res/operational-insights/workspace/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.8", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/operations-management/solution/README.md b/avm/res/operations-management/solution/README.md index f8f05da8f6..6d4b835b48 100644 --- a/avm/res/operations-management/solution/README.md +++ b/avm/res/operations-management/solution/README.md @@ -27,7 +27,8 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Microsoft solution](#example-2-microsoft-solution) - [Non-Microsoft solution](#example-3-non-microsoft-solution) -- [WAF-aligned](#example-4-waf-aligned) +- [SQLAuditing solution](#example-4-sqlauditing-solution) +- [WAF-aligned](#example-5-waf-aligned) ### Example 1: _Using only defaults_ @@ -44,7 +45,10 @@ module solution 'br/public:avm/res/operations-management/solution:' = { params: { // Required parameters logAnalyticsWorkspaceName: '' - name: 'Updates' + name: '' + plan: { + product: 'OMSGallery/Updates' + } // Non-required parameters location: '' } @@ -68,7 +72,12 @@ module solution 'br/public:avm/res/operations-management/solution:' = { "value": "" }, "name": { - "value": "Updates" + "value": "" + }, + "plan": { + "value": { + "product": "OMSGallery/Updates" + } }, // Non-required parameters "location": { @@ -90,7 +99,10 @@ using 'br/public:avm/res/operations-management/solution:' // Required parameters param logAnalyticsWorkspaceName = '' -param name = 'Updates' +param name = '' +param plan = { + product: 'OMSGallery/Updates' +} // Non-required parameters param location = '' ``` @@ -113,11 +125,12 @@ module solution 'br/public:avm/res/operations-management/solution:' = { params: { // Required parameters logAnalyticsWorkspaceName: '' - name: 'AzureAutomation' + name: '' + plan: { + product: 'OMSGallery/AzureAutomation' + } // Non-required parameters location: '' - product: 'OMSGallery' - publisher: 'Microsoft' } } ``` @@ -139,17 +152,16 @@ module solution 'br/public:avm/res/operations-management/solution:' = { "value": "" }, "name": { - "value": "AzureAutomation" + "value": "" + }, + "plan": { + "value": { + "product": "OMSGallery/AzureAutomation" + } }, // Non-required parameters "location": { "value": "" - }, - "product": { - "value": "OMSGallery" - }, - "publisher": { - "value": "Microsoft" } } } @@ -167,11 +179,12 @@ using 'br/public:avm/res/operations-management/solution:' // Required parameters param logAnalyticsWorkspaceName = '' -param name = 'AzureAutomation' +param name = '' +param plan = { + product: 'OMSGallery/AzureAutomation' +} // Non-required parameters param location = '' -param product = 'OMSGallery' -param publisher = 'Microsoft' ``` @@ -193,10 +206,13 @@ module solution 'br/public:avm/res/operations-management/solution:' = { // Required parameters logAnalyticsWorkspaceName: '' name: 'omsnonms001' + plan: { + name: 'nonmsTestSolutionPlan' + product: 'nonmsTestSolutionProduct' + publisher: 'nonmsTestSolutionPublisher' + } // Non-required parameters location: '' - product: 'nonmsTestSolutionProduct' - publisher: 'nonmsTestSolutionPublisher' } } ``` @@ -220,15 +236,16 @@ module solution 'br/public:avm/res/operations-management/solution:' = { "name": { "value": "omsnonms001" }, + "plan": { + "value": { + "name": "nonmsTestSolutionPlan", + "product": "nonmsTestSolutionProduct", + "publisher": "nonmsTestSolutionPublisher" + } + }, // Non-required parameters "location": { "value": "" - }, - "product": { - "value": "nonmsTestSolutionProduct" - }, - "publisher": { - "value": "nonmsTestSolutionPublisher" } } } @@ -247,18 +264,21 @@ using 'br/public:avm/res/operations-management/solution:' // Required parameters param logAnalyticsWorkspaceName = '' param name = 'omsnonms001' +param plan = { + name: 'nonmsTestSolutionPlan' + product: 'nonmsTestSolutionProduct' + publisher: 'nonmsTestSolutionPublisher' +} // Non-required parameters param location = '' -param product = 'nonmsTestSolutionProduct' -param publisher = 'nonmsTestSolutionPublisher' ```

    -### Example 4: _WAF-aligned_ +### Example 4: _SQLAuditing solution_ -This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. +This instance deploys the module with the SQLAuditing solution. This solution is authored by Microsoft, but uses a non-standard value for the `product` parameter.

    @@ -271,11 +291,13 @@ module solution 'br/public:avm/res/operations-management/solution:' = { params: { // Required parameters logAnalyticsWorkspaceName: '' - name: 'AzureAutomation' + name: '' + plan: { + product: 'SQLAuditing' + publisher: 'Microsoft' + } // Non-required parameters location: '' - product: 'OMSGallery' - publisher: 'Microsoft' } } ``` @@ -297,17 +319,102 @@ module solution 'br/public:avm/res/operations-management/solution:' = { "value": "" }, "name": { - "value": "AzureAutomation" + "value": "" + }, + "plan": { + "value": { + "product": "SQLAuditing", + "publisher": "Microsoft" + } }, // Non-required parameters "location": { "value": "" + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/operations-management/solution:' + +// Required parameters +param logAnalyticsWorkspaceName = '' +param name = '' +param plan = { + product: 'SQLAuditing' + publisher: 'Microsoft' +} +// Non-required parameters +param location = '' +``` + +
    +

    + +### Example 5: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

    + +via Bicep module + +```bicep +module solution 'br/public:avm/res/operations-management/solution:' = { + name: 'solutionDeployment' + params: { + // Required parameters + logAnalyticsWorkspaceName: '' + name: '' + plan: { + name: '' + product: 'OMSGallery/AzureAutomation' + publisher: 'Microsoft' + } + // Non-required parameters + location: '' + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "logAnalyticsWorkspaceName": { + "value": "" + }, + "name": { + "value": "" }, - "product": { - "value": "OMSGallery" + "plan": { + "value": { + "name": "", + "product": "OMSGallery/AzureAutomation", + "publisher": "Microsoft" + } }, - "publisher": { - "value": "Microsoft" + // Non-required parameters + "location": { + "value": "" } } } @@ -325,11 +432,14 @@ using 'br/public:avm/res/operations-management/solution:' // Required parameters param logAnalyticsWorkspaceName = '' -param name = 'AzureAutomation' +param name = '' +param plan = { + name: '' + product: 'OMSGallery/AzureAutomation' + publisher: 'Microsoft' +} // Non-required parameters param location = '' -param product = 'OMSGallery' -param publisher = 'Microsoft' ```
    @@ -342,7 +452,8 @@ param publisher = 'Microsoft' | Parameter | Type | Description | | :-- | :-- | :-- | | [`logAnalyticsWorkspaceName`](#parameter-loganalyticsworkspacename) | string | Name of the Log Analytics workspace where the solution will be deployed/enabled. | -| [`name`](#parameter-name) | string | Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`. | +| [`name`](#parameter-name) | string | Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. | +| [`plan`](#parameter-plan) | object | Plan for solution object supported by the OperationsManagement resource provider. | **Optional parameters** @@ -350,8 +461,6 @@ param publisher = 'Microsoft' | :-- | :-- | :-- | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`location`](#parameter-location) | string | Location for all resources. | -| [`product`](#parameter-product) | string | 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`](#parameter-publisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`. | ### Parameter: `logAnalyticsWorkspaceName` @@ -362,42 +471,67 @@ Name of the Log Analytics workspace where the solution will be deployed/enabled. ### Parameter: `name` -Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`. +Name of the solution.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

    The solution type is case-sensitive. - Required: Yes - Type: string -### Parameter: `enableTelemetry` +### Parameter: `plan` -Enable/Disable usage telemetry for module. +Plan for solution object supported by the OperationsManagement resource provider. -- Required: No -- Type: bool -- Default: `True` +- Required: Yes +- Type: object -### Parameter: `location` +**Required parameters** -Location for all resources. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`product`](#parameter-planproduct) | string | The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-planname) | string | Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. | +| [`publisher`](#parameter-planpublisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. | + +### Parameter: `plan.product` + +The product name of the deployed solution.

    For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

    For a third party solution, it can be anything.

    This is case sensitive. + +- Required: Yes +- Type: string + +### Parameter: `plan.name` + +Name of the solution to be created.

    For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

    For solutions authored by third parties, it can be anything.

    The solution type is case-sensitive.

    If not provided, the value of the `name` parameter will be used. - Required: No - Type: string -- Default: `[resourceGroup().location]` -### Parameter: `product` +### Parameter: `plan.publisher` -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. +The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. - Required: No - Type: string -- Default: `'OMSGallery'` -### Parameter: `publisher` +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` -The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`. +### Parameter: `location` + +Location for all resources. - Required: No - Type: string -- Default: `'Microsoft'` +- Default: `[resourceGroup().location]` ## Outputs diff --git a/avm/res/operations-management/solution/main.bicep b/avm/res/operations-management/solution/main.bicep index 3a98c1a92f..cfe628cad7 100644 --- a/avm/res/operations-management/solution/main.bicep +++ b/avm/res/operations-management/solution/main.bicep @@ -2,21 +2,21 @@ metadata name = 'Operations Management Solutions' metadata description = 'This module deploys an Operations Management Solution.' metadata owner = 'Azure/module-maintainers' -@description('Required. Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`.') +@description('''Required. Name of the solution. +For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`. +For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`. +The solution type is case-sensitive.''') param name string +@description('Required. Plan for solution object supported by the OperationsManagement resource provider.') +param plan solutionPlanType + @description('Required. Name of the Log Analytics workspace where the solution will be deployed/enabled.') param logAnalyticsWorkspaceName string @description('Optional. Location for all resources.') param location string = resourceGroup().location -@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.') -param product string = 'OMSGallery' - -@description('Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`.') -param publisher string = 'Microsoft' - @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -43,21 +43,17 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06 name: logAnalyticsWorkspaceName } -var solutionName = publisher == 'Microsoft' ? '${name}(${logAnalyticsWorkspace.name})' : name - -var solutionProduct = publisher == 'Microsoft' ? 'OMSGallery/${name}' : product - resource solution 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = { - name: solutionName + name: name location: location properties: { workspaceResourceId: logAnalyticsWorkspace.id } plan: { - name: solutionName + name: plan.?name ?? name promotionCode: '' - product: solutionProduct - publisher: publisher + product: plan.product + publisher: plan.?publisher ?? 'Microsoft' } } @@ -72,3 +68,26 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = solution.location + +// =============== // +// Definitions // +// =============== // + +@export() +type solutionPlanType = { + @description('''Optional. Name of the solution to be created. + For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`. + For solutions authored by third parties, it can be anything. + The solution type is case-sensitive. + If not provided, the value of the `name` parameter will be used.''') + name: string? + + @description('''Required. The product name of the deployed solution. + For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`. + For a third party solution, it can be anything. + This is case sensitive.''') + product: string + + @description('Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value.') + publisher: string? +} diff --git a/avm/res/operations-management/solution/main.json b/avm/res/operations-management/solution/main.json index 4153919039..91a3ab0d52 100644 --- a/avm/res/operations-management/solution/main.json +++ b/avm/res/operations-management/solution/main.json @@ -1,21 +1,58 @@ { "$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": "13605710277319315849" + "version": "0.30.23.60470", + "templateHash": "787568686333677059" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", "owner": "Azure/module-maintainers" }, + "definitions": { + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "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})`." + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } }, "logAnalyticsWorkspaceName": { @@ -31,20 +68,6 @@ "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, @@ -53,12 +76,8 @@ } } }, - "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": [ - { + "resources": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", @@ -78,36 +97,45 @@ } } }, - { + "logAnalyticsWorkspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "solution": { "type": "Microsoft.OperationsManagement/solutions", "apiVersion": "2015-11-01-preview", - "name": "[variables('solutionName')]", + "name": "[parameters('name')]", "location": "[parameters('location')]", "properties": { "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" }, "plan": { - "name": "[variables('solutionName')]", + "name": "[coalesce(tryGet(parameters('plan'), 'name'), parameters('name'))]", "promotionCode": "", - "product": "[variables('solutionProduct')]", - "publisher": "[parameters('publisher')]" - } + "product": "[parameters('plan').product]", + "publisher": "[coalesce(tryGet(parameters('plan'), 'publisher'), 'Microsoft')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the deployed solution." }, - "value": "[variables('solutionName')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed solution." }, - "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + "value": "[resourceId('Microsoft.OperationsManagement/solutions', parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -121,7 +149,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + "value": "[reference('solution', '2015-11-01-preview', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep index 8be0e169ad..ce2cc0cec8 100644 --- a/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep +++ b/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep @@ -48,7 +48,10 @@ module testDeployment '../../../main.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' params: { - name: 'Updates' + name: 'Updates(${nestedDependencies.outputs.logAnalyticsWorkspaceName})' + plan: { + product: 'OMSGallery/Updates' + } location: resourceLocation logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName } diff --git a/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep index 314aae1901..66af8a8ab1 100644 --- a/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep +++ b/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep @@ -48,10 +48,11 @@ module testDeployment '../../../main.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' params: { - name: 'AzureAutomation' + name: 'AzureAutomation(${nestedDependencies.outputs.logAnalyticsWorkspaceName})' location: resourceLocation logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName - product: 'OMSGallery' - publisher: 'Microsoft' + plan: { + product: 'OMSGallery/AzureAutomation' + } } } diff --git a/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep index c5211d6040..97a79ad525 100644 --- a/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep +++ b/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep @@ -51,7 +51,10 @@ module testDeployment '../../../main.bicep' = { name: '${namePrefix}${serviceShort}001' location: resourceLocation logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName - product: 'nonmsTestSolutionProduct' - publisher: 'nonmsTestSolutionPublisher' + plan: { + name: 'nonmsTestSolutionPlan' + product: 'nonmsTestSolutionProduct' + publisher: 'nonmsTestSolutionPublisher' + } } } diff --git a/avm/res/operations-management/solution/tests/e2e/sql-auditing/dependencies.bicep b/avm/res/operations-management/solution/tests/e2e/sql-auditing/dependencies.bicep new file mode 100644 index 0000000000..ef3592fb5f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/sql-auditing/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The name of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/avm/res/operations-management/solution/tests/e2e/sql-auditing/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/sql-auditing/main.test.bicep new file mode 100644 index 0000000000..881e251f49 --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/sql-auditing/main.test.bicep @@ -0,0 +1,59 @@ +targetScope = 'subscription' + +metadata name = 'SQLAuditing solution' +metadata description = 'This instance deploys the module with the SQLAuditing solution. This solution is authored by Microsoft, but uses a non-standard value for the `product` parameter.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-operationsmanagement.solutions-${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 = 'omssqa' + +@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 +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: 'SQLAuditing(${nestedDependencies.outputs.logAnalyticsWorkspaceName})' + location: resourceLocation + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + plan: { + product: 'SQLAuditing' + publisher: 'Microsoft' + } + } +} diff --git a/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep index 606797373d..0d5167193e 100644 --- a/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep @@ -50,11 +50,14 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: 'AzureAutomation' + name: 'AzureAutomation(${nestedDependencies.outputs.logAnalyticsWorkspaceName})' location: resourceLocation logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName - product: 'OMSGallery' - publisher: 'Microsoft' + plan: { + name: 'AzureAutomation(${nestedDependencies.outputs.logAnalyticsWorkspaceName})' + product: 'OMSGallery/AzureAutomation' + publisher: 'Microsoft' + } } } ] diff --git a/avm/res/operations-management/solution/version.json b/avm/res/operations-management/solution/version.json index 83083db694..17dd49a0b9 100644 --- a/avm/res/operations-management/solution/version.json +++ b/avm/res/operations-management/solution/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", - "pathFilters": [ - "./main.json" - ] -} \ No newline at end of file + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.3", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/purview/account/README.md b/avm/res/purview/account/README.md index cb24aad194..1abd9cda78 100644 --- a/avm/res/purview/account/README.md +++ b/avm/res/purview/account/README.md @@ -3452,6 +3452,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/purview/account/main.bicep b/avm/res/purview/account/main.bicep index 025b0371b0..e3ec79f296 100644 --- a/avm/res/purview/account/main.bicep +++ b/avm/res/purview/account/main.bicep @@ -13,7 +13,7 @@ param location string = resourceGroup().location @description('Optional. Tags of the resource.') param tags object? -import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.1.0' +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') param managedIdentities managedIdentityOnlyUserAssignedType? diff --git a/avm/res/purview/account/main.json b/avm/res/purview/account/main.json index 1b147c97ac..20e38c94f8 100644 --- a/avm/res/purview/account/main.json +++ b/avm/res/purview/account/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "3897776991818014507" + "templateHash": "6120060466877826337" }, "name": "Purview Accounts", "description": "This module deploys a Purview Account.", @@ -468,7 +468,7 @@ "metadata": { "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.1.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } diff --git a/avm/res/relay/namespace/README.md b/avm/res/relay/namespace/README.md index 026971ecfd..0470949e3d 100644 --- a/avm/res/relay/namespace/README.md +++ b/avm/res/relay/namespace/README.md @@ -994,7 +994,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -1104,7 +1104,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -1208,22 +1208,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -1234,7 +1234,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -1274,7 +1274,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -1288,7 +1288,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -1352,7 +1352,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -1402,14 +1402,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -1418,7 +1418,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -1428,7 +1428,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -1443,7 +1443,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1454,7 +1454,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -1475,7 +1475,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -1590,14 +1590,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1754,6 +1754,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/relay/namespace/authorization-rule/main.json b/avm/res/relay/namespace/authorization-rule/main.json index 1dcf45602b..7862acd2c2 100644 --- a/avm/res/relay/namespace/authorization-rule/main.json +++ b/avm/res/relay/namespace/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13234316448276715063" + "version": "0.30.23.60470", + "templateHash": "9137586793857005081" }, "name": "Relay Namespace Authorization Rules", "description": "This module deploys a Relay Namespace Authorization Rule.", diff --git a/avm/res/relay/namespace/hybrid-connection/authorization-rule/main.json b/avm/res/relay/namespace/hybrid-connection/authorization-rule/main.json index 01bb4c827b..645ef9e6c1 100644 --- a/avm/res/relay/namespace/hybrid-connection/authorization-rule/main.json +++ b/avm/res/relay/namespace/hybrid-connection/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "11780139902470137859" + "version": "0.30.23.60470", + "templateHash": "4431168643851665214" }, "name": "Hybrid Connection Authorization Rules", "description": "This module deploys a Hybrid Connection Authorization Rule.", diff --git a/avm/res/relay/namespace/hybrid-connection/main.json b/avm/res/relay/namespace/hybrid-connection/main.json index b5807ecc0d..6b8fe5109b 100644 --- a/avm/res/relay/namespace/hybrid-connection/main.json +++ b/avm/res/relay/namespace/hybrid-connection/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "3066452421480890151" + "version": "0.30.23.60470", + "templateHash": "16821503954722419440" }, "name": "Relay Namespace Hybrid Connections", "description": "This module deploys a Relay Namespace Hybrid Connection.", @@ -290,8 +290,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "11780139902470137859" + "version": "0.30.23.60470", + "templateHash": "4431168643851665214" }, "name": "Hybrid Connection Authorization Rules", "description": "This module deploys a Hybrid Connection Authorization Rule.", diff --git a/avm/res/relay/namespace/main.bicep b/avm/res/relay/namespace/main.bicep index c3afc10479..95847ac31a 100644 --- a/avm/res/relay/namespace/main.bicep +++ b/avm/res/relay/namespace/main.bicep @@ -28,17 +28,21 @@ param authorizationRules array = [ } ] +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? @description('Optional. Configure networking options for Relay. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace.') param networkRuleSets object = {} @@ -354,172 +358,3 @@ output privateEndpoints array = [ networkInterfaceIds: namespace_privateEndpoints[i].outputs.networkInterfaceIds } ] - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? diff --git a/avm/res/relay/namespace/main.json b/avm/res/relay/namespace/main.json index 8c8228f6fc..9f8094485f 100644 --- a/avm/res/relay/namespace/main.json +++ b/avm/res/relay/namespace/main.json @@ -6,450 +6,490 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "7064419851782803288" + "templateHash": "14262477260882181529" }, "name": "Relay Namespaces", "description": "This module deploys a Relay Namespace", "owner": "Azure/module-maintainers" }, "definitions": { - "lockType": { + "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { - "name": { + "fqdn": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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." + "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." + } } }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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": { + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + "description": "Optional. The name of the private DNS Zone Group config." } }, - "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." - } - } - } - }, + "privateDnsZoneResourceId": { + "type": "string", "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": "Optional. 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." - } + "description": "Required. The resource id of the private DNS zone." } } - }, - "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." - } + "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": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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`." - } + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + }, + "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." - } + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" }, - "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." - } + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" }, - "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." - } + "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" }, - "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." - } + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -495,25 +535,38 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } diff --git a/avm/res/relay/namespace/network-rule-set/main.json b/avm/res/relay/namespace/network-rule-set/main.json index 3af1bab1b5..2ed1fecd4a 100644 --- a/avm/res/relay/namespace/network-rule-set/main.json +++ b/avm/res/relay/namespace/network-rule-set/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13158990350519912635" + "version": "0.30.23.60470", + "templateHash": "9578854855013298380" }, "name": "Relay Namespace Network Rules Sets", "description": "This module deploys a Relay Namespace Network Rule Set.", diff --git a/avm/res/relay/namespace/wcf-relay/authorization-rule/main.json b/avm/res/relay/namespace/wcf-relay/authorization-rule/main.json index a864b5d569..851d97b435 100644 --- a/avm/res/relay/namespace/wcf-relay/authorization-rule/main.json +++ b/avm/res/relay/namespace/wcf-relay/authorization-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "9846145731132177305" + "version": "0.30.23.60470", + "templateHash": "15492272456787428584" }, "name": "WCF Relay Authorization Rules", "description": "This module deploys a WCF Relay Authorization Rule.", diff --git a/avm/res/relay/namespace/wcf-relay/main.json b/avm/res/relay/namespace/wcf-relay/main.json index 681b9dac73..84c4e487cb 100644 --- a/avm/res/relay/namespace/wcf-relay/main.json +++ b/avm/res/relay/namespace/wcf-relay/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "25032660008872161" + "version": "0.30.23.60470", + "templateHash": "10679723922873486376" }, "name": "Relay Namespace WCF Relays", "description": "This module deploys a Relay Namespace WCF Relay.", @@ -310,8 +310,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "9846145731132177305" + "version": "0.30.23.60470", + "templateHash": "15492272456787428584" }, "name": "WCF Relay Authorization Rules", "description": "This module deploys a WCF Relay Authorization Rule.", diff --git a/avm/res/resources/deployment-script/README.md b/avm/res/resources/deployment-script/README.md index 6cb35243e4..cde40a6843 100644 --- a/avm/res/resources/deployment-script/README.md +++ b/avm/res/resources/deployment-script/README.md @@ -8,6 +8,7 @@ This module deploys Deployment Scripts. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -51,7 +52,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'AzureCLI' name: 'rdscli001' // Non-required parameters - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' environmentVariables: [ { name: 'var1' @@ -60,7 +61,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: ] location: '' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -92,7 +93,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, // Non-required parameters "azCliVersion": { - "value": "2.9.1" + "value": "2.52.0" }, "environmentVariables": { "value": [ @@ -107,7 +108,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -139,7 +140,7 @@ using 'br/public:avm/res/resources/deployment-script:' param kind = 'AzureCLI' param name = 'rdscli001' // Non-required parameters -param azCliVersion = '2.9.1' +param azCliVersion = '2.52.0' param environmentVariables = [ { name: 'var1' @@ -148,7 +149,7 @@ param environmentVariables = [ ] param location = '' param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -177,10 +178,10 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'AzurePowerShell' name: 'rdsmin001' // Non-required parameters - azPowerShellVersion: '9.7' + azPowerShellVersion: '12.3' location: '' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -210,14 +211,14 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, // Non-required parameters "azPowerShellVersion": { - "value": "9.7" + "value": "12.3" }, "location": { "value": "" }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -243,10 +244,10 @@ using 'br/public:avm/res/resources/deployment-script:' param kind = 'AzurePowerShell' param name = 'rdsmin001' // Non-required parameters -param azPowerShellVersion = '9.7' +param azPowerShellVersion = '12.3' param location = '' param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -274,7 +275,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: name: 'rdsmax001' // Non-required parameters arguments: '-argument1 \\\'test\\\'' - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' cleanupPreference: 'Always' containerGroupName: 'dep-cg-rdsmax' environmentVariables: [ @@ -292,7 +293,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'None' } managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -353,7 +354,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: "value": "-argument1 \\\"test\\\"" }, "azCliVersion": { - "value": "2.9.1" + "value": "2.52.0" }, "cleanupPreference": { "value": "Always" @@ -383,7 +384,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -450,7 +451,7 @@ param kind = 'AzureCLI' param name = 'rdsmax001' // Non-required parameters param arguments = '-argument1 \\\'test\\\'' -param azCliVersion = '2.9.1' +param azCliVersion = '2.52.0' param cleanupPreference = 'Always' param containerGroupName = 'dep-cg-rdsmax' param environmentVariables = [ @@ -468,7 +469,7 @@ param lock = { kind: 'None' } param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -523,11 +524,11 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'AzureCLI' name: 'rdspe001' // Non-required parameters - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' cleanupPreference: 'Always' location: '' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -564,7 +565,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, // Non-required parameters "azCliVersion": { - "value": "2.9.1" + "value": "2.52.0" }, "cleanupPreference": { "value": "Always" @@ -574,7 +575,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -617,11 +618,11 @@ using 'br/public:avm/res/resources/deployment-script:' param kind = 'AzureCLI' param name = 'rdspe001' // Non-required parameters -param azCliVersion = '2.9.1' +param azCliVersion = '2.52.0' param cleanupPreference = 'Always' param location = '' param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -655,11 +656,11 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'AzureCLI' name: 'rdsnet001' // Non-required parameters - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' cleanupPreference: 'Always' location: '' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -696,7 +697,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, // Non-required parameters "azCliVersion": { - "value": "2.9.1" + "value": "2.52.0" }, "cleanupPreference": { "value": "Always" @@ -706,7 +707,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -749,11 +750,11 @@ using 'br/public:avm/res/resources/deployment-script:' param kind = 'AzureCLI' param name = 'rdsnet001' // Non-required parameters -param azCliVersion = '2.9.1' +param azCliVersion = '2.52.0' param cleanupPreference = 'Always' param location = '' param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -788,10 +789,10 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: name: 'rdsps001' // Non-required parameters arguments: '-var1 \\\'AVM Deployment Script test!\\\'' - azPowerShellVersion: '9.7' + azPowerShellVersion: '12.3' location: '' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -826,14 +827,14 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: "value": "-var1 \\\"AVM Deployment Script test!\\\"" }, "azPowerShellVersion": { - "value": "9.7" + "value": "12.3" }, "location": { "value": "" }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -866,10 +867,10 @@ param kind = 'AzurePowerShell' param name = 'rdsps001' // Non-required parameters param arguments = '-var1 \\\'AVM Deployment Script test!\\\'' -param azPowerShellVersion = '9.7' +param azPowerShellVersion = '12.3' param location = '' param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -898,14 +899,14 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: kind: 'AzureCLI' name: 'rdswaf001' // Non-required parameters - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' cleanupPreference: 'Always' location: '' lock: { kind: 'None' } managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -944,7 +945,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, // Non-required parameters "azCliVersion": { - "value": "2.9.1" + "value": "2.52.0" }, "cleanupPreference": { "value": "Always" @@ -959,7 +960,7 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: }, "managedIdentities": { "value": { - "userAssignedResourcesIds": [ + "userAssignedResourceIds": [ "" ] } @@ -1004,14 +1005,14 @@ using 'br/public:avm/res/resources/deployment-script:' param kind = 'AzureCLI' param name = 'rdswaf001' // Non-required parameters -param azCliVersion = '2.9.1' +param azCliVersion = '2.52.0' param cleanupPreference = 'Always' param location = '' param lock = { kind: 'None' } param managedIdentities = { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ '' ] } @@ -1155,8 +1156,13 @@ The environment variables to pass over to the script. | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-environmentvariablesname) | string | The name of the environment variable. | -| [`secureValue`](#parameter-environmentvariablessecurevalue) | securestring | The value of the secure environment variable. | -| [`value`](#parameter-environmentvariablesvalue) | string | The value of the environment variable. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`secureValue`](#parameter-environmentvariablessecurevalue) | securestring | The value of the secure environment variable. Required if `value` is null. | +| [`value`](#parameter-environmentvariablesvalue) | string | The value of the environment variable. Required if `secureValue` is null. | ### Parameter: `environmentVariables.name` @@ -1167,14 +1173,14 @@ The name of the environment variable. ### Parameter: `environmentVariables.secureValue` -The value of the secure environment variable. +The value of the secure environment variable. Required if `value` is null. - Required: No - Type: securestring ### Parameter: `environmentVariables.value` -The value of the environment variable. +The value of the environment variable. Required if `secureValue` is null. - Required: No - Type: string @@ -1234,13 +1240,13 @@ The managed identity definition for this resource. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`userAssignedResourcesIds`](#parameter-managedidentitiesuserassignedresourcesids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | -### Parameter: `managedIdentities.userAssignedResourcesIds` +### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. -- Required: Yes +- Required: No - Type: array ### Parameter: `primaryScriptUri` @@ -1431,6 +1437,14 @@ Do not provide a value! This date value is used to make sure the script run ever | `resourceGroupName` | string | The resource group the deployment script was deployed into. | | `resourceId` | string | The resource ID of the deployment script. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/resources/deployment-script/main.bicep b/avm/res/resources/deployment-script/main.bicep index 49b96d7a48..9ee3886795 100644 --- a/avm/res/resources/deployment-script/main.bicep +++ b/avm/res/resources/deployment-script/main.bicep @@ -19,8 +19,9 @@ param location string = resourceGroup().location ]) param kind string +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityOnlyUserAssignedType? @description('Optional. Resource tags.') param tags object? @@ -75,11 +76,13 @@ param storageAccountResourceId string = '' @description('Optional. Maximum allowed script execution time specified in ISO 8601 format. Default value is PT1H - 1 hour; \'PT30M\' - 30 minutes; \'P5D\' - 5 days; \'P1Y\' 1 year.') param timeout string? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -125,19 +128,19 @@ var containerSettings = { } var formattedUserAssignedIdentities = reduce( - map((managedIdentities.?userAssignedResourcesIds ?? []), (id) => { '${id}': {} }), + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next) ) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } var identity = !empty(managedIdentities) ? { - type: !empty(managedIdentities.?userAssignedResourcesIds ?? {}) ? 'UserAssigned' : null + type: !empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null } : null -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' existing = if (!empty(storageAccountResourceId)) { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' existing = if (!empty(storageAccountResourceId)) { name: last(split((!empty(storageAccountResourceId) ? storageAccountResourceId : 'dummyAccount'), '/'))! scope: resourceGroup( split((!empty(storageAccountResourceId) ? storageAccountResourceId : '//'), '/')[2], @@ -256,53 +259,14 @@ output deploymentScriptLogs string[] = split(deploymentScriptLogs.properties.log // Definitions // // ================ // -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type managedIdentitiesType = { - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourcesIds: string[] -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - type environmentVariableType = { @description('Required. The name of the environment variable.') name: string - @description('Required. The value of the secure environment variable.') + @description('Conditional. The value of the secure environment variable. Required if `value` is null.') @secure() secureValue: string? - @description('Required. The value of the environment variable.') + @description('Conditional. The value of the environment variable. Required if `secureValue` is null.') value: string? } diff --git a/avm/res/resources/deployment-script/main.json b/avm/res/resources/deployment-script/main.json index 37eaaa6a2a..49a7c1bf8c 100644 --- a/avm/res/resources/deployment-script/main.json +++ b/avm/res/resources/deployment-script/main.json @@ -5,14 +5,39 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "8443498654175834102" + "version": "0.30.23.60470", + "templateHash": "17881568717048891322" }, "name": "Deployment Scripts", "description": "This module deploys Deployment Scripts.", "owner": "Azure/module-maintainers" }, "definitions": { + "environmentVariableType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the environment variable." + } + }, + "secureValue": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Conditional. The value of the secure environment variable. Required if `value` is null." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The value of the environment variable. Required if `secureValue` is null." + } + } + } + }, "lockType": { "type": "object", "properties": { @@ -36,118 +61,106 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "managedIdentitiesType": { + "managedIdentityOnlyUserAssignedType": { "type": "object", "properties": { - "userAssignedResourcesIds": { + "userAssignedResourceIds": { "type": "array", "items": { "type": "string" }, + "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } }, - "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." - } - } + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } - }, - "nullable": true + } }, - "environmentVariableType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the environment variable." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "secureValue": { - "type": "securestring", + "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": "Required. The value of the secure environment variable." + "description": "Optional. The principal type of the assigned principal ID." } }, - "value": { + "description": { "type": "string", "nullable": true, "metadata": { - "description": "Required. The value of the environment variable." + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -178,7 +191,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } @@ -308,12 +322,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -352,15 +371,15 @@ "containerGroupName": "[parameters('containerGroupName')]", "subnetIds": "[if(not(empty(coalesce(variables('subnetIds'), createArray()))), variables('subnetIds'), null())]" }, - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), 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(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null()), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" + "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(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null()), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" }, "resources": { "storageAccount": { "condition": "[not(empty(parameters('storageAccountResourceId')))]", "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-04-01", + "apiVersion": "2023-05-01", "subscriptionId": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '//'), '/')[2]]", "resourceGroup": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '////'), '/')[4]]", "name": "[last(split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), 'dummyAccount'), '/'))]" diff --git a/avm/res/resources/deployment-script/tests/e2e/cli/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/cli/main.test.bicep index 461b6f0409..67725082af 100644 --- a/avm/res/resources/deployment-script/tests/e2e/cli/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/cli/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' kind: 'AzureCLI' retentionInterval: 'P1D' environmentVariables: [ @@ -63,7 +63,7 @@ module testDeployment '../../../main.bicep' = { scriptContent: 'echo \'Enviornment variable value is: \' $var1' storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep index 48cdcc9741..f6aa3d3468 100644 --- a/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep @@ -50,11 +50,11 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azPowerShellVersion: '9.7' + azPowerShellVersion: '12.3' kind: 'AzurePowerShell' scriptContent: 'Write-Host \'AVM Deployment Script test!\'' managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep index 5311631d44..09e967f3cc 100644 --- a/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/max/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' kind: 'AzureCLI' retentionInterval: 'P1D' cleanupPreference: 'Always' @@ -76,7 +76,7 @@ module testDeployment '../../../main.bicep' = { } ] managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/private-endpoint/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/private-endpoint/main.test.bicep index 67a1eb7402..6805475cf1 100644 --- a/avm/res/resources/deployment-script/tests/e2e/private-endpoint/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/private-endpoint/main.test.bicep @@ -53,7 +53,7 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' kind: 'AzureCLI' retentionInterval: 'P1D' cleanupPreference: 'Always' @@ -61,7 +61,7 @@ module testDeployment '../../../main.bicep' = { nestedDependencies.outputs.subnetResourceId ] managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/private-network/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/private-network/main.test.bicep index a3ba9539db..1c568ec90e 100644 --- a/avm/res/resources/deployment-script/tests/e2e/private-network/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/private-network/main.test.bicep @@ -52,7 +52,7 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' kind: 'AzureCLI' retentionInterval: 'P1D' cleanupPreference: 'Always' @@ -60,7 +60,7 @@ module testDeployment '../../../main.bicep' = { nestedDependencies.outputs.subnetResourceId ] managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/ps/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/ps/main.test.bicep index 3ec26ca905..f30d89377d 100644 --- a/avm/res/resources/deployment-script/tests/e2e/ps/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/ps/main.test.bicep @@ -51,14 +51,14 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azPowerShellVersion: '9.7' + azPowerShellVersion: '12.3' kind: 'AzurePowerShell' retentionInterval: 'P1D' arguments: '-var1 \\"AVM Deployment Script test!\\"' scriptContent: 'param([string] $var1);Write-Host \'Argument var1 value is:\' $var1' storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/tests/e2e/waf-aligned/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/waf-aligned/main.test.bicep index 4277a59fc1..69828fe1bc 100644 --- a/avm/res/resources/deployment-script/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/waf-aligned/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: resourceLocation - azCliVersion: '2.9.1' + azCliVersion: '2.52.0' kind: 'AzureCLI' retentionInterval: 'P1D' cleanupPreference: 'Always' @@ -68,7 +68,7 @@ module testDeployment '../../../main.bicep' = { scriptContent: 'echo \'AVM Deployment Script test!\'' storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId managedIdentities: { - userAssignedResourcesIds: [ + userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId ] } diff --git a/avm/res/resources/deployment-script/version.json b/avm/res/resources/deployment-script/version.json index 13669e6601..41fc8c654f 100644 --- a/avm/res/resources/deployment-script/version.json +++ b/avm/res/resources/deployment-script/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", + "version": "0.5", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +} diff --git a/avm/res/search/search-service/README.md b/avm/res/search/search-service/README.md index 6de0311d62..22bf2edaaf 100644 --- a/avm/res/search/search-service/README.md +++ b/avm/res/search/search-service/README.md @@ -255,6 +255,7 @@ module searchService 'br/public:avm/res/search/search-service:' = { ] } networkRuleSet: { + bypass: 'AzurePortal' ipRules: [ { value: '40.74.28.0/23' @@ -364,6 +365,7 @@ module searchService 'br/public:avm/res/search/search-service:' = { }, "networkRuleSet": { "value": { + "bypass": "AzurePortal", "ipRules": [ { "value": "40.74.28.0/23" @@ -465,6 +467,7 @@ param managedIdentities = { ] } param networkRuleSet = { + bypass: 'AzurePortal' ipRules: [ { value: '40.74.28.0/23' @@ -971,7 +974,7 @@ param tags = { | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`hostingMode`](#parameter-hostingmode) | string | 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`](#parameter-location) | string | Location for all Resources. | -| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`lock`](#parameter-lock) | object | The lock settings for all Resources in the solution. | | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | | [`networkRuleSet`](#parameter-networkruleset) | object | Network specific rules that determine how the Azure Cognitive Search service may be reached. | | [`partitionCount`](#parameter-partitioncount) | int | 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. | @@ -998,7 +1001,47 @@ Defines the options for how the data plane API of a Search service authenticates - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`aadOrApiKey`](#parameter-authoptionsaadorapikey) | object | Indicates that either the API key or an access token from a Microsoft Entra ID tenant can be used for authentication. | +| [`apiKeyOnly`](#parameter-authoptionsapikeyonly) | object | Indicates that only the API key can be used for authentication. | + +### Parameter: `authOptions.aadOrApiKey` + +Indicates that either the API key or an access token from a Microsoft Entra ID tenant can be used for authentication. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`aadAuthFailureMode`](#parameter-authoptionsaadorapikeyaadauthfailuremode) | string | Describes what response the data plane API of a search service would send for requests that failed authentication. | + +### Parameter: `authOptions.aadOrApiKey.aadAuthFailureMode` + +Describes what response the data plane API of a search service would send for requests that failed authentication. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'http401WithBearerChallenge' + 'http403' + ] + ``` + +### Parameter: `authOptions.apiKeyOnly` + +Indicates that only the API key can be used for authentication. + +- Required: No +- Type: object ### Parameter: `cmkEnforcement` @@ -1033,7 +1076,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -1143,7 +1186,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -1203,7 +1246,7 @@ Location for all Resources. ### Parameter: `lock` -The lock settings of the service. +The lock settings for all Resources in the solution. - Required: No - Type: object @@ -1271,7 +1314,47 @@ Network specific rules that determine how the Azure Cognitive Search service may - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`bypass`](#parameter-networkrulesetbypass) | string | Network specific rules that determine how the Azure AI Search service may be reached. | +| [`ipRules`](#parameter-networkrulesetiprules) | array | A list of IP restriction rules that defines the inbound network(s) with allowing access to the search service endpoint. At the meantime, all other public IP networks are blocked by the firewall. These restriction rules are applied only when the 'publicNetworkAccess' of the search service is 'enabled'; otherwise, traffic over public interface is not allowed even with any public IP rules, and private endpoint connections would be the exclusive access method. | + +### Parameter: `networkRuleSet.bypass` + +Network specific rules that determine how the Azure AI Search service may be reached. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzurePortal' + 'None' + ] + ``` + +### Parameter: `networkRuleSet.ipRules` + +A list of IP restriction rules that defines the inbound network(s) with allowing access to the search service endpoint. At the meantime, all other public IP networks are blocked by the firewall. These restriction rules are applied only when the 'publicNetworkAccess' of the search service is 'enabled'; otherwise, traffic over public interface is not allowed even with any public IP rules, and private endpoint connections would be the exclusive access method. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`value`](#parameter-networkrulesetiprulesvalue) | string | Value corresponding to a single IPv4 address (eg., 123.1.2.3) or an IP range in CIDR format (eg., 123.1.2.3/24) to be allowed. | + +### Parameter: `networkRuleSet.ipRules.value` + +Value corresponding to a single IPv4 address (eg., 123.1.2.3) or an IP range in CIDR format (eg., 123.1.2.3/24) to be allowed. + +- Required: Yes +- Type: string ### Parameter: `partitionCount` @@ -1298,22 +1381,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -1324,7 +1407,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -1364,7 +1447,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -1378,7 +1461,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -1442,7 +1525,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -1492,14 +1575,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -1508,7 +1591,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -1518,7 +1601,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -1533,7 +1616,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1544,7 +1627,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -1565,7 +1648,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -1680,14 +1763,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1930,6 +2013,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.3.0` | Remote reference | ## Data Collection diff --git a/avm/res/search/search-service/main.bicep b/avm/res/search/search-service/main.bicep index 4adadf8896..b9868f4b64 100644 --- a/avm/res/search/search-service/main.bicep +++ b/avm/res/search/search-service/main.bicep @@ -10,7 +10,7 @@ metadata owner = 'Azure/module-maintainers' param name string @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 = {} +param authOptions authOptionsType? @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 = true @@ -36,19 +36,21 @@ param hostingMode string = 'default' @description('Optional. Location for all Resources.') param location string = resourceGroup().location -@description('Optional. The lock settings of the service.') -param lock lockType +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' +@description('Optional. The lock settings for all Resources in the solution.') +param lock lockType? @description('Optional. Network specific rules that determine how the Azure Cognitive Search service may be reached.') -param networkRuleSet object = {} +param networkRuleSet networkRuleSetType? @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 +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? @description('Optional. The sharedPrivateLinkResources to create as part of the search Service.') param sharedPrivateLinkResources array = [] @@ -68,8 +70,9 @@ param secretsExportConfiguration secretsExportConfigurationType? @maxValue(12) param replicaCount int = 3 +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @allowed([ 'disabled' @@ -91,11 +94,13 @@ param semanticSearch string? ]) param sku string = 'standard' +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? @description('Optional. Tags to help categorize the resource in the Azure portal.') param tags object? @@ -187,7 +192,7 @@ resource searchService 'Microsoft.Search/searchServices@2024-03-01-preview' = { tags: tags identity: identity properties: { - authOptions: !empty(authOptions) ? authOptions : null + authOptions: authOptions disableLocalAuth: disableLocalAuth encryptionWithCmk: { enforcement: cmkEnforcement @@ -385,179 +390,6 @@ output exportedSecrets secretsOutputType = (secretsExportConfiguration != null) // 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[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? - type secretsExportConfigurationType = { @description('Required. The key vault name where to store the API Admin keys generated by the modules.') keyVaultResourceId: string @@ -574,3 +406,28 @@ type secretsOutputType = { @description('An exported secret\'s references.') *: secretSetType } + +@export() +type authOptionsType = { + @description('Optional. Indicates that either the API key or an access token from a Microsoft Entra ID tenant can be used for authentication.') + aadOrApiKey: { + @description('Optional. Describes what response the data plane API of a search service would send for requests that failed authentication.') + aadAuthFailureMode: ('http401WithBearerChallenge' | 'http403')? + }? + @description('Optional. Indicates that only the API key can be used for authentication.') + apiKeyOnly: object? +} + +@export() +type networkRuleSetType = { + @description('Optional. Network specific rules that determine how the Azure AI Search service may be reached.') + bypass: ('AzurePortal' | 'None')? + @description('Optional. A list of IP restriction rules that defines the inbound network(s) with allowing access to the search service endpoint. At the meantime, all other public IP networks are blocked by the firewall. These restriction rules are applied only when the \'publicNetworkAccess\' of the search service is \'enabled\'; otherwise, traffic over public interface is not allowed even with any public IP rules, and private endpoint connections would be the exclusive access method.') + ipRules: ipRuleType[]? +} + +@export() +type ipRuleType = { + @description('Required. Value corresponding to a single IPv4 address (eg., 123.1.2.3) or an IP range in CIDR format (eg., 123.1.2.3/24) to be allowed.') + value: string +} diff --git a/avm/res/search/search-service/main.json b/avm/res/search/search-service/main.json index 7166a21a5d..d2fd601fa8 100644 --- a/avm/res/search/search-service/main.json +++ b/avm/res/search/search-service/main.json @@ -5,507 +5,630 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2146382794975309304" + "version": "0.31.34.60546", + "templateHash": "18312735267946671495" }, "name": "Search Services", "description": "This module deploys a Search Service.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "secretsExportConfigurationType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The key vault name where to store the API Admin keys generated by the modules." + } + }, + "primaryAdminKeyName": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "Optional. The primaryAdminKey secret name to create." } }, - "userAssignedResourceIds": { - "type": "array", - "items": { - "type": "string" - }, + "secondaryAdminKeyName": { + "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." + "description": "Optional. The secondaryAdminKey secret name to create." } } - }, - "nullable": true + } }, - "lockType": { + "secretsOutputType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "$ref": "#/definitions/secretSetType", + "metadata": { + "description": "An exported secret's references." + } + } + }, + "authOptionsType": { "type": "object", "properties": { - "name": { - "type": "string", + "aadOrApiKey": { + "type": "object", + "properties": { + "aadAuthFailureMode": { + "type": "string", + "allowedValues": [ + "http401WithBearerChallenge", + "http403" + ], + "nullable": true, + "metadata": { + "description": "Optional. Describes what response the data plane API of a search service would send for requests that failed authentication." + } + } + }, "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. Indicates that either the API key or an access token from a Microsoft Entra ID tenant can be used for authentication." } }, - "kind": { + "apiKeyOnly": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Indicates that only the API key can be used for authentication." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "networkRuleSetType": { + "type": "object", + "properties": { + "bypass": { "type": "string", "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" + "AzurePortal", + "None" ], "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. Network specific rules that determine how the Azure AI Search service may be reached." + } + }, + "ipRules": { + "type": "array", + "items": { + "$ref": "#/definitions/ipRuleType" + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP restriction rules that defines the inbound network(s) with allowing access to the search service endpoint. At the meantime, all other public IP networks are blocked by the firewall. These restriction rules are applied only when the 'publicNetworkAccess' of the search service is 'enabled'; otherwise, traffic over public interface is not allowed even with any public IP rules, and private endpoint connections would be the exclusive access method." } } }, - "nullable": true + "metadata": { + "__bicep_export!": 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." - } + "ipRuleType": { + "type": "object", + "properties": { + "value": { + "type": "string", + "metadata": { + "description": "Required. Value corresponding to a single IPv4 address (eg., 123.1.2.3) or an IP range in CIDR format (eg., 123.1.2.3/24) to be allowed." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_1.privateEndpointCustomDnsConfigType": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } }, - "privateEndpointType": { - "type": "array", - "items": { - "type": "object", + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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." + "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." + } } }, - "privateDnsZoneGroup": { + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } + }, + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + "description": "Optional. The name of the private DNS Zone Group config." } }, - "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." - } - } - } - }, + "privateDnsZoneResourceId": { + "type": "string", "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + "description": "Required. The resource id of the private DNS zone." } } - }, - "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": "Optional. 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." - } + "metadata": { + "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." } - } - }, - "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." - } + }, + "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. 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": { + "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", - "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." + "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`." + } + } } }, - "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, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } + }, + "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 + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } }, - "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." - } + "managedIdentityAllType": { + "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" }, - "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." - } + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } + }, + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" }, - "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." - } + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" }, - "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." - } + "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" }, - "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." - } + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } }, - "secretsExportConfigurationType": { + "roleAssignmentType": { "type": "object", "properties": { - "keyVaultResourceId": { + "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The key vault name where to store the API Admin keys generated by the modules." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "primaryAdminKeyName": { + "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 primaryAdminKey secret name to create." + "description": "Optional. The principal type of the assigned principal ID." } }, - "secondaryAdminKeyName": { + "description": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The secondaryAdminKey secret name to create." + "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." } } - } - }, - "secretsOutputType": { - "type": "object", - "properties": {}, - "additionalProperties": { - "$ref": "#/definitions/secretSetType", - "metadata": { - "description": "An exported secret's references." + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" } } }, @@ -540,8 +663,8 @@ } }, "authOptions": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/authOptionsType", + "nullable": true, "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." } @@ -592,13 +715,14 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Optional. The lock settings for all Resources in the solution." } }, "networkRuleSet": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/networkRuleSetType", + "nullable": true, "metadata": { "description": "Optional. Network specific rules that determine how the Azure Cognitive Search service may be reached." } @@ -613,7 +737,11 @@ } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } @@ -653,7 +781,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -687,13 +819,18 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -759,7 +896,7 @@ "tags": "[parameters('tags')]", "identity": "[variables('identity')]", "properties": { - "authOptions": "[if(not(empty(parameters('authOptions'))), parameters('authOptions'), null())]", + "authOptions": "[parameters('authOptions')]", "disableLocalAuth": "[parameters('disableLocalAuth')]", "encryptionWithCmk": { "enforcement": "[parameters('cmkEnforcement')]" @@ -1657,8 +1794,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1073269867332822875" + "version": "0.31.34.60546", + "templateHash": "13697564567147510981" }, "name": "Search Services Private Link Resources", "description": "This module deploys a Search Service Private Link Resource.", @@ -1719,10 +1856,7 @@ "groupId": "[parameters('groupId')]", "requestMessage": "[parameters('requestMessage')]", "resourceRegion": "[parameters('resourceRegion')]" - }, - "dependsOn": [ - "searchService" - ] + } } }, "outputs": { @@ -1781,8 +1915,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12263717469683062316" + "version": "0.31.34.60546", + "templateHash": "251825345610643647" } }, "definitions": { @@ -1858,10 +1992,7 @@ "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]", "properties": { "value": "[parameters('secretsToSet')[copyIndex()].value]" - }, - "dependsOn": [ - "keyVault" - ] + } } }, "outputs": { diff --git a/avm/res/search/search-service/shared-private-link-resource/main.json b/avm/res/search/search-service/shared-private-link-resource/main.json index ccb69cdd79..e465debc7b 100644 --- a/avm/res/search/search-service/shared-private-link-resource/main.json +++ b/avm/res/search/search-service/shared-private-link-resource/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "2330033720810948871" + "version": "0.31.34.60546", + "templateHash": "13697564567147510981" }, "name": "Search Services Private Link Resources", "description": "This module deploys a Search Service Private Link Resource.", @@ -67,10 +67,7 @@ "groupId": "[parameters('groupId')]", "requestMessage": "[parameters('requestMessage')]", "resourceRegion": "[parameters('resourceRegion')]" - }, - "dependsOn": [ - "searchService" - ] + } } }, "outputs": { diff --git a/avm/res/search/search-service/tests/e2e/max/main.test.bicep b/avm/res/search/search-service/tests/e2e/max/main.test.bicep index 0fc341ea23..93c3460fa4 100644 --- a/avm/res/search/search-service/tests/e2e/max/main.test.bicep +++ b/avm/res/search/search-service/tests/e2e/max/main.test.bicep @@ -111,6 +111,7 @@ module testDeployment '../../../main.bicep' = [ } ] networkRuleSet: { + bypass: 'AzurePortal' ipRules: [ { value: '40.74.28.0/23' diff --git a/avm/res/search/search-service/version.json b/avm/res/search/search-service/version.json index 7e1d3f4157..9a9a06e897 100644 --- a/avm/res/search/search-service/version.json +++ b/avm/res/search/search-service/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.8", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/service-bus/namespace/README.md b/avm/res/service-bus/namespace/README.md index 3d43ecdc7c..94af8bd1dd 100644 --- a/avm/res/service-bus/namespace/README.md +++ b/avm/res/service-bus/namespace/README.md @@ -3517,6 +3517,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/service-bus/namespace/queue/README.md b/avm/res/service-bus/namespace/queue/README.md index 0c581d4e73..9a321d7ef5 100644 --- a/avm/res/service-bus/namespace/queue/README.md +++ b/avm/res/service-bus/namespace/queue/README.md @@ -7,6 +7,7 @@ This module deploys a Service Bus Namespace Queue. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -365,3 +366,11 @@ Enumerates the possible values for the status of a messaging entity. - Active, D | `name` | string | The name of the deployed queue. | | `resourceGroupName` | string | The resource group of the deployed queue. | | `resourceId` | string | The resource ID of the deployed queue. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/service-bus/namespace/topic/README.md b/avm/res/service-bus/namespace/topic/README.md index adea8eec40..721da36bda 100644 --- a/avm/res/service-bus/namespace/topic/README.md +++ b/avm/res/service-bus/namespace/topic/README.md @@ -7,6 +7,7 @@ This module deploys a Service Bus Namespace Topic. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -509,3 +510,11 @@ Value that indicates whether the topic supports ordering. | `name` | string | The name of the deployed topic. | | `resourceGroupName` | string | The resource group of the deployed topic. | | `resourceId` | string | The resource ID of the deployed topic. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/service-networking/traffic-controller/README.md b/avm/res/service-networking/traffic-controller/README.md index c85a18a11b..4c60b78868 100644 --- a/avm/res/service-networking/traffic-controller/README.md +++ b/avm/res/service-networking/traffic-controller/README.md @@ -8,6 +8,7 @@ This module deploys an Application Gateway for Containers - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -512,7 +513,7 @@ param tags = { | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`frontends`](#parameter-frontends) | array | List of Application Gateway for Containers frontends. | | [`location`](#parameter-location) | string | Location for all Resources. | -| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`lock`](#parameter-lock) | object | The lock settings for all Resources in the solution. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`tags`](#parameter-tags) | object | Resource tags. | @@ -568,7 +569,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -678,7 +679,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -735,7 +736,7 @@ Location for all Resources. ### Parameter: `lock` -The lock settings of the service. +The lock settings for all Resources in the solution. - Required: No - Type: object @@ -891,6 +892,15 @@ Resource tags. | `resourceGroupName` | string | The name of the resource group the resource was created in. | | `resourceId` | string | The resource ID of the Application Gateway for Containers. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.3.0` | Remote reference | + ## Notes > **Limitation**: At this time, the number of associations is limited to 1 (Source: [Application Gateway for Containers associations](https://learn.microsoft.com/en-us/azure/application-gateway/for-containers/application-gateway-for-containers-components#application-gateway-for-containers-associations)) diff --git a/avm/res/service-networking/traffic-controller/association/README.md b/avm/res/service-networking/traffic-controller/association/README.md index 87488abfe2..e706d522f5 100644 --- a/avm/res/service-networking/traffic-controller/association/README.md +++ b/avm/res/service-networking/traffic-controller/association/README.md @@ -21,6 +21,7 @@ This module deploys an Application Gateway for Containers Association | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | Name of the association to create. | +| [`subnetResourceId`](#parameter-subnetresourceid) | string | The resource ID of the subnet to associate with the traffic controller. | **Conditional parameters** @@ -34,12 +35,6 @@ This module deploys an Application Gateway for Containers Association | :-- | :-- | :-- | | [`location`](#parameter-location) | string | Location for all Resources. | -**Reuired parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`subnetResourceId`](#parameter-subnetresourceid) | string | The resource ID of the subnet to associate with the traffic controller. | - ### Parameter: `name` Name of the association to create. @@ -47,6 +42,13 @@ Name of the association to create. - Required: Yes - Type: string +### Parameter: `subnetResourceId` + +The resource ID of the subnet to associate with the traffic controller. + +- Required: Yes +- Type: string + ### Parameter: `trafficControllerName` The name of the parent Application Gateway for Containers instance. Required if the template is used in a standalone deployment. @@ -62,13 +64,6 @@ Location for all Resources. - Type: string - Default: `[resourceGroup().location]` -### Parameter: `subnetResourceId` - -The resource ID of the subnet to associate with the traffic controller. - -- Required: Yes -- Type: string - ## Outputs | Output | Type | Description | diff --git a/avm/res/service-networking/traffic-controller/association/main.bicep b/avm/res/service-networking/traffic-controller/association/main.bicep index 70cc047a29..8837f9de56 100644 --- a/avm/res/service-networking/traffic-controller/association/main.bicep +++ b/avm/res/service-networking/traffic-controller/association/main.bicep @@ -11,7 +11,7 @@ param location string = resourceGroup().location @description('Conditional. The name of the parent Application Gateway for Containers instance. Required if the template is used in a standalone deployment.') param trafficControllerName string -@description('Reuired. The resource ID of the subnet to associate with the traffic controller.') +@description('Required. The resource ID of the subnet to associate with the traffic controller.') param subnetResourceId string // ============== // diff --git a/avm/res/service-networking/traffic-controller/association/main.json b/avm/res/service-networking/traffic-controller/association/main.json index 638bc670f4..97650934a4 100644 --- a/avm/res/service-networking/traffic-controller/association/main.json +++ b/avm/res/service-networking/traffic-controller/association/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17751059838446450774" + "version": "0.31.34.60546", + "templateHash": "16237699923821445314" }, "name": "Application Gateway for Containers Association", "description": "This module deploys an Application Gateway for Containers Association", @@ -34,7 +34,7 @@ "subnetResourceId": { "type": "string", "metadata": { - "description": "Reuired. The resource ID of the subnet to associate with the traffic controller." + "description": "Required. The resource ID of the subnet to associate with the traffic controller." } } }, diff --git a/avm/res/service-networking/traffic-controller/frontend/main.json b/avm/res/service-networking/traffic-controller/frontend/main.json index f3fb57ad7e..5866bc8d1f 100644 --- a/avm/res/service-networking/traffic-controller/frontend/main.json +++ b/avm/res/service-networking/traffic-controller/frontend/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12093954076612099884" + "version": "0.31.34.60546", + "templateHash": "12126990142824202083" }, "name": "Application Gateway for Containers Frontend", "description": "This module deploys an Application Gateway for Containers Frontend", diff --git a/avm/res/service-networking/traffic-controller/main.bicep b/avm/res/service-networking/traffic-controller/main.bicep index 2ac083b224..13dc424458 100644 --- a/avm/res/service-networking/traffic-controller/main.bicep +++ b/avm/res/service-networking/traffic-controller/main.bicep @@ -14,20 +14,24 @@ param enableTelemetry bool = true @description('Optional. Resource tags.') param tags object? -@description('Optional. The lock settings of the service.') -param lock lockType +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' +@description('Optional. The lock settings for all Resources in the solution.') +param lock lockType? +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.3.0' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingFullType[]? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. List of Application Gateway for Containers frontends.') -param frontends frontendType +param frontends frontendType[]? +@maxLength(1) @description('Optional. List of Application Gateway for Containers associations. At this time, the number of associations is limited to 1.') -param associations associationType +param associations associationType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -208,94 +212,17 @@ output associations array = [ // Definitions // // ================ // +@export() type frontendType = { @description('Required. The name of the Application Gateway for Containers frontend.') name: string -}[]? +} -@maxLength(1) +@export() type associationType = { @description('Required. The name of the Application Gateway for Containers association.') name: string @description('Required. The resource ID of the subnet to associate with the Application Gateway for Containers.') subnetResourceId: string -}[]? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string - - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? +} diff --git a/avm/res/service-networking/traffic-controller/main.json b/avm/res/service-networking/traffic-controller/main.json index aa85cfc38c..2153d32460 100644 --- a/avm/res/service-networking/traffic-controller/main.json +++ b/avm/res/service-networking/traffic-controller/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13555357375349247834" + "version": "0.31.34.60546", + "templateHash": "1270772577226075570" }, "name": "Application Gateway for Containers", "description": "This module deploys an Application Gateway for Containers", @@ -14,41 +14,160 @@ }, "definitions": { "frontendType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the Application Gateway for Containers frontend." - } + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Application Gateway for Containers frontend." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "associationType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the Application Gateway for Containers association." + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Application Gateway for Containers association." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the subnet to associate with the Application Gateway for Containers." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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`." + } + } } }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the subnet to associate with the Application Gateway for Containers." + "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, - "maxLength": 1 + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } }, "lockType": { "type": "object", @@ -73,200 +192,87 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.3.0" + } + } }, "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." - } + "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." } - } - }, - "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." - } + }, + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -299,30 +305,48 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Optional. The lock settings for all Resources in the solution." } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "frontends": { - "$ref": "#/definitions/frontendType", + "type": "array", + "items": { + "$ref": "#/definitions/frontendType" + }, + "nullable": true, "metadata": { "description": "Optional. List of Application Gateway for Containers frontends." } }, "associations": { - "$ref": "#/definitions/associationType", + "type": "array", + "items": { + "$ref": "#/definitions/associationType" + }, + "nullable": true, + "maxLength": 1, "metadata": { "description": "Optional. List of Application Gateway for Containers associations. At this time, the number of associations is limited to 1." } @@ -480,8 +504,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12093954076612099884" + "version": "0.31.34.60546", + "templateHash": "12126990142824202083" }, "name": "Application Gateway for Containers Frontend", "description": "This module deploys an Application Gateway for Containers Frontend", @@ -586,8 +610,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17751059838446450774" + "version": "0.31.34.60546", + "templateHash": "16237699923821445314" }, "name": "Application Gateway for Containers Association", "description": "This module deploys an Application Gateway for Containers Association", @@ -616,7 +640,7 @@ "subnetResourceId": { "type": "string", "metadata": { - "description": "Reuired. The resource ID of the subnet to associate with the traffic controller." + "description": "Required. The resource ID of the subnet to associate with the traffic controller." } } }, diff --git a/avm/res/signal-r-service/signal-r/README.md b/avm/res/signal-r-service/signal-r/README.md index 211ba9d260..6d626e2528 100644 --- a/avm/res/signal-r-service/signal-r/README.md +++ b/avm/res/signal-r-service/signal-r/README.md @@ -128,6 +128,10 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: '' + } networkAcls: { defaultAction: 'Allow' privateEndpoints: [ @@ -248,6 +252,12 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { "name": "myCustomLockName" } }, + "managedIdentities": { + "value": { + "systemAssigned": false, + "userAssignedResourceIds": "" + } + }, "networkAcls": { "value": { "defaultAction": "Allow", @@ -362,6 +372,10 @@ param lock = { kind: 'CanNotDelete' name: 'myCustomLockName' } +param managedIdentities = { + systemAssigned: false + userAssignedResourceIds: '' +} param networkAcls = { defaultAction: 'Allow' privateEndpoints: [ @@ -702,6 +716,7 @@ param tags = { | [`liveTraceCatagoriesToEnable`](#parameter-livetracecatagoriestoenable) | array | Control permission for data plane traffic coming from public networks while private endpoint is enabled. | | [`location`](#parameter-location) | string | The location for the resource. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | | [`networkAcls`](#parameter-networkacls) | object | Networks ACLs, this value contains IPs to allow and/or Subnet information. Can only be set if the 'SKU' is not 'Free_F1'. For security reasons, it is recommended to set the DefaultAction Deny. | | [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | | [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | 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. | @@ -868,6 +883,34 @@ Specify the name of lock. - Required: No - Type: string +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | + +### Parameter: `managedIdentities.systemAssigned` + +Enables system assigned managed identity on the resource. + +- Required: No +- Type: bool + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. + +- Required: No +- Type: array + ### Parameter: `networkAcls` Networks ACLs, this value contains IPs to allow and/or Subnet information. Can only be set if the 'SKU' is not 'Free_F1'. For security reasons, it is recommended to set the DefaultAction Deny. @@ -893,22 +936,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -919,7 +962,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -959,7 +1002,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -973,7 +1016,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -1037,7 +1080,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -1087,14 +1130,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -1103,7 +1146,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -1113,7 +1156,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -1128,7 +1171,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1139,7 +1182,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -1160,7 +1203,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -1181,7 +1224,7 @@ Array of role assignments to create. - `'Owner'` - `'Private DNS Zone Contributor'` - `'Reader'` - - `'Role Based Access Control Administrator (Preview)'` + - `'Role Based Access Control Administrator'` **Required parameters** @@ -1275,14 +1318,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1492,6 +1535,7 @@ Upstream templates to enable. For more information, see https://learn.microsoft. | `privateEndpoints` | array | The private endpoints of the SignalR. | | `resourceGroupName` | string | The SignalR resource group. | | `resourceId` | string | The SignalR resource ID. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | ## Cross-referenced modules @@ -1499,7 +1543,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.8.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/signal-r-service/signal-r/main.bicep b/avm/res/signal-r-service/signal-r/main.bicep index b4803a82a9..c458befb65 100644 --- a/avm/res/signal-r-service/signal-r/main.bicep +++ b/avm/res/signal-r-service/signal-r/main.bicep @@ -2,6 +2,10 @@ metadata name = 'SignalR Service SignalR' metadata description = 'This module deploys a SignalR Service SignalR.' metadata owner = 'Azure/module-maintainers' +// ============== // +// Parameters // +// ============== // + @description('Optional. The location for the resource.') param location string = resourceGroup().location @@ -98,18 +102,43 @@ param clientCertEnabled bool = false @description('Optional. Upstream templates to enable. For more information, see https://learn.microsoft.com/en-us/azure/templates/microsoft.signalrservice/2022-02-01/signalr?pivots=deployment-language-bicep#upstreamtemplate.') param upstreamTemplatesToEnable array? +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' +@description('Optional. The managed identity definition for this resource.') +param managedIdentities managedIdentityAllType? + +// ============= // +// Variables // +// ============= // + +var formattedUserAssignedIdentities = reduce( + map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), + {}, + (cur, next) => union(cur, next) +) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } +var identity = !empty(managedIdentities) + ? { + type: (managedIdentities.?systemAssigned ?? false) + ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') + : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null + } + : null + var liveTraceCatagories = [ for configuration in liveTraceCatagoriesToEnable: { name: configuration @@ -210,6 +239,7 @@ resource signalR 'Microsoft.SignalRService/signalR@2022-02-01' = { tier: tier } tags: tags + identity: identity properties: { cors: { allowedOrigins: allowedOrigins @@ -240,7 +270,7 @@ resource signalR 'Microsoft.SignalRService/signalR@2022-02-01' = { } } -module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ +module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.8.0' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-signalR-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -331,6 +361,9 @@ output resourceId string = signalR.id @description('The location the resource was deployed into.') output location string = signalR.location +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = signalR.?identity.?principalId ?? '' + @description('The private endpoints of the SignalR.') output privateEndpoints array = [ for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { @@ -341,128 +374,3 @@ output privateEndpoints array = [ networkInterfaceIds: signalR_privateEndpoints[i].outputs.networkInterfaceIds } ] - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? diff --git a/avm/res/signal-r-service/signal-r/main.json b/avm/res/signal-r-service/signal-r/main.json index 822b12da50..c0ee5618de 100644 --- a/avm/res/signal-r-service/signal-r/main.json +++ b/avm/res/signal-r-service/signal-r/main.json @@ -6,330 +6,396 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "18392200258467570081" + "templateHash": "7411558632564019868" }, "name": "SignalR Service SignalR", "description": "This module deploys a SignalR Service SignalR.", "owner": "Azure/module-maintainers" }, "definitions": { - "lockType": { + "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { - "name": { + "fqdn": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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." + "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." + } } }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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": { + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + "description": "Optional. The name of the private DNS Zone Group config." } }, - "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." - } - } - } - }, + "privateDnsZoneResourceId": { + "type": "string", "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": "Optional. 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." - } + "description": "Required. The resource id of the private DNS zone." } } - }, - "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." - } + "metadata": { + "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "managedIdentityAllType": { + "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" }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. Specify the type of lock." - } + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } + "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" }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "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, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -495,19 +561,28 @@ } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -518,6 +593,13 @@ "metadata": { "description": "Optional. Enable/Disable usage telemetry for module." } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } } }, "variables": { @@ -544,6 +626,8 @@ "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": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", @@ -593,6 +677,7 @@ "tier": "[parameters('tier')]" }, "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", "properties": { "cors": { "allowedOrigins": "[parameters('allowedOrigins')]" @@ -710,7 +795,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "1277254088602407590" + "templateHash": "10193943972635711937" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", @@ -1124,7 +1209,7 @@ "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')]" + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" } }, "resources": { @@ -1132,7 +1217,7 @@ "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))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.8.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1444,6 +1529,13 @@ }, "value": "[reference('signalR', '2022-02-01', 'full').location]" }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('signalR', '2022-02-01', 'full'), 'identity'), 'principalId'), '')]" + }, "privateEndpoints": { "type": "array", "metadata": { diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep index 8f4198f941..eb0146d99a 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/defaults/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/max/dependencies.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/max/dependencies.bicep index 3f02e7b5ad..f7696bde96 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/max/dependencies.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/max/dependencies.bicep @@ -9,7 +9,7 @@ param managedIdentityName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { name: virtualNetworkName location: location properties: { @@ -31,11 +31,11 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } } -resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2024-06-01' = { name: 'privatelink.service.signalr.net' location: 'global' - resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + resource virtualNetworkLinks 'virtualNetworkLinks@2024-06-01' = { name: '${virtualNetwork.name}-vnetlink' location: 'global' properties: { @@ -47,7 +47,7 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { } } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: managedIdentityName location: location } @@ -60,3 +60,6 @@ output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity') +output managedIdentityResourceId string = managedIdentity.id diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep index 8ec75e7dac..55703b7f95 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } @@ -53,6 +53,10 @@ module testDeployment '../../../main.bicep' = [ params: { name: '${namePrefix}-${serviceShort}-001' location: resourceLocation + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [nestedDependencies.outputs.managedIdentityResourceId] + } capacity: 2 clientCertEnabled: false disableAadAuth: false diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/dependencies.bicep index c9b4120285..4ec8f243df 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/dependencies.bicep @@ -28,11 +28,11 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } } -resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2024-06-01' = { name: 'privatelink.service.signalr.net' location: 'global' - resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + resource virtualNetworkLinks 'virtualNetworkLinks@2024-06-01' = { name: '${virtualNetwork.name}-vnetlink' location: 'global' properties: { diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep index 009b496f45..6d4848011e 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/signal-r-service/signal-r/version.json b/avm/res/signal-r-service/signal-r/version.json index a8eda31021..21226dd43f 100644 --- a/avm/res/signal-r-service/signal-r/version.json +++ b/avm/res/signal-r-service/signal-r/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.6", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file diff --git a/avm/res/signal-r-service/web-pub-sub/README.md b/avm/res/signal-r-service/web-pub-sub/README.md index b2d0df64ec..0a3a40caad 100644 --- a/avm/res/signal-r-service/web-pub-sub/README.md +++ b/avm/res/signal-r-service/web-pub-sub/README.md @@ -828,7 +828,7 @@ The managed identity definition for this resource. Only one type of identity is | Parameter | Type | Description | | :-- | :-- | :-- | | [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.systemAssigned` @@ -839,7 +839,7 @@ Enables system assigned managed identity on the resource. ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. - Required: No - Type: array @@ -868,22 +868,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -894,7 +894,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -934,7 +934,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -948,7 +948,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -1012,7 +1012,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -1062,14 +1062,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -1078,7 +1078,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -1088,7 +1088,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -1103,7 +1103,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1114,7 +1114,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -1135,7 +1135,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -1250,14 +1250,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1452,6 +1452,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/signal-r-service/web-pub-sub/main.bicep b/avm/res/signal-r-service/web-pub-sub/main.bicep index 5961f398e0..7a67928135 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.bicep +++ b/avm/res/signal-r-service/web-pub-sub/main.bicep @@ -8,14 +8,17 @@ param location string = resourceGroup().location @description('Required. The name of the Web PubSub Service resource.') param name string +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -30,8 +33,9 @@ param capacity int = 1 @description('Optional. Pricing tier of the resource.') param sku string = 'Standard_S1' +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? @description('Optional. When set as true, connection with AuthType=aad won\'t work.') param disableAadAuth bool = false @@ -305,136 +309,3 @@ output privateEndpoints array = [ networkInterfaceIds: webPubSub_privateEndpoints[i].outputs.networkInterfaceIds } ] - -// =============== // -// 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.') - userAssignedResourceIds: string[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? diff --git a/avm/res/signal-r-service/web-pub-sub/main.json b/avm/res/signal-r-service/web-pub-sub/main.json index 5eba55a55e..6bff47322b 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.json +++ b/avm/res/signal-r-service/web-pub-sub/main.json @@ -6,35 +6,121 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "7385525531059358555" + "templateHash": "3908904397017008201" }, "name": "SignalR Web PubSub Services", "description": "This module deploys a SignalR Web PubSub Service.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "fqdn": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, - "userAssignedResourceIds": { + "ipAddresses": { "type": "array", "items": { "type": "string" }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.privateEndpointIpConfigurationType": { + "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." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.privateEndpointPrivateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "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": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, "lockType": { "type": "object", @@ -59,300 +145,257 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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." - } + "managedIdentityAllType": { + "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" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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": "Optional. 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." - } + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } + "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" }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -370,19 +413,28 @@ } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -413,7 +465,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "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." } diff --git a/avm/res/sql/server/README.md b/avm/res/sql/server/README.md index 74874cacc4..5540a01906 100644 --- a/avm/res/sql/server/README.md +++ b/avm/res/sql/server/README.md @@ -25,7 +25,7 @@ This module deploys an Azure SQL Server. | `Microsoft.Sql/servers` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers) | | `Microsoft.Sql/servers/auditingSettings` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/auditingSettings) | | `Microsoft.Sql/servers/databases` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases) | -| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies) | +| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/2023-05-01-preview/servers/databases/backupLongTermRetentionPolicies) | | `Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies) | | `Microsoft.Sql/servers/elasticPools` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/elasticPools) | | `Microsoft.Sql/servers/encryptionProtector` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/encryptionProtector) | @@ -46,11 +46,12 @@ The following section provides usage examples for the module, which were used to - [With an administrator](#example-1-with-an-administrator) - [With audit settings](#example-2-with-audit-settings) - [Using only defaults](#example-3-using-only-defaults) -- [Deploying with a key vault reference to save secrets](#example-4-deploying-with-a-key-vault-reference-to-save-secrets) -- [Using large parameter set](#example-5-using-large-parameter-set) -- [With a secondary database](#example-6-with-a-secondary-database) -- [With vulnerability assessment](#example-7-with-vulnerability-assessment) -- [WAF-aligned](#example-8-waf-aligned) +- [Using elastic pool](#example-4-using-elastic-pool) +- [Deploying with a key vault reference to save secrets](#example-5-deploying-with-a-key-vault-reference-to-save-secrets) +- [Using large parameter set](#example-6-using-large-parameter-set) +- [With a secondary database](#example-7-with-a-secondary-database) +- [With vulnerability assessment](#example-8-with-vulnerability-assessment) +- [WAF-aligned](#example-9-waf-aligned) ### Example 1: _With an administrator_ @@ -312,7 +313,134 @@ param location = ''

    -### Example 4: _Deploying with a key vault reference to save secrets_ +### Example 4: _Using elastic pool_ + +This instance deploys the module with an elastic pool. + + +

    + +via Bicep module + +```bicep +module server 'br/public:avm/res/sql/server:' = { + name: 'serverDeployment' + params: { + // Required parameters + name: 'ssep001' + // Non-required parameters + administratorLogin: 'adminUserName' + administratorLoginPassword: '' + elasticPools: [ + { + name: 'ssep-ep-001' + } + { + name: 'ssep-ep-002' + perDatabaseSettings: { + maxCapacity: '4' + minCapacity: '0.5' + } + sku: { + capacity: 4 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } + } + ] + location: '' + } +} +``` + +
    +

    + +

    + +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ssep001" + }, + // Non-required parameters + "administratorLogin": { + "value": "adminUserName" + }, + "administratorLoginPassword": { + "value": "" + }, + "elasticPools": { + "value": [ + { + "name": "ssep-ep-001" + }, + { + "name": "ssep-ep-002", + "perDatabaseSettings": { + "maxCapacity": "4", + "minCapacity": "0.5" + }, + "sku": { + "capacity": 4, + "name": "GP_Gen5", + "tier": "GeneralPurpose" + } + } + ] + }, + "location": { + "value": "" + } + } +} +``` + +
    +

    + +

    + +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/sql/server:' + +// Required parameters +param name = 'ssep001' +// Non-required parameters +param administratorLogin = 'adminUserName' +param administratorLoginPassword = '' +param elasticPools = [ + { + name: 'ssep-ep-001' + } + { + name: 'ssep-ep-002' + perDatabaseSettings: { + maxCapacity: '4' + minCapacity: '0.5' + } + sku: { + capacity: 4 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } + } +] +param location = '' +``` + +
    +

    + +### Example 5: _Deploying with a key vault reference to save secrets_ This instance deploys the module saving all its secrets in a key vault. @@ -420,7 +548,7 @@ param secretsExportConfiguration = {

    -### Example 5: _Using large parameter set_ +### Example 6: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -456,27 +584,31 @@ module server 'br/public:avm/res/sql/server:' = { workspaceResourceId: '' } ] - elasticPoolId: '' - encryptionProtectorObj: { - serverKeyName: '' - serverKeyType: 'AzureKeyVault' - } + elasticPoolResourceId: '' licenseType: 'LicenseIncluded' maxSizeBytes: 34359738368 name: 'sqlsmaxdb-001' - skuCapacity: 0 - skuName: 'ElasticPool' - skuTier: 'GeneralPurpose' + sku: { + capacity: 0 + name: 'ElasticPool' + tier: 'GeneralPurpose' + } } ] elasticPools: [ { name: 'sqlsmax-ep-001' - skuCapacity: 10 - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' + sku: { + capacity: 10 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } } ] + encryptionProtectorObj: { + serverKeyName: '' + serverKeyType: 'AzureKeyVault' + } firewallRules: [ { endIpAddress: '0.0.0.0' @@ -623,17 +755,15 @@ module server 'br/public:avm/res/sql/server:' = { "workspaceResourceId": "" } ], - "elasticPoolId": "", - "encryptionProtectorObj": { - "serverKeyName": "", - "serverKeyType": "AzureKeyVault" - }, + "elasticPoolResourceId": "", "licenseType": "LicenseIncluded", "maxSizeBytes": 34359738368, "name": "sqlsmaxdb-001", - "skuCapacity": 0, - "skuName": "ElasticPool", - "skuTier": "GeneralPurpose" + "sku": { + "capacity": 0, + "name": "ElasticPool", + "tier": "GeneralPurpose" + } } ] }, @@ -641,12 +771,20 @@ module server 'br/public:avm/res/sql/server:' = { "value": [ { "name": "sqlsmax-ep-001", - "skuCapacity": 10, - "skuName": "GP_Gen5", - "skuTier": "GeneralPurpose" + "sku": { + "capacity": 10, + "name": "GP_Gen5", + "tier": "GeneralPurpose" + } } ] }, + "encryptionProtectorObj": { + "value": { + "serverKeyName": "", + "serverKeyType": "AzureKeyVault" + } + }, "firewallRules": { "value": [ { @@ -812,27 +950,31 @@ param databases = [ workspaceResourceId: '' } ] - elasticPoolId: '' - encryptionProtectorObj: { - serverKeyName: '' - serverKeyType: 'AzureKeyVault' - } + elasticPoolResourceId: '' licenseType: 'LicenseIncluded' maxSizeBytes: 34359738368 name: 'sqlsmaxdb-001' - skuCapacity: 0 - skuName: 'ElasticPool' - skuTier: 'GeneralPurpose' + sku: { + capacity: 0 + name: 'ElasticPool' + tier: 'GeneralPurpose' + } } ] param elasticPools = [ { name: 'sqlsmax-ep-001' - skuCapacity: 10 - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' + sku: { + capacity: 10 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } } ] +param encryptionProtectorObj = { + serverKeyName: '' + serverKeyType: 'AzureKeyVault' +} param firewallRules = [ { endIpAddress: '0.0.0.0' @@ -940,7 +1082,7 @@ param vulnerabilityAssessmentsObj = {

    -### Example 6: _With a secondary database_ +### Example 7: _With a secondary database_ This instance deploys the module with a secondary database. @@ -963,8 +1105,10 @@ module server 'br/public:avm/res/sql/server:' = { createMode: 'Secondary' maxSizeBytes: 2147483648 name: '' - skuName: 'Basic' - skuTier: 'Basic' + sku: { + name: 'Basic' + tier: 'Basic' + } sourceDatabaseResourceId: '' } ] @@ -1007,8 +1151,10 @@ module server 'br/public:avm/res/sql/server:' = { "createMode": "Secondary", "maxSizeBytes": 2147483648, "name": "", - "skuName": "Basic", - "skuTier": "Basic", + "sku": { + "name": "Basic", + "tier": "Basic" + }, "sourceDatabaseResourceId": "" } ] @@ -1047,8 +1193,10 @@ param databases = [ createMode: 'Secondary' maxSizeBytes: 2147483648 name: '' - skuName: 'Basic' - skuTier: 'Basic' + sku: { + name: 'Basic' + tier: 'Basic' + } sourceDatabaseResourceId: '' } ] @@ -1063,7 +1211,7 @@ param tags = {

    -### Example 7: _With vulnerability assessment_ +### Example 8: _With vulnerability assessment_ This instance deploys the module with a vulnerability assessment. @@ -1240,7 +1388,7 @@ param vulnerabilityAssessmentsObj = {

    -### Example 8: _WAF-aligned_ +### Example 9: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -1281,28 +1429,32 @@ module server 'br/public:avm/res/sql/server:' = { workspaceResourceId: '' } ] - elasticPoolId: '' - encryptionProtectorObj: { - serverKeyName: '' - serverKeyType: 'AzureKeyVault' - } + elasticPoolResourceId: '' licenseType: 'LicenseIncluded' maxSizeBytes: 34359738368 name: 'sqlswafdb-001' - skuCapacity: 0 - skuName: 'ElasticPool' - skuTier: 'GeneralPurpose' + sku: { + capacity: 0 + name: 'ElasticPool' + tier: 'GeneralPurpose' + } } ] elasticPools: [ { maintenanceConfigurationId: '' name: 'sqlswaf-ep-001' - skuCapacity: 10 - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' + sku: { + capacity: 10 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } } ] + encryptionProtectorObj: { + serverKeyName: '' + serverKeyType: 'AzureKeyVault' + } keys: [ { serverKeyType: 'AzureKeyVault' @@ -1412,17 +1564,15 @@ module server 'br/public:avm/res/sql/server:' = { "workspaceResourceId": "" } ], - "elasticPoolId": "", - "encryptionProtectorObj": { - "serverKeyName": "", - "serverKeyType": "AzureKeyVault" - }, + "elasticPoolResourceId": "", "licenseType": "LicenseIncluded", "maxSizeBytes": 34359738368, "name": "sqlswafdb-001", - "skuCapacity": 0, - "skuName": "ElasticPool", - "skuTier": "GeneralPurpose" + "sku": { + "capacity": 0, + "name": "ElasticPool", + "tier": "GeneralPurpose" + } } ] }, @@ -1431,12 +1581,20 @@ module server 'br/public:avm/res/sql/server:' = { { "maintenanceConfigurationId": "", "name": "sqlswaf-ep-001", - "skuCapacity": 10, - "skuName": "GP_Gen5", - "skuTier": "GeneralPurpose" + "sku": { + "capacity": 10, + "name": "GP_Gen5", + "tier": "GeneralPurpose" + } } ] }, + "encryptionProtectorObj": { + "value": { + "serverKeyName": "", + "serverKeyType": "AzureKeyVault" + } + }, "keys": { "value": [ { @@ -1561,28 +1719,32 @@ param databases = [ workspaceResourceId: '' } ] - elasticPoolId: '' - encryptionProtectorObj: { - serverKeyName: '' - serverKeyType: 'AzureKeyVault' - } + elasticPoolResourceId: '' licenseType: 'LicenseIncluded' maxSizeBytes: 34359738368 name: 'sqlswafdb-001' - skuCapacity: 0 - skuName: 'ElasticPool' - skuTier: 'GeneralPurpose' + sku: { + capacity: 0 + name: 'ElasticPool' + tier: 'GeneralPurpose' + } } ] param elasticPools = [ { maintenanceConfigurationId: '' name: 'sqlswaf-ep-001' - skuCapacity: 10 - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' + sku: { + capacity: 10 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } } ] +param encryptionProtectorObj = { + serverKeyName: '' + serverKeyType: 'AzureKeyVault' +} param keys = [ { serverKeyType: 'AzureKeyVault' @@ -1676,8 +1838,10 @@ param vulnerabilityAssessmentsObj = { | [`elasticPools`](#parameter-elasticpools) | array | The Elastic Pools to create in the server. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`encryptionProtectorObj`](#parameter-encryptionprotectorobj) | object | The encryption protection configuration. | +| [`federatedClientId`](#parameter-federatedclientid) | string | The Client id used for cross tenant CMK scenario. | | [`firewallRules`](#parameter-firewallrules) | array | The firewall rules to create in the server. | | [`isIPv6Enabled`](#parameter-isipv6enabled) | string | Whether or not to enable IPv6 support for this server. | +| [`keyId`](#parameter-keyid) | string | A CMK URI of the key to use for encryption. | | [`keys`](#parameter-keys) | array | The keys to configure. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | @@ -1722,7 +1886,78 @@ The Azure Active Directory (AAD) administrator authentication. Required if no `a - Required: No - Type: object -- Default: `{}` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`azureADOnlyAuthentication`](#parameter-administratorsazureadonlyauthentication) | bool | Azure Active Directory only Authentication enabled. | +| [`login`](#parameter-administratorslogin) | string | Login name of the server administrator. | +| [`principalType`](#parameter-administratorsprincipaltype) | string | Principal Type of the sever administrator. | +| [`sid`](#parameter-administratorssid) | string | SID (object ID) of the server administrator. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`administratorType`](#parameter-administratorsadministratortype) | string | Type of the sever administrator. | +| [`tenantId`](#parameter-administratorstenantid) | string | Tenant ID of the administrator. | + +### Parameter: `administrators.azureADOnlyAuthentication` + +Azure Active Directory only Authentication enabled. + +- Required: Yes +- Type: bool + +### Parameter: `administrators.login` + +Login name of the server administrator. + +- Required: Yes +- Type: string + +### Parameter: `administrators.principalType` + +Principal Type of the sever administrator. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Application' + 'Group' + 'User' + ] + ``` + +### Parameter: `administrators.sid` + +SID (object ID) of the server administrator. + +- Required: Yes +- Type: string + +### Parameter: `administrators.administratorType` + +Type of the sever administrator. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'ActiveDirectory' + ] + ``` + +### Parameter: `administrators.tenantId` + +Tenant ID of the administrator. + +- Required: No +- Type: string ### Parameter: `primaryUserAssignedIdentityId` @@ -1738,12 +1973,7 @@ The audit settings configuration. - Required: No - Type: object - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`state`](#parameter-auditsettingsstate) | string | Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. | +- Default: `{}` **Optional parameters** @@ -1757,22 +1987,9 @@ The audit settings configuration. | [`name`](#parameter-auditsettingsname) | string | Specifies the name of the audit settings. | | [`queueDelayMs`](#parameter-auditsettingsqueuedelayms) | int | Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed. | | [`retentionDays`](#parameter-auditsettingsretentiondays) | int | Specifies the number of days to keep in the audit logs in the storage account. | +| [`state`](#parameter-auditsettingsstate) | string | Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. | | [`storageAccountResourceId`](#parameter-auditsettingsstorageaccountresourceid) | string | Specifies the identifier key of the auditing storage account. | -### Parameter: `auditSettings.state` - -Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. - -- Required: Yes -- Type: string -- Allowed: - ```Bicep - [ - 'Disabled' - 'Enabled' - ] - ``` - ### Parameter: `auditSettings.auditActionsAndGroups` Specifies the Actions-Groups and Actions to audit. @@ -1829,6 +2046,20 @@ Specifies the number of days to keep in the audit logs in the storage account. - Required: No - Type: int +### Parameter: `auditSettings.state` + +Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + ### Parameter: `auditSettings.storageAccountResourceId` Specifies the identifier key of the auditing storage account. @@ -1844,38 +2075,944 @@ The databases to create in the server. - Type: array - Default: `[]` -### Parameter: `elasticPools` - -The Elastic Pools to create in the server. +**Required parameters** -- Required: No -- Type: array -- Default: `[]` +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-databasesname) | string | The name of the Elastic Pool. | -### Parameter: `enableTelemetry` +**Optional parameters** -Enable/Disable usage telemetry for module. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoPauseDelay`](#parameter-databasesautopausedelay) | int | Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled. | +| [`availabilityZone`](#parameter-databasesavailabilityzone) | string | Specifies the availability zone the database is pinned to. | +| [`backupLongTermRetentionPolicy`](#parameter-databasesbackuplongtermretentionpolicy) | object | The long term backup retention policy for the database. | +| [`backupShortTermRetentionPolicy`](#parameter-databasesbackupshorttermretentionpolicy) | object | The short term backup retention policy for the database. | +| [`catalogCollation`](#parameter-databasescatalogcollation) | string | Collation of the metadata catalog. | +| [`collation`](#parameter-databasescollation) | string | The collation of the database. | +| [`createMode`](#parameter-databasescreatemode) | string | Specifies the mode of database creation. | +| [`diagnosticSettings`](#parameter-databasesdiagnosticsettings) | array | The diagnostic settings of the service. | +| [`elasticPoolResourceId`](#parameter-databaseselasticpoolresourceid) | string | The resource identifier of the elastic pool containing this database. | +| [`encryptionProtector`](#parameter-databasesencryptionprotector) | string | The azure key vault URI of the database if it's configured with per Database Customer Managed Keys. | +| [`encryptionProtectorAutoRotation`](#parameter-databasesencryptionprotectorautorotation) | bool | The flag to enable or disable auto rotation of database encryption protector AKV key. | +| [`federatedClientId`](#parameter-databasesfederatedclientid) | string | The Client id used for cross tenant per database CMK scenario. | +| [`freeLimitExhaustionBehavior`](#parameter-databasesfreelimitexhaustionbehavior) | string | Specifies the behavior when monthly free limits are exhausted for the free database. | +| [`highAvailabilityReplicaCount`](#parameter-databaseshighavailabilityreplicacount) | int | The number of secondary replicas associated with the database that are used to provide high availability. Not applicable to a Hyperscale database within an elastic pool. | +| [`isLedgerOn`](#parameter-databasesisledgeron) | bool | Whether or not this database is a ledger database, which means all tables in the database are ledger tables. | +| [`licenseType`](#parameter-databaseslicensetype) | string | The license type to apply for this database. | +| [`longTermRetentionBackupResourceId`](#parameter-databaseslongtermretentionbackupresourceid) | string | The resource identifier of the long term retention backup associated with create operation of this database. | +| [`maintenanceConfigurationId`](#parameter-databasesmaintenanceconfigurationid) | string | Maintenance configuration id assigned to the database. This configuration defines the period when the maintenance updates will occur. | +| [`manualCutover`](#parameter-databasesmanualcutover) | bool | Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier. | +| [`maxSizeBytes`](#parameter-databasesmaxsizebytes) | int | The max size of the database expressed in bytes. | +| [`minCapacity`](#parameter-databasesmincapacity) | string | Minimal capacity that database will always have allocated, if not paused. | +| [`performCutover`](#parameter-databasesperformcutover) | bool | To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress. | +| [`preferredEnclaveType`](#parameter-databasespreferredenclavetype) | string | Type of enclave requested on the database. | +| [`readScale`](#parameter-databasesreadscale) | string | The state of read-only routing. If enabled, connections that have application intent set to readonly in their connection string may be routed to a readonly secondary replica in the same region. Not applicable to a Hyperscale database within an elastic pool. | +| [`recoverableDatabaseResourceId`](#parameter-databasesrecoverabledatabaseresourceid) | string | The resource identifier of the recoverable database associated with create operation of this database. | +| [`recoveryServicesRecoveryPointResourceId`](#parameter-databasesrecoveryservicesrecoverypointresourceid) | string | The resource identifier of the recovery point associated with create operation of this database. | +| [`requestedBackupStorageRedundancy`](#parameter-databasesrequestedbackupstorageredundancy) | string | The storage account type to be used to store backups for this database. | +| [`restorableDroppedDatabaseResourceId`](#parameter-databasesrestorabledroppeddatabaseresourceid) | string | The resource identifier of the restorable dropped database associated with create operation of this database. | +| [`restorePointInTime`](#parameter-databasesrestorepointintime) | string | Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database. | +| [`sampleName`](#parameter-databasessamplename) | string | The name of the sample schema to apply when creating this database. | +| [`secondaryType`](#parameter-databasessecondarytype) | string | The secondary type of the database if it is a secondary. | +| [`sku`](#parameter-databasessku) | object | The database SKU. | +| [`sourceDatabaseDeletionDate`](#parameter-databasessourcedatabasedeletiondate) | string | Specifies the time that the database was deleted. | +| [`sourceDatabaseResourceId`](#parameter-databasessourcedatabaseresourceid) | string | The resource identifier of the source database associated with create operation of this database. | +| [`sourceResourceId`](#parameter-databasessourceresourceid) | string | The resource identifier of the source associated with the create operation of this database. | +| [`tags`](#parameter-databasestags) | object | Tags of the resource. | +| [`useFreeLimit`](#parameter-databasesusefreelimit) | bool | Whether or not the database uses free monthly limits. Allowed on one database in a subscription. | +| [`zoneRedundant`](#parameter-databaseszoneredundant) | bool | Whether or not this database is zone redundant, which means the replicas of this database will be spread across multiple availability zones. | + +### Parameter: `databases.name` + +The name of the Elastic Pool. -- Required: No -- Type: bool -- Default: `True` +- Required: Yes +- Type: string -### Parameter: `encryptionProtectorObj` +### Parameter: `databases.autoPauseDelay` -The encryption protection configuration. +Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled. - Required: No -- Type: object -- Default: `{}` +- Type: int -### Parameter: `firewallRules` +### Parameter: `databases.availabilityZone` -The firewall rules to create in the server. +Specifies the availability zone the database is pinned to. - Required: No -- Type: array -- Default: `[]` - +- Type: string +- Allowed: + ```Bicep + [ + '1' + '2' + '3' + 'NoPreference' + ] + ``` + +### Parameter: `databases.backupLongTermRetentionPolicy` + +The long term backup retention policy for the database. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupStorageAccessTier`](#parameter-databasesbackuplongtermretentionpolicybackupstorageaccesstier) | string | The BackupStorageAccessTier for the LTR backups. | +| [`makeBackupsImmutable`](#parameter-databasesbackuplongtermretentionpolicymakebackupsimmutable) | bool | The setting whether to make LTR backups immutable. | +| [`monthlyRetention`](#parameter-databasesbackuplongtermretentionpolicymonthlyretention) | string | Monthly retention in ISO 8601 duration format. | +| [`weeklyRetention`](#parameter-databasesbackuplongtermretentionpolicyweeklyretention) | string | Weekly retention in ISO 8601 duration format. | +| [`weekOfYear`](#parameter-databasesbackuplongtermretentionpolicyweekofyear) | int | Week of year backup to keep for yearly retention. | +| [`yearlyRetention`](#parameter-databasesbackuplongtermretentionpolicyyearlyretention) | string | Yearly retention in ISO 8601 duration format. | + +### Parameter: `databases.backupLongTermRetentionPolicy.backupStorageAccessTier` + +The BackupStorageAccessTier for the LTR backups. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Archive' + 'Hot' + ] + ``` + +### Parameter: `databases.backupLongTermRetentionPolicy.makeBackupsImmutable` + +The setting whether to make LTR backups immutable. + +- Required: No +- Type: bool + +### Parameter: `databases.backupLongTermRetentionPolicy.monthlyRetention` + +Monthly retention in ISO 8601 duration format. + +- Required: No +- Type: string + +### Parameter: `databases.backupLongTermRetentionPolicy.weeklyRetention` + +Weekly retention in ISO 8601 duration format. + +- Required: No +- Type: string + +### Parameter: `databases.backupLongTermRetentionPolicy.weekOfYear` + +Week of year backup to keep for yearly retention. + +- Required: No +- Type: int + +### Parameter: `databases.backupLongTermRetentionPolicy.yearlyRetention` + +Yearly retention in ISO 8601 duration format. + +- Required: No +- Type: string + +### Parameter: `databases.backupShortTermRetentionPolicy` + +The short term backup retention policy for the database. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`diffBackupIntervalInHours`](#parameter-databasesbackupshorttermretentionpolicydiffbackupintervalinhours) | int | Differential backup interval in hours. For Hyperscale tiers this value will be ignored. | +| [`retentionDays`](#parameter-databasesbackupshorttermretentionpolicyretentiondays) | int | Point-in-time retention in days. | + +### Parameter: `databases.backupShortTermRetentionPolicy.diffBackupIntervalInHours` + +Differential backup interval in hours. For Hyperscale tiers this value will be ignored. + +- Required: No +- Type: int + +### Parameter: `databases.backupShortTermRetentionPolicy.retentionDays` + +Point-in-time retention in days. + +- Required: No +- Type: int + +### Parameter: `databases.catalogCollation` + +Collation of the metadata catalog. + +- Required: No +- Type: string + +### Parameter: `databases.collation` + +The collation of the database. + +- Required: No +- Type: string + +### Parameter: `databases.createMode` + +Specifies the mode of database creation. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Copy' + 'Default' + 'OnlineSecondary' + 'PointInTimeRestore' + 'Recovery' + 'Restore' + 'RestoreExternalBackup' + 'RestoreExternalBackupSecondary' + 'RestoreLongTermRetentionBackup' + 'Secondary' + ] + ``` + +### Parameter: `databases.diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-databasesdiagnosticsettingseventhubauthorizationruleresourceid) | string | 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`](#parameter-databasesdiagnosticsettingseventhubname) | string | 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. | +| [`logAnalyticsDestinationType`](#parameter-databasesdiagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-databasesdiagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-databasesdiagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`metricCategories`](#parameter-databasesdiagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | +| [`name`](#parameter-databasesdiagnosticsettingsname) | string | The name of the diagnostic setting. | +| [`storageAccountResourceId`](#parameter-databasesdiagnosticsettingsstorageaccountresourceid) | string | 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. | +| [`workspaceResourceId`](#parameter-databasesdiagnosticsettingsworkspaceresourceid) | string | 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. | + +### Parameter: `databases.diagnosticSettings.eventHubAuthorizationRuleResourceId` + +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. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.eventHubName` + +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. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `databases.diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-databasesdiagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-databasesdiagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-databasesdiagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `databases.diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `databases.diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.metricCategories` + +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-databasesdiagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-databasesdiagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `databases.diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `databases.diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `databases.diagnosticSettings.name` + +The name of the diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.storageAccountResourceId` + +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. + +- Required: No +- Type: string + +### Parameter: `databases.diagnosticSettings.workspaceResourceId` + +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. + +- Required: No +- Type: string + +### Parameter: `databases.elasticPoolResourceId` + +The resource identifier of the elastic pool containing this database. + +- Required: No +- Type: string + +### Parameter: `databases.encryptionProtector` + +The azure key vault URI of the database if it's configured with per Database Customer Managed Keys. + +- Required: No +- Type: string + +### Parameter: `databases.encryptionProtectorAutoRotation` + +The flag to enable or disable auto rotation of database encryption protector AKV key. + +- Required: No +- Type: bool + +### Parameter: `databases.federatedClientId` + +The Client id used for cross tenant per database CMK scenario. + +- Required: No +- Type: string + +### Parameter: `databases.freeLimitExhaustionBehavior` + +Specifies the behavior when monthly free limits are exhausted for the free database. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AutoPause' + 'BillOverUsage' + ] + ``` + +### Parameter: `databases.highAvailabilityReplicaCount` + +The number of secondary replicas associated with the database that are used to provide high availability. Not applicable to a Hyperscale database within an elastic pool. + +- Required: No +- Type: int + +### Parameter: `databases.isLedgerOn` + +Whether or not this database is a ledger database, which means all tables in the database are ledger tables. + +- Required: No +- Type: bool + +### Parameter: `databases.licenseType` + +The license type to apply for this database. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'BasePrice' + 'LicenseIncluded' + ] + ``` + +### Parameter: `databases.longTermRetentionBackupResourceId` + +The resource identifier of the long term retention backup associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.maintenanceConfigurationId` + +Maintenance configuration id assigned to the database. This configuration defines the period when the maintenance updates will occur. + +- Required: No +- Type: string + +### Parameter: `databases.manualCutover` + +Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier. + +- Required: No +- Type: bool + +### Parameter: `databases.maxSizeBytes` + +The max size of the database expressed in bytes. + +- Required: No +- Type: int + +### Parameter: `databases.minCapacity` + +Minimal capacity that database will always have allocated, if not paused. + +- Required: No +- Type: string + +### Parameter: `databases.performCutover` + +To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress. + +- Required: No +- Type: bool + +### Parameter: `databases.preferredEnclaveType` + +Type of enclave requested on the database. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Default' + 'VBS' + ] + ``` + +### Parameter: `databases.readScale` + +The state of read-only routing. If enabled, connections that have application intent set to readonly in their connection string may be routed to a readonly secondary replica in the same region. Not applicable to a Hyperscale database within an elastic pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `databases.recoverableDatabaseResourceId` + +The resource identifier of the recoverable database associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.recoveryServicesRecoveryPointResourceId` + +The resource identifier of the recovery point associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.requestedBackupStorageRedundancy` + +The storage account type to be used to store backups for this database. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Geo' + 'GeoZone' + 'Local' + 'Zone' + ] + ``` + +### Parameter: `databases.restorableDroppedDatabaseResourceId` + +The resource identifier of the restorable dropped database associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.restorePointInTime` + +Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database. + +- Required: No +- Type: string + +### Parameter: `databases.sampleName` + +The name of the sample schema to apply when creating this database. + +- Required: No +- Type: string + +### Parameter: `databases.secondaryType` + +The secondary type of the database if it is a secondary. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Geo' + 'Named' + 'Standby' + ] + ``` + +### Parameter: `databases.sku` + +The database SKU. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-databasesskuname) | string | The name of the SKU, typically, a letter + Number code, e.g. P3. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacity`](#parameter-databasesskucapacity) | int | The capacity of the particular SKU. | +| [`family`](#parameter-databasesskufamily) | string | If the service has different generations of hardware, for the same SKU, then that can be captured here. | +| [`size`](#parameter-databasesskusize) | string | Size of the particular SKU. | +| [`tier`](#parameter-databasesskutier) | string | The tier or edition of the particular SKU, e.g. Basic, Premium. | + +### Parameter: `databases.sku.name` + +The name of the SKU, typically, a letter + Number code, e.g. P3. + +- Required: Yes +- Type: string + +### Parameter: `databases.sku.capacity` + +The capacity of the particular SKU. + +- Required: No +- Type: int + +### Parameter: `databases.sku.family` + +If the service has different generations of hardware, for the same SKU, then that can be captured here. + +- Required: No +- Type: string + +### Parameter: `databases.sku.size` + +Size of the particular SKU. + +- Required: No +- Type: string + +### Parameter: `databases.sku.tier` + +The tier or edition of the particular SKU, e.g. Basic, Premium. + +- Required: No +- Type: string + +### Parameter: `databases.sourceDatabaseDeletionDate` + +Specifies the time that the database was deleted. + +- Required: No +- Type: string + +### Parameter: `databases.sourceDatabaseResourceId` + +The resource identifier of the source database associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.sourceResourceId` + +The resource identifier of the source associated with the create operation of this database. + +- Required: No +- Type: string + +### Parameter: `databases.tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `databases.useFreeLimit` + +Whether or not the database uses free monthly limits. Allowed on one database in a subscription. + +- Required: No +- Type: bool + +### Parameter: `databases.zoneRedundant` + +Whether or not this database is zone redundant, which means the replicas of this database will be spread across multiple availability zones. + +- Required: No +- Type: bool + +### Parameter: `elasticPools` + +The Elastic Pools to create in the server. + +- Required: No +- Type: array +- Default: `[]` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-elasticpoolsname) | string | The name of the Elastic Pool. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoPauseDelay`](#parameter-elasticpoolsautopausedelay) | int | Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. | +| [`availabilityZone`](#parameter-elasticpoolsavailabilityzone) | string | Specifies the availability zone the pool's primary replica is pinned to. | +| [`highAvailabilityReplicaCount`](#parameter-elasticpoolshighavailabilityreplicacount) | int | The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools. | +| [`licenseType`](#parameter-elasticpoolslicensetype) | string | The license type to apply for this elastic pool. | +| [`maintenanceConfigurationId`](#parameter-elasticpoolsmaintenanceconfigurationid) | string | Maintenance configuration id assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur. | +| [`maxSizeBytes`](#parameter-elasticpoolsmaxsizebytes) | int | The storage limit for the database elastic pool in bytes. | +| [`minCapacity`](#parameter-elasticpoolsmincapacity) | int | Minimal capacity that serverless pool will not shrink below, if not paused. | +| [`perDatabaseSettings`](#parameter-elasticpoolsperdatabasesettings) | object | The per database settings for the elastic pool. | +| [`preferredEnclaveType`](#parameter-elasticpoolspreferredenclavetype) | string | Type of enclave requested on the elastic pool. | +| [`sku`](#parameter-elasticpoolssku) | object | The elastic pool SKU. | +| [`tags`](#parameter-elasticpoolstags) | object | Tags of the resource. | +| [`zoneRedundant`](#parameter-elasticpoolszoneredundant) | bool | Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones. | + +### Parameter: `elasticPools.name` + +The name of the Elastic Pool. + +- Required: Yes +- Type: string + +### Parameter: `elasticPools.autoPauseDelay` + +Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. + +- Required: No +- Type: int + +### Parameter: `elasticPools.availabilityZone` + +Specifies the availability zone the pool's primary replica is pinned to. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '1' + '2' + '3' + 'NoPreference' + ] + ``` + +### Parameter: `elasticPools.highAvailabilityReplicaCount` + +The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools. + +- Required: No +- Type: int + +### Parameter: `elasticPools.licenseType` + +The license type to apply for this elastic pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'BasePrice' + 'LicenseIncluded' + ] + ``` + +### Parameter: `elasticPools.maintenanceConfigurationId` + +Maintenance configuration id assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur. + +- Required: No +- Type: string + +### Parameter: `elasticPools.maxSizeBytes` + +The storage limit for the database elastic pool in bytes. + +- Required: No +- Type: int + +### Parameter: `elasticPools.minCapacity` + +Minimal capacity that serverless pool will not shrink below, if not paused. + +- Required: No +- Type: int + +### Parameter: `elasticPools.perDatabaseSettings` + +The per database settings for the elastic pool. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`maxCapacity`](#parameter-elasticpoolsperdatabasesettingsmaxcapacity) | string | The maximum capacity any one database can consume. Examples: '0.5', '2'. | +| [`minCapacity`](#parameter-elasticpoolsperdatabasesettingsmincapacity) | string | The minimum capacity all databases are guaranteed. Examples: '0.5', '1'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoPauseDelay`](#parameter-elasticpoolsperdatabasesettingsautopausedelay) | int | Auto Pause Delay for per database within pool. | + +### Parameter: `elasticPools.perDatabaseSettings.maxCapacity` + +The maximum capacity any one database can consume. Examples: '0.5', '2'. + +- Required: Yes +- Type: string + +### Parameter: `elasticPools.perDatabaseSettings.minCapacity` + +The minimum capacity all databases are guaranteed. Examples: '0.5', '1'. + +- Required: Yes +- Type: string + +### Parameter: `elasticPools.perDatabaseSettings.autoPauseDelay` + +Auto Pause Delay for per database within pool. + +- Required: No +- Type: int + +### Parameter: `elasticPools.preferredEnclaveType` + +Type of enclave requested on the elastic pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Default' + 'VBS' + ] + ``` + +### Parameter: `elasticPools.sku` + +The elastic pool SKU. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-elasticpoolsskuname) | string | The name of the SKU, typically, a letter + Number code, e.g. P3. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacity`](#parameter-elasticpoolsskucapacity) | int | The capacity of the particular SKU. | +| [`family`](#parameter-elasticpoolsskufamily) | string | If the service has different generations of hardware, for the same SKU, then that can be captured here. | +| [`size`](#parameter-elasticpoolsskusize) | string | Size of the particular SKU. | +| [`tier`](#parameter-elasticpoolsskutier) | string | The tier or edition of the particular SKU, e.g. Basic, Premium. | + +### Parameter: `elasticPools.sku.name` + +The name of the SKU, typically, a letter + Number code, e.g. P3. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'BasicPool' + 'BC_DC' + 'BC_Gen5' + 'GP_DC' + 'GP_FSv2' + 'GP_Gen5' + 'HS_Gen5' + 'HS_MOPRMS' + 'HS_PRMS' + 'PremiumPool' + 'ServerlessPool' + 'StandardPool' + ] + ``` + +### Parameter: `elasticPools.sku.capacity` + +The capacity of the particular SKU. + +- Required: No +- Type: int + +### Parameter: `elasticPools.sku.family` + +If the service has different generations of hardware, for the same SKU, then that can be captured here. + +- Required: No +- Type: string + +### Parameter: `elasticPools.sku.size` + +Size of the particular SKU. + +- Required: No +- Type: string + +### Parameter: `elasticPools.sku.tier` + +The tier or edition of the particular SKU, e.g. Basic, Premium. + +- Required: No +- Type: string + +### Parameter: `elasticPools.tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `elasticPools.zoneRedundant` + +Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones. + +- Required: No +- Type: bool + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `encryptionProtectorObj` + +The encryption protection configuration. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `federatedClientId` + +The Client id used for cross tenant CMK scenario. + +- Required: No +- Type: string + +### Parameter: `firewallRules` + +The firewall rules to create in the server. + +- Required: No +- Type: array +- Default: `[]` + ### Parameter: `isIPv6Enabled` Whether or not to enable IPv6 support for this server. @@ -1891,6 +3028,13 @@ Whether or not to enable IPv6 support for this server. ] ``` +### Parameter: `keyId` + +A CMK URI of the key to use for encryption. + +- Required: No +- Type: string + ### Parameter: `keys` The keys to configure. @@ -1955,7 +3099,7 @@ The managed identity definition for this resource. | Parameter | Type | Description | | :-- | :-- | :-- | | [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.systemAssigned` @@ -1966,7 +3110,7 @@ Enables system assigned managed identity on the resource. ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. - Required: No - Type: array @@ -2005,22 +3149,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -2031,7 +3175,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -2071,7 +3215,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -2085,7 +3229,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -2149,7 +3293,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -2199,14 +3343,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -2215,7 +3359,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -2225,7 +3369,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -2240,7 +3384,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -2251,7 +3395,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -2272,7 +3416,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -2387,14 +3531,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -2633,6 +3777,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Notes diff --git a/avm/res/sql/server/audit-settings/README.md b/avm/res/sql/server/audit-settings/README.md index 0192be9674..79759eb42a 100644 --- a/avm/res/sql/server/audit-settings/README.md +++ b/avm/res/sql/server/audit-settings/README.md @@ -22,7 +22,6 @@ This module deploys an Azure SQL Server Audit Settings. | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | The name of the audit settings. | -| [`state`](#parameter-state) | string | The resource group of the SQL Server. Required if the template is used in a standalone deployment. | **Conditional parameters** @@ -41,6 +40,7 @@ This module deploys an Azure SQL Server Audit Settings. | [`isStorageSecondaryKeyInUse`](#parameter-isstoragesecondarykeyinuse) | bool | Specifies whether storageAccountAccessKey value is the storage's secondary key. | | [`queueDelayMs`](#parameter-queuedelayms) | int | Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed. | | [`retentionDays`](#parameter-retentiondays) | int | Specifies the number of days to keep in the audit logs in the storage account. | +| [`state`](#parameter-state) | string | Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. | | [`storageAccountResourceId`](#parameter-storageaccountresourceid) | string | A blob storage to hold the auditing storage account. | ### Parameter: `name` @@ -50,20 +50,6 @@ The name of the audit settings. - Required: Yes - Type: string -### Parameter: `state` - -The resource group of the SQL Server. Required if the template is used in a standalone deployment. - -- Required: Yes -- Type: string -- Allowed: - ```Bicep - [ - 'Disabled' - 'Enabled' - ] - ``` - ### Parameter: `serverName` The Name of SQL Server. Required if the template is used in a standalone deployment. @@ -77,6 +63,14 @@ Specifies the Actions-Groups and Actions to audit. - Required: No - Type: array +- Default: + ```Bicep + [ + 'BATCH_COMPLETED_GROUP' + 'FAILED_DATABASE_AUTHENTICATION_GROUP' + 'SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP' + ] + ``` ### Parameter: `isAzureMonitorTargetEnabled` @@ -84,7 +78,7 @@ Specifies whether audit events are sent to Azure Monitor. - Required: No - Type: bool -- Default: `False` +- Default: `True` ### Parameter: `isDevopsAuditEnabled` @@ -92,6 +86,7 @@ Specifies the state of devops audit. If state is Enabled, devops logs will be se - Required: No - Type: bool +- Default: `False` ### Parameter: `isManagedIdentityInUse` @@ -107,6 +102,7 @@ Specifies whether storageAccountAccessKey value is the storage's secondary key. - Required: No - Type: bool +- Default: `False` ### Parameter: `queueDelayMs` @@ -114,6 +110,7 @@ Specifies the amount of time in milliseconds that can elapse before audit action - Required: No - Type: int +- Default: `1000` ### Parameter: `retentionDays` @@ -121,6 +118,22 @@ Specifies the number of days to keep in the audit logs in the storage account. - Required: No - Type: int +- Default: `90` + +### Parameter: `state` + +Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required. + +- Required: No +- Type: string +- Default: `'Enabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` ### Parameter: `storageAccountResourceId` diff --git a/avm/res/sql/server/audit-settings/main.bicep b/avm/res/sql/server/audit-settings/main.bicep index 4419b942b0..8d23380517 100644 --- a/avm/res/sql/server/audit-settings/main.bicep +++ b/avm/res/sql/server/audit-settings/main.bicep @@ -8,33 +8,37 @@ param name string @description('Conditional. The Name of SQL Server. Required if the template is used in a standalone deployment.') param serverName string -@description('Required. The resource group of the SQL Server. Required if the template is used in a standalone deployment.') +@description('Optional. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required.') @allowed([ 'Enabled' 'Disabled' ]) -param state string +param state string = 'Enabled' @description('Optional. Specifies the Actions-Groups and Actions to audit.') -param auditActionsAndGroups array? +param auditActionsAndGroups string[] = [ + 'BATCH_COMPLETED_GROUP' + 'SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP' + 'FAILED_DATABASE_AUTHENTICATION_GROUP' +] @description('Optional. Specifies whether audit events are sent to Azure Monitor.') -param isAzureMonitorTargetEnabled bool = false +param isAzureMonitorTargetEnabled bool = true @description('Optional. Specifies the state of devops audit. If state is Enabled, devops logs will be sent to Azure Monitor.') -param isDevopsAuditEnabled bool? +param isDevopsAuditEnabled bool = false @description('Optional. Specifies whether Managed Identity is used to access blob storage.') param isManagedIdentityInUse bool = false @description('Optional. Specifies whether storageAccountAccessKey value is the storage\'s secondary key.') -param isStorageSecondaryKeyInUse bool? +param isStorageSecondaryKeyInUse bool = false @description('Optional. Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed.') -param queueDelayMs int? +param queueDelayMs int = 1000 @description('Optional. Specifies the number of days to keep in the audit logs in the storage account.') -param retentionDays int? +param retentionDays int = 90 @description('Optional. A blob storage to hold the auditing storage account.') param storageAccountResourceId string = '' diff --git a/avm/res/sql/server/audit-settings/main.json b/avm/res/sql/server/audit-settings/main.json index e18c9a0494..4c12fe1854 100644 --- a/avm/res/sql/server/audit-settings/main.json +++ b/avm/res/sql/server/audit-settings/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "4165841300638093382" + "version": "0.30.23.60470", + "templateHash": "6303070680265885029" }, "name": "Azure SQL Server Audit Settings", "description": "This module deploys an Azure SQL Server Audit Settings.", @@ -27,31 +27,39 @@ }, "state": { "type": "string", + "defaultValue": "Enabled", "allowedValues": [ "Enabled", "Disabled" ], "metadata": { - "description": "Required. The resource group of the SQL Server. Required if the template is used in a standalone deployment." + "description": "Optional. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required." } }, "auditActionsAndGroups": { "type": "array", - "nullable": true, + "items": { + "type": "string" + }, + "defaultValue": [ + "BATCH_COMPLETED_GROUP", + "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP", + "FAILED_DATABASE_AUTHENTICATION_GROUP" + ], "metadata": { "description": "Optional. Specifies the Actions-Groups and Actions to audit." } }, "isAzureMonitorTargetEnabled": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { "description": "Optional. Specifies whether audit events are sent to Azure Monitor." } }, "isDevopsAuditEnabled": { "type": "bool", - "nullable": true, + "defaultValue": false, "metadata": { "description": "Optional. Specifies the state of devops audit. If state is Enabled, devops logs will be sent to Azure Monitor." } @@ -65,21 +73,21 @@ }, "isStorageSecondaryKeyInUse": { "type": "bool", - "nullable": true, + "defaultValue": false, "metadata": { "description": "Optional. Specifies whether storageAccountAccessKey value is the storage's secondary key." } }, "queueDelayMs": { "type": "int", - "nullable": true, + "defaultValue": 1000, "metadata": { "description": "Optional. Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed." } }, "retentionDays": { "type": "int", - "nullable": true, + "defaultValue": 90, "metadata": { "description": "Optional. Specifies the number of days to keep in the audit logs in the storage account." } @@ -144,8 +152,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "17251889896692066430" + "version": "0.30.23.60470", + "templateHash": "13956215614091387428" } }, "parameters": { diff --git a/avm/res/sql/server/database/README.md b/avm/res/sql/server/database/README.md index 1abb8e303b..9783dcfb7a 100644 --- a/avm/res/sql/server/database/README.md +++ b/avm/res/sql/server/database/README.md @@ -7,6 +7,7 @@ This module deploys an Azure SQL Server Database. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -14,7 +15,7 @@ This module deploys an Azure SQL Server Database. | :-- | :-- | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Sql/servers/databases` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases) | -| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies) | +| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/2023-05-01-preview/servers/databases/backupLongTermRetentionPolicies) | | `Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies) | ## Parameters @@ -36,33 +37,43 @@ This module deploys an Azure SQL Server Database. | Parameter | Type | Description | | :-- | :-- | :-- | | [`autoPauseDelay`](#parameter-autopausedelay) | int | Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled. | +| [`availabilityZone`](#parameter-availabilityzone) | string | Specifies the availability zone the database is pinned to. | | [`backupLongTermRetentionPolicy`](#parameter-backuplongtermretentionpolicy) | object | The long term backup retention policy to create for the database. | | [`backupShortTermRetentionPolicy`](#parameter-backupshorttermretentionpolicy) | object | The short term backup retention policy to create for the database. | +| [`catalogCollation`](#parameter-catalogcollation) | string | Collation of the metadata catalog. | | [`collation`](#parameter-collation) | string | The collation of the database. | | [`createMode`](#parameter-createmode) | string | Specifies the mode of database creation. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | -| [`elasticPoolId`](#parameter-elasticpoolid) | string | The resource ID of the elastic pool containing this database. | +| [`elasticPoolResourceId`](#parameter-elasticpoolresourceid) | string | The resource ID of the elastic pool containing this database. | +| [`encryptionProtector`](#parameter-encryptionprotector) | string | The azure key vault URI of the database if it's configured with per Database Customer Managed Keys. | +| [`encryptionProtectorAutoRotation`](#parameter-encryptionprotectorautorotation) | bool | The flag to enable or disable auto rotation of database encryption protector AKV key. | +| [`federatedClientId`](#parameter-federatedclientid) | string | The Client id used for cross tenant per database CMK scenario. | +| [`freeLimitExhaustionBehavior`](#parameter-freelimitexhaustionbehavior) | string | Specifies the behavior when monthly free limits are exhausted for the free database. | | [`highAvailabilityReplicaCount`](#parameter-highavailabilityreplicacount) | int | The number of readonly secondary replicas associated with the database. | | [`isLedgerOn`](#parameter-isledgeron) | bool | Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created. | | [`licenseType`](#parameter-licensetype) | string | The license type to apply for this database. | | [`location`](#parameter-location) | string | Location for all resources. | +| [`longTermRetentionBackupResourceId`](#parameter-longtermretentionbackupresourceid) | string | The resource identifier of the long term retention backup associated with create operation of this database. | | [`maintenanceConfigurationId`](#parameter-maintenanceconfigurationid) | string | Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur. | +| [`manualCutover`](#parameter-manualcutover) | bool | Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier. | | [`maxSizeBytes`](#parameter-maxsizebytes) | int | The max size of the database expressed in bytes. | | [`minCapacity`](#parameter-mincapacity) | string | Minimal capacity that database will always have allocated. | +| [`performCutover`](#parameter-performcutover) | bool | To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress. | | [`preferredEnclaveType`](#parameter-preferredenclavetype) | string | Type of enclave requested on the database i.e. Default or VBS enclaves. | | [`readScale`](#parameter-readscale) | string | The state of read-only routing. | -| [`recoveryServicesRecoveryPointResourceId`](#parameter-recoveryservicesrecoverypointresourceid) | string | Resource ID of backup if createMode set to RestoreLongTermRetentionBackup. | +| [`recoverableDatabaseResourceId`](#parameter-recoverabledatabaseresourceid) | string | The resource identifier of the recoverable database associated with create operation of this database. | +| [`recoveryServicesRecoveryPointResourceId`](#parameter-recoveryservicesrecoverypointresourceid) | string | The resource identifier of the recovery point associated with create operation of this database. | | [`requestedBackupStorageRedundancy`](#parameter-requestedbackupstorageredundancy) | string | The storage account type to be used to store backups for this database. | +| [`restorableDroppedDatabaseResourceId`](#parameter-restorabledroppeddatabaseresourceid) | string | The resource identifier of the restorable dropped database associated with create operation of this database. | | [`restorePointInTime`](#parameter-restorepointintime) | string | Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore. | | [`sampleName`](#parameter-samplename) | string | The name of the sample schema to apply when creating this database. | -| [`skuCapacity`](#parameter-skucapacity) | int | Capacity of the particular SKU. | -| [`skuFamily`](#parameter-skufamily) | string | If the service has different generations of hardware, for the same SKU, then that can be captured here. | -| [`skuName`](#parameter-skuname) | string | The name of the SKU. | -| [`skuSize`](#parameter-skusize) | string | Size of the particular SKU. | -| [`skuTier`](#parameter-skutier) | string | The skuTier or edition of the particular SKU. | +| [`secondaryType`](#parameter-secondarytype) | string | The secondary type of the database if it is a secondary. | +| [`sku`](#parameter-sku) | object | The database SKU. | | [`sourceDatabaseDeletionDate`](#parameter-sourcedatabasedeletiondate) | string | The time that the database was deleted when restoring a deleted database. | -| [`sourceDatabaseResourceId`](#parameter-sourcedatabaseresourceid) | string | Resource ID of database if createMode set to Copy, Secondary, PointInTimeRestore, Recovery or Restore. | +| [`sourceDatabaseResourceId`](#parameter-sourcedatabaseresourceid) | string | The resource identifier of the source database associated with create operation of this database. | +| [`sourceResourceId`](#parameter-sourceresourceid) | string | The resource identifier of the source associated with the create operation of this database. | | [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`useFreeLimit`](#parameter-usefreelimit) | bool | Whether or not the database uses free monthly limits. Allowed on one database in a subscription. | | [`zoneRedundant`](#parameter-zoneredundant) | bool | Whether or not this database is zone redundant. | ### Parameter: `name` @@ -85,7 +96,24 @@ Time in minutes after which database is automatically paused. A value of -1 mean - Required: No - Type: int -- Default: `0` +- Default: `-1` + +### Parameter: `availabilityZone` + +Specifies the availability zone the database is pinned to. + +- Required: No +- Type: string +- Default: `'NoPreference'` +- Allowed: + ```Bicep + [ + '1' + '2' + '3' + 'NoPreference' + ] + ``` ### Parameter: `backupLongTermRetentionPolicy` @@ -93,7 +121,66 @@ The long term backup retention policy to create for the database. - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupStorageAccessTier`](#parameter-backuplongtermretentionpolicybackupstorageaccesstier) | string | The BackupStorageAccessTier for the LTR backups. | +| [`makeBackupsImmutable`](#parameter-backuplongtermretentionpolicymakebackupsimmutable) | bool | The setting whether to make LTR backups immutable. | +| [`monthlyRetention`](#parameter-backuplongtermretentionpolicymonthlyretention) | string | Monthly retention in ISO 8601 duration format. | +| [`weeklyRetention`](#parameter-backuplongtermretentionpolicyweeklyretention) | string | Weekly retention in ISO 8601 duration format. | +| [`weekOfYear`](#parameter-backuplongtermretentionpolicyweekofyear) | int | Week of year backup to keep for yearly retention. | +| [`yearlyRetention`](#parameter-backuplongtermretentionpolicyyearlyretention) | string | Yearly retention in ISO 8601 duration format. | + +### Parameter: `backupLongTermRetentionPolicy.backupStorageAccessTier` + +The BackupStorageAccessTier for the LTR backups. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Archive' + 'Hot' + ] + ``` + +### Parameter: `backupLongTermRetentionPolicy.makeBackupsImmutable` + +The setting whether to make LTR backups immutable. + +- Required: No +- Type: bool + +### Parameter: `backupLongTermRetentionPolicy.monthlyRetention` + +Monthly retention in ISO 8601 duration format. + +- Required: No +- Type: string + +### Parameter: `backupLongTermRetentionPolicy.weeklyRetention` + +Weekly retention in ISO 8601 duration format. + +- Required: No +- Type: string + +### Parameter: `backupLongTermRetentionPolicy.weekOfYear` + +Week of year backup to keep for yearly retention. + +- Required: No +- Type: int + +### Parameter: `backupLongTermRetentionPolicy.yearlyRetention` + +Yearly retention in ISO 8601 duration format. + +- Required: No +- Type: string ### Parameter: `backupShortTermRetentionPolicy` @@ -101,7 +188,35 @@ The short term backup retention policy to create for the database. - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`diffBackupIntervalInHours`](#parameter-backupshorttermretentionpolicydiffbackupintervalinhours) | int | Differential backup interval in hours. For Hyperscale tiers this value will be ignored. | +| [`retentionDays`](#parameter-backupshorttermretentionpolicyretentiondays) | int | Point-in-time retention in days. | + +### Parameter: `backupShortTermRetentionPolicy.diffBackupIntervalInHours` + +Differential backup interval in hours. For Hyperscale tiers this value will be ignored. + +- Required: No +- Type: int + +### Parameter: `backupShortTermRetentionPolicy.retentionDays` + +Point-in-time retention in days. + +- Required: No +- Type: int + +### Parameter: `catalogCollation` + +Collation of the metadata catalog. + +- Required: No +- Type: string +- Default: `'DATABASE_DEFAULT'` ### Parameter: `collation` @@ -127,6 +242,8 @@ Specifies the mode of database creation. 'PointInTimeRestore' 'Recovery' 'Restore' + 'RestoreExternalBackup' + 'RestoreExternalBackupSecondary' 'RestoreLongTermRetentionBackup' 'Secondary' ] @@ -149,7 +266,7 @@ The diagnostic settings of the service. | [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | -| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of the diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | | [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | 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. | @@ -259,7 +376,7 @@ Enable or disable the category explicitly. Default is `true`. ### Parameter: `diagnosticSettings.name` -The name of diagnostic setting. +The name of the diagnostic setting. - Required: No - Type: string @@ -278,13 +395,47 @@ Resource ID of the diagnostic log analytics workspace. For security reasons, it - Required: No - Type: string -### Parameter: `elasticPoolId` +### Parameter: `elasticPoolResourceId` The resource ID of the elastic pool containing this database. - Required: No - Type: string -- Default: `''` + +### Parameter: `encryptionProtector` + +The azure key vault URI of the database if it's configured with per Database Customer Managed Keys. + +- Required: No +- Type: string + +### Parameter: `encryptionProtectorAutoRotation` + +The flag to enable or disable auto rotation of database encryption protector AKV key. + +- Required: No +- Type: bool + +### Parameter: `federatedClientId` + +The Client id used for cross tenant per database CMK scenario. + +- Required: No +- Type: string + +### Parameter: `freeLimitExhaustionBehavior` + +Specifies the behavior when monthly free limits are exhausted for the free database. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AutoPause' + 'BillOverUsage' + ] + ``` ### Parameter: `highAvailabilityReplicaCount` @@ -308,7 +459,13 @@ The license type to apply for this database. - Required: No - Type: string -- Default: `''` +- Allowed: + ```Bicep + [ + 'BasePrice' + 'LicenseIncluded' + ] + ``` ### Parameter: `location` @@ -318,6 +475,13 @@ Location for all resources. - Type: string - Default: `[resourceGroup().location]` +### Parameter: `longTermRetentionBackupResourceId` + +The resource identifier of the long term retention backup associated with create operation of this database. + +- Required: No +- Type: string + ### Parameter: `maintenanceConfigurationId` Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur. @@ -325,6 +489,13 @@ Maintenance configuration ID assigned to the database. This configuration define - Required: No - Type: string +### Parameter: `manualCutover` + +Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier. + +- Required: No +- Type: bool + ### Parameter: `maxSizeBytes` The max size of the database expressed in bytes. @@ -339,7 +510,14 @@ Minimal capacity that database will always have allocated. - Required: No - Type: string -- Default: `''` +- Default: `'0'` + +### Parameter: `performCutover` + +To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress. + +- Required: No +- Type: bool ### Parameter: `preferredEnclaveType` @@ -347,11 +525,9 @@ Type of enclave requested on the database i.e. Default or VBS enclaves. - Required: No - Type: string -- Default: `''` - Allowed: ```Bicep [ - '' 'Default' 'VBS' ] @@ -372,13 +548,19 @@ The state of read-only routing. ] ``` +### Parameter: `recoverableDatabaseResourceId` + +The resource identifier of the recoverable database associated with create operation of this database. + +- Required: No +- Type: string + ### Parameter: `recoveryServicesRecoveryPointResourceId` -Resource ID of backup if createMode set to RestoreLongTermRetentionBackup. +The resource identifier of the recovery point associated with create operation of this database. - Required: No - Type: string -- Default: `''` ### Parameter: `requestedBackupStorageRedundancy` @@ -386,24 +568,30 @@ The storage account type to be used to store backups for this database. - Required: No - Type: string -- Default: `''` +- Default: `'Local'` - Allowed: ```Bicep [ - '' 'Geo' + 'GeoZone' 'Local' 'Zone' ] ``` +### Parameter: `restorableDroppedDatabaseResourceId` + +The resource identifier of the restorable dropped database associated with create operation of this database. + +- Required: No +- Type: string + ### Parameter: `restorePointInTime` Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore. - Required: No - Type: string -- Default: `''` ### Parameter: `sampleName` @@ -413,44 +601,84 @@ The name of the sample schema to apply when creating this database. - Type: string - Default: `''` -### Parameter: `skuCapacity` +### Parameter: `secondaryType` -Capacity of the particular SKU. +The secondary type of the database if it is a secondary. - Required: No -- Type: int +- Type: string +- Allowed: + ```Bicep + [ + 'Geo' + 'Named' + 'Standby' + ] + ``` -### Parameter: `skuFamily` +### Parameter: `sku` -If the service has different generations of hardware, for the same SKU, then that can be captured here. +The database SKU. - Required: No +- Type: object +- Default: + ```Bicep + { + name: 'GP_Gen5_2' + tier: 'GeneralPurpose' + } + ``` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-skuname) | string | The name of the SKU, typically, a letter + Number code, e.g. P3. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacity`](#parameter-skucapacity) | int | The capacity of the particular SKU. | +| [`family`](#parameter-skufamily) | string | If the service has different generations of hardware, for the same SKU, then that can be captured here. | +| [`size`](#parameter-skusize) | string | Size of the particular SKU. | +| [`tier`](#parameter-skutier) | string | The tier or edition of the particular SKU, e.g. Basic, Premium. | + +### Parameter: `sku.name` + +The name of the SKU, typically, a letter + Number code, e.g. P3. + +- Required: Yes - Type: string -- Default: `''` -### Parameter: `skuName` +### Parameter: `sku.capacity` -The name of the SKU. +The capacity of the particular SKU. + +- Required: No +- Type: int + +### Parameter: `sku.family` + +If the service has different generations of hardware, for the same SKU, then that can be captured here. - Required: No - Type: string -- Default: `'GP_Gen5_2'` -### Parameter: `skuSize` +### Parameter: `sku.size` Size of the particular SKU. - Required: No - Type: string -- Default: `''` -### Parameter: `skuTier` +### Parameter: `sku.tier` -The skuTier or edition of the particular SKU. +The tier or edition of the particular SKU, e.g. Basic, Premium. - Required: No - Type: string -- Default: `'GeneralPurpose'` ### Parameter: `sourceDatabaseDeletionDate` @@ -458,15 +686,20 @@ The time that the database was deleted when restoring a deleted database. - Required: No - Type: string -- Default: `''` ### Parameter: `sourceDatabaseResourceId` -Resource ID of database if createMode set to Copy, Secondary, PointInTimeRestore, Recovery or Restore. +The resource identifier of the source database associated with create operation of this database. + +- Required: No +- Type: string + +### Parameter: `sourceResourceId` + +The resource identifier of the source associated with the create operation of this database. - Required: No - Type: string -- Default: `''` ### Parameter: `tags` @@ -475,6 +708,13 @@ Tags of the resource. - Required: No - Type: object +### Parameter: `useFreeLimit` + +Whether or not the database uses free monthly limits. Allowed on one database in a subscription. + +- Required: No +- Type: bool + ### Parameter: `zoneRedundant` Whether or not this database is zone redundant. @@ -491,3 +731,11 @@ Whether or not this database is zone redundant. | `name` | string | The name of the deployed database. | | `resourceGroupName` | string | The resource group of the deployed database. | | `resourceId` | string | The resource ID of the deployed database. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/sql/server/database/backup-long-term-retention-policy/README.md b/avm/res/sql/server/database/backup-long-term-retention-policy/README.md index cc8f638db5..4e9e070b02 100644 --- a/avm/res/sql/server/database/backup-long-term-retention-policy/README.md +++ b/avm/res/sql/server/database/backup-long-term-retention-policy/README.md @@ -12,7 +12,7 @@ This module deploys an Azure SQL Server Database Long-Term Backup Retention Poli | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-08-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies) | +| `Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies` | [2023-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Sql/2023-05-01-preview/servers/databases/backupLongTermRetentionPolicies) | ## Parameters @@ -27,8 +27,10 @@ This module deploys an Azure SQL Server Database Long-Term Backup Retention Poli | Parameter | Type | Description | | :-- | :-- | :-- | -| [`monthlyRetention`](#parameter-monthlyretention) | string | Weekly retention in ISO 8601 duration format. | -| [`weeklyRetention`](#parameter-weeklyretention) | string | Monthly retention in ISO 8601 duration format. | +| [`backupStorageAccessTier`](#parameter-backupstorageaccesstier) | string | The BackupStorageAccessTier for the LTR backups. | +| [`makeBackupsImmutable`](#parameter-makebackupsimmutable) | bool | The setting whether to make LTR backups immutable. | +| [`monthlyRetention`](#parameter-monthlyretention) | string | Monthly retention in ISO 8601 duration format. | +| [`weeklyRetention`](#parameter-weeklyretention) | string | Weekly retention in ISO 8601 duration format. | | [`weekOfYear`](#parameter-weekofyear) | int | Week of year backup to keep for yearly retention. | | [`yearlyRetention`](#parameter-yearlyretention) | string | Yearly retention in ISO 8601 duration format. | @@ -46,21 +48,40 @@ The name of the parent SQL Server. - Required: Yes - Type: string +### Parameter: `backupStorageAccessTier` + +The BackupStorageAccessTier for the LTR backups. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Archive' + 'Hot' + ] + ``` + +### Parameter: `makeBackupsImmutable` + +The setting whether to make LTR backups immutable. + +- Required: No +- Type: bool + ### Parameter: `monthlyRetention` -Weekly retention in ISO 8601 duration format. +Monthly retention in ISO 8601 duration format. - Required: No - Type: string -- Default: `''` ### Parameter: `weeklyRetention` -Monthly retention in ISO 8601 duration format. +Weekly retention in ISO 8601 duration format. - Required: No - Type: string -- Default: `''` ### Parameter: `weekOfYear` @@ -76,7 +97,6 @@ Yearly retention in ISO 8601 duration format. - Required: No - Type: string -- Default: `''` ## Outputs diff --git a/avm/res/sql/server/database/backup-long-term-retention-policy/main.bicep b/avm/res/sql/server/database/backup-long-term-retention-policy/main.bicep index 86a4e8f0dd..e143e98f53 100644 --- a/avm/res/sql/server/database/backup-long-term-retention-policy/main.bicep +++ b/avm/res/sql/server/database/backup-long-term-retention-policy/main.bicep @@ -8,17 +8,23 @@ param serverName string @description('Required. The name of the parent database.') param databaseName string +@description('Optional. The BackupStorageAccessTier for the LTR backups.') +param backupStorageAccessTier 'Archive' | 'Hot'? + +@description('Optional. The setting whether to make LTR backups immutable.') +param makeBackupsImmutable bool? + @description('Optional. Monthly retention in ISO 8601 duration format.') -param weeklyRetention string = '' +param monthlyRetention string? @description('Optional. Weekly retention in ISO 8601 duration format.') -param monthlyRetention string = '' +param weeklyRetention string? @description('Optional. Week of year backup to keep for yearly retention.') param weekOfYear int = 1 @description('Optional. Yearly retention in ISO 8601 duration format.') -param yearlyRetention string = '' +param yearlyRetention string? resource server 'Microsoft.Sql/servers@2023-08-01-preview' existing = { name: serverName @@ -28,10 +34,12 @@ resource server 'Microsoft.Sql/servers@2023-08-01-preview' existing = { } } -resource backupLongTermRetentionPolicy 'Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies@2023-08-01-preview' = { +resource backupLongTermRetentionPolicy 'Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies@2023-05-01-preview' = { name: 'default' parent: server::database properties: { + backupStorageAccessTier: backupStorageAccessTier + makeBackupsImmutable: makeBackupsImmutable monthlyRetention: monthlyRetention weeklyRetention: weeklyRetention weekOfYear: weekOfYear diff --git a/avm/res/sql/server/database/backup-long-term-retention-policy/main.json b/avm/res/sql/server/database/backup-long-term-retention-policy/main.json index b54683c3bc..aa4ac7652a 100644 --- a/avm/res/sql/server/database/backup-long-term-retention-policy/main.json +++ b/avm/res/sql/server/database/backup-long-term-retention-policy/main.json @@ -1,11 +1,12 @@ { "$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": "2778016138108001251" + "version": "0.30.23.60470", + "templateHash": "841731129374883266" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", @@ -24,16 +25,34 @@ "description": "Required. The name of the parent database." } }, - "weeklyRetention": { + "backupStorageAccessTier": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, "metadata": { - "description": "Optional. Monthly retention in ISO 8601 duration format." + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." } }, "monthlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, "metadata": { "description": "Optional. Weekly retention in ISO 8601 duration format." } @@ -47,25 +66,45 @@ }, "yearlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Yearly retention in ISO 8601 duration format." } } }, - "resources": [ - { - "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "resources": { + "server::database": { + "existing": true, + "type": "Microsoft.Sql/servers/databases", "apiVersion": "2023-08-01-preview", + "name": "[format('{0}/{1}', parameters('serverName'), parameters('databaseName'))]", + "dependsOn": [ + "server" + ] + }, + "server": { + "existing": true, + "type": "Microsoft.Sql/servers", + "apiVersion": "2023-08-01-preview", + "name": "[parameters('serverName')]" + }, + "backupLongTermRetentionPolicy": { + "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "apiVersion": "2023-05-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { + "backupStorageAccessTier": "[parameters('backupStorageAccessTier')]", + "makeBackupsImmutable": "[parameters('makeBackupsImmutable')]", "monthlyRetention": "[parameters('monthlyRetention')]", "weeklyRetention": "[parameters('weeklyRetention')]", "weekOfYear": "[parameters('weekOfYear')]", "yearlyRetention": "[parameters('yearlyRetention')]" - } + }, + "dependsOn": [ + "server::database" + ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", diff --git a/avm/res/sql/server/database/backup-short-term-retention-policy/README.md b/avm/res/sql/server/database/backup-short-term-retention-policy/README.md index 9f742d71b4..711861fcd1 100644 --- a/avm/res/sql/server/database/backup-short-term-retention-policy/README.md +++ b/avm/res/sql/server/database/backup-short-term-retention-policy/README.md @@ -27,7 +27,7 @@ This module deploys an Azure SQL Server Database Short-Term Backup Retention Pol | Parameter | Type | Description | | :-- | :-- | :-- | -| [`diffBackupIntervalInHours`](#parameter-diffbackupintervalinhours) | int | Differential backup interval in hours. | +| [`diffBackupIntervalInHours`](#parameter-diffbackupintervalinhours) | int | Differential backup interval in hours. For Hyperscal tiers this value will be ignored. | | [`retentionDays`](#parameter-retentiondays) | int | Poin-in-time retention in days. | ### Parameter: `databaseName` @@ -46,7 +46,7 @@ The name of the parent SQL Server. ### Parameter: `diffBackupIntervalInHours` -Differential backup interval in hours. +Differential backup interval in hours. For Hyperscal tiers this value will be ignored. - Required: No - Type: int diff --git a/avm/res/sql/server/database/backup-short-term-retention-policy/main.bicep b/avm/res/sql/server/database/backup-short-term-retention-policy/main.bicep index e5154bd1f2..fc3321c8ea 100644 --- a/avm/res/sql/server/database/backup-short-term-retention-policy/main.bicep +++ b/avm/res/sql/server/database/backup-short-term-retention-policy/main.bicep @@ -8,16 +8,16 @@ param serverName string @description('Required. The name of the parent database.') param databaseName string -@description('Optional. Differential backup interval in hours.') +@description('Optional. Differential backup interval in hours. For Hyperscal tiers this value will be ignored.') param diffBackupIntervalInHours int = 24 @description('Optional. Poin-in-time retention in days.') param retentionDays int = 7 -resource server 'Microsoft.Sql/servers@2022-05-01-preview' existing = { +resource server 'Microsoft.Sql/servers@2023-08-01-preview' existing = { name: serverName - resource database 'databases@2022-05-01-preview' existing = { + resource database 'databases@2023-08-01-preview' existing = { name: databaseName } } @@ -26,7 +26,7 @@ resource backupShortTermRetentionPolicy 'Microsoft.Sql/servers/databases/backupS name: 'default' parent: server::database properties: { - diffBackupIntervalInHours: diffBackupIntervalInHours + diffBackupIntervalInHours: server::database.sku.tier == 'Hyperscale' ? null : diffBackupIntervalInHours retentionDays: retentionDays } } diff --git a/avm/res/sql/server/database/backup-short-term-retention-policy/main.json b/avm/res/sql/server/database/backup-short-term-retention-policy/main.json index 842e54ba64..9b5484f2d3 100644 --- a/avm/res/sql/server/database/backup-short-term-retention-policy/main.json +++ b/avm/res/sql/server/database/backup-short-term-retention-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "8635162595153731245" + "version": "0.30.23.60470", + "templateHash": "14890409200962565555" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -28,7 +28,7 @@ "type": "int", "defaultValue": 24, "metadata": { - "description": "Optional. Differential backup interval in hours." + "description": "Optional. Differential backup interval in hours. For Hyperscal tiers this value will be ignored." } }, "retentionDays": { @@ -45,7 +45,7 @@ "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { - "diffBackupIntervalInHours": "[parameters('diffBackupIntervalInHours')]", + "diffBackupIntervalInHours": "[if(equals(reference(resourceId('Microsoft.Sql/servers/databases', parameters('serverName'), parameters('databaseName')), '2023-08-01-preview', 'full').sku.tier, 'Hyperscale'), null(), parameters('diffBackupIntervalInHours'))]", "retentionDays": "[parameters('retentionDays')]" } } diff --git a/avm/res/sql/server/database/main.bicep b/avm/res/sql/server/database/main.bicep index 8919f4c720..0e80da6f9b 100644 --- a/avm/res/sql/server/database/main.bicep +++ b/avm/res/sql/server/database/main.bicep @@ -2,145 +2,148 @@ metadata name = 'SQL Server Database' metadata description = 'This module deploys an Azure SQL Server Database.' metadata owner = 'Azure/module-maintainers' +// START OF DATABASE PROPERTIES + @description('Required. The name of the database.') param name string @description('Conditional. The name of the parent SQL Server. Required if the template is used in a standalone deployment.') param serverName string +@description('Optional. The database SKU.') +param sku databaseSkuType = { + name: 'GP_Gen5_2' + tier: 'GeneralPurpose' +} + +@description('Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled.') +param autoPauseDelay int = -1 + +@description('Optional. Specifies the availability zone the database is pinned to.') +param availabilityZone '1' | '2' | '3' | 'NoPreference' = 'NoPreference' + +@description('Optional. Collation of the metadata catalog.') +param catalogCollation string = 'DATABASE_DEFAULT' + @description('Optional. The collation of the database.') param collation string = 'SQL_Latin1_General_CP1_CI_AS' -@description('Optional. The skuTier or edition of the particular SKU.') -param skuTier string = 'GeneralPurpose' +@description('Optional. Specifies the mode of database creation.') +param createMode + | 'Default' + | 'Copy' + | 'OnlineSecondary' + | 'PointInTimeRestore' + | 'Recovery' + | 'Restore' + | 'RestoreExternalBackup' + | 'RestoreExternalBackupSecondary' + | 'RestoreLongTermRetentionBackup' + | 'Secondary' = 'Default' -@description('Optional. The name of the SKU.') -param skuName string = 'GP_Gen5_2' +@description('Optional. The resource ID of the elastic pool containing this database.') +param elasticPoolResourceId string? -@description('Optional. Capacity of the particular SKU.') -param skuCapacity int? +@description('Optional. The azure key vault URI of the database if it\'s configured with per Database Customer Managed Keys.') +param encryptionProtector string? -@description('Optional. Type of enclave requested on the database i.e. Default or VBS enclaves.') -@allowed([ - '' - 'Default' - 'VBS' -]) -param preferredEnclaveType string = '' +@description('Optional. The flag to enable or disable auto rotation of database encryption protector AKV key.') +param encryptionProtectorAutoRotation bool? + +@description('Optional. The Client id used for cross tenant per database CMK scenario.') +@minLength(36) +@maxLength(36) +param federatedClientId string? + +@description('Optional. Specifies the behavior when monthly free limits are exhausted for the free database.') +param freeLimitExhaustionBehavior 'AutoPause' | 'BillOverUsage'? + +@description('Optional. The number of readonly secondary replicas associated with the database.') +param highAvailabilityReplicaCount int = 0 + +@description('Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created.') +param isLedgerOn bool = false + +@description('Optional. The license type to apply for this database.') +param licenseType 'BasePrice' | 'LicenseIncluded'? + +@description('Optional. The resource identifier of the long term retention backup associated with create operation of this database.') +param longTermRetentionBackupResourceId string? -@description('Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here.') -param skuFamily string = '' +@description('Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur.') +param maintenanceConfigurationId string? -@description('Optional. Size of the particular SKU.') -param skuSize string = '' +@description('Optional. Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier.') +param manualCutover bool? @description('Optional. The max size of the database expressed in bytes.') param maxSizeBytes int = 34359738368 -@description('Optional. The name of the sample schema to apply when creating this database.') -param sampleName string = '' +@description('Optional. Minimal capacity that database will always have allocated.') +param minCapacity string = '0' -@description('Optional. Whether or not this database is zone redundant.') -param zoneRedundant bool = true +@description('Optional. To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress.') +param performCutover bool? -@description('Optional. The license type to apply for this database.') -param licenseType string = '' +@description('Optional. Type of enclave requested on the database i.e. Default or VBS enclaves.') +param preferredEnclaveType 'Default' | 'VBS'? @description('Optional. The state of read-only routing.') -@allowed([ - 'Enabled' - 'Disabled' -]) -param readScale string = 'Disabled' +param readScale 'Enabled' | 'Disabled' = 'Disabled' -@description('Optional. The number of readonly secondary replicas associated with the database.') -param highAvailabilityReplicaCount int = 0 +@description('Optional. The resource identifier of the recoverable database associated with create operation of this database.') +param recoverableDatabaseResourceId string? -@description('Optional. Minimal capacity that database will always have allocated.') -param minCapacity string = '' - -@description('Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled.') -param autoPauseDelay int = 0 +@description('Optional. The resource identifier of the recovery point associated with create operation of this database.') +param recoveryServicesRecoveryPointResourceId string? -@description('Optional. Tags of the resource.') -param tags object? +@description('Optional. The storage account type to be used to store backups for this database.') +param requestedBackupStorageRedundancy 'Geo' | 'GeoZone' | 'Local' | 'Zone' = 'Local' -@description('Optional. The resource ID of the elastic pool containing this database.') -param elasticPoolId string = '' +@description('Optional. The resource identifier of the restorable dropped database associated with create operation of this database.') +param restorableDroppedDatabaseResourceId string? -@description('Optional. Location for all resources.') -param location string = resourceGroup().location +@description('Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore.') +param restorePointInTime string? -@description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +@description('Optional. The name of the sample schema to apply when creating this database.') +param sampleName string = '' -@description('Optional. Specifies the mode of database creation.') -@allowed([ - 'Default' - 'Copy' - 'OnlineSecondary' - 'PointInTimeRestore' - 'Recovery' - 'Restore' - 'RestoreLongTermRetentionBackup' - 'Secondary' -]) -param createMode string = 'Default' - -@description('Optional. Resource ID of database if createMode set to Copy, Secondary, PointInTimeRestore, Recovery or Restore.') -param sourceDatabaseResourceId string = '' +@description('Optional. The secondary type of the database if it is a secondary.') +param secondaryType 'Geo' | 'Named' | 'Standby'? @description('Optional. The time that the database was deleted when restoring a deleted database.') -param sourceDatabaseDeletionDate string = '' +param sourceDatabaseDeletionDate string? -@description('Optional. Resource ID of backup if createMode set to RestoreLongTermRetentionBackup.') -param recoveryServicesRecoveryPointResourceId string = '' +@description('Optional. The resource identifier of the source database associated with create operation of this database.') +param sourceDatabaseResourceId string? -@description('Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore.') -param restorePointInTime string = '' +@description('Optional. The resource identifier of the source associated with the create operation of this database.') +param sourceResourceId string? -@description('Optional. The storage account type to be used to store backups for this database.') -@allowed([ - 'Geo' - 'Local' - 'Zone' - '' -]) -param requestedBackupStorageRedundancy string = '' +@description('Optional. Whether or not the database uses free monthly limits. Allowed on one database in a subscription.') +param useFreeLimit bool? -@description('Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created.') -param isLedgerOn bool = false +@description('Optional. Whether or not this database is zone redundant.') +param zoneRedundant bool = true -@description('Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur.') -param maintenanceConfigurationId string? +// END OF DATABASE PROPERTIES + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' +@description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingFullType[]? @description('Optional. The short term backup retention policy to create for the database.') -param backupShortTermRetentionPolicy object = {} +param backupShortTermRetentionPolicy shortTermBackupRetentionPolicyType? @description('Optional. The long term backup retention policy to create for the database.') -param backupLongTermRetentionPolicy object = {} - -// The SKU object must be built in a variable -// The alternative, 'null' as default values, leads to non-terminating deployments -var skuVar = union( - { - name: skuName - tier: skuTier - }, - (skuCapacity != null) - ? { - capacity: skuCapacity - } - : !empty(skuFamily) - ? { - family: skuFamily - } - : !empty(skuSize) - ? { - size: skuSize - } - : {} -) +param backupLongTermRetentionPolicy longTermBackupRetentionPolicyType? resource server 'Microsoft.Sql/servers@2023-08-01-preview' existing = { name: serverName @@ -151,30 +154,43 @@ resource database 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { parent: server location: location tags: tags + sku: sku properties: { - preferredEnclaveType: !empty(preferredEnclaveType) ? preferredEnclaveType : null - collation: collation - maxSizeBytes: maxSizeBytes - sampleName: sampleName - zoneRedundant: zoneRedundant - licenseType: licenseType - readScale: readScale - minCapacity: !empty(minCapacity) ? json(minCapacity) : 0 // The json() function is used to allow specifying a decimal value. autoPauseDelay: autoPauseDelay + availabilityZone: availabilityZone + catalogCollation: catalogCollation + collation: collation + createMode: createMode + elasticPoolId: elasticPoolResourceId + encryptionProtector: encryptionProtector + encryptionProtectorAutoRotation: encryptionProtectorAutoRotation + federatedClientId: federatedClientId + freeLimitExhaustionBehavior: freeLimitExhaustionBehavior highAvailabilityReplicaCount: highAvailabilityReplicaCount - requestedBackupStorageRedundancy: any(requestedBackupStorageRedundancy) isLedgerOn: isLedgerOn + licenseType: licenseType + longTermRetentionBackupResourceId: longTermRetentionBackupResourceId maintenanceConfigurationId: maintenanceConfigurationId - elasticPoolId: elasticPoolId - createMode: createMode - sourceDatabaseId: !empty(sourceDatabaseResourceId) ? sourceDatabaseResourceId : null - sourceDatabaseDeletionDate: !empty(sourceDatabaseDeletionDate) ? sourceDatabaseDeletionDate : null - recoveryServicesRecoveryPointId: !empty(recoveryServicesRecoveryPointResourceId) - ? recoveryServicesRecoveryPointResourceId - : null - restorePointInTime: !empty(restorePointInTime) ? restorePointInTime : null + manualCutover: manualCutover + maxSizeBytes: maxSizeBytes + // The json() function is used to allow specifying a decimal value. + minCapacity: !empty(minCapacity) ? json(minCapacity) : 0 + performCutover: performCutover + preferredEnclaveType: preferredEnclaveType + readScale: readScale + recoverableDatabaseId: recoverableDatabaseResourceId + recoveryServicesRecoveryPointId: recoveryServicesRecoveryPointResourceId + requestedBackupStorageRedundancy: requestedBackupStorageRedundancy + restorableDroppedDatabaseId: restorableDroppedDatabaseResourceId + restorePointInTime: restorePointInTime + sampleName: sampleName + secondaryType: secondaryType + sourceDatabaseDeletionDate: sourceDatabaseDeletionDate + sourceDatabaseId: sourceDatabaseResourceId + sourceResourceId: sourceResourceId + useFreeLimit: useFreeLimit + zoneRedundant: zoneRedundant } - sku: skuVar } resource database_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [ @@ -206,28 +222,34 @@ resource database_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021 } ] -module database_backupShortTermRetentionPolicy 'backup-short-term-retention-policy/main.bicep' = { +module database_backupShortTermRetentionPolicy 'backup-short-term-retention-policy/main.bicep' = if (!empty(backupShortTermRetentionPolicy)) { name: '${uniqueString(deployment().name, location)}-${name}-shBakRetPol' params: { serverName: serverName databaseName: database.name - diffBackupIntervalInHours: backupShortTermRetentionPolicy.?diffBackupIntervalInHours ?? 24 - retentionDays: backupShortTermRetentionPolicy.?retentionDays ?? 7 + diffBackupIntervalInHours: backupShortTermRetentionPolicy.?diffBackupIntervalInHours + retentionDays: backupShortTermRetentionPolicy.?retentionDays } } -module database_backupLongTermRetentionPolicy 'backup-long-term-retention-policy/main.bicep' = { +module database_backupLongTermRetentionPolicy 'backup-long-term-retention-policy/main.bicep' = if (!empty(backupLongTermRetentionPolicy)) { name: '${uniqueString(deployment().name, location)}-${name}-lgBakRetPol' params: { serverName: serverName databaseName: database.name - weeklyRetention: backupLongTermRetentionPolicy.?weeklyRetention ?? '' - monthlyRetention: backupLongTermRetentionPolicy.?monthlyRetention ?? '' - yearlyRetention: backupLongTermRetentionPolicy.?yearlyRetention ?? '' - weekOfYear: backupLongTermRetentionPolicy.?weekOfYear ?? 1 + backupStorageAccessTier: backupLongTermRetentionPolicy.?backupStorageAccessTier + makeBackupsImmutable: backupLongTermRetentionPolicy.?makeBackupsImmutable + weeklyRetention: backupLongTermRetentionPolicy.?weeklyRetention + monthlyRetention: backupLongTermRetentionPolicy.?monthlyRetention + yearlyRetention: backupLongTermRetentionPolicy.?yearlyRetention + weekOfYear: backupLongTermRetentionPolicy.?weekOfYear } } +// =============== // +// Outputs // +// =============== // + @description('The name of the deployed database.') output name string = database.name @@ -244,46 +266,53 @@ output location string = database.location // Definitions // // =============== // -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? +@export() +@description('The database SKU.') +type databaseSkuType = { + @description('Optional. The capacity of the particular SKU.') + capacity: int? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? + @description('Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here.') + family: string? - @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.') - categoryGroup: string? + @description('Required. The name of the SKU, typically, a letter + Number code, e.g. P3.') + name: string - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? + @description('Optional. Size of the particular SKU.') + size: string? - @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') - metricCategories: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') - category: string + @description('Optional. The tier or edition of the particular SKU, e.g. Basic, Premium.') + tier: string? +} - @description('Optional. Enable or disable the category explicitly. Default is `true`.') - enabled: bool? - }[]? +@export() +@description('The short-term backup retention policy for the database.') +type shortTermBackupRetentionPolicyType = { + @description('Optional. Differential backup interval in hours. For Hyperscale tiers this value will be ignored.') + diffBackupIntervalInHours: int? - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + @description('Optional. Point-in-time retention in days.') + retentionDays: int? +} - @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.') - workspaceResourceId: string? +@export() +@description('The long-term backup retention policy for the database.') +type longTermBackupRetentionPolicyType = { + @description('Optional. The BackupStorageAccessTier for the LTR backups.') + backupStorageAccessTier: 'Archive' | 'Hot'? - @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.') - storageAccountResourceId: string? + @description('Optional. The setting whether to make LTR backups immutable.') + makeBackupsImmutable: bool? - @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.') - eventHubAuthorizationRuleResourceId: string? + @description('Optional. Monthly retention in ISO 8601 duration format.') + monthlyRetention: string? - @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.') - eventHubName: string? + @description('Optional. Weekly retention in ISO 8601 duration format.') + weeklyRetention: string? - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? + @description('Optional. Week of year backup to keep for yearly retention.') + weekOfYear: int? + + @description('Optional. Yearly retention in ISO 8601 duration format.') + yearlyRetention: string? +} diff --git a/avm/res/sql/server/database/main.json b/avm/res/sql/server/database/main.json index 4be7b1af7f..1e9d3badae 100644 --- a/avm/res/sql/server/database/main.json +++ b/avm/res/sql/server/database/main.json @@ -5,133 +5,256 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "18021918128213514276" + "version": "0.30.23.60470", + "templateHash": "18018827030977470456" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", "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`." - } + "databaseSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The database SKU." + } + }, + "shortTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "diffBackupIntervalInHours": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Differential backup interval in hours. For Hyperscale tiers this value will be ignored." + } + }, + "retentionDays": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Point-in-time retention in days." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The short-term backup retention policy for the database." + } + }, + "longTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "backupStorageAccessTier": { + "type": "string", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, + "metadata": { + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." + } + }, + "monthlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Weekly retention in ISO 8601 duration format." + } + }, + "weekOfYear": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Week of year backup to keep for yearly retention." + } + }, + "yearlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Yearly retention in ISO 8601 duration format." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The long-term backup retention policy for the database." + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + }, + "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -147,237 +270,333 @@ "description": "Conditional. The name of the parent SQL Server. Required if the template is used in a standalone deployment." } }, - "collation": { - "type": "string", - "defaultValue": "SQL_Latin1_General_CP1_CI_AS", + "sku": { + "$ref": "#/definitions/databaseSkuType", + "defaultValue": { + "name": "GP_Gen5_2", + "tier": "GeneralPurpose" + }, "metadata": { - "description": "Optional. The collation of the database." + "description": "Optional. The database SKU." + } + }, + "autoPauseDelay": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled." } }, - "skuTier": { + "availabilityZone": { "type": "string", - "defaultValue": "GeneralPurpose", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "defaultValue": "NoPreference", "metadata": { - "description": "Optional. The skuTier or edition of the particular SKU." + "description": "Optional. Specifies the availability zone the database is pinned to." } }, - "skuName": { + "catalogCollation": { "type": "string", - "defaultValue": "GP_Gen5_2", + "defaultValue": "DATABASE_DEFAULT", "metadata": { - "description": "Optional. The name of the SKU." + "description": "Optional. Collation of the metadata catalog." } }, - "skuCapacity": { - "type": "int", - "nullable": true, + "collation": { + "type": "string", + "defaultValue": "SQL_Latin1_General_CP1_CI_AS", "metadata": { - "description": "Optional. Capacity of the particular SKU." + "description": "Optional. The collation of the database." } }, - "preferredEnclaveType": { + "createMode": { "type": "string", - "defaultValue": "", "allowedValues": [ - "", + "Copy", "Default", - "VBS" + "OnlineSecondary", + "PointInTimeRestore", + "Recovery", + "Restore", + "RestoreExternalBackup", + "RestoreExternalBackupSecondary", + "RestoreLongTermRetentionBackup", + "Secondary" ], + "defaultValue": "Default", "metadata": { - "description": "Optional. Type of enclave requested on the database i.e. Default or VBS enclaves." + "description": "Optional. Specifies the mode of database creation." } }, - "skuFamily": { + "elasticPoolResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + "description": "Optional. The resource ID of the elastic pool containing this database." } }, - "skuSize": { + "encryptionProtector": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Size of the particular SKU." + "description": "Optional. The azure key vault URI of the database if it's configured with per Database Customer Managed Keys." } }, - "maxSizeBytes": { - "type": "int", - "defaultValue": 34359738368, + "encryptionProtectorAutoRotation": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. The max size of the database expressed in bytes." + "description": "Optional. The flag to enable or disable auto rotation of database encryption protector AKV key." } }, - "sampleName": { + "federatedClientId": { "type": "string", - "defaultValue": "", + "nullable": true, + "minLength": 36, + "maxLength": 36, "metadata": { - "description": "Optional. The name of the sample schema to apply when creating this database." + "description": "Optional. The Client id used for cross tenant per database CMK scenario." } }, - "zoneRedundant": { + "freeLimitExhaustionBehavior": { + "type": "string", + "allowedValues": [ + "AutoPause", + "BillOverUsage" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the behavior when monthly free limits are exhausted for the free database." + } + }, + "highAvailabilityReplicaCount": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. The number of readonly secondary replicas associated with the database." + } + }, + "isLedgerOn": { "type": "bool", - "defaultValue": true, + "defaultValue": false, "metadata": { - "description": "Optional. Whether or not this database is zone redundant." + "description": "Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created." } }, "licenseType": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "BasePrice", + "LicenseIncluded" + ], + "nullable": true, "metadata": { "description": "Optional. The license type to apply for this database." } }, - "readScale": { + "longTermRetentionBackupResourceId": { "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Enabled", - "Disabled" - ], + "nullable": true, "metadata": { - "description": "Optional. The state of read-only routing." + "description": "Optional. The resource identifier of the long term retention backup associated with create operation of this database." } }, - "highAvailabilityReplicaCount": { + "maintenanceConfigurationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur." + } + }, + "manualCutover": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier." + } + }, + "maxSizeBytes": { "type": "int", - "defaultValue": 0, + "defaultValue": 34359738368, "metadata": { - "description": "Optional. The number of readonly secondary replicas associated with the database." + "description": "Optional. The max size of the database expressed in bytes." } }, "minCapacity": { "type": "string", - "defaultValue": "", + "defaultValue": "0", "metadata": { "description": "Optional. Minimal capacity that database will always have allocated." } }, - "autoPauseDelay": { - "type": "int", - "defaultValue": 0, + "performCutover": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled." + "description": "Optional. To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress." } }, - "tags": { - "type": "object", + "preferredEnclaveType": { + "type": "string", + "allowedValues": [ + "Default", + "VBS" + ], "nullable": true, "metadata": { - "description": "Optional. Tags of the resource." + "description": "Optional. Type of enclave requested on the database i.e. Default or VBS enclaves." } }, - "elasticPoolId": { + "readScale": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "defaultValue": "Disabled", "metadata": { - "description": "Optional. The resource ID of the elastic pool containing this database." + "description": "Optional. The state of read-only routing." } }, - "location": { + "recoverableDatabaseResourceId": { "type": "string", - "defaultValue": "[resourceGroup().location]", + "nullable": true, "metadata": { - "description": "Optional. Location for all resources." + "description": "Optional. The resource identifier of the recoverable database associated with create operation of this database." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "recoveryServicesRecoveryPointResourceId": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Optional. The resource identifier of the recovery point associated with create operation of this database." } }, - "createMode": { + "requestedBackupStorageRedundancy": { "type": "string", - "defaultValue": "Default", "allowedValues": [ - "Default", - "Copy", - "OnlineSecondary", - "PointInTimeRestore", - "Recovery", - "Restore", - "RestoreLongTermRetentionBackup", - "Secondary" + "Geo", + "GeoZone", + "Local", + "Zone" ], + "defaultValue": "Local", "metadata": { - "description": "Optional. Specifies the mode of database creation." + "description": "Optional. The storage account type to be used to store backups for this database." } }, - "sourceDatabaseResourceId": { + "restorableDroppedDatabaseResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the restorable dropped database associated with create operation of this database." + } + }, + "restorePointInTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore." + } + }, + "sampleName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Resource ID of database if createMode set to Copy, Secondary, PointInTimeRestore, Recovery or Restore." + "description": "Optional. The name of the sample schema to apply when creating this database." + } + }, + "secondaryType": { + "type": "string", + "allowedValues": [ + "Geo", + "Named", + "Standby" + ], + "nullable": true, + "metadata": { + "description": "Optional. The secondary type of the database if it is a secondary." } }, "sourceDatabaseDeletionDate": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The time that the database was deleted when restoring a deleted database." } }, - "recoveryServicesRecoveryPointResourceId": { + "sourceDatabaseResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Resource ID of backup if createMode set to RestoreLongTermRetentionBackup." + "description": "Optional. The resource identifier of the source database associated with create operation of this database." } }, - "restorePointInTime": { + "sourceResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore." + "description": "Optional. The resource identifier of the source associated with the create operation of this database." } }, - "requestedBackupStorageRedundancy": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "Geo", - "Local", - "Zone", - "" - ], + "useFreeLimit": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. The storage account type to be used to store backups for this database." + "description": "Optional. Whether or not the database uses free monthly limits. Allowed on one database in a subscription." } }, - "isLedgerOn": { + "zoneRedundant": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { - "description": "Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created." + "description": "Optional. Whether or not this database is zone redundant." } }, - "maintenanceConfigurationId": { + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "diagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, "nullable": true, "metadata": { - "description": "Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur." + "description": "Optional. The diagnostic settings of the service." } }, "backupShortTermRetentionPolicy": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/shortTermBackupRetentionPolicyType", + "nullable": true, "metadata": { "description": "Optional. The short term backup retention policy to create for the database." } }, "backupLongTermRetentionPolicy": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/longTermBackupRetentionPolicyType", + "nullable": true, "metadata": { "description": "Optional. The long term backup retention policy to create for the database." } } }, - "variables": { - "skuVar": "[union(createObject('name', parameters('skuName'), 'tier', parameters('skuTier')), if(not(equals(parameters('skuCapacity'), null())), createObject('capacity', parameters('skuCapacity')), if(not(empty(parameters('skuFamily'))), createObject('family', parameters('skuFamily')), if(not(empty(parameters('skuSize'))), createObject('size', parameters('skuSize')), createObject()))))]" - }, "resources": { "server": { "existing": true, @@ -391,28 +610,42 @@ "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", + "sku": "[parameters('sku')]", "properties": { - "preferredEnclaveType": "[if(not(empty(parameters('preferredEnclaveType'))), parameters('preferredEnclaveType'), null())]", - "collation": "[parameters('collation')]", - "maxSizeBytes": "[parameters('maxSizeBytes')]", - "sampleName": "[parameters('sampleName')]", - "zoneRedundant": "[parameters('zoneRedundant')]", - "licenseType": "[parameters('licenseType')]", - "readScale": "[parameters('readScale')]", - "minCapacity": "[if(not(empty(parameters('minCapacity'))), json(parameters('minCapacity')), 0)]", "autoPauseDelay": "[parameters('autoPauseDelay')]", + "availabilityZone": "[parameters('availabilityZone')]", + "catalogCollation": "[parameters('catalogCollation')]", + "collation": "[parameters('collation')]", + "createMode": "[parameters('createMode')]", + "elasticPoolId": "[parameters('elasticPoolResourceId')]", + "encryptionProtector": "[parameters('encryptionProtector')]", + "encryptionProtectorAutoRotation": "[parameters('encryptionProtectorAutoRotation')]", + "federatedClientId": "[parameters('federatedClientId')]", + "freeLimitExhaustionBehavior": "[parameters('freeLimitExhaustionBehavior')]", "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]", - "requestedBackupStorageRedundancy": "[parameters('requestedBackupStorageRedundancy')]", "isLedgerOn": "[parameters('isLedgerOn')]", + "licenseType": "[parameters('licenseType')]", + "longTermRetentionBackupResourceId": "[parameters('longTermRetentionBackupResourceId')]", "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]", - "elasticPoolId": "[parameters('elasticPoolId')]", - "createMode": "[parameters('createMode')]", - "sourceDatabaseId": "[if(not(empty(parameters('sourceDatabaseResourceId'))), parameters('sourceDatabaseResourceId'), null())]", - "sourceDatabaseDeletionDate": "[if(not(empty(parameters('sourceDatabaseDeletionDate'))), parameters('sourceDatabaseDeletionDate'), null())]", - "recoveryServicesRecoveryPointId": "[if(not(empty(parameters('recoveryServicesRecoveryPointResourceId'))), parameters('recoveryServicesRecoveryPointResourceId'), null())]", - "restorePointInTime": "[if(not(empty(parameters('restorePointInTime'))), parameters('restorePointInTime'), null())]" + "manualCutover": "[parameters('manualCutover')]", + "maxSizeBytes": "[parameters('maxSizeBytes')]", + "minCapacity": "[if(not(empty(parameters('minCapacity'))), json(parameters('minCapacity')), 0)]", + "performCutover": "[parameters('performCutover')]", + "preferredEnclaveType": "[parameters('preferredEnclaveType')]", + "readScale": "[parameters('readScale')]", + "recoverableDatabaseId": "[parameters('recoverableDatabaseResourceId')]", + "recoveryServicesRecoveryPointId": "[parameters('recoveryServicesRecoveryPointResourceId')]", + "requestedBackupStorageRedundancy": "[parameters('requestedBackupStorageRedundancy')]", + "restorableDroppedDatabaseId": "[parameters('restorableDroppedDatabaseResourceId')]", + "restorePointInTime": "[parameters('restorePointInTime')]", + "sampleName": "[parameters('sampleName')]", + "secondaryType": "[parameters('secondaryType')]", + "sourceDatabaseDeletionDate": "[parameters('sourceDatabaseDeletionDate')]", + "sourceDatabaseId": "[parameters('sourceDatabaseResourceId')]", + "sourceResourceId": "[parameters('sourceResourceId')]", + "useFreeLimit": "[parameters('useFreeLimit')]", + "zoneRedundant": "[parameters('zoneRedundant')]" }, - "sku": "[variables('skuVar')]", "dependsOn": [ "server" ] @@ -459,6 +692,7 @@ ] }, "database_backupShortTermRetentionPolicy": { + "condition": "[not(empty(parameters('backupShortTermRetentionPolicy')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-{1}-shBakRetPol', uniqueString(deployment().name, parameters('location')), parameters('name'))]", @@ -475,10 +709,10 @@ "value": "[parameters('name')]" }, "diffBackupIntervalInHours": { - "value": "[coalesce(tryGet(parameters('backupShortTermRetentionPolicy'), 'diffBackupIntervalInHours'), 24)]" + "value": "[tryGet(parameters('backupShortTermRetentionPolicy'), 'diffBackupIntervalInHours')]" }, "retentionDays": { - "value": "[coalesce(tryGet(parameters('backupShortTermRetentionPolicy'), 'retentionDays'), 7)]" + "value": "[tryGet(parameters('backupShortTermRetentionPolicy'), 'retentionDays')]" } }, "template": { @@ -487,8 +721,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "8635162595153731245" + "version": "0.30.23.60470", + "templateHash": "14890409200962565555" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -511,7 +745,7 @@ "type": "int", "defaultValue": 24, "metadata": { - "description": "Optional. Differential backup interval in hours." + "description": "Optional. Differential backup interval in hours. For Hyperscal tiers this value will be ignored." } }, "retentionDays": { @@ -528,7 +762,7 @@ "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { - "diffBackupIntervalInHours": "[parameters('diffBackupIntervalInHours')]", + "diffBackupIntervalInHours": "[if(equals(reference(resourceId('Microsoft.Sql/servers/databases', parameters('serverName'), parameters('databaseName')), '2023-08-01-preview', 'full').sku.tier, 'Hyperscale'), null(), parameters('diffBackupIntervalInHours'))]", "retentionDays": "[parameters('retentionDays')]" } } @@ -563,6 +797,7 @@ ] }, "database_backupLongTermRetentionPolicy": { + "condition": "[not(empty(parameters('backupLongTermRetentionPolicy')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-{1}-lgBakRetPol', uniqueString(deployment().name, parameters('location')), parameters('name'))]", @@ -578,27 +813,34 @@ "databaseName": { "value": "[parameters('name')]" }, + "backupStorageAccessTier": { + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'backupStorageAccessTier')]" + }, + "makeBackupsImmutable": { + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'makeBackupsImmutable')]" + }, "weeklyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'weeklyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'weeklyRetention')]" }, "monthlyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'monthlyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'monthlyRetention')]" }, "yearlyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'yearlyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'yearlyRetention')]" }, "weekOfYear": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'weekOfYear'), 1)]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'weekOfYear')]" } }, "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": "2778016138108001251" + "version": "0.30.23.60470", + "templateHash": "841731129374883266" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", @@ -617,16 +859,34 @@ "description": "Required. The name of the parent database." } }, - "weeklyRetention": { + "backupStorageAccessTier": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, "metadata": { - "description": "Optional. Monthly retention in ISO 8601 duration format." + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." } }, "monthlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, "metadata": { "description": "Optional. Weekly retention in ISO 8601 duration format." } @@ -640,25 +900,45 @@ }, "yearlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Yearly retention in ISO 8601 duration format." } } }, - "resources": [ - { - "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "resources": { + "server::database": { + "existing": true, + "type": "Microsoft.Sql/servers/databases", "apiVersion": "2023-08-01-preview", + "name": "[format('{0}/{1}', parameters('serverName'), parameters('databaseName'))]", + "dependsOn": [ + "server" + ] + }, + "server": { + "existing": true, + "type": "Microsoft.Sql/servers", + "apiVersion": "2023-08-01-preview", + "name": "[parameters('serverName')]" + }, + "backupLongTermRetentionPolicy": { + "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "apiVersion": "2023-05-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { + "backupStorageAccessTier": "[parameters('backupStorageAccessTier')]", + "makeBackupsImmutable": "[parameters('makeBackupsImmutable')]", "monthlyRetention": "[parameters('monthlyRetention')]", "weeklyRetention": "[parameters('weeklyRetention')]", "weekOfYear": "[parameters('weekOfYear')]", "yearlyRetention": "[parameters('yearlyRetention')]" - } + }, + "dependsOn": [ + "server::database" + ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", diff --git a/avm/res/sql/server/elastic-pool/README.md b/avm/res/sql/server/elastic-pool/README.md index ef598e5fa3..33336196b5 100644 --- a/avm/res/sql/server/elastic-pool/README.md +++ b/avm/res/sql/server/elastic-pool/README.md @@ -32,17 +32,17 @@ This module deploys an Azure SQL Server Elastic Pool. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`databaseMaxCapacity`](#parameter-databasemaxcapacity) | int | The maximum capacity any one database can consume. | -| [`databaseMinCapacity`](#parameter-databasemincapacity) | int | The minimum capacity all databases are guaranteed. | +| [`autoPauseDelay`](#parameter-autopausedelay) | int | Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. | +| [`availabilityZone`](#parameter-availabilityzone) | string | Specifies the availability zone the pool's primary replica is pinned to. | | [`highAvailabilityReplicaCount`](#parameter-highavailabilityreplicacount) | int | The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools. | | [`licenseType`](#parameter-licensetype) | string | The license type to apply for this elastic pool. | | [`location`](#parameter-location) | string | Location for all resources. | | [`maintenanceConfigurationId`](#parameter-maintenanceconfigurationid) | string | Maintenance configuration resource ID assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur. | | [`maxSizeBytes`](#parameter-maxsizebytes) | int | The storage limit for the database elastic pool in bytes. | | [`minCapacity`](#parameter-mincapacity) | int | Minimal capacity that serverless pool will not shrink below, if not paused. | -| [`skuCapacity`](#parameter-skucapacity) | int | Capacity of the particular SKU. | -| [`skuName`](#parameter-skuname) | string | The name of the SKU, typically, a letter + Number code, e.g. P3. | -| [`skuTier`](#parameter-skutier) | string | The tier or edition of the particular SKU, e.g. Basic, Premium. | +| [`perDatabaseSettings`](#parameter-perdatabasesettings) | object | The per database settings for the elastic pool. | +| [`preferredEnclaveType`](#parameter-preferredenclavetype) | string | Type of enclave requested on the elastic pool. | +| [`sku`](#parameter-sku) | object | The elastic pool SKU. | | [`tags`](#parameter-tags) | object | Tags of the resource. | | [`zoneRedundant`](#parameter-zoneredundant) | bool | Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones. | @@ -60,21 +60,30 @@ The name of the parent SQL Server. Required if the template is used in a standal - Required: Yes - Type: string -### Parameter: `databaseMaxCapacity` +### Parameter: `autoPauseDelay` -The maximum capacity any one database can consume. +Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. - Required: No - Type: int -- Default: `2` +- Default: `-1` -### Parameter: `databaseMinCapacity` +### Parameter: `availabilityZone` -The minimum capacity all databases are guaranteed. +Specifies the availability zone the pool's primary replica is pinned to. - Required: No -- Type: int -- Default: `0` +- Type: string +- Default: `'NoPreference'` +- Allowed: + ```Bicep + [ + '1' + '2' + '3' + 'NoPreference' + ] + ``` ### Parameter: `highAvailabilityReplicaCount` @@ -128,29 +137,151 @@ Minimal capacity that serverless pool will not shrink below, if not paused. - Required: No - Type: int -### Parameter: `skuCapacity` +### Parameter: `perDatabaseSettings` -Capacity of the particular SKU. +The per database settings for the elastic pool. + +- Required: No +- Type: object +- Default: + ```Bicep + { + autoPauseDelay: -1 + maxCapacity: '2' + minCapacity: '0' + } + ``` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`maxCapacity`](#parameter-perdatabasesettingsmaxcapacity) | string | The maximum capacity any one database can consume. Examples: '0.5', '2'. | +| [`minCapacity`](#parameter-perdatabasesettingsmincapacity) | string | The minimum capacity all databases are guaranteed. Examples: '0.5', '1'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoPauseDelay`](#parameter-perdatabasesettingsautopausedelay) | int | Auto Pause Delay for per database within pool. | + +### Parameter: `perDatabaseSettings.maxCapacity` + +The maximum capacity any one database can consume. Examples: '0.5', '2'. + +- Required: Yes +- Type: string + +### Parameter: `perDatabaseSettings.minCapacity` + +The minimum capacity all databases are guaranteed. Examples: '0.5', '1'. + +- Required: Yes +- Type: string + +### Parameter: `perDatabaseSettings.autoPauseDelay` + +Auto Pause Delay for per database within pool. - Required: No - Type: int -- Default: `2` -### Parameter: `skuName` +### Parameter: `preferredEnclaveType` + +Type of enclave requested on the elastic pool. + +- Required: No +- Type: string +- Default: `'Default'` +- Allowed: + ```Bicep + [ + 'Default' + 'VBS' + ] + ``` + +### Parameter: `sku` + +The elastic pool SKU. + +- Required: No +- Type: object +- Default: + ```Bicep + { + capacity: 2 + name: 'GP_Gen5' + tier: 'GeneralPurpose' + } + ``` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-skuname) | string | The name of the SKU, typically, a letter + Number code, e.g. P3. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacity`](#parameter-skucapacity) | int | The capacity of the particular SKU. | +| [`family`](#parameter-skufamily) | string | If the service has different generations of hardware, for the same SKU, then that can be captured here. | +| [`size`](#parameter-skusize) | string | Size of the particular SKU. | +| [`tier`](#parameter-skutier) | string | The tier or edition of the particular SKU, e.g. Basic, Premium. | + +### Parameter: `sku.name` The name of the SKU, typically, a letter + Number code, e.g. P3. +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'BasicPool' + 'BC_DC' + 'BC_Gen5' + 'GP_DC' + 'GP_FSv2' + 'GP_Gen5' + 'HS_Gen5' + 'HS_MOPRMS' + 'HS_PRMS' + 'PremiumPool' + 'ServerlessPool' + 'StandardPool' + ] + ``` + +### Parameter: `sku.capacity` + +The capacity of the particular SKU. + +- Required: No +- Type: int + +### Parameter: `sku.family` + +If the service has different generations of hardware, for the same SKU, then that can be captured here. + +- Required: No +- Type: string + +### Parameter: `sku.size` + +Size of the particular SKU. + - Required: No - Type: string -- Default: `'GP_Gen5'` -### Parameter: `skuTier` +### Parameter: `sku.tier` The tier or edition of the particular SKU, e.g. Basic, Premium. - Required: No - Type: string -- Default: `'GeneralPurpose'` ### Parameter: `tags` diff --git a/avm/res/sql/server/elastic-pool/main.bicep b/avm/res/sql/server/elastic-pool/main.bicep index df5d5510ea..1fb87683b2 100644 --- a/avm/res/sql/server/elastic-pool/main.bicep +++ b/avm/res/sql/server/elastic-pool/main.bicep @@ -14,14 +14,18 @@ param tags object? @description('Optional. Location for all resources.') param location string = resourceGroup().location -@description('Optional. Capacity of the particular SKU.') -param skuCapacity int = 2 +@description('Optional. The elastic pool SKU.') +param sku elasticPoolSkuType = { + capacity: 2 + name: 'GP_Gen5' + tier: 'GeneralPurpose' +} -@description('Optional. The name of the SKU, typically, a letter + Number code, e.g. P3.') -param skuName string = 'GP_Gen5' +@description('Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled.') +param autoPauseDelay int = -1 -@description('Optional. The tier or edition of the particular SKU, e.g. Basic, Premium.') -param skuTier string = 'GeneralPurpose' +@description('Optional. Specifies the availability zone the pool\'s primary replica is pinned to.') +param availabilityZone '1' | '2' | '3' | 'NoPreference' = 'NoPreference' @description('Optional. The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.') param highAvailabilityReplicaCount int? @@ -42,11 +46,15 @@ param maxSizeBytes int = 34359738368 @description('Optional. Minimal capacity that serverless pool will not shrink below, if not paused.') param minCapacity int? -@description('Optional. The maximum capacity any one database can consume.') -param databaseMaxCapacity int = 2 +@description('Optional. The per database settings for the elastic pool.') +param perDatabaseSettings elasticPoolPerDatabaseSettingsType = { + autoPauseDelay: -1 + maxCapacity: '2' + minCapacity: '0' +} -@description('Optional. The minimum capacity all databases are guaranteed.') -param databaseMinCapacity int = 0 +@description('Optional. Type of enclave requested on the elastic pool.') +param preferredEnclaveType 'Default' | 'VBS' = 'Default' @description('Optional. Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones.') param zoneRedundant bool = true @@ -60,21 +68,24 @@ resource elasticPool 'Microsoft.Sql/servers/elasticPools@2023-08-01-preview' = { location: location parent: server tags: tags - sku: { - capacity: skuCapacity - name: skuName - tier: skuTier - } + sku: sku properties: { + autoPauseDelay: autoPauseDelay + availabilityZone: availabilityZone highAvailabilityReplicaCount: highAvailabilityReplicaCount licenseType: licenseType maintenanceConfigurationId: maintenanceConfigurationId maxSizeBytes: maxSizeBytes minCapacity: minCapacity - perDatabaseSettings: { - minCapacity: databaseMinCapacity - maxCapacity: databaseMaxCapacity - } + perDatabaseSettings: !empty(perDatabaseSettings) + ? { + autoPauseDelay: perDatabaseSettings.?autoPauseDelay + // To handle fractional values, we need to convert from string :( + maxCapacity: json(perDatabaseSettings.?maxCapacity) + minCapacity: json(perDatabaseSettings.?minCapacity) + } + : null + preferredEnclaveType: preferredEnclaveType zoneRedundant: zoneRedundant } } @@ -90,3 +101,52 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = elasticPool.location + +// =============== // +// Definitions // +// =============== // + +@export() +@description('The per database settings for the elastic pool.') +type elasticPoolPerDatabaseSettingsType = { + @description('Optional. Auto Pause Delay for per database within pool.') + autoPauseDelay: int? + + @description('Required. The maximum capacity any one database can consume. Examples: \'0.5\', \'2\'.') + maxCapacity: string + + // using string as minCapacity can be fractional + @description('Required. The minimum capacity all databases are guaranteed. Examples: \'0.5\', \'1\'.') + minCapacity: string +} + +@export() +@description('The elastic pool SKU.') +type elasticPoolSkuType = { + @description('Optional. The capacity of the particular SKU.') + capacity: int? + + @description('Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here.') + family: string? + + @description('Required. The name of the SKU, typically, a letter + Number code, e.g. P3.') + name: + | 'BasicPool' + | 'StandardPool' + | 'PremiumPool' + | 'GP_Gen5' + | 'GP_DC' + | 'GP_FSv2' + | 'BC_Gen5' + | 'BC_DC' + | 'HS_Gen5' + | 'HS_PRMS' + | 'HS_MOPRMS' + | 'ServerlessPool' + + @description('Optional. Size of the particular SKU.') + size: string? + + @description('Optional. The tier or edition of the particular SKU, e.g. Basic, Premium.') + tier: string? +} diff --git a/avm/res/sql/server/elastic-pool/main.json b/avm/res/sql/server/elastic-pool/main.json index 5acc2b0818..d74f427cbe 100644 --- a/avm/res/sql/server/elastic-pool/main.json +++ b/avm/res/sql/server/elastic-pool/main.json @@ -5,13 +5,100 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "17774091526328280898" + "version": "0.30.23.60470", + "templateHash": "10024079638382167120" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", "owner": "Azure/module-maintainers" }, + "definitions": { + "elasticPoolPerDatabaseSettingsType": { + "type": "object", + "properties": { + "autoPauseDelay": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Auto Pause Delay for per database within pool." + } + }, + "maxCapacity": { + "type": "string", + "metadata": { + "description": "Required. The maximum capacity any one database can consume. Examples: '0.5', '2'." + } + }, + "minCapacity": { + "type": "string", + "metadata": { + "description": "Required. The minimum capacity all databases are guaranteed. Examples: '0.5', '1'." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The per database settings for the elastic pool." + } + }, + "elasticPoolSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "allowedValues": [ + "BC_DC", + "BC_Gen5", + "BasicPool", + "GP_DC", + "GP_FSv2", + "GP_Gen5", + "HS_Gen5", + "HS_MOPRMS", + "HS_PRMS", + "PremiumPool", + "ServerlessPool", + "StandardPool" + ], + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The elastic pool SKU." + } + } + }, "parameters": { "name": { "type": "string", @@ -39,25 +126,35 @@ "description": "Optional. Location for all resources." } }, - "skuCapacity": { - "type": "int", - "defaultValue": 2, + "sku": { + "$ref": "#/definitions/elasticPoolSkuType", + "defaultValue": { + "capacity": 2, + "name": "GP_Gen5", + "tier": "GeneralPurpose" + }, "metadata": { - "description": "Optional. Capacity of the particular SKU." + "description": "Optional. The elastic pool SKU." } }, - "skuName": { - "type": "string", - "defaultValue": "GP_Gen5", + "autoPauseDelay": { + "type": "int", + "defaultValue": -1, "metadata": { - "description": "Optional. The name of the SKU, typically, a letter + Number code, e.g. P3." + "description": "Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled." } }, - "skuTier": { + "availabilityZone": { "type": "string", - "defaultValue": "GeneralPurpose", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "defaultValue": "NoPreference", "metadata": { - "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to." } }, "highAvailabilityReplicaCount": { @@ -99,18 +196,26 @@ "description": "Optional. Minimal capacity that serverless pool will not shrink below, if not paused." } }, - "databaseMaxCapacity": { - "type": "int", - "defaultValue": 2, + "perDatabaseSettings": { + "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType", + "defaultValue": { + "autoPauseDelay": -1, + "maxCapacity": "2", + "minCapacity": "0" + }, "metadata": { - "description": "Optional. The maximum capacity any one database can consume." + "description": "Optional. The per database settings for the elastic pool." } }, - "databaseMinCapacity": { - "type": "int", - "defaultValue": 0, + "preferredEnclaveType": { + "type": "string", + "allowedValues": [ + "Default", + "VBS" + ], + "defaultValue": "Default", "metadata": { - "description": "Optional. The minimum capacity all databases are guaranteed." + "description": "Optional. Type of enclave requested on the elastic pool." } }, "zoneRedundant": { @@ -134,21 +239,17 @@ "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", - "sku": { - "capacity": "[parameters('skuCapacity')]", - "name": "[parameters('skuName')]", - "tier": "[parameters('skuTier')]" - }, + "sku": "[parameters('sku')]", "properties": { + "autoPauseDelay": "[parameters('autoPauseDelay')]", + "availabilityZone": "[parameters('availabilityZone')]", "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]", "licenseType": "[parameters('licenseType')]", "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]", "maxSizeBytes": "[parameters('maxSizeBytes')]", "minCapacity": "[parameters('minCapacity')]", - "perDatabaseSettings": { - "minCapacity": "[parameters('databaseMinCapacity')]", - "maxCapacity": "[parameters('databaseMaxCapacity')]" - }, + "perDatabaseSettings": "[if(not(empty(parameters('perDatabaseSettings'))), createObject('autoPauseDelay', tryGet(parameters('perDatabaseSettings'), 'autoPauseDelay'), 'maxCapacity', json(tryGet(parameters('perDatabaseSettings'), 'maxCapacity')), 'minCapacity', json(tryGet(parameters('perDatabaseSettings'), 'minCapacity'))), null())]", + "preferredEnclaveType": "[parameters('preferredEnclaveType')]", "zoneRedundant": "[parameters('zoneRedundant')]" }, "dependsOn": [ diff --git a/avm/res/sql/server/encryption-protector/main.json b/avm/res/sql/server/encryption-protector/main.json index 8e8deb599e..2191d5c1ae 100644 --- a/avm/res/sql/server/encryption-protector/main.json +++ b/avm/res/sql/server/encryption-protector/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6914924378490463775" + "version": "0.30.23.60470", + "templateHash": "11473914706327458055" }, "name": "Azure SQL Server Encryption Protector", "description": "This module deploys an Azure SQL Server Encryption Protector.", diff --git a/avm/res/sql/server/firewall-rule/main.json b/avm/res/sql/server/firewall-rule/main.json index 006ddcd226..fb23b82744 100644 --- a/avm/res/sql/server/firewall-rule/main.json +++ b/avm/res/sql/server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "7779473510493338097" + "version": "0.30.23.60470", + "templateHash": "6449556555046717103" }, "name": "Azure SQL Server Firewall Rule", "description": "This module deploys an Azure SQL Server Firewall Rule.", diff --git a/avm/res/sql/server/key/main.json b/avm/res/sql/server/key/main.json index 78e43db8f4..78220cdf1f 100644 --- a/avm/res/sql/server/key/main.json +++ b/avm/res/sql/server/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5863771213375512760" + "version": "0.30.23.60470", + "templateHash": "17839617504395216689" }, "name": "Azure SQL Server Keys", "description": "This module deploys an Azure SQL Server Key.", diff --git a/avm/res/sql/server/main.bicep b/avm/res/sql/server/main.bicep index 6b5adb95f1..8115aa75d6 100644 --- a/avm/res/sql/server/main.bicep +++ b/avm/res/sql/server/main.bicep @@ -15,17 +15,20 @@ param location string = resourceGroup().location @description('Required. The name of the server.') param name string +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? @description('Conditional. The resource ID of a user assigned identity to be used by default. Required if "userAssignedIdentities" is not empty.') param primaryUserAssignedIdentityId string = '' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -34,10 +37,10 @@ param tags object? param enableTelemetry bool = true @description('Optional. The databases to create in the server.') -param databases array = [] +param databases databasePropertyType[] = [] @description('Optional. The Elastic Pools to create in the server.') -param elasticPools array = [] +param elasticPools elasticPoolPropertyType[] = [] @description('Optional. The firewall rules to create in the server.') param firewallRules array = [] @@ -52,7 +55,15 @@ param securityAlertPolicies array = [] param keys array = [] @description('Conditional. The Azure Active Directory (AAD) administrator authentication. Required if no `administratorLogin` & `administratorLoginPassword` is provided.') -param administrators object = {} +param administrators serverExternalAdministratorType? + +@description('Optional. The Client id used for cross tenant CMK scenario.') +@minLength(36) +@maxLength(36) +param federatedClientId string? + +@description('Optional. A CMK URI of the key to use for encryption.') +param keyId string? @allowed([ '1.0' @@ -70,8 +81,9 @@ param minimalTlsVersion string = '1.2' @description('Optional. Whether or not to enable IPv6 support for this server.') param isIPv6Enabled string = 'Disabled' +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? @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 neither firewall rules nor virtual network rules are set.') @allowed([ @@ -112,7 +124,7 @@ param encryptionProtectorObj object = {} param vulnerabilityAssessmentsObj object = {} @description('Optional. The audit settings configuration.') -param auditSettings auditSettingsType? +param auditSettings auditSettingsType = {} //Use the defaults from the child module @description('Optional. Key vault reference and secret settings for the module\'s secrets export.') param secretsExportConfiguration secretsExportConfigurationType? @@ -197,16 +209,10 @@ resource server 'Microsoft.Sql/servers@2023-08-01-preview' = { properties: { administratorLogin: !empty(administratorLogin) ? administratorLogin : null administratorLoginPassword: !empty(administratorLoginPassword) ? administratorLoginPassword : null - administrators: !empty(administrators) - ? { - administratorType: 'ActiveDirectory' - azureADOnlyAuthentication: administrators.azureADOnlyAuthentication - login: administrators.login - principalType: administrators.principalType - sid: administrators.sid - tenantId: administrators.?tenantId ?? tenant().tenantId - } - : null + administrators: union({ administratorType: 'ActiveDirectory' }, administrators ?? {}) + federatedClientId: federatedClientId + isIPv6Enabled: isIPv6Enabled + keyId: keyId version: '12.0' minimalTlsVersion: minimalTlsVersion primaryUserAssignedIdentityId: !empty(primaryUserAssignedIdentityId) ? primaryUserAssignedIdentityId : null @@ -214,7 +220,6 @@ resource server 'Microsoft.Sql/servers@2023-08-01-preview' = { ? publicNetworkAccess : (!empty(privateEndpoints) && empty(firewallRules) && empty(virtualNetworkRules) ? 'Disabled' : null) restrictOutboundNetworkAccess: !empty(restrictOutboundNetworkAccess) ? restrictOutboundNetworkAccess : null - isIPv6Enabled: isIPv6Enabled } } @@ -249,36 +254,53 @@ module server_databases 'database/main.bicep' = [ for (database, index) in databases: { name: '${uniqueString(deployment().name, location)}-Sql-DB-${index}' params: { - name: database.name + // properties derived from parent server resource, no override allowed serverName: server.name - skuTier: database.?skuTier ?? 'GeneralPurpose' - skuName: database.?skuName ?? 'GP_Gen5_2' - skuCapacity: database.?skuCapacity - skuFamily: database.?skuFamily ?? '' - skuSize: database.?skuSize ?? '' - collation: database.?collation ?? 'SQL_Latin1_General_CP1_CI_AS' - maxSizeBytes: database.?maxSizeBytes ?? 34359738368 - autoPauseDelay: database.?autoPauseDelay ?? 0 - diagnosticSettings: database.?diagnosticSettings - isLedgerOn: database.?isLedgerOn ?? false location: location - licenseType: database.?licenseType ?? '' - maintenanceConfigurationId: database.?maintenanceConfigurationId - minCapacity: database.?minCapacity ?? '' - highAvailabilityReplicaCount: database.?highAvailabilityReplicaCount ?? 0 - readScale: database.?readScale ?? 'Disabled' - requestedBackupStorageRedundancy: database.?requestedBackupStorageRedundancy ?? '' - sampleName: database.?sampleName ?? '' + + // properties from the database object. If not provided, parent server resource properties will be used tags: database.?tags ?? tags - zoneRedundant: database.?zoneRedundant ?? true - elasticPoolId: database.?elasticPoolId ?? '' - backupShortTermRetentionPolicy: database.?backupShortTermRetentionPolicy ?? {} - backupLongTermRetentionPolicy: database.?backupLongTermRetentionPolicy ?? {} - createMode: database.?createMode ?? 'Default' - sourceDatabaseResourceId: database.?sourceDatabaseResourceId ?? '' - sourceDatabaseDeletionDate: database.?sourceDatabaseDeletionDate ?? '' - recoveryServicesRecoveryPointResourceId: database.?recoveryServicesRecoveryPointResourceId ?? '' - restorePointInTime: database.?restorePointInTime ?? '' + + // properties from the databse object. If not provided, defaults specified in the child resource will be used + name: database.name + sku: database.?sku + autoPauseDelay: database.?autoPauseDelay + availabilityZone: database.?availabilityZone + catalogCollation: database.?catalogCollation + collation: database.?collation + createMode: database.?createMode + elasticPoolResourceId: database.?elasticPoolResourceId + encryptionProtector: database.?encryptionProtector + encryptionProtectorAutoRotation: database.?encryptionProtectorAutoRotation + federatedClientId: database.?federatedClientId + freeLimitExhaustionBehavior: database.?freeLimitExhaustionBehavior + highAvailabilityReplicaCount: database.?highAvailabilityReplicaCount + isLedgerOn: database.?isLedgerOn + licenseType: database.?licenseType + longTermRetentionBackupResourceId: database.?longTermRetentionBackupResourceId + maintenanceConfigurationId: database.?maintenanceConfigurationId + manualCutover: database.?manualCutover + maxSizeBytes: database.?maxSizeBytes + minCapacity: database.?minCapacity + performCutover: database.?performCutover + preferredEnclaveType: database.?preferredEnclaveType + readScale: database.?readScale + recoverableDatabaseResourceId: database.?recoverableDatabaseResourceId + recoveryServicesRecoveryPointResourceId: database.?recoveryServicesRecoveryPointResourceId + requestedBackupStorageRedundancy: database.?requestedBackupStorageRedundancy + restorableDroppedDatabaseResourceId: database.?restorableDroppedDatabaseResourceId + restorePointInTime: database.?restorePointInTime + sampleName: database.?sampleName + secondaryType: database.?secondaryType + sourceDatabaseDeletionDate: database.?sourceDatabaseDeletionDate + sourceDatabaseResourceId: database.?sourceDatabaseResourceId + sourceResourceId: database.?sourceResourceId + useFreeLimit: database.?useFreeLimit + zoneRedundant: database.?zoneRedundant + + diagnosticSettings: database.?diagnosticSettings + backupShortTermRetentionPolicy: database.?backupShortTermRetentionPolicy + backupLongTermRetentionPolicy: database.?backupLongTermRetentionPolicy } dependsOn: [ server_elasticPools // Enables us to add databases to existing elastic pools @@ -290,21 +312,26 @@ module server_elasticPools 'elastic-pool/main.bicep' = [ for (elasticPool, index) in elasticPools: { name: '${uniqueString(deployment().name, location)}-SQLServer-ElasticPool-${index}' params: { - name: elasticPool.name + // properties derived from parent server resource, no override allowed serverName: server.name - databaseMaxCapacity: elasticPool.?databaseMaxCapacity ?? 2 - databaseMinCapacity: elasticPool.?databaseMinCapacity ?? 0 + location: location + + // properties from the elastic pool object. If not provided, parent server resource properties will be used + tags: elasticPool.?tags ?? tags + + // properties from the elastic pool object. If not provided, defaults specified in the child resource will be used + name: elasticPool.name + sku: elasticPool.?sku + autoPauseDelay: elasticPool.?autoPauseDelay + availabilityZone: elasticPool.?availabilityZone highAvailabilityReplicaCount: elasticPool.?highAvailabilityReplicaCount - licenseType: elasticPool.?licenseType ?? 'LicenseIncluded' + licenseType: elasticPool.?licenseType maintenanceConfigurationId: elasticPool.?maintenanceConfigurationId - maxSizeBytes: elasticPool.?maxSizeBytes ?? 34359738368 + maxSizeBytes: elasticPool.?maxSizeBytes minCapacity: elasticPool.?minCapacity - skuCapacity: elasticPool.?skuCapacity ?? 2 - skuName: elasticPool.?skuName ?? 'GP_Gen5' - skuTier: elasticPool.?skuTier ?? 'GeneralPurpose' - zoneRedundant: elasticPool.?zoneRedundant ?? true - location: location - tags: elasticPool.?tags ?? tags + perDatabaseSettings: elasticPool.?perDatabaseSettings + preferredEnclaveType: elasticPool.?preferredEnclaveType + zoneRedundant: elasticPool.?zoneRedundant } } ] @@ -444,23 +471,19 @@ module server_encryptionProtector 'encryption-protector/main.bicep' = if (!empty ] } -module server_audit_settings 'audit-settings/main.bicep' = if (!empty(auditSettings)) { +module server_audit_settings 'audit-settings/main.bicep' = if (auditSettings != null) { name: '${uniqueString(deployment().name, location)}-Sql-AuditSettings' params: { serverName: server.name name: auditSettings.?name ?? 'default' - state: auditSettings.?state ?? 'Disabled' - auditActionsAndGroups: auditSettings.?auditActionsAndGroups ?? [ - 'BATCH_COMPLETED_GROUP' - 'SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP' - 'FAILED_DATABASE_AUTHENTICATION_GROUP' - ] - isAzureMonitorTargetEnabled: auditSettings.?isAzureMonitorTargetEnabled ?? false - isDevopsAuditEnabled: auditSettings.?isDevopsAuditEnabled ?? false - isManagedIdentityInUse: auditSettings.?isManagedIdentityInUse ?? false - isStorageSecondaryKeyInUse: auditSettings.?isStorageSecondaryKeyInUse ?? false - queueDelayMs: auditSettings.?queueDelayMs ?? 1000 - retentionDays: auditSettings.?retentionDays ?? 90 + state: auditSettings.?state + auditActionsAndGroups: auditSettings.?auditActionsAndGroups + isAzureMonitorTargetEnabled: auditSettings.?isAzureMonitorTargetEnabled + isDevopsAuditEnabled: auditSettings.?isDevopsAuditEnabled + isManagedIdentityInUse: auditSettings.?isManagedIdentityInUse + isStorageSecondaryKeyInUse: auditSettings.?isStorageSecondaryKeyInUse + queueDelayMs: auditSettings.?queueDelayMs + retentionDays: auditSettings.?retentionDays storageAccountResourceId: auditSettings.?storageAccountResourceId } } @@ -510,6 +533,7 @@ output systemAssignedMIPrincipalId string = server.?identity.?principalId ?? '' @description('The location the resource was deployed into.') output location string = server.location +import { secretsOutputType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret\'s name.') output exportedSecrets secretsOutputType = (secretsExportConfiguration != null) ? toObject(secretsExport.outputs.secretsSet, secret => last(split(secret.secretResourceId, '/')), secret => secret) @@ -530,180 +554,248 @@ output privateEndpoints array = [ // Definitions // // =============== // -type managedIdentitiesType = { - @description('Optional. Enables system assigned managed identity on the resource.') - systemAssigned: bool? +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' +import { elasticPoolPerDatabaseSettingsType, elasticPoolSkuType } from 'elastic-pool/main.bicep' +import { databaseSkuType, shortTermBackupRetentionPolicyType, longTermBackupRetentionPolicyType } from 'database/main.bicep' - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourceIds: string[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') +@export() +type auditSettingsType = { + @description('Optional. Specifies the name of the audit settings.') name: string? - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? + @description('Optional. Specifies the Actions-Groups and Actions to audit.') + auditActionsAndGroups: string[]? -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? + @description('Optional. Specifies whether audit events are sent to Azure Monitor.') + isAzureMonitorTargetEnabled: bool? - @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\'.') - roleDefinitionIdOrName: string + @description('Optional. Specifies the state of devops audit. If state is Enabled, devops logs will be sent to Azure Monitor.') + isDevopsAuditEnabled: bool? - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string + @description('Optional. Specifies whether Managed Identity is used to access blob storage.') + isManagedIdentityInUse: bool? - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + @description('Optional. Specifies whether storageAccountAccessKey value is the storage\'s secondary key.') + isStorageSecondaryKeyInUse: bool? - @description('Optional. The description of the role assignment.') - description: string? + @description('Optional. Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed.') + queueDelayMs: int? - @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".') - condition: string? + @description('Optional. Specifies the number of days to keep in the audit logs in the storage account.') + retentionDays: int? - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? + @description('Optional. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required.') + state: 'Enabled' | 'Disabled'? - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? + @description('Optional. Specifies the identifier key of the auditing storage account.') + storageAccountResourceId: string? +} -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? +@export() +type secretsExportConfigurationType = { + @description('Required. The resource ID of the key vault where to store the secrets of this module.') + keyVaultResourceId: string - @description('Optional. The location to deploy the private endpoint to.') - location: string? + @description('Optional. The sqlAdminPassword secret name to create.') + sqlAdminPasswordSecretName: string? - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? + @description('Optional. The sqlAzureConnectionString secret name to create.') + sqlAzureConnectionStringSercretName: string? +} - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? +@export() +type serverExternalAdministratorType = { + @description('Optional. Type of the sever administrator.') + administratorType: 'ActiveDirectory'? - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string + @description('Required. Azure Active Directory only Authentication enabled.') + azureADOnlyAuthentication: bool - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? + @description('Required. Login name of the server administrator.') + login: string - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? + @description('Required. Principal Type of the sever administrator.') + principalType: 'Application' | 'Group' | 'User' - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? + @description('Required. SID (object ID) of the server administrator.') + sid: string - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? + @description('Optional. Tenant ID of the administrator.') + tenantId: string? +} - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? +@export() +type databasePropertyType = { + @description('Required. The name of the Elastic Pool.') + name: string - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? + @description('Optional. Tags of the resource.') + tags: object? - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? + @description('Optional. The database SKU.') + sku: databaseSkuType? - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string + @description('Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled.') + autoPauseDelay: int? - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string + @description('Optional. Specifies the availability zone the database is pinned to.') + availabilityZone: '1' | '2' | '3' | 'NoPreference'? - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string + @description('Optional. Collation of the metadata catalog.') + catalogCollation: string? - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? + @description('Optional. The collation of the database.') + collation: string? - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? + @description('Optional. Specifies the mode of database creation.') + createMode: + | 'Copy' + | 'Default' + | 'OnlineSecondary' + | 'PointInTimeRestore' + | 'Recovery' + | 'Restore' + | 'RestoreExternalBackup' + | 'RestoreExternalBackupSecondary' + | 'RestoreLongTermRetentionBackup' + | 'Secondary'? - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? + @description('Optional. The resource identifier of the elastic pool containing this database.') + elasticPoolResourceId: string? - @description('Optional. Specify the type of lock.') - lock: lockType + @description('Optional. The azure key vault URI of the database if it\'s configured with per Database Customer Managed Keys.') + encryptionProtector: string? - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType + @description('Optional. The flag to enable or disable auto rotation of database encryption protector AKV key.') + encryptionProtectorAutoRotation: bool? - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? + @description('Optional. The Client id used for cross tenant per database CMK scenario.') + @minLength(36) + @maxLength(36) + federatedClientId: string? - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? + @description('Optional. Specifies the behavior when monthly free limits are exhausted for the free database.') + freeLimitExhaustionBehavior: 'AutoPause' | 'BillOverUsage'? - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? + @description('Optional. The number of secondary replicas associated with the database that are used to provide high availability. Not applicable to a Hyperscale database within an elastic pool.') + highAvailabilityReplicaCount: int? -type auditSettingsType = { - @description('Optional. Specifies the name of the audit settings.') - name: string? + @description('Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables.') + isLedgerOn: bool? - @description('Optional. Specifies the Actions-Groups and Actions to audit.') - auditActionsAndGroups: string[]? + // keys + @description('Optional. The license type to apply for this database.') + licenseType: 'BasePrice' | 'LicenseIncluded'? - @description('Optional. Specifies whether audit events are sent to Azure Monitor.') - isAzureMonitorTargetEnabled: bool? + @description('Optional. The resource identifier of the long term retention backup associated with create operation of this database.') + longTermRetentionBackupResourceId: string? - @description('Optional. Specifies the state of devops audit. If state is Enabled, devops logs will be sent to Azure Monitor.') - isDevopsAuditEnabled: bool? + @description('Optional. Maintenance configuration id assigned to the database. This configuration defines the period when the maintenance updates will occur.') + maintenanceConfigurationId: string? - @description('Optional. Specifies whether Managed Identity is used to access blob storage.') - isManagedIdentityInUse: bool? + @description('Optional. Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier.') + manualCutover: bool? - @description('Optional. Specifies whether storageAccountAccessKey value is the storage\'s secondary key.') - isStorageSecondaryKeyInUse: bool? + @description('Optional. The max size of the database expressed in bytes.') + maxSizeBytes: int? - @description('Optional. Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed.') - queueDelayMs: int? + // string to enable fractional values + @description('Optional. Minimal capacity that database will always have allocated, if not paused.') + minCapacity: string? - @description('Optional. Specifies the number of days to keep in the audit logs in the storage account.') - retentionDays: int? + @description('Optional. To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress.') + performCutover: bool? - @description('Required. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required.') - state: 'Enabled' | 'Disabled' + @description('Optional. Type of enclave requested on the database.') + preferredEnclaveType: 'Default' | 'VBS'? - @description('Optional. Specifies the identifier key of the auditing storage account.') - storageAccountResourceId: string? + @description('Optional. The state of read-only routing. If enabled, connections that have application intent set to readonly in their connection string may be routed to a readonly secondary replica in the same region. Not applicable to a Hyperscale database within an elastic pool.') + readScale: 'Disabled' | 'Enabled'? + + @description('Optional. The resource identifier of the recoverable database associated with create operation of this database.') + recoverableDatabaseResourceId: string? + + @description('Optional. The resource identifier of the recovery point associated with create operation of this database.') + recoveryServicesRecoveryPointResourceId: string? + + @description('Optional. The storage account type to be used to store backups for this database.') + requestedBackupStorageRedundancy: 'Geo' | 'GeoZone' | 'Local' | 'Zone'? + + @description('Optional. The resource identifier of the restorable dropped database associated with create operation of this database.') + restorableDroppedDatabaseResourceId: string? + + @description('Optional. Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database.') + restorePointInTime: string? + + @description('Optional. The name of the sample schema to apply when creating this database.') + sampleName: string? + + @description('Optional. The secondary type of the database if it is a secondary.') + secondaryType: 'Geo' | 'Named' | 'Standby'? + + @description('Optional. Specifies the time that the database was deleted.') + sourceDatabaseDeletionDate: string? + + @description('Optional. The resource identifier of the source database associated with create operation of this database.') + sourceDatabaseResourceId: string? + + @description('Optional. The resource identifier of the source associated with the create operation of this database.') + sourceResourceId: string? + + @description('Optional. Whether or not the database uses free monthly limits. Allowed on one database in a subscription.') + useFreeLimit: bool? + + @description('Optional. Whether or not this database is zone redundant, which means the replicas of this database will be spread across multiple availability zones.') + zoneRedundant: bool? + + @description('Optional. The diagnostic settings of the service.') + diagnosticSettings: diagnosticSettingFullType[]? + + @description('Optional. The short term backup retention policy for the database.') + backupShortTermRetentionPolicy: shortTermBackupRetentionPolicyType? + + @description('Optional. The long term backup retention policy for the database.') + backupLongTermRetentionPolicy: longTermBackupRetentionPolicyType? } -type secretsExportConfigurationType = { - @description('Required. The resource ID of the key vault where to store the secrets of this module.') - keyVaultResourceId: string +@export() +type elasticPoolPropertyType = { + @description('Required. The name of the Elastic Pool.') + name: string - @description('Optional. The sqlAdminPassword secret name to create.') - sqlAdminPasswordSecretName: string? + @description('Optional. Tags of the resource.') + tags: object? - @description('Optional. The sqlAzureConnectionString secret name to create.') - sqlAzureConnectionStringSercretName: string? -}? + @description('Optional. The elastic pool SKU.') + sku: elasticPoolSkuType? + + @description('Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled.') + autoPauseDelay: int? + + @description('Optional. Specifies the availability zone the pool\'s primary replica is pinned to.') + availabilityZone: '1' | '2' | '3' | 'NoPreference'? + + @description('Optional. The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.') + highAvailabilityReplicaCount: int? + + @description('Optional. The license type to apply for this elastic pool.') + licenseType: 'BasePrice' | 'LicenseIncluded'? + + @description('Optional. Maintenance configuration id assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur.') + maintenanceConfigurationId: string? + + @description('Optional. The storage limit for the database elastic pool in bytes.') + maxSizeBytes: int? + + @description('Optional. Minimal capacity that serverless pool will not shrink below, if not paused.') + minCapacity: int? + + @description('Optional. The per database settings for the elastic pool.') + perDatabaseSettings: elasticPoolPerDatabaseSettingsType? + + @description('Optional. Type of enclave requested on the elastic pool.') + preferredEnclaveType: 'Default' | 'VBS'? -import { secretSetType } from 'modules/keyVaultExport.bicep' -type secretsOutputType = { - @description('An exported secret\'s references.') - *: secretSetType + @description('Optional. Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones.') + zoneRedundant: bool? } diff --git a/avm/res/sql/server/main.json b/avm/res/sql/server/main.json index 4af86582a2..0434d51bda 100644 --- a/avm/res/sql/server/main.json +++ b/avm/res/sql/server/main.json @@ -6,354 +6,13 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "8810892363183845130" + "templateHash": "14327182870559615261" }, "name": "Azure SQL Servers", "description": "This module deploys an Azure SQL Server.", "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." - } - }, - "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": "Optional. 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 - }, "auditSettingsType": { "type": "object", "properties": { @@ -422,8 +81,9 @@ "Disabled", "Enabled" ], + "nullable": true, "metadata": { - "description": "Required. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required." + "description": "Optional. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required." } }, "storageAccountResourceId": { @@ -433,6 +93,9 @@ "description": "Optional. Specifies the identifier key of the auditing storage account." } } + }, + "metadata": { + "__bicep_export!": true } }, "secretsExportConfigurationType": { @@ -459,71 +122,1305 @@ } } }, - "nullable": true - }, - "secretsOutputType": { - "type": "object", - "properties": {}, - "additionalProperties": { - "$ref": "#/definitions/secretSetType", - "metadata": { - "description": "An exported secret's references." - } + "metadata": { + "__bicep_export!": true } }, - "secretSetType": { + "serverExternalAdministratorType": { "type": "object", "properties": { - "secretResourceId": { + "administratorType": { "type": "string", + "allowedValues": [ + "ActiveDirectory" + ], + "nullable": true, "metadata": { - "description": "The resourceId of the exported secret." + "description": "Optional. Type of the sever administrator." } }, - "secretUri": { + "azureADOnlyAuthentication": { + "type": "bool", + "metadata": { + "description": "Required. Azure Active Directory only Authentication enabled." + } + }, + "login": { "type": "string", "metadata": { - "description": "The secret URI of the exported secret." + "description": "Required. Login name of the server administrator." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Application", + "Group", + "User" + ], + "metadata": { + "description": "Required. Principal Type of the sever administrator." + } + }, + "sid": { + "type": "string", + "metadata": { + "description": "Required. SID (object ID) of the server administrator." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Tenant ID of the administrator." } } }, "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/keyVaultExport.bicep" - } - } - } - }, - "parameters": { - "administratorLogin": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Conditional. The administrator username for the server. Required if no `administrators` object for AAD authentication is provided." - } - }, - "administratorLoginPassword": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Conditional. The administrator login password. Required if no `administrators` object for AAD authentication is provided." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." + "__bicep_export!": true } }, - "name": { - "type": "string", + "databasePropertyType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Elastic Pool." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "sku": { + "$ref": "#/definitions/databaseSkuType", + "nullable": true, + "metadata": { + "description": "Optional. The database SKU." + } + }, + "autoPauseDelay": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled." + } + }, + "availabilityZone": { + "type": "string", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the availability zone the database is pinned to." + } + }, + "catalogCollation": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Collation of the metadata catalog." + } + }, + "collation": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The collation of the database." + } + }, + "createMode": { + "type": "string", + "allowedValues": [ + "Copy", + "Default", + "OnlineSecondary", + "PointInTimeRestore", + "Recovery", + "Restore", + "RestoreExternalBackup", + "RestoreExternalBackupSecondary", + "RestoreLongTermRetentionBackup", + "Secondary" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the mode of database creation." + } + }, + "elasticPoolResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the elastic pool containing this database." + } + }, + "encryptionProtector": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The azure key vault URI of the database if it's configured with per Database Customer Managed Keys." + } + }, + "encryptionProtectorAutoRotation": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The flag to enable or disable auto rotation of database encryption protector AKV key." + } + }, + "federatedClientId": { + "type": "string", + "nullable": true, + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Optional. The Client id used for cross tenant per database CMK scenario." + } + }, + "freeLimitExhaustionBehavior": { + "type": "string", + "allowedValues": [ + "AutoPause", + "BillOverUsage" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the behavior when monthly free limits are exhausted for the free database." + } + }, + "highAvailabilityReplicaCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of secondary replicas associated with the database that are used to provide high availability. Not applicable to a Hyperscale database within an elastic pool." + } + }, + "isLedgerOn": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables." + } + }, + "licenseType": { + "type": "string", + "allowedValues": [ + "BasePrice", + "LicenseIncluded" + ], + "nullable": true, + "metadata": { + "description": "Optional. The license type to apply for this database." + } + }, + "longTermRetentionBackupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the long term retention backup associated with create operation of this database." + } + }, + "maintenanceConfigurationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Maintenance configuration id assigned to the database. This configuration defines the period when the maintenance updates will occur." + } + }, + "manualCutover": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier." + } + }, + "maxSizeBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The max size of the database expressed in bytes." + } + }, + "minCapacity": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Minimal capacity that database will always have allocated, if not paused." + } + }, + "performCutover": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress." + } + }, + "preferredEnclaveType": { + "type": "string", + "allowedValues": [ + "Default", + "VBS" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of enclave requested on the database." + } + }, + "readScale": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. The state of read-only routing. If enabled, connections that have application intent set to readonly in their connection string may be routed to a readonly secondary replica in the same region. Not applicable to a Hyperscale database within an elastic pool." + } + }, + "recoverableDatabaseResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the recoverable database associated with create operation of this database." + } + }, + "recoveryServicesRecoveryPointResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the recovery point associated with create operation of this database." + } + }, + "requestedBackupStorageRedundancy": { + "type": "string", + "allowedValues": [ + "Geo", + "GeoZone", + "Local", + "Zone" + ], + "nullable": true, + "metadata": { + "description": "Optional. The storage account type to be used to store backups for this database." + } + }, + "restorableDroppedDatabaseResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the restorable dropped database associated with create operation of this database." + } + }, + "restorePointInTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the point in time (ISO8601 format) of the source database that will be restored to create the new database." + } + }, + "sampleName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the sample schema to apply when creating this database." + } + }, + "secondaryType": { + "type": "string", + "allowedValues": [ + "Geo", + "Named", + "Standby" + ], + "nullable": true, + "metadata": { + "description": "Optional. The secondary type of the database if it is a secondary." + } + }, + "sourceDatabaseDeletionDate": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the time that the database was deleted." + } + }, + "sourceDatabaseResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the source database associated with create operation of this database." + } + }, + "sourceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource identifier of the source associated with the create operation of this database." + } + }, + "useFreeLimit": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not the database uses free monthly limits. Allowed on one database in a subscription." + } + }, + "zoneRedundant": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not this database is zone redundant, which means the replicas of this database will be spread across multiple availability zones." + } + }, + "diagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "backupShortTermRetentionPolicy": { + "$ref": "#/definitions/shortTermBackupRetentionPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. The short term backup retention policy for the database." + } + }, + "backupLongTermRetentionPolicy": { + "$ref": "#/definitions/longTermBackupRetentionPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. The long term backup retention policy for the database." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "elasticPoolPropertyType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Elastic Pool." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "sku": { + "$ref": "#/definitions/elasticPoolSkuType", + "nullable": true, + "metadata": { + "description": "Optional. The elastic pool SKU." + } + }, + "autoPauseDelay": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled." + } + }, + "availabilityZone": { + "type": "string", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to." + } + }, + "highAvailabilityReplicaCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools." + } + }, + "licenseType": { + "type": "string", + "allowedValues": [ + "BasePrice", + "LicenseIncluded" + ], + "nullable": true, + "metadata": { + "description": "Optional. The license type to apply for this elastic pool." + } + }, + "maintenanceConfigurationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Maintenance configuration id assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur." + } + }, + "maxSizeBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The storage limit for the database elastic pool in bytes." + } + }, + "minCapacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Minimal capacity that serverless pool will not shrink below, if not paused." + } + }, + "perDatabaseSettings": { + "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The per database settings for the elastic pool." + } + }, + "preferredEnclaveType": { + "type": "string", + "allowedValues": [ + "Default", + "VBS" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of enclave requested on the elastic pool." + } + }, + "zoneRedundant": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_1.privateEndpointCustomDnsConfigType": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. 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." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.privateEndpointIpConfigurationType": { + "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." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.secretSetOutputType": { + "type": "object", + "properties": { + "secretResourceId": { + "type": "string", + "metadata": { + "description": "The resourceId of the exported secret." + } + }, + "secretUri": { + "type": "string", + "metadata": { + "description": "The secret URI of the exported secret." + } + }, + "secretUriWithVersion": { + "type": "string", + "metadata": { + "description": "The secret URI with version of the exported secret." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "databaseSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "description": "The database SKU.", + "__bicep_imported_from!": { + "sourceTemplate": "database/main.bicep" + } + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "elasticPoolPerDatabaseSettingsType": { + "type": "object", + "properties": { + "autoPauseDelay": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Auto Pause Delay for per database within pool." + } + }, + "maxCapacity": { + "type": "string", + "metadata": { + "description": "Required. The maximum capacity any one database can consume. Examples: '0.5', '2'." + } + }, + "minCapacity": { + "type": "string", + "metadata": { + "description": "Required. The minimum capacity all databases are guaranteed. Examples: '0.5', '1'." + } + } + }, + "metadata": { + "description": "The per database settings for the elastic pool.", + "__bicep_imported_from!": { + "sourceTemplate": "elastic-pool/main.bicep" + } + } + }, + "elasticPoolSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "allowedValues": [ + "BC_DC", + "BC_Gen5", + "BasicPool", + "GP_DC", + "GP_FSv2", + "GP_Gen5", + "HS_Gen5", + "HS_MOPRMS", + "HS_PRMS", + "PremiumPool", + "ServerlessPool", + "StandardPool" + ], + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "description": "The elastic pool SKU.", + "__bicep_imported_from!": { + "sourceTemplate": "elastic-pool/main.bicep" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "longTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "backupStorageAccessTier": { + "type": "string", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, + "metadata": { + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." + } + }, + "monthlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Weekly retention in ISO 8601 duration format." + } + }, + "weekOfYear": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Week of year backup to keep for yearly retention." + } + }, + "yearlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Yearly retention in ISO 8601 duration format." + } + } + }, + "metadata": { + "description": "The long-term backup retention policy for the database.", + "__bicep_imported_from!": { + "sourceTemplate": "database/main.bicep" + } + } + }, + "managedIdentityAllType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" + }, + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "secretsOutputType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "$ref": "#/definitions/_1.secretSetOutputType", + "metadata": { + "description": "An exported secret's references." + } + }, + "metadata": { + "description": "A map of the exported secrets", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "shortTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "diffBackupIntervalInHours": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Differential backup interval in hours. For Hyperscale tiers this value will be ignored." + } + }, + "retentionDays": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Point-in-time retention in days." + } + } + }, + "metadata": { + "description": "The short-term backup retention policy for the database.", + "__bicep_imported_from!": { + "sourceTemplate": "database/main.bicep" + } + } + } + }, + "parameters": { + "administratorLogin": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Conditional. The administrator username for the server. Required if no `administrators` object for AAD authentication is provided." + } + }, + "administratorLoginPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Conditional. The administrator login password. Required if no `administrators` object for AAD authentication is provided." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "name": { + "type": "string", "metadata": { "description": "Required. The name of the server." } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } @@ -537,12 +1434,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -563,6 +1465,9 @@ }, "databases": { "type": "array", + "items": { + "$ref": "#/definitions/databasePropertyType" + }, "defaultValue": [], "metadata": { "description": "Optional. The databases to create in the server." @@ -570,6 +1475,9 @@ }, "elasticPools": { "type": "array", + "items": { + "$ref": "#/definitions/elasticPoolPropertyType" + }, "defaultValue": [], "metadata": { "description": "Optional. The Elastic Pools to create in the server." @@ -604,12 +1512,28 @@ } }, "administrators": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/serverExternalAdministratorType", + "nullable": true, "metadata": { "description": "Conditional. The Azure Active Directory (AAD) administrator authentication. Required if no `administratorLogin` & `administratorLoginPassword` is provided." } }, + "federatedClientId": { + "type": "string", + "nullable": true, + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Optional. The Client id used for cross tenant CMK scenario." + } + }, + "keyId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A CMK URI of the key to use for encryption." + } + }, "minimalTlsVersion": { "type": "string", "defaultValue": "1.2", @@ -635,7 +1559,11 @@ } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } @@ -681,7 +1609,7 @@ }, "auditSettings": { "$ref": "#/definitions/auditSettingsType", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. The audit settings configuration." } @@ -750,13 +1678,15 @@ "properties": { "administratorLogin": "[if(not(empty(parameters('administratorLogin'))), parameters('administratorLogin'), null())]", "administratorLoginPassword": "[if(not(empty(parameters('administratorLoginPassword'))), parameters('administratorLoginPassword'), null())]", - "administrators": "[if(not(empty(parameters('administrators'))), createObject('administratorType', 'ActiveDirectory', 'azureADOnlyAuthentication', parameters('administrators').azureADOnlyAuthentication, 'login', parameters('administrators').login, 'principalType', parameters('administrators').principalType, 'sid', parameters('administrators').sid, 'tenantId', coalesce(tryGet(parameters('administrators'), 'tenantId'), tenant().tenantId)), null())]", + "administrators": "[union(createObject('administratorType', 'ActiveDirectory'), coalesce(parameters('administrators'), createObject()))]", + "federatedClientId": "[parameters('federatedClientId')]", + "isIPv6Enabled": "[parameters('isIPv6Enabled')]", + "keyId": "[parameters('keyId')]", "version": "12.0", "minimalTlsVersion": "[parameters('minimalTlsVersion')]", "primaryUserAssignedIdentityId": "[if(not(empty(parameters('primaryUserAssignedIdentityId'))), parameters('primaryUserAssignedIdentityId'), null())]", "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(and(not(empty(parameters('privateEndpoints'))), empty(parameters('firewallRules'))), empty(parameters('virtualNetworkRules'))), 'Disabled', null()))]", - "restrictOutboundNetworkAccess": "[if(not(empty(parameters('restrictOutboundNetworkAccess'))), parameters('restrictOutboundNetworkAccess'), null())]", - "isIPv6Enabled": "[parameters('isIPv6Enabled')]" + "restrictOutboundNetworkAccess": "[if(not(empty(parameters('restrictOutboundNetworkAccess'))), parameters('restrictOutboundNetworkAccess'), null())]" } }, "server_lock": { @@ -809,95 +1739,128 @@ }, "mode": "Incremental", "parameters": { - "name": { - "value": "[parameters('databases')[copyIndex()].name]" - }, "serverName": { "value": "[parameters('name')]" }, - "skuTier": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'skuTier'), 'GeneralPurpose')]" + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'tags'), parameters('tags'))]" + }, + "name": { + "value": "[parameters('databases')[copyIndex()].name]" }, - "skuName": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'skuName'), 'GP_Gen5_2')]" + "sku": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'sku')]" }, - "skuCapacity": { - "value": "[tryGet(parameters('databases')[copyIndex()], 'skuCapacity')]" + "autoPauseDelay": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'autoPauseDelay')]" }, - "skuFamily": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'skuFamily'), '')]" + "availabilityZone": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'availabilityZone')]" }, - "skuSize": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'skuSize'), '')]" + "catalogCollation": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'catalogCollation')]" }, "collation": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'collation'), 'SQL_Latin1_General_CP1_CI_AS')]" + "value": "[tryGet(parameters('databases')[copyIndex()], 'collation')]" }, - "maxSizeBytes": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'maxSizeBytes'), json('34359738368'))]" + "createMode": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'createMode')]" }, - "autoPauseDelay": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'autoPauseDelay'), 0)]" + "elasticPoolResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'elasticPoolResourceId')]" }, - "diagnosticSettings": { - "value": "[tryGet(parameters('databases')[copyIndex()], 'diagnosticSettings')]" + "encryptionProtector": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'encryptionProtector')]" }, - "isLedgerOn": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'isLedgerOn'), false())]" + "encryptionProtectorAutoRotation": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'encryptionProtectorAutoRotation')]" }, - "location": { - "value": "[parameters('location')]" + "federatedClientId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'federatedClientId')]" + }, + "freeLimitExhaustionBehavior": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'freeLimitExhaustionBehavior')]" + }, + "highAvailabilityReplicaCount": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'highAvailabilityReplicaCount')]" + }, + "isLedgerOn": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'isLedgerOn')]" }, "licenseType": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'licenseType'), '')]" + "value": "[tryGet(parameters('databases')[copyIndex()], 'licenseType')]" + }, + "longTermRetentionBackupResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'longTermRetentionBackupResourceId')]" }, "maintenanceConfigurationId": { "value": "[tryGet(parameters('databases')[copyIndex()], 'maintenanceConfigurationId')]" }, + "manualCutover": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'manualCutover')]" + }, + "maxSizeBytes": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'maxSizeBytes')]" + }, "minCapacity": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'minCapacity'), '')]" + "value": "[tryGet(parameters('databases')[copyIndex()], 'minCapacity')]" }, - "highAvailabilityReplicaCount": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'highAvailabilityReplicaCount'), 0)]" + "performCutover": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'performCutover')]" + }, + "preferredEnclaveType": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'preferredEnclaveType')]" }, "readScale": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'readScale'), 'Disabled')]" + "value": "[tryGet(parameters('databases')[copyIndex()], 'readScale')]" }, - "requestedBackupStorageRedundancy": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'requestedBackupStorageRedundancy'), '')]" + "recoverableDatabaseResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'recoverableDatabaseResourceId')]" }, - "sampleName": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'sampleName'), '')]" + "recoveryServicesRecoveryPointResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'recoveryServicesRecoveryPointResourceId')]" }, - "tags": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'tags'), parameters('tags'))]" + "requestedBackupStorageRedundancy": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'requestedBackupStorageRedundancy')]" }, - "zoneRedundant": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'zoneRedundant'), true())]" + "restorableDroppedDatabaseResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'restorableDroppedDatabaseResourceId')]" }, - "elasticPoolId": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'elasticPoolId'), '')]" + "restorePointInTime": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'restorePointInTime')]" }, - "backupShortTermRetentionPolicy": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'backupShortTermRetentionPolicy'), createObject())]" + "sampleName": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'sampleName')]" }, - "backupLongTermRetentionPolicy": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'backupLongTermRetentionPolicy'), createObject())]" + "secondaryType": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'secondaryType')]" }, - "createMode": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'createMode'), 'Default')]" + "sourceDatabaseDeletionDate": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseDeletionDate')]" }, "sourceDatabaseResourceId": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseResourceId'), '')]" + "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseResourceId')]" }, - "sourceDatabaseDeletionDate": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseDeletionDate'), '')]" + "sourceResourceId": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceResourceId')]" }, - "recoveryServicesRecoveryPointResourceId": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'recoveryServicesRecoveryPointResourceId'), '')]" + "useFreeLimit": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'useFreeLimit')]" }, - "restorePointInTime": { - "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'restorePointInTime'), '')]" + "zoneRedundant": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'zoneRedundant')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'diagnosticSettings')]" + }, + "backupShortTermRetentionPolicy": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'backupShortTermRetentionPolicy')]" + }, + "backupLongTermRetentionPolicy": { + "value": "[tryGet(parameters('databases')[copyIndex()], 'backupLongTermRetentionPolicy')]" } }, "template": { @@ -908,132 +1871,255 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6415977783551326128" + "templateHash": "18018827030977470456" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", "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`." - } + "databaseSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The database SKU." + } + }, + "shortTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "diffBackupIntervalInHours": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Differential backup interval in hours. For Hyperscale tiers this value will be ignored." + } + }, + "retentionDays": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Point-in-time retention in days." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The short-term backup retention policy for the database." + } + }, + "longTermBackupRetentionPolicyType": { + "type": "object", + "properties": { + "backupStorageAccessTier": { + "type": "string", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, + "metadata": { + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." + } + }, + "monthlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Weekly retention in ISO 8601 duration format." + } + }, + "weekOfYear": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Week of year backup to keep for yearly retention." + } + }, + "yearlyRetention": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Yearly retention in ISO 8601 duration format." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The long-term backup retention policy for the database." + } + }, + "diagnosticSettingFullType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the 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." + } + }, + "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if both logs & metrics are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -1049,6 +2135,43 @@ "description": "Conditional. The name of the parent SQL Server. Required if the template is used in a standalone deployment." } }, + "sku": { + "$ref": "#/definitions/databaseSkuType", + "defaultValue": { + "name": "GP_Gen5_2", + "tier": "GeneralPurpose" + }, + "metadata": { + "description": "Optional. The database SKU." + } + }, + "autoPauseDelay": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled." + } + }, + "availabilityZone": { + "type": "string", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "defaultValue": "NoPreference", + "metadata": { + "description": "Optional. Specifies the availability zone the database is pinned to." + } + }, + "catalogCollation": { + "type": "string", + "defaultValue": "DATABASE_DEFAULT", + "metadata": { + "description": "Optional. Collation of the metadata catalog." + } + }, "collation": { "type": "string", "defaultValue": "SQL_Latin1_General_CP1_CI_AS", @@ -1056,51 +2179,110 @@ "description": "Optional. The collation of the database." } }, - "skuTier": { + "createMode": { + "type": "string", + "allowedValues": [ + "Copy", + "Default", + "OnlineSecondary", + "PointInTimeRestore", + "Recovery", + "Restore", + "RestoreExternalBackup", + "RestoreExternalBackupSecondary", + "RestoreLongTermRetentionBackup", + "Secondary" + ], + "defaultValue": "Default", + "metadata": { + "description": "Optional. Specifies the mode of database creation." + } + }, + "elasticPoolResourceId": { "type": "string", - "defaultValue": "GeneralPurpose", + "nullable": true, "metadata": { - "description": "Optional. The skuTier or edition of the particular SKU." + "description": "Optional. The resource ID of the elastic pool containing this database." } }, - "skuName": { + "encryptionProtector": { "type": "string", - "defaultValue": "GP_Gen5_2", + "nullable": true, "metadata": { - "description": "Optional. The name of the SKU." + "description": "Optional. The azure key vault URI of the database if it's configured with per Database Customer Managed Keys." } }, - "skuCapacity": { - "type": "int", + "encryptionProtectorAutoRotation": { + "type": "bool", "nullable": true, "metadata": { - "description": "Optional. Capacity of the particular SKU." + "description": "Optional. The flag to enable or disable auto rotation of database encryption protector AKV key." } }, - "preferredEnclaveType": { + "federatedClientId": { + "type": "string", + "nullable": true, + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Optional. The Client id used for cross tenant per database CMK scenario." + } + }, + "freeLimitExhaustionBehavior": { "type": "string", - "defaultValue": "", "allowedValues": [ - "", - "Default", - "VBS" + "AutoPause", + "BillOverUsage" ], + "nullable": true, "metadata": { - "description": "Optional. Type of enclave requested on the database i.e. Default or VBS enclaves." + "description": "Optional. Specifies the behavior when monthly free limits are exhausted for the free database." + } + }, + "highAvailabilityReplicaCount": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. The number of readonly secondary replicas associated with the database." + } + }, + "isLedgerOn": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created." } }, - "skuFamily": { + "licenseType": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "BasePrice", + "LicenseIncluded" + ], + "nullable": true, "metadata": { - "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + "description": "Optional. The license type to apply for this database." } }, - "skuSize": { + "longTermRetentionBackupResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Size of the particular SKU." + "description": "Optional. The resource identifier of the long term retention backup associated with create operation of this database." + } + }, + "maintenanceConfigurationId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur." + } + }, + "manualCutover": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether or not customer controlled manual cutover needs to be done during Update Database operation to Hyperscale tier." } }, "maxSizeBytes": { @@ -1110,176 +2292,176 @@ "description": "Optional. The max size of the database expressed in bytes." } }, - "sampleName": { + "minCapacity": { "type": "string", - "defaultValue": "", + "defaultValue": "0", "metadata": { - "description": "Optional. The name of the sample schema to apply when creating this database." + "description": "Optional. Minimal capacity that database will always have allocated." } }, - "zoneRedundant": { + "performCutover": { "type": "bool", - "defaultValue": true, + "nullable": true, "metadata": { - "description": "Optional. Whether or not this database is zone redundant." + "description": "Optional. To trigger customer controlled manual cutover during the wait state while Scaling operation is in progress." } }, - "licenseType": { + "preferredEnclaveType": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "Default", + "VBS" + ], + "nullable": true, "metadata": { - "description": "Optional. The license type to apply for this database." + "description": "Optional. Type of enclave requested on the database i.e. Default or VBS enclaves." } }, "readScale": { "type": "string", - "defaultValue": "Disabled", "allowedValues": [ - "Enabled", - "Disabled" + "Disabled", + "Enabled" ], + "defaultValue": "Disabled", "metadata": { "description": "Optional. The state of read-only routing." } }, - "highAvailabilityReplicaCount": { - "type": "int", - "defaultValue": 0, - "metadata": { - "description": "Optional. The number of readonly secondary replicas associated with the database." - } - }, - "minCapacity": { + "recoverableDatabaseResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Minimal capacity that database will always have allocated." + "description": "Optional. The resource identifier of the recoverable database associated with create operation of this database." } }, - "autoPauseDelay": { - "type": "int", - "defaultValue": 0, + "recoveryServicesRecoveryPointResourceId": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled." + "description": "Optional. The resource identifier of the recovery point associated with create operation of this database." } }, - "tags": { - "type": "object", - "nullable": true, + "requestedBackupStorageRedundancy": { + "type": "string", + "allowedValues": [ + "Geo", + "GeoZone", + "Local", + "Zone" + ], + "defaultValue": "Local", "metadata": { - "description": "Optional. Tags of the resource." + "description": "Optional. The storage account type to be used to store backups for this database." } }, - "elasticPoolId": { + "restorableDroppedDatabaseResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. The resource ID of the elastic pool containing this database." + "description": "Optional. The resource identifier of the restorable dropped database associated with create operation of this database." } }, - "location": { + "restorePointInTime": { "type": "string", - "defaultValue": "[resourceGroup().location]", + "nullable": true, "metadata": { - "description": "Optional. Location for all resources." + "description": "Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "sampleName": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Optional. The name of the sample schema to apply when creating this database." } }, - "createMode": { + "secondaryType": { "type": "string", - "defaultValue": "Default", "allowedValues": [ - "Default", - "Copy", - "OnlineSecondary", - "PointInTimeRestore", - "Recovery", - "Restore", - "RestoreLongTermRetentionBackup", - "Secondary" + "Geo", + "Named", + "Standby" ], + "nullable": true, "metadata": { - "description": "Optional. Specifies the mode of database creation." - } - }, - "sourceDatabaseResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of database if createMode set to Copy, Secondary, PointInTimeRestore, Recovery or Restore." + "description": "Optional. The secondary type of the database if it is a secondary." } }, "sourceDatabaseDeletionDate": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The time that the database was deleted when restoring a deleted database." } }, - "recoveryServicesRecoveryPointResourceId": { + "sourceDatabaseResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Resource ID of backup if createMode set to RestoreLongTermRetentionBackup." + "description": "Optional. The resource identifier of the source database associated with create operation of this database." } }, - "restorePointInTime": { + "sourceResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { - "description": "Optional. Point in time (ISO8601 format) of the source database to restore when createMode set to Restore or PointInTimeRestore." + "description": "Optional. The resource identifier of the source associated with the create operation of this database." } }, - "requestedBackupStorageRedundancy": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "Geo", - "Local", - "Zone", - "" - ], + "useFreeLimit": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. The storage account type to be used to store backups for this database." + "description": "Optional. Whether or not the database uses free monthly limits. Allowed on one database in a subscription." } }, - "isLedgerOn": { + "zoneRedundant": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { - "description": "Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created." + "description": "Optional. Whether or not this database is zone redundant." } }, - "maintenanceConfigurationId": { + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "diagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, "nullable": true, "metadata": { - "description": "Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur." + "description": "Optional. The diagnostic settings of the service." } }, "backupShortTermRetentionPolicy": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/shortTermBackupRetentionPolicyType", + "nullable": true, "metadata": { "description": "Optional. The short term backup retention policy to create for the database." } }, "backupLongTermRetentionPolicy": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/longTermBackupRetentionPolicyType", + "nullable": true, "metadata": { "description": "Optional. The long term backup retention policy to create for the database." } } }, - "variables": { - "skuVar": "[union(createObject('name', parameters('skuName'), 'tier', parameters('skuTier')), if(not(equals(parameters('skuCapacity'), null())), createObject('capacity', parameters('skuCapacity')), if(not(empty(parameters('skuFamily'))), createObject('family', parameters('skuFamily')), if(not(empty(parameters('skuSize'))), createObject('size', parameters('skuSize')), createObject()))))]" - }, "resources": { "server": { "existing": true, @@ -1293,28 +2475,42 @@ "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", + "sku": "[parameters('sku')]", "properties": { - "preferredEnclaveType": "[if(not(empty(parameters('preferredEnclaveType'))), parameters('preferredEnclaveType'), null())]", - "collation": "[parameters('collation')]", - "maxSizeBytes": "[parameters('maxSizeBytes')]", - "sampleName": "[parameters('sampleName')]", - "zoneRedundant": "[parameters('zoneRedundant')]", - "licenseType": "[parameters('licenseType')]", - "readScale": "[parameters('readScale')]", - "minCapacity": "[if(not(empty(parameters('minCapacity'))), json(parameters('minCapacity')), 0)]", "autoPauseDelay": "[parameters('autoPauseDelay')]", + "availabilityZone": "[parameters('availabilityZone')]", + "catalogCollation": "[parameters('catalogCollation')]", + "collation": "[parameters('collation')]", + "createMode": "[parameters('createMode')]", + "elasticPoolId": "[parameters('elasticPoolResourceId')]", + "encryptionProtector": "[parameters('encryptionProtector')]", + "encryptionProtectorAutoRotation": "[parameters('encryptionProtectorAutoRotation')]", + "federatedClientId": "[parameters('federatedClientId')]", + "freeLimitExhaustionBehavior": "[parameters('freeLimitExhaustionBehavior')]", "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]", - "requestedBackupStorageRedundancy": "[parameters('requestedBackupStorageRedundancy')]", "isLedgerOn": "[parameters('isLedgerOn')]", + "licenseType": "[parameters('licenseType')]", + "longTermRetentionBackupResourceId": "[parameters('longTermRetentionBackupResourceId')]", "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]", - "elasticPoolId": "[parameters('elasticPoolId')]", - "createMode": "[parameters('createMode')]", - "sourceDatabaseId": "[if(not(empty(parameters('sourceDatabaseResourceId'))), parameters('sourceDatabaseResourceId'), null())]", - "sourceDatabaseDeletionDate": "[if(not(empty(parameters('sourceDatabaseDeletionDate'))), parameters('sourceDatabaseDeletionDate'), null())]", - "recoveryServicesRecoveryPointId": "[if(not(empty(parameters('recoveryServicesRecoveryPointResourceId'))), parameters('recoveryServicesRecoveryPointResourceId'), null())]", - "restorePointInTime": "[if(not(empty(parameters('restorePointInTime'))), parameters('restorePointInTime'), null())]" + "manualCutover": "[parameters('manualCutover')]", + "maxSizeBytes": "[parameters('maxSizeBytes')]", + "minCapacity": "[if(not(empty(parameters('minCapacity'))), json(parameters('minCapacity')), 0)]", + "performCutover": "[parameters('performCutover')]", + "preferredEnclaveType": "[parameters('preferredEnclaveType')]", + "readScale": "[parameters('readScale')]", + "recoverableDatabaseId": "[parameters('recoverableDatabaseResourceId')]", + "recoveryServicesRecoveryPointId": "[parameters('recoveryServicesRecoveryPointResourceId')]", + "requestedBackupStorageRedundancy": "[parameters('requestedBackupStorageRedundancy')]", + "restorableDroppedDatabaseId": "[parameters('restorableDroppedDatabaseResourceId')]", + "restorePointInTime": "[parameters('restorePointInTime')]", + "sampleName": "[parameters('sampleName')]", + "secondaryType": "[parameters('secondaryType')]", + "sourceDatabaseDeletionDate": "[parameters('sourceDatabaseDeletionDate')]", + "sourceDatabaseId": "[parameters('sourceDatabaseResourceId')]", + "sourceResourceId": "[parameters('sourceResourceId')]", + "useFreeLimit": "[parameters('useFreeLimit')]", + "zoneRedundant": "[parameters('zoneRedundant')]" }, - "sku": "[variables('skuVar')]", "dependsOn": [ "server" ] @@ -1361,6 +2557,7 @@ ] }, "database_backupShortTermRetentionPolicy": { + "condition": "[not(empty(parameters('backupShortTermRetentionPolicy')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-{1}-shBakRetPol', uniqueString(deployment().name, parameters('location')), parameters('name'))]", @@ -1377,10 +2574,10 @@ "value": "[parameters('name')]" }, "diffBackupIntervalInHours": { - "value": "[coalesce(tryGet(parameters('backupShortTermRetentionPolicy'), 'diffBackupIntervalInHours'), 24)]" + "value": "[tryGet(parameters('backupShortTermRetentionPolicy'), 'diffBackupIntervalInHours')]" }, "retentionDays": { - "value": "[coalesce(tryGet(parameters('backupShortTermRetentionPolicy'), 'retentionDays'), 7)]" + "value": "[tryGet(parameters('backupShortTermRetentionPolicy'), 'retentionDays')]" } }, "template": { @@ -1390,7 +2587,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "10836519140305169908" + "templateHash": "14890409200962565555" }, "name": "Azure SQL Server Database Short Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Short-Term Backup Retention Policy.", @@ -1413,7 +2610,7 @@ "type": "int", "defaultValue": 24, "metadata": { - "description": "Optional. Differential backup interval in hours." + "description": "Optional. Differential backup interval in hours. For Hyperscal tiers this value will be ignored." } }, "retentionDays": { @@ -1430,7 +2627,7 @@ "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { - "diffBackupIntervalInHours": "[parameters('diffBackupIntervalInHours')]", + "diffBackupIntervalInHours": "[if(equals(reference(resourceId('Microsoft.Sql/servers/databases', parameters('serverName'), parameters('databaseName')), '2023-08-01-preview', 'full').sku.tier, 'Hyperscale'), null(), parameters('diffBackupIntervalInHours'))]", "retentionDays": "[parameters('retentionDays')]" } } @@ -1465,6 +2662,7 @@ ] }, "database_backupLongTermRetentionPolicy": { + "condition": "[not(empty(parameters('backupLongTermRetentionPolicy')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-{1}-lgBakRetPol', uniqueString(deployment().name, parameters('location')), parameters('name'))]", @@ -1480,27 +2678,34 @@ "databaseName": { "value": "[parameters('name')]" }, + "backupStorageAccessTier": { + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'backupStorageAccessTier')]" + }, + "makeBackupsImmutable": { + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'makeBackupsImmutable')]" + }, "weeklyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'weeklyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'weeklyRetention')]" }, "monthlyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'monthlyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'monthlyRetention')]" }, "yearlyRetention": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'yearlyRetention'), '')]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'yearlyRetention')]" }, "weekOfYear": { - "value": "[coalesce(tryGet(parameters('backupLongTermRetentionPolicy'), 'weekOfYear'), 1)]" + "value": "[tryGet(parameters('backupLongTermRetentionPolicy'), 'weekOfYear')]" } }, "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.30.23.60470", - "templateHash": "10064519186693398262" + "templateHash": "841731129374883266" }, "name": "SQL Server Database Long Term Backup Retention Policies", "description": "This module deploys an Azure SQL Server Database Long-Term Backup Retention Policy.", @@ -1519,16 +2724,34 @@ "description": "Required. The name of the parent database." } }, - "weeklyRetention": { + "backupStorageAccessTier": { "type": "string", - "defaultValue": "", + "allowedValues": [ + "Archive", + "Hot" + ], + "nullable": true, "metadata": { - "description": "Optional. Monthly retention in ISO 8601 duration format." + "description": "Optional. The BackupStorageAccessTier for the LTR backups." + } + }, + "makeBackupsImmutable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The setting whether to make LTR backups immutable." } }, "monthlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, + "metadata": { + "description": "Optional. Monthly retention in ISO 8601 duration format." + } + }, + "weeklyRetention": { + "type": "string", + "nullable": true, "metadata": { "description": "Optional. Weekly retention in ISO 8601 duration format." } @@ -1542,25 +2765,45 @@ }, "yearlyRetention": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Yearly retention in ISO 8601 duration format." } } }, - "resources": [ - { - "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "resources": { + "server::database": { + "existing": true, + "type": "Microsoft.Sql/servers/databases", + "apiVersion": "2023-08-01-preview", + "name": "[format('{0}/{1}', parameters('serverName'), parameters('databaseName'))]", + "dependsOn": [ + "server" + ] + }, + "server": { + "existing": true, + "type": "Microsoft.Sql/servers", "apiVersion": "2023-08-01-preview", + "name": "[parameters('serverName')]" + }, + "backupLongTermRetentionPolicy": { + "type": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies", + "apiVersion": "2023-05-01-preview", "name": "[format('{0}/{1}/{2}', parameters('serverName'), parameters('databaseName'), 'default')]", "properties": { + "backupStorageAccessTier": "[parameters('backupStorageAccessTier')]", + "makeBackupsImmutable": "[parameters('makeBackupsImmutable')]", "monthlyRetention": "[parameters('monthlyRetention')]", "weeklyRetention": "[parameters('weeklyRetention')]", "weekOfYear": "[parameters('weekOfYear')]", "yearlyRetention": "[parameters('yearlyRetention')]" - } + }, + "dependsOn": [ + "server::database" + ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1642,50 +2885,50 @@ }, "mode": "Incremental", "parameters": { + "serverName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'tags'), parameters('tags'))]" + }, "name": { "value": "[parameters('elasticPools')[copyIndex()].name]" }, - "serverName": { - "value": "[parameters('name')]" + "sku": { + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'sku')]" }, - "databaseMaxCapacity": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'databaseMaxCapacity'), 2)]" + "autoPauseDelay": { + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'autoPauseDelay')]" }, - "databaseMinCapacity": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'databaseMinCapacity'), 0)]" + "availabilityZone": { + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'availabilityZone')]" }, "highAvailabilityReplicaCount": { "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'highAvailabilityReplicaCount')]" }, "licenseType": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'licenseType'), 'LicenseIncluded')]" + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'licenseType')]" }, "maintenanceConfigurationId": { "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'maintenanceConfigurationId')]" }, "maxSizeBytes": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'maxSizeBytes'), json('34359738368'))]" + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'maxSizeBytes')]" }, "minCapacity": { "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'minCapacity')]" }, - "skuCapacity": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'skuCapacity'), 2)]" + "perDatabaseSettings": { + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'perDatabaseSettings')]" }, - "skuName": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'skuName'), 'GP_Gen5')]" - }, - "skuTier": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'skuTier'), 'GeneralPurpose')]" + "preferredEnclaveType": { + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'preferredEnclaveType')]" }, "zoneRedundant": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'zoneRedundant'), true())]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'tags'), parameters('tags'))]" + "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'zoneRedundant')]" } }, "template": { @@ -1696,12 +2939,99 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "15389069656635651285" + "templateHash": "10024079638382167120" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", "owner": "Azure/module-maintainers" }, + "definitions": { + "elasticPoolPerDatabaseSettingsType": { + "type": "object", + "properties": { + "autoPauseDelay": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Auto Pause Delay for per database within pool." + } + }, + "maxCapacity": { + "type": "string", + "metadata": { + "description": "Required. The maximum capacity any one database can consume. Examples: '0.5', '2'." + } + }, + "minCapacity": { + "type": "string", + "metadata": { + "description": "Required. The minimum capacity all databases are guaranteed. Examples: '0.5', '1'." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The per database settings for the elastic pool." + } + }, + "elasticPoolSkuType": { + "type": "object", + "properties": { + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The capacity of the particular SKU." + } + }, + "family": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here." + } + }, + "name": { + "type": "string", + "allowedValues": [ + "BC_DC", + "BC_Gen5", + "BasicPool", + "GP_DC", + "GP_FSv2", + "GP_Gen5", + "HS_Gen5", + "HS_MOPRMS", + "HS_PRMS", + "PremiumPool", + "ServerlessPool", + "StandardPool" + ], + "metadata": { + "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3." + } + }, + "size": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Size of the particular SKU." + } + }, + "tier": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The elastic pool SKU." + } + } + }, "parameters": { "name": { "type": "string", @@ -1729,25 +3059,35 @@ "description": "Optional. Location for all resources." } }, - "skuCapacity": { - "type": "int", - "defaultValue": 2, + "sku": { + "$ref": "#/definitions/elasticPoolSkuType", + "defaultValue": { + "capacity": 2, + "name": "GP_Gen5", + "tier": "GeneralPurpose" + }, "metadata": { - "description": "Optional. Capacity of the particular SKU." + "description": "Optional. The elastic pool SKU." } }, - "skuName": { - "type": "string", - "defaultValue": "GP_Gen5", + "autoPauseDelay": { + "type": "int", + "defaultValue": -1, "metadata": { - "description": "Optional. The name of the SKU, typically, a letter + Number code, e.g. P3." + "description": "Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled." } }, - "skuTier": { + "availabilityZone": { "type": "string", - "defaultValue": "GeneralPurpose", + "allowedValues": [ + "1", + "2", + "3", + "NoPreference" + ], + "defaultValue": "NoPreference", "metadata": { - "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium." + "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to." } }, "highAvailabilityReplicaCount": { @@ -1789,18 +3129,26 @@ "description": "Optional. Minimal capacity that serverless pool will not shrink below, if not paused." } }, - "databaseMaxCapacity": { - "type": "int", - "defaultValue": 2, + "perDatabaseSettings": { + "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType", + "defaultValue": { + "autoPauseDelay": -1, + "maxCapacity": "2", + "minCapacity": "0" + }, "metadata": { - "description": "Optional. The maximum capacity any one database can consume." + "description": "Optional. The per database settings for the elastic pool." } }, - "databaseMinCapacity": { - "type": "int", - "defaultValue": 0, + "preferredEnclaveType": { + "type": "string", + "allowedValues": [ + "Default", + "VBS" + ], + "defaultValue": "Default", "metadata": { - "description": "Optional. The minimum capacity all databases are guaranteed." + "description": "Optional. Type of enclave requested on the elastic pool." } }, "zoneRedundant": { @@ -1824,21 +3172,17 @@ "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", - "sku": { - "capacity": "[parameters('skuCapacity')]", - "name": "[parameters('skuName')]", - "tier": "[parameters('skuTier')]" - }, + "sku": "[parameters('sku')]", "properties": { + "autoPauseDelay": "[parameters('autoPauseDelay')]", + "availabilityZone": "[parameters('availabilityZone')]", "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]", "licenseType": "[parameters('licenseType')]", "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]", "maxSizeBytes": "[parameters('maxSizeBytes')]", "minCapacity": "[parameters('minCapacity')]", - "perDatabaseSettings": { - "minCapacity": "[parameters('databaseMinCapacity')]", - "maxCapacity": "[parameters('databaseMaxCapacity')]" - }, + "perDatabaseSettings": "[if(not(empty(parameters('perDatabaseSettings'))), createObject('autoPauseDelay', tryGet(parameters('perDatabaseSettings'), 'autoPauseDelay'), 'maxCapacity', json(tryGet(parameters('perDatabaseSettings'), 'maxCapacity')), 'minCapacity', json(tryGet(parameters('perDatabaseSettings'), 'minCapacity'))), null())]", + "preferredEnclaveType": "[parameters('preferredEnclaveType')]", "zoneRedundant": "[parameters('zoneRedundant')]" }, "dependsOn": [ @@ -3473,7 +4817,7 @@ ] }, "server_audit_settings": { - "condition": "[not(empty(parameters('auditSettings')))]", + "condition": "[not(equals(parameters('auditSettings'), null()))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-Sql-AuditSettings', uniqueString(deployment().name, parameters('location')))]", @@ -3490,28 +4834,28 @@ "value": "[coalesce(tryGet(parameters('auditSettings'), 'name'), 'default')]" }, "state": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'state'), 'Disabled')]" + "value": "[tryGet(parameters('auditSettings'), 'state')]" }, "auditActionsAndGroups": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'auditActionsAndGroups'), createArray('BATCH_COMPLETED_GROUP', 'SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP', 'FAILED_DATABASE_AUTHENTICATION_GROUP'))]" + "value": "[tryGet(parameters('auditSettings'), 'auditActionsAndGroups')]" }, "isAzureMonitorTargetEnabled": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'isAzureMonitorTargetEnabled'), false())]" + "value": "[tryGet(parameters('auditSettings'), 'isAzureMonitorTargetEnabled')]" }, "isDevopsAuditEnabled": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'isDevopsAuditEnabled'), false())]" + "value": "[tryGet(parameters('auditSettings'), 'isDevopsAuditEnabled')]" }, "isManagedIdentityInUse": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'isManagedIdentityInUse'), false())]" + "value": "[tryGet(parameters('auditSettings'), 'isManagedIdentityInUse')]" }, "isStorageSecondaryKeyInUse": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'isStorageSecondaryKeyInUse'), false())]" + "value": "[tryGet(parameters('auditSettings'), 'isStorageSecondaryKeyInUse')]" }, "queueDelayMs": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'queueDelayMs'), 1000)]" + "value": "[tryGet(parameters('auditSettings'), 'queueDelayMs')]" }, "retentionDays": { - "value": "[coalesce(tryGet(parameters('auditSettings'), 'retentionDays'), 90)]" + "value": "[tryGet(parameters('auditSettings'), 'retentionDays')]" }, "storageAccountResourceId": { "value": "[tryGet(parameters('auditSettings'), 'storageAccountResourceId')]" @@ -3525,7 +4869,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "2456263707393734456" + "templateHash": "6303070680265885029" }, "name": "Azure SQL Server Audit Settings", "description": "This module deploys an Azure SQL Server Audit Settings.", @@ -3546,31 +4890,39 @@ }, "state": { "type": "string", + "defaultValue": "Enabled", "allowedValues": [ "Enabled", "Disabled" ], "metadata": { - "description": "Required. The resource group of the SQL Server. Required if the template is used in a standalone deployment." + "description": "Optional. Specifies the state of the audit. If state is Enabled, storageEndpoint or isAzureMonitorTargetEnabled are required." } }, "auditActionsAndGroups": { "type": "array", - "nullable": true, + "items": { + "type": "string" + }, + "defaultValue": [ + "BATCH_COMPLETED_GROUP", + "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP", + "FAILED_DATABASE_AUTHENTICATION_GROUP" + ], "metadata": { "description": "Optional. Specifies the Actions-Groups and Actions to audit." } }, "isAzureMonitorTargetEnabled": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { "description": "Optional. Specifies whether audit events are sent to Azure Monitor." } }, "isDevopsAuditEnabled": { "type": "bool", - "nullable": true, + "defaultValue": false, "metadata": { "description": "Optional. Specifies the state of devops audit. If state is Enabled, devops logs will be sent to Azure Monitor." } @@ -3584,21 +4936,21 @@ }, "isStorageSecondaryKeyInUse": { "type": "bool", - "nullable": true, + "defaultValue": false, "metadata": { "description": "Optional. Specifies whether storageAccountAccessKey value is the storage's secondary key." } }, "queueDelayMs": { "type": "int", - "nullable": true, + "defaultValue": 1000, "metadata": { "description": "Optional. Specifies the amount of time in milliseconds that can elapse before audit actions are forced to be processed." } }, "retentionDays": { "type": "int", - "nullable": true, + "defaultValue": 90, "metadata": { "description": "Optional. Specifies the number of days to keep in the audit logs in the storage account." } @@ -3752,11 +5104,11 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "16142913599202614386" + "templateHash": "13150358169332921706" } }, "definitions": { - "secretSetType": { + "secretSetOutputType": { "type": "object", "properties": { "secretResourceId": { @@ -3770,10 +5122,19 @@ "metadata": { "description": "The secret URI of the exported secret." } + }, + "secretUriWithVersion": { + "type": "string", + "metadata": { + "description": "The secret URI with version of the exported secret." + } } }, "metadata": { - "__bicep_export!": true + "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } } }, "secretToSetType": { @@ -3791,6 +5152,12 @@ "description": "Required. The value of the secret to set." } } + }, + "metadata": { + "description": "An AVM-aligned type for the secret to set via the secrets export feature.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } } } }, @@ -3838,7 +5205,7 @@ "secretsSet": { "type": "array", "items": { - "$ref": "#/definitions/secretSetType" + "$ref": "#/definitions/secretSetOutputType" }, "metadata": { "description": "The references to the secrets exported to the provided Key Vault." @@ -3847,7 +5214,8 @@ "count": "[length(range(0, length(coalesce(parameters('secretsToSet'), createArray()))))]", "input": { "secretResourceId": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretsToSet')[range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()]].name)]", - "secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]" + "secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]", + "secretUriWithVersion": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUriWithVersion]" } } } diff --git a/avm/res/sql/server/modules/keyVaultExport.bicep b/avm/res/sql/server/modules/keyVaultExport.bicep index c4ff7c2f9d..61c84e06a2 100644 --- a/avm/res/sql/server/modules/keyVaultExport.bicep +++ b/avm/res/sql/server/modules/keyVaultExport.bicep @@ -5,6 +5,7 @@ @description('Required. The name of the Key Vault to set the secrets in.') param keyVaultName string +import { secretToSetType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Required. The secrets to set in the Key Vault.') param secretsToSet secretToSetType[] @@ -30,33 +31,13 @@ resource secrets 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = [ // Outputs // // =========== // +import { secretSetOutputType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('The references to the secrets exported to the provided Key Vault.') -output secretsSet secretSetType[] = [ +output secretsSet secretSetOutputType[] = [ #disable-next-line outputs-should-not-contain-secrets // Only returning the references, not a secret value for index in range(0, length(secretsToSet ?? [])): { secretResourceId: secrets[index].id secretUri: secrets[index].properties.secretUri + secretUriWithVersion: secrets[index].properties.secretUriWithVersion } ] - -// =============== // -// Definitions // -// =============== // - -@export() -type secretSetType = { - @description('The resourceId of the exported secret.') - secretResourceId: string - - @description('The secret URI of the exported secret.') - secretUri: string -} - -type secretToSetType = { - @description('Required. The name of the secret to set.') - name: string - - @description('Required. The value of the secret to set.') - @secure() - value: string -} diff --git a/avm/res/sql/server/security-alert-policy/main.json b/avm/res/sql/server/security-alert-policy/main.json index 8ac3df6310..08cdceaee6 100644 --- a/avm/res/sql/server/security-alert-policy/main.json +++ b/avm/res/sql/server/security-alert-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6025191760768766090" + "version": "0.30.23.60470", + "templateHash": "15406914222375641032" }, "name": "Azure SQL Server Security Alert Policies", "description": "This module deploys an Azure SQL Server Security Alert Policy.", diff --git a/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep b/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep new file mode 100644 index 0000000000..9202a2fe6c --- /dev/null +++ b/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep @@ -0,0 +1,73 @@ +targetScope = 'subscription' + +metadata name = 'Using elastic pool' +metadata description = 'This instance deploys the module with an elastic pool.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-sql.servers-${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 = 'ssep' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@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 // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + administratorLogin: 'adminUserName' + administratorLoginPassword: password + elasticPools: [ + // bare minimum elastic pool: only a name is specified + { + name: '${namePrefix}-${serviceShort}-ep-001' + } + // more complex elastic pool with non-default SKU and per database settings + { + name: '${namePrefix}-${serviceShort}-ep-002' + sku: { + name: 'GP_Gen5' + tier: 'GeneralPurpose' + capacity: 4 + } + perDatabaseSettings: { + minCapacity: '0.5' + maxCapacity: '4' + } + } + ] + } + } +] diff --git a/avm/res/sql/server/tests/e2e/max/dependencies.bicep b/avm/res/sql/server/tests/e2e/max/dependencies.bicep index f2797af2b7..7bea7face2 100644 --- a/avm/res/sql/server/tests/e2e/max/dependencies.bicep +++ b/avm/res/sql/server/tests/e2e/max/dependencies.bicep @@ -60,7 +60,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { name: 'standard' } tenantId: tenant().tenantId - enablePurgeProtection: null + enablePurgeProtection: true // Required for encryption to work enabledForTemplateDeployment: true enabledForDiskEncryption: true enabledForDeployment: true diff --git a/avm/res/sql/server/tests/e2e/max/main.test.bicep b/avm/res/sql/server/tests/e2e/max/main.test.bicep index e95f51ae35..232c88c9cb 100644 --- a/avm/res/sql/server/tests/e2e/max/main.test.bicep +++ b/avm/res/sql/server/tests/e2e/max/main.test.bicep @@ -25,6 +25,9 @@ param password string = newGuid() @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + // ============ // // Dependencies // // ============ // @@ -40,7 +43,8 @@ module nestedDependencies 'dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-nestedDependencies' params: { - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' location: enforcedLocation @@ -113,18 +117,22 @@ module testDeployment '../../../main.bicep' = { elasticPools: [ { name: '${namePrefix}-${serviceShort}-ep-001' - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' - skuCapacity: 10 + sku: { + name: 'GP_Gen5' + tier: 'GeneralPurpose' + capacity: 10 + } } ] databases: [ { name: '${namePrefix}-${serviceShort}db-001' collation: 'SQL_Latin1_General_CP1_CI_AS' - skuTier: 'GeneralPurpose' - skuName: 'ElasticPool' - skuCapacity: 0 + sku: { + name: 'ElasticPool' + tier: 'GeneralPurpose' + capacity: 0 + } maxSizeBytes: 34359738368 licenseType: 'LicenseIncluded' diagnosticSettings: [ @@ -136,11 +144,7 @@ module testDeployment '../../../main.bicep' = { workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - elasticPoolId: '${resourceGroup.id}/providers/Microsoft.Sql/servers/${namePrefix}-${serviceShort}/elasticPools/${namePrefix}-${serviceShort}-ep-001' - encryptionProtectorObj: { - serverKeyType: 'AzureKeyVault' - serverKeyName: '${nestedDependencies.outputs.keyVaultName}_${nestedDependencies.outputs.keyVaultKeyName}_${last(split(nestedDependencies.outputs.keyVaultEncryptionKeyUrl, '/'))}' - } + elasticPoolResourceId: '${resourceGroup.id}/providers/Microsoft.Sql/servers/${namePrefix}-${serviceShort}/elasticPools/${namePrefix}-${serviceShort}-ep-001' backupShortTermRetentionPolicy: { retentionDays: 14 } @@ -149,6 +153,10 @@ module testDeployment '../../../main.bicep' = { } } ] + encryptionProtectorObj: { + serverKeyType: 'AzureKeyVault' + serverKeyName: '${nestedDependencies.outputs.keyVaultName}_${nestedDependencies.outputs.keyVaultKeyName}_${last(split(nestedDependencies.outputs.keyVaultEncryptionKeyUrl, '/'))}' + } firewallRules: [ { name: 'AllowAllWindowsAzureIps' diff --git a/avm/res/sql/server/tests/e2e/secondary/main.test.bicep b/avm/res/sql/server/tests/e2e/secondary/main.test.bicep index d86a8377b4..d2b8cfab0f 100644 --- a/avm/res/sql/server/tests/e2e/secondary/main.test.bicep +++ b/avm/res/sql/server/tests/e2e/secondary/main.test.bicep @@ -59,8 +59,10 @@ module testDeployment '../../../main.bicep' = { databases: [ { name: nestedDependencies.outputs.databaseName - skuTier: 'Basic' - skuName: 'Basic' + sku: { + name: 'Basic' + tier: 'Basic' + } maxSizeBytes: 2147483648 createMode: 'Secondary' sourceDatabaseResourceId: nestedDependencies.outputs.databaseResourceId diff --git a/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep index f2797af2b7..7bea7face2 100644 --- a/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/sql/server/tests/e2e/waf-aligned/dependencies.bicep @@ -60,7 +60,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { name: 'standard' } tenantId: tenant().tenantId - enablePurgeProtection: null + enablePurgeProtection: true // Required for encryption to work enabledForTemplateDeployment: true enabledForDiskEncryption: true enabledForDeployment: true diff --git a/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep b/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep index 3777c51c2c..a8da430a58 100644 --- a/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep @@ -21,6 +21,9 @@ param serviceShort string = 'sqlswaf' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + // ============ // // Dependencies // // ============ // @@ -36,7 +39,8 @@ module nestedDependencies 'dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, enforcedLocation)}-nestedDependencies' params: { - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' location: enforcedLocation @@ -88,9 +92,11 @@ module testDeployment '../../../main.bicep' = { elasticPools: [ { name: '${namePrefix}-${serviceShort}-ep-001' - skuName: 'GP_Gen5' - skuTier: 'GeneralPurpose' - skuCapacity: 10 + sku: { + name: 'GP_Gen5' + tier: 'GeneralPurpose' + capacity: 10 + } maintenanceConfigurationId: '${subscription().id}/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/SQL_${enforcedLocation}_DB_1' } ] @@ -98,9 +104,11 @@ module testDeployment '../../../main.bicep' = { { name: '${namePrefix}-${serviceShort}db-001' collation: 'SQL_Latin1_General_CP1_CI_AS' - skuTier: 'GeneralPurpose' - skuName: 'ElasticPool' - skuCapacity: 0 + sku: { + name: 'ElasticPool' + tier: 'GeneralPurpose' + capacity: 0 + } maxSizeBytes: 34359738368 licenseType: 'LicenseIncluded' diagnosticSettings: [ @@ -112,11 +120,7 @@ module testDeployment '../../../main.bicep' = { workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - elasticPoolId: '${resourceGroup.id}/providers/Microsoft.Sql/servers/${namePrefix}-${serviceShort}/elasticPools/${namePrefix}-${serviceShort}-ep-001' - encryptionProtectorObj: { - serverKeyType: 'AzureKeyVault' - serverKeyName: '${nestedDependencies.outputs.keyVaultName}_${nestedDependencies.outputs.keyVaultKeyName}_${last(split(nestedDependencies.outputs.keyVaultEncryptionKeyUrl, '/'))}' - } + elasticPoolResourceId: '${resourceGroup.id}/providers/Microsoft.Sql/servers/${namePrefix}-${serviceShort}/elasticPools/${namePrefix}-${serviceShort}-ep-001' backupShortTermRetentionPolicy: { retentionDays: 14 } @@ -125,6 +129,10 @@ module testDeployment '../../../main.bicep' = { } } ] + encryptionProtectorObj: { + serverKeyType: 'AzureKeyVault' + serverKeyName: '${nestedDependencies.outputs.keyVaultName}_${nestedDependencies.outputs.keyVaultKeyName}_${last(split(nestedDependencies.outputs.keyVaultEncryptionKeyUrl, '/'))}' + } securityAlertPolicies: [ { name: 'Default' diff --git a/avm/res/sql/server/version.json b/avm/res/sql/server/version.json index b8b30a0125..9c08aae215 100644 --- a/avm/res/sql/server/version.json +++ b/avm/res/sql/server/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.9", + "version": "0.10", "pathFilters": [ "./main.json" ] diff --git a/avm/res/sql/server/virtual-network-rule/main.json b/avm/res/sql/server/virtual-network-rule/main.json index 6e94f437e0..8aeb38250b 100644 --- a/avm/res/sql/server/virtual-network-rule/main.json +++ b/avm/res/sql/server/virtual-network-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "7859066741604114060" + "version": "0.30.23.60470", + "templateHash": "4969955763304077350" }, "name": "Azure SQL Server Virtual Network Rules", "description": "This module deploys an Azure SQL Server Virtual Network Rule.", diff --git a/avm/res/sql/server/vulnerability-assessment/main.json b/avm/res/sql/server/vulnerability-assessment/main.json index 431b5c318c..134adac324 100644 --- a/avm/res/sql/server/vulnerability-assessment/main.json +++ b/avm/res/sql/server/vulnerability-assessment/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5682596516926040129" + "version": "0.30.23.60470", + "templateHash": "11004049200994426011" }, "name": "Azure SQL Server Vulnerability Assessments", "description": "This module deploys an Azure SQL Server Vulnerability Assessment.", @@ -107,8 +107,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "17251889896692066430" + "version": "0.30.23.60470", + "templateHash": "13956215614091387428" } }, "parameters": { diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md index fef7c23475..607e1004b9 100644 --- a/avm/res/storage/storage-account/README.md +++ b/avm/res/storage/storage-account/README.md @@ -4484,6 +4484,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Notes diff --git a/avm/res/storage/storage-account/blob-service/README.md b/avm/res/storage/storage-account/blob-service/README.md index b64079b54a..464c506615 100644 --- a/avm/res/storage/storage-account/blob-service/README.md +++ b/avm/res/storage/storage-account/blob-service/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Blob Service. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -333,3 +334,11 @@ The blob service properties for blob restore policy. If point-in-time restore is | `name` | string | The name of the deployed blob service. | | `resourceGroupName` | string | The name of the deployed blob service. | | `resourceId` | string | The resource ID of the deployed blob service. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/blob-service/container/README.md b/avm/res/storage/storage-account/blob-service/container/README.md index 34d861e3b5..f90db350e2 100644 --- a/avm/res/storage/storage-account/blob-service/container/README.md +++ b/avm/res/storage/storage-account/blob-service/container/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Blob Container. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -265,3 +266,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the deployed container. | | `resourceGroupName` | string | The resource group of the deployed container. | | `resourceId` | string | The resource ID of the deployed container. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/file-service/README.md b/avm/res/storage/storage-account/file-service/README.md index 5056736875..3321ebe9ed 100644 --- a/avm/res/storage/storage-account/file-service/README.md +++ b/avm/res/storage/storage-account/file-service/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account File Share Service. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -231,3 +232,11 @@ File shares to create. | `name` | string | The name of the deployed file share service. | | `resourceGroupName` | string | The resource group of the deployed file share service. | | `resourceId` | string | The resource ID of the deployed file share service. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/file-service/share/README.md b/avm/res/storage/storage-account/file-service/share/README.md index 7cebc24570..ea95552ebd 100644 --- a/avm/res/storage/storage-account/file-service/share/README.md +++ b/avm/res/storage/storage-account/file-service/share/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account File Share. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -221,3 +222,11 @@ The maximum size of the share, in gigabytes. Must be greater than 0, and less th | `name` | string | The name of the deployed file share. | | `resourceGroupName` | string | The resource group of the deployed file share. | | `resourceId` | string | The resource ID of the deployed file share. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/queue-service/README.md b/avm/res/storage/storage-account/queue-service/README.md index e1b6b9ad41..5c8d2c0fbb 100644 --- a/avm/res/storage/storage-account/queue-service/README.md +++ b/avm/res/storage/storage-account/queue-service/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Queue Service. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -199,3 +200,11 @@ Queues to create. | `name` | string | The name of the deployed file share service. | | `resourceGroupName` | string | The resource group of the deployed file share service. | | `resourceId` | string | The resource ID of the deployed file share service. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/queue-service/queue/README.md b/avm/res/storage/storage-account/queue-service/queue/README.md index 901bd14104..da14c3e7ef 100644 --- a/avm/res/storage/storage-account/queue-service/queue/README.md +++ b/avm/res/storage/storage-account/queue-service/queue/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Queue. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -176,3 +177,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the deployed queue. | | `resourceGroupName` | string | The resource group of the deployed queue. | | `resourceId` | string | The resource ID of the deployed queue. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/table-service/README.md b/avm/res/storage/storage-account/table-service/README.md index e67f32ebfa..ba3f15b61d 100644 --- a/avm/res/storage/storage-account/table-service/README.md +++ b/avm/res/storage/storage-account/table-service/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Table Service. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -200,3 +201,11 @@ tables to create. | `name` | string | The name of the deployed table service. | | `resourceGroupName` | string | The resource group of the deployed table service. | | `resourceId` | string | The resource ID of the deployed table service. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/storage/storage-account/table-service/table/README.md b/avm/res/storage/storage-account/table-service/table/README.md index 63e5d835bf..8fda131b17 100644 --- a/avm/res/storage/storage-account/table-service/table/README.md +++ b/avm/res/storage/storage-account/table-service/table/README.md @@ -7,6 +7,7 @@ This module deploys a Storage Account Table. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -165,3 +166,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the deployed file share service. | | `resourceGroupName` | string | The resource group of the deployed file share service. | | `resourceId` | string | The resource ID of the deployed file share service. | + +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/synapse/private-link-hub/README.md b/avm/res/synapse/private-link-hub/README.md index db18dfbadc..8121cd395a 100644 --- a/avm/res/synapse/private-link-hub/README.md +++ b/avm/res/synapse/private-link-hub/README.md @@ -556,22 +556,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the Private Endpoint. | | [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the Private Endpoint to. | | [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | -| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS Zone Group to configure for the Private Endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -582,7 +582,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -622,7 +622,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -636,7 +636,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -700,7 +700,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -750,14 +750,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -766,7 +766,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -776,7 +776,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -791,7 +791,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -802,7 +802,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -823,7 +823,7 @@ The name of the private link connection to create. ### Parameter: `privateEndpoints.resourceGroupName` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +Specify if you want to deploy the Private Endpoint into a different Resource Group than the main resource. - Required: No - Type: string @@ -938,14 +938,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1077,6 +1077,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/synapse/private-link-hub/main.bicep b/avm/res/synapse/private-link-hub/main.bicep index b0669167de..578825e611 100644 --- a/avm/res/synapse/private-link-hub/main.bicep +++ b/avm/res/synapse/private-link-hub/main.bicep @@ -11,17 +11,20 @@ param location string = resourceGroup().location @description('Optional. Tags of the resource.') param tags object? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -177,128 +180,3 @@ output privateEndpoints array = [ networkInterfaceIds: privateLinkHub_privateEndpoints[i].outputs.networkInterfaceIds } ] - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? diff --git a/avm/res/synapse/private-link-hub/main.json b/avm/res/synapse/private-link-hub/main.json index 0f6e41099b..bdf7440ec8 100644 --- a/avm/res/synapse/private-link-hub/main.json +++ b/avm/res/synapse/private-link-hub/main.json @@ -6,330 +6,368 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "11580034515425711922" + "templateHash": "4249101597778316184" }, "name": "Azure Synapse Analytics", "description": "This module deploys an Azure Synapse Analytics (Private Link Hub).", "owner": "Azure/module-maintainers" }, "definitions": { - "lockType": { + "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { - "name": { + "fqdn": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. FQDN that resolves to private endpoint IP address." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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." + "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." + } } }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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": { + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + "description": "Optional. The name of the private DNS Zone Group config." } }, - "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." - } - } - } - }, + "privateDnsZoneResourceId": { + "type": "string", "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + "description": "Required. The resource id of the private DNS zone." } } - }, - "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": "Optional. 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." - } + "metadata": { + "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "privateEndpointSingleServiceType": { + "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\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "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": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } + "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" }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" }, - "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "roleAssignmentType": { + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -355,6 +393,7 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } @@ -367,13 +406,21 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index b3c6f94efb..0bc85c9350 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1422,7 +1422,7 @@ The diagnostic settings of the service. | [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | 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`](#parameter-diagnosticsettingseventhubname) | string | 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. | | [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | -| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | | [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | | [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | | [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | 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. | @@ -1458,7 +1458,7 @@ A string indicating whether the export to Log Analytics should use the default d ### Parameter: `diagnosticSettings.logCategoriesAndGroups` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. - Required: No - Type: array @@ -1468,7 +1468,8 @@ The name of logs that will be streamed. "allLogs" includes all possible logs for | Parameter | Type | Description | | :-- | :-- | :-- | | [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | -| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | ### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` @@ -1479,11 +1480,18 @@ Name of a Diagnostic Log category for a resource type this setting is applied to ### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` -Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs. +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. - Required: No - Type: string +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + ### Parameter: `diagnosticSettings.marketplacePartnerResourceId` The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. @@ -1643,11 +1651,11 @@ The managed identity definition for this resource. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. - Required: No - Type: array @@ -1687,7 +1695,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file". | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file" for a Storage Account's Private Endpoints. | | [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | **Optional parameters** @@ -1712,7 +1720,7 @@ Configuration details for private endpoints. For security reasons, it is recomme ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file". +The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file" for a Storage Account's Private Endpoints. - Required: Yes - Type: string @@ -1910,7 +1918,7 @@ The private DNS zone group to configure for the private endpoint. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. | **Optional parameters** @@ -1920,7 +1928,7 @@ The private DNS zone group to configure for the private endpoint. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` -The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones. - Required: Yes - Type: array @@ -1935,7 +1943,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1946,7 +1954,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -2255,6 +2263,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/synapse/workspace/administrators/main.json b/avm/res/synapse/workspace/administrators/main.json index bb9e0505cd..09e136c25e 100644 --- a/avm/res/synapse/workspace/administrators/main.json +++ b/avm/res/synapse/workspace/administrators/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "15890618337043813918" + "version": "0.30.23.60470", + "templateHash": "11234358964964275645" }, "name": "Synapse Workspaces Administrators", "description": "This module deploys Synapse Workspaces Administrators.", diff --git a/avm/res/synapse/workspace/firewall-rules/main.json b/avm/res/synapse/workspace/firewall-rules/main.json index ce7fd0baaa..628d2c6d98 100644 --- a/avm/res/synapse/workspace/firewall-rules/main.json +++ b/avm/res/synapse/workspace/firewall-rules/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6729418057172891787" + "version": "0.30.23.60470", + "templateHash": "1410907925603155251" }, "name": "Synapse Workspaces Firewall Rules", "description": "This module deploys Synapse Workspaces Firewall Rules.", diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json index 07711c9fcc..0b1fe277af 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.json +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "4134219125418987684" + "version": "0.30.23.60470", + "templateHash": "2875700223215345190" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index d98324c30c..704f8e78b6 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6170014210030770909" + "version": "0.30.23.60470", + "templateHash": "15229329511207297146" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 36f43b2715..0a27c87f95 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -32,10 +32,11 @@ param defaultDataLakeStorageFilesystem string param defaultDataLakeStorageCreateManagedPrivateEndpoint bool = false @description('Optional. The Entra ID administrator for the synapse workspace.') -param administrator adminType +param administrator administratorType? +import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The customer managed key definition.') -param customerManagedKey customerManagedKeyType +param customerManagedKey customerManagedKeyType? @description('Optional. Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace.') param encryptionActivateWorkspace bool = false @@ -85,20 +86,25 @@ param accountUrl string = 'https://${last(split(defaultDataLakeStorageAccountRes @description('Optional. Git integration settings.') param workspaceRepositoryConfiguration object? +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityOnlyUserAssignedType? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? +import { privateEndpointMultiServiceType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointMultiServiceType[]? +import { diagnosticSettingLogsOnlyType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingLogsOnlyType[]? // Variables @@ -253,7 +259,7 @@ module synapse_integrationRuntimes 'integration-runtime/main.bicep' = [ workspaceName: workspace.name name: integrationRuntime.name type: integrationRuntime.type - typeProperties: contains(integrationRuntime, 'typeProperties') ? integrationRuntime.typeProperties : {} + typeProperties: integrationRuntime.?typeProperties ?? {} } } ] @@ -453,179 +459,9 @@ output privateEndpoints array = [ // Definitions // // =============== // -type managedIdentitiesType = { - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourceIds: string[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Required. The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file".') - service: string - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The private DNS zone group to configure for the private endpoint.') - privateDnsZoneGroup: { - @description('Optional. The name of the Private DNS Zone Group.') - name: string? - - @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') - privateDnsZoneGroupConfigs: { - @description('Optional. The name of the private DNS zone group config.') - name: string? - - @description('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? - - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? - - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? - - @description('Optional. Custom DNS configurations.') - customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') - fqdn: string? - - @description('Required. A list of private IP addresses of the private endpoint.') - ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? - - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @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.') - categoryGroup: string? - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? - -type customerManagedKeyType = { - @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') - keyVaultResourceId: string - - @description('Required. The name of the customer managed key to use for encryption.') - keyName: string - - @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using \'latest\'.') - keyVersion: string? - - @description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') - userAssignedIdentityResourceId: string? -}? - -type adminType = { +@export() +@description('The synapse workspace administrator\'s interface.') +type administratorType = { @description('Required. Workspace active directory administrator type.') administratorType: string @@ -640,8 +476,10 @@ type adminType = { @description('Optional. Tenant ID of the workspace active directory administrator.') @secure() tenantId: string? -}? +} +@export() +@description('The synapse workspace firewall rule\'s interface.') type firewallRuleType = { @description('Required. The name of the firewall rule.') name: string diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index fe2f7f7090..860caa8682 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,518 +6,582 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "13977544414417545286" + "templateHash": "14298198840929360566" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "administratorType": { "type": "object", "properties": { - "userAssignedResourceIds": { - "type": "array", - "items": { - "type": "string" - }, + "administratorType": { + "type": "string", + "metadata": { + "description": "Required. Workspace active directory administrator type." + } + }, + "login": { + "type": "securestring", + "metadata": { + "description": "Required. Login of the workspace active directory administrator." + } + }, + "sid": { + "type": "securestring", + "metadata": { + "description": "Required. Object ID of the workspace active directory administrator." + } + }, + "tenantId": { + "type": "securestring", "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. Tenant ID of the workspace active directory administrator." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true, + "description": "The synapse workspace administrator's interface." + } }, - "lockType": { + "firewallRuleType": { "type": "object", "properties": { "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Required. The name of the firewall rule." } }, - "kind": { + "startIpAddress": { "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Required. The start IP address of the firewall rule. Must be IPv4 format." + } + }, + "endIpAddress": { + "type": "string", + "metadata": { + "description": "Required. The end IP address of the firewall rule. Must be IPv4 format. Must be greater than or equal to startIpAddress." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true, + "description": "The synapse workspace firewall rule's interface." + } }, - "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." - } + "_1.privateEndpointCustomDnsConfigType": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "privateEndpointType": { - "type": "array", - "items": { - "type": "object", + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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", - "metadata": { - "description": "Required. The subresource to deploy the private endpoint for. For example \"blob\", \"table\", \"queue\" or \"file\"." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + "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." + } } }, - "privateDnsZoneGroup": { + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + "description": "Optional. The name of the private DNS Zone Group config." } }, - "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." - } - } - } - }, + "privateDnsZoneResourceId": { + "type": "string", "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + "description": "Required. The resource id of the private DNS zone." } } - }, - "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": "Optional. 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." - } + "metadata": { + "description": "Required. The private DNS Zone Groups to associate the Private Endpoint. A DNS Zone Group can support up to 5 DNS zones." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a customer-managed key.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "diagnosticSettingLogsOnlyType": { + "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." } - } - }, - "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." - } + }, + "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." } - } - }, - "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." + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } } }, - "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, + "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 + "metadata": { + "description": "An AVM-aligned type for a diagnostic setting. To be used if only logs are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "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." - } - } - } - }, - "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." - } + "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." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "managedIdentityOnlyUserAssignedType": { + "type": "object", + "properties": { + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "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, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "customerManagedKeyType": { + "privateEndpointMultiServiceType": { "type": "object", "properties": { - "keyVaultResourceId": { + "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + "description": "Optional. The name of the private endpoint." } }, - "keyName": { + "location": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the customer managed key to use for encryption." + "description": "Optional. The location to deploy the private endpoint to." } }, - "keyVersion": { + "privateLinkServiceConnectionName": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + "description": "Optional. The name of the private link connection to create." } }, - "userAssignedIdentityResourceId": { + "service": { + "type": "string", + "metadata": { + "description": "Required. The subresource to deploy the private endpoint for. For example \"blob\", \"table\", \"queue\" or \"file\" for a Storage Account's Private Endpoints." + } + }, + "subnetResourceId": { "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } - } - }, - "nullable": true - }, - "adminType": { - "type": "object", - "properties": { - "administratorType": { + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { "type": "string", + "nullable": true, + "maxLength": 140, "metadata": { - "description": "Required. Workspace active directory administrator type." + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." } }, - "login": { - "type": "securestring", + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" + }, + "nullable": true, "metadata": { - "description": "Required. Login of the workspace active directory administrator." + "description": "Optional. Custom DNS configurations." } }, - "sid": { - "type": "securestring", + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" + }, + "nullable": true, "metadata": { - "description": "Required. Object ID of the workspace active directory administrator." + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." } }, - "tenantId": { - "type": "securestring", + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, "nullable": true, "metadata": { - "description": "Optional. Tenant ID of the workspace active directory administrator." + "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", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "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 + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can NOT be assumed (i.e., for services that have more than one subresource, like Storage Account with Blob (blob, table, queue, file, ...).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "firewallRuleType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the firewall rule." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "startIpAddress": { + "roleDefinitionIdOrName": { "type": "string", "metadata": { - "description": "Required. The start IP address of the firewall rule. Must be IPv4 format." + "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'." } }, - "endIpAddress": { + "principalId": { "type": "string", "metadata": { - "description": "Required. The end IP address of the firewall rule. Must be IPv4 format. Must be greater than or equal to startIpAddress." + "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." } } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } } } }, @@ -584,13 +648,15 @@ } }, "administrator": { - "$ref": "#/definitions/adminType", + "$ref": "#/definitions/administratorType", + "nullable": true, "metadata": { "description": "Optional. The Entra ID administrator for the synapse workspace." } }, "customerManagedKey": { "$ref": "#/definitions/customerManagedKeyType", + "nullable": true, "metadata": { "description": "Optional. The customer managed key definition." } @@ -701,31 +767,45 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointMultiServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingLogsOnlyType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -918,7 +998,9 @@ "type": { "value": "[parameters('integrationRuntimes')[copyIndex()].type]" }, - "typeProperties": "[if(contains(parameters('integrationRuntimes')[copyIndex()], 'typeProperties'), createObject('value', parameters('integrationRuntimes')[copyIndex()].typeProperties), createObject('value', createObject()))]" + "typeProperties": { + "value": "[coalesce(tryGet(parameters('integrationRuntimes')[copyIndex()], 'typeProperties'), createObject())]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", diff --git a/avm/res/virtual-machine-images/image-template/README.md b/avm/res/virtual-machine-images/image-template/README.md index 35506743de..139856eedf 100644 --- a/avm/res/virtual-machine-images/image-template/README.md +++ b/avm/res/virtual-machine-images/image-template/README.md @@ -8,6 +8,7 @@ This module deploys a Virtual Machine Image Template that can be consumed by Azu - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -58,14 +59,14 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' managedIdentities: { userAssignedResourceIds: [ '' ] } + name: 'vmiitmin001' + // Non-required parameters + location: '' } } ``` @@ -100,19 +101,19 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:" - }, "managedIdentities": { "value": { "userAssignedResourceIds": [ "" ] } + }, + "name": { + "value": "vmiitmin001" + }, + // Non-required parameters + "location": { + "value": "" } } } @@ -142,14 +143,14 @@ param imageSource = { type: 'PlatformImage' version: 'latest' } -param name = 'vmiitmin001' -// Non-required parameters -param location = '' param managedIdentities = { userAssignedResourceIds: [ '' ] } +param name = 'vmiitmin001' +// Non-required parameters +param location = '' ``` @@ -194,6 +195,11 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' + ] + } name: 'vmiitmax001' // Non-required parameters buildTimeoutInMinutes: 60 @@ -222,11 +228,6 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' - ] - } optimizeVmBoot: 'Enabled' osDiskSizeGB: 127 roleAssignments: [ @@ -318,6 +319,13 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:" + ] + } + }, "name": { "value": "vmiitmax001" }, @@ -356,13 +364,6 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:" - ] - } - }, "optimizeVmBoot": { "value": "Enabled" }, @@ -466,6 +467,11 @@ param imageSource = { type: 'PlatformImage' version: 'latest' } +param managedIdentities = { + userAssignedResourceIds: [ + '' + ] +} param name = 'vmiitmax001' // Non-required parameters param buildTimeoutInMinutes = 60 @@ -494,11 +500,6 @@ param lock = { kind: 'CanNotDelete' name: 'myCustomLockName' } -param managedIdentities = { - userAssignedResourceIds: [ - '' - ] -} param optimizeVmBoot = 'Enabled' param osDiskSizeGB = 127 param roleAssignments = [ @@ -576,6 +577,11 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' + ] + } name: 'vmiitwaf001' // Non-required parameters customizationSteps: [ @@ -585,11 +591,6 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:' - managedIdentities: { - userAssignedResourceIds: [ - '' - ] - } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -630,6 +631,13 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:" + ] + } + }, "name": { "value": "vmiitwaf001" }, @@ -645,13 +653,6 @@ module imageTemplate 'br/public:avm/res/virtual-machine-images/image-template:" }, - "managedIdentities": { - "value": { - "userAssignedResourceIds": [ - "" - ] - } - }, "subnetResourceId": { "value": "" }, @@ -690,6 +691,11 @@ param imageSource = { type: 'PlatformImage' version: 'latest' } +param managedIdentities = { + userAssignedResourceIds: [ + '' + ] +} param name = 'vmiitwaf001' // Non-required parameters param customizationSteps = [ @@ -699,11 +705,6 @@ param customizationSteps = [ } ] param location = '' -param managedIdentities = { - userAssignedResourceIds: [ - '' - ] -} param subnetResourceId = '' param tags = { Environment: 'Non-Prod' @@ -769,7 +770,7 @@ Image source definition in object format. The managed identity definition for this resource. -- Required: No +- Required: Yes - Type: object **Optional parameters** @@ -1174,6 +1175,14 @@ Do not provide a value! This date is used to generate a unique image template na | `resourceId` | string | The resource ID of the image template. | | `runThisCommand` | string | The command to run in order to trigger the image build. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | + ## Notes ### Parameter Usage: `imageSource` diff --git a/avm/res/virtual-machine-images/image-template/main.bicep b/avm/res/virtual-machine-images/image-template/main.bicep index e578df5309..e7f7de9f07 100644 --- a/avm/res/virtual-machine-images/image-template/main.bicep +++ b/avm/res/virtual-machine-images/image-template/main.bicep @@ -31,7 +31,7 @@ param customizationSteps array? @description('Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

    If this field is empty, a resource group with a random name will be created.

    If the resource group specified in this field doesn\'t exist, it will be created with the same name.

    If the resource group specified exists, it must be empty and in the same region as the image template.

    The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn\'t exist,

    but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain.') param stagingResourceGroupResourceId string? -import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.0' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') param lock lockType? @@ -44,7 +44,7 @@ param baseTime string = utcNow('yyyy-MM-dd-HH-mm-ss') @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? @@ -54,9 +54,9 @@ param distributions distributionType[] @description('Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the \'managedIdentities\' parameter must have the \'Managed Identity Operator\' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM.') param vmUserAssignedIdentities array = [] -import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.0' +import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Required. The managed identity definition for this resource.') -param managedIdentities managedIdentityOnlyUserAssignedType? +param managedIdentities managedIdentityOnlyUserAssignedType @description('Optional. Configuration options and list of validations to be performed on the resulting image.') param validationProcess validationProcessType? diff --git a/avm/res/virtual-machine-images/image-template/main.json b/avm/res/virtual-machine-images/image-template/main.json index b1470f143e..bd36673878 100644 --- a/avm/res/virtual-machine-images/image-template/main.json +++ b/avm/res/virtual-machine-images/image-template/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "11745682874369411361" + "templateHash": "9021236296601587261" }, "name": "Virtual Machine Image Templates", "description": "This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB).", @@ -333,7 +333,7 @@ "metadata": { "description": "An AVM-aligned type for a lock.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -354,7 +354,7 @@ "metadata": { "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } }, @@ -429,7 +429,7 @@ "metadata": { "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" } } } @@ -554,7 +554,6 @@ }, "managedIdentities": { "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", - "nullable": true, "metadata": { "description": "Required. The managed identity definition for this resource." } diff --git a/avm/res/web/connection/README.md b/avm/res/web/connection/README.md index a192ce132b..abc60ff2d9 100644 --- a/avm/res/web/connection/README.md +++ b/avm/res/web/connection/README.md @@ -13,6 +13,7 @@ This module deploys an Azure API Connection. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -687,6 +688,14 @@ Links to test the API connection. | `resourceGroupName` | string | The resource group the connection was deployed into. | | `resourceId` | string | The resource ID of the connection. | +## 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 | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.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/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index db51edfc25..a3f8796030 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -76,14 +76,16 @@ param parameterValues object? }) param parameterValueSet object? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. The status of the connection.') param statuses object[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @metadata({ example: ''' @@ -206,41 +208,3 @@ output name string = connection.name @description('The location the resource was deployed into.') output location string = connection.location - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @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\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @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".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index 0d5894685a..86912a1993 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1429787560788637007" + "version": "0.30.23.60470", + "templateHash": "15595731517219272130" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -36,80 +36,87 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, "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." - } + "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 + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -178,7 +185,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -195,6 +206,7 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } diff --git a/avm/res/web/hosting-environment/README.md b/avm/res/web/hosting-environment/README.md index 603da12c24..8866773fca 100644 --- a/avm/res/web/hosting-environment/README.md +++ b/avm/res/web/hosting-environment/README.md @@ -17,8 +17,8 @@ This module deploys an App Service Environment. | `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.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Web/hostingEnvironments` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/hostingEnvironments) | -| `Microsoft.Web/hostingEnvironments/configurations` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/hostingEnvironments/configurations) | +| `Microsoft.Web/hostingEnvironments` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/hostingEnvironments) | +| `Microsoft.Web/hostingEnvironments/configurations` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/hostingEnvironments/configurations) | ## Usage examples diff --git a/avm/res/web/hosting-environment/configuration--customdnssuffix/README.md b/avm/res/web/hosting-environment/configuration--customdnssuffix/README.md index bec42b448a..c49c8106ac 100644 --- a/avm/res/web/hosting-environment/configuration--customdnssuffix/README.md +++ b/avm/res/web/hosting-environment/configuration--customdnssuffix/README.md @@ -12,7 +12,7 @@ This module deploys a Hosting Environment Custom DNS Suffix Configuration. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/hostingEnvironments/configurations` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/hostingEnvironments/configurations) | +| `Microsoft.Web/hostingEnvironments/configurations` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/hostingEnvironments/configurations) | ## Parameters diff --git a/avm/res/web/site/README.md b/avm/res/web/site/README.md index 333e5cfddf..7e1a4a2b04 100644 --- a/avm/res/web/site/README.md +++ b/avm/res/web/site/README.md @@ -21,16 +21,16 @@ This module deploys a Web or Function App. | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `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.Web/sites` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/extensions) | -| `Microsoft.Web/sites/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/hybridConnectionNamespaces/relays) | -| `Microsoft.Web/sites/slots` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/slots) | -| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays) | +| `Microsoft.Web/sites` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites) | +| `Microsoft.Web/sites/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/basicPublishingCredentialsPolicies) | +| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/config) | +| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/extensions) | +| `Microsoft.Web/sites/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/hybridConnectionNamespaces/relays) | +| `Microsoft.Web/sites/slots` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots) | +| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/basicPublishingCredentialsPolicies) | +| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-09-01/sites/slots/config) | +| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/config) | +| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/hybridConnectionNamespaces/relays) | ## Usage examples diff --git a/avm/res/web/site/basic-publishing-credentials-policy/README.md b/avm/res/web/site/basic-publishing-credentials-policy/README.md index 032b8bc3f1..e5324dbcb1 100644 --- a/avm/res/web/site/basic-publishing-credentials-policy/README.md +++ b/avm/res/web/site/basic-publishing-credentials-policy/README.md @@ -12,7 +12,7 @@ This module deploys a Web Site Basic Publishing Credentials Policy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/basicPublishingCredentialsPolicies) | ## Parameters diff --git a/avm/res/web/site/config--appsettings/README.md b/avm/res/web/site/config--appsettings/README.md index db4a05b7d7..534da22e89 100644 --- a/avm/res/web/site/config--appsettings/README.md +++ b/avm/res/web/site/config--appsettings/README.md @@ -13,7 +13,7 @@ This module deploys a Site App Setting. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/config) | ## Parameters diff --git a/avm/res/web/site/config--authsettingsv2/README.md b/avm/res/web/site/config--authsettingsv2/README.md index f70a940831..2e46d48d19 100644 --- a/avm/res/web/site/config--authsettingsv2/README.md +++ b/avm/res/web/site/config--authsettingsv2/README.md @@ -12,7 +12,7 @@ This module deploys a Site Auth Settings V2 Configuration. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/config) | ## Parameters diff --git a/avm/res/web/site/config--logs/README.md b/avm/res/web/site/config--logs/README.md index 12ed9ed5ab..32a5167e71 100644 --- a/avm/res/web/site/config--logs/README.md +++ b/avm/res/web/site/config--logs/README.md @@ -12,7 +12,7 @@ This module deploys a Site logs Configuration. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/config) | ## Parameters diff --git a/avm/res/web/site/config--web/README.md b/avm/res/web/site/config--web/README.md index 11557f6693..3b3cf09561 100644 --- a/avm/res/web/site/config--web/README.md +++ b/avm/res/web/site/config--web/README.md @@ -12,7 +12,7 @@ This module deploys a Site Api Management Configuration. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/config) | ## Parameters diff --git a/avm/res/web/site/extensions--msdeploy/README.md b/avm/res/web/site/extensions--msdeploy/README.md index 5e606af88c..6b5415e2ac 100644 --- a/avm/res/web/site/extensions--msdeploy/README.md +++ b/avm/res/web/site/extensions--msdeploy/README.md @@ -12,7 +12,7 @@ This module deploys a Site extension for MSDeploy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/extensions) | +| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/extensions) | ## Parameters diff --git a/avm/res/web/site/hybrid-connection-namespace/relay/README.md b/avm/res/web/site/hybrid-connection-namespace/relay/README.md index 9ca8f11036..eb49bee22e 100644 --- a/avm/res/web/site/hybrid-connection-namespace/relay/README.md +++ b/avm/res/web/site/hybrid-connection-namespace/relay/README.md @@ -12,7 +12,7 @@ This module deploys a Site Hybrid Connection Namespace Relay. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/hybridConnectionNamespaces/relays) | +| `Microsoft.Web/sites/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/hybridConnectionNamespaces/relays) | ## Parameters diff --git a/avm/res/web/site/slot/README.md b/avm/res/web/site/slot/README.md index 99b234b7e0..e34643c5e3 100644 --- a/avm/res/web/site/slot/README.md +++ b/avm/res/web/site/slot/README.md @@ -20,12 +20,12 @@ This module deploys a Web or Function App Deployment Slot. | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `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.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/extensions) | -| `Microsoft.Web/sites/slots` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/slots) | -| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | -| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays) | +| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/extensions) | +| `Microsoft.Web/sites/slots` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots) | +| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/basicPublishingCredentialsPolicies) | +| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-09-01/sites/slots/config) | +| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/config) | +| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/hybridConnectionNamespaces/relays) | ## Parameters diff --git a/avm/res/web/site/slot/basic-publishing-credentials-policy/README.md b/avm/res/web/site/slot/basic-publishing-credentials-policy/README.md index bad6df0867..578bda4353 100644 --- a/avm/res/web/site/slot/basic-publishing-credentials-policy/README.md +++ b/avm/res/web/site/slot/basic-publishing-credentials-policy/README.md @@ -12,7 +12,7 @@ This module deploys a Web Site Slot Basic Publishing Credentials Policy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/basicPublishingCredentialsPolicies) | ## Parameters diff --git a/avm/res/web/site/slot/config--appsettings/README.md b/avm/res/web/site/slot/config--appsettings/README.md index a4eaf7b5e3..2bca1e1517 100644 --- a/avm/res/web/site/slot/config--appsettings/README.md +++ b/avm/res/web/site/slot/config--appsettings/README.md @@ -13,7 +13,7 @@ This module deploys a Site Slot App Setting. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/slots/config` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-09-01/sites/slots/config) | ## Parameters diff --git a/avm/res/web/site/slot/config--authsettingsv2/README.md b/avm/res/web/site/slot/config--authsettingsv2/README.md index 29b1a3c545..8efa659e21 100644 --- a/avm/res/web/site/slot/config--authsettingsv2/README.md +++ b/avm/res/web/site/slot/config--authsettingsv2/README.md @@ -12,7 +12,7 @@ This module deploys a Site Auth Settings V2 Configuration. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) | +| `Microsoft.Web/sites/slots/config` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/config) | ## Parameters diff --git a/avm/res/web/site/slot/extensions--msdeploy/README.md b/avm/res/web/site/slot/extensions--msdeploy/README.md index f52c7e19c3..62bcdb5f31 100644 --- a/avm/res/web/site/slot/extensions--msdeploy/README.md +++ b/avm/res/web/site/slot/extensions--msdeploy/README.md @@ -12,7 +12,7 @@ This module deploys a Site extension for MSDeploy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/extensions) | +| `Microsoft.Web/sites/extensions` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/extensions) | ## Parameters diff --git a/avm/res/web/site/slot/hybrid-connection-namespace/relay/README.md b/avm/res/web/site/slot/hybrid-connection-namespace/relay/README.md index 05370af739..7e4e8b6a41 100644 --- a/avm/res/web/site/slot/hybrid-connection-namespace/relay/README.md +++ b/avm/res/web/site/slot/hybrid-connection-namespace/relay/README.md @@ -12,7 +12,7 @@ This module deploys a Site Slot Hybrid Connection Namespace Relay. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays) | +| `Microsoft.Web/sites/slots/hybridConnectionNamespaces/relays` | [2023-12-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2023-12-01/sites/slots/hybridConnectionNamespaces/relays) | ## Parameters diff --git a/avm/res/web/static-site/README.md b/avm/res/web/static-site/README.md index 0fc8ad5a31..a8e07b95db 100644 --- a/avm/res/web/static-site/README.md +++ b/avm/res/web/static-site/README.md @@ -20,7 +20,7 @@ This module deploys a Static Web App. | `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.Web/staticSites` | [2021-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2021-03-01/staticSites) | -| `Microsoft.Web/staticSites/config` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/staticSites/config) | +| `Microsoft.Web/staticSites/config` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-03-01/staticSites/config) | | `Microsoft.Web/staticSites/customDomains` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-03-01/staticSites/customDomains) | | `Microsoft.Web/staticSites/linkedBackends` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-03-01/staticSites/linkedBackends) | diff --git a/avm/res/web/static-site/config/README.md b/avm/res/web/static-site/config/README.md index d3c33bfabe..b129d6c357 100644 --- a/avm/res/web/static-site/config/README.md +++ b/avm/res/web/static-site/config/README.md @@ -12,7 +12,7 @@ This module deploys a Static Web App Site Config. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Web/staticSites/config` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/staticSites/config) | +| `Microsoft.Web/staticSites/config` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Web/2022-03-01/staticSites/config) | ## Parameters diff --git a/avm/utilities/pipelines/sharedScripts/helper/Get-CrossReferencedModuleList.ps1 b/avm/utilities/pipelines/sharedScripts/helper/Get-CrossReferencedModuleList.ps1 index ec32409602..00e5617b17 100644 --- a/avm/utilities/pipelines/sharedScripts/helper/Get-CrossReferencedModuleList.ps1 +++ b/avm/utilities/pipelines/sharedScripts/helper/Get-CrossReferencedModuleList.ps1 @@ -92,7 +92,7 @@ function Get-ReferenceObject { $moduleContent = $TemplateMap[$involvedFilePath] $resultSet.resourceReferences += @() + $moduleContent | Where-Object { $_ -match "^resource .+ '(.+?)' .+$" } | ForEach-Object { $matches[1] } - $resultSet.remoteReferences += @() + $moduleContent | Where-Object { $_ -match "^module .+ '(.+:.+?)' .+$" } | ForEach-Object { $matches[1] } + $resultSet.remoteReferences += @() + $moduleContent | Where-Object { $_ -match "^module .+ '(.+:.+?)' .+$" -or $_ -match "^import .+ '(.+:.+?)'$" } | ForEach-Object { $matches[1] } } return @{ diff --git a/avm/utl/types/avm-common-types/README.md b/avm/utl/types/avm-common-types/README.md index 26bc5bfc2b..286bde8c8d 100644 --- a/avm/utl/types/avm-common-types/README.md +++ b/avm/utl/types/avm-common-types/README.md @@ -54,6 +54,7 @@ Note: In your module you would import only the types you need. import { customerManagedKeyType + customerManagedKeyWithAutoRotateType diagnosticSettingFullType diagnosticSettingLogsOnlyType diagnosticSettingMetricsOnlyType @@ -297,6 +298,14 @@ param customerManagedKeyDefaults customerManagedKeyType = { } output customerManagedKeyDefaultsOutput customerManagedKeyType = customerManagedKeyDefaults +param customerManagedKeyWithAutoRotate customerManagedKeyWithAutoRotateType = { + keyName: 'myKey' + keyVaultResourceId: '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.KeyVault/vaults/myVault' + autoRotationDisabled: true + userAssignedIdentityResourceId: '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity' +} +output customerManagedKeyWithAutoRotateOutput customerManagedKeyWithAutoRotateType = customerManagedKeyWithAutoRotate + // ================== // // Secrets Export // // ================== // diff --git a/avm/utl/types/avm-common-types/main.bicep b/avm/utl/types/avm-common-types/main.bicep index ea0706103f..0fb1f0bbc8 100644 --- a/avm/utl/types/avm-common-types/main.bicep +++ b/avm/utl/types/avm-common-types/main.bicep @@ -362,7 +362,7 @@ type privateEndpointMultiServiceType = { // ======================== // @export() -@description('An AVM-aligned type for a customer-managed key.') +@description('An AVM-aligned type for a customer-managed key. To be used if the resource type does not support auto-rotation of the customer-managed key.') type customerManagedKeyType = { @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') keyVaultResourceId: string @@ -370,13 +370,32 @@ type customerManagedKeyType = { @description('Required. The name of the customer managed key to use for encryption.') keyName: string - @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using \'latest\'.') + @description('Optional. The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time.') keyVersion: string? @description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') userAssignedIdentityResourceId: string? } +@export() +@description('An AVM-aligned type for a customer-managed key. To be used if the resource type supports auto-rotation of the customer-managed key.') +type customerManagedKeyWithAutoRotateType = { + @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') + keyVaultResourceId: string + + @description('Required. The name of the customer managed key to use for encryption.') + keyName: string + + @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using version as per \'autoRotationDisabled\' setting.') + keyVersion: string? + + @description('Optional. If configured, instead of auto-rotating to the latest key version, the latest key version at the time of the deployment is used.') + autoRotationDisabled: bool? + + @description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') + userAssignedIdentityResourceId: string? +} + // ================== // // Secrets Export // // ================== // diff --git a/avm/utl/types/avm-common-types/main.json b/avm/utl/types/avm-common-types/main.json index 85969026ff..f13c5001d0 100644 --- a/avm/utl/types/avm-common-types/main.json +++ b/avm/utl/types/avm-common-types/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "10247512052602214331" + "templateHash": "18359033509174375913" }, "name": "Default interface types for AVM modules", "description": "This module provides you with all common variants for AVM interfaces to be used in AVM modules.\n\nDetails for how to implement these interfaces can be found in the AVM documentation [here](https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces).\n", @@ -869,7 +869,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time." } }, "userAssignedIdentityResourceId": { @@ -882,7 +882,49 @@ }, "metadata": { "__bicep_export!": true, - "description": "An AVM-aligned type for a customer-managed key." + "description": "An AVM-aligned type for a customer-managed key. To be used if the resource type does not support auto-rotation of the customer-managed key." + } + }, + "customerManagedKeyWithAutoRotateType": { + "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 version as per 'autoRotationDisabled' setting." + } + }, + "autoRotationDisabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If configured, instead of auto-rotating to the latest key version, the latest key version at the time of the deployment is used." + } + }, + "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." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "An AVM-aligned type for a customer-managed key. To be used if the resource type supports auto-rotation of the customer-managed key." } }, "secretToSetType": { diff --git a/avm/utl/types/avm-common-types/tests/e2e/import/main.test.bicep b/avm/utl/types/avm-common-types/tests/e2e/import/main.test.bicep index dd580dec93..f6a755034d 100644 --- a/avm/utl/types/avm-common-types/tests/e2e/import/main.test.bicep +++ b/avm/utl/types/avm-common-types/tests/e2e/import/main.test.bicep @@ -13,6 +13,7 @@ Note: In your module you would import only the types you need. import { customerManagedKeyType + customerManagedKeyWithAutoRotateType diagnosticSettingFullType diagnosticSettingLogsOnlyType diagnosticSettingMetricsOnlyType @@ -256,6 +257,14 @@ param customerManagedKeyDefaults customerManagedKeyType = { } output customerManagedKeyDefaultsOutput customerManagedKeyType = customerManagedKeyDefaults +param customerManagedKeyWithAutoRotate customerManagedKeyWithAutoRotateType = { + keyName: 'myKey' + keyVaultResourceId: '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.KeyVault/vaults/myVault' + autoRotationDisabled: true + userAssignedIdentityResourceId: '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity' +} +output customerManagedKeyWithAutoRotateOutput customerManagedKeyWithAutoRotateType = customerManagedKeyWithAutoRotate + // ================== // // Secrets Export // // ================== // diff --git a/avm/utl/types/avm-common-types/version.json b/avm/utl/types/avm-common-types/version.json index 1c035df49f..c177b1bb58 100644 --- a/avm/utl/types/avm-common-types/version.json +++ b/avm/utl/types/avm-common-types/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.2", + "version": "0.3", "pathFilters": [ "./main.json" ]