From 244ce5f139121cb016de17ed630b5da96feb25c1 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 4 Feb 2025 13:08:54 +0100 Subject: [PATCH 01/31] fix: CDN Profile - Updated JSON templates to latest (#4371) ## Description Regenerated JSON files to latest Closes #4310 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.cdn.profile](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cdn.profile.yml/badge.svg?branch=users%2Falsehr%2FcdnStaticFix&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cdn.profile.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [x] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/cdn/profile/afdEndpoint/main.json | 12 ++++++------ avm/res/cdn/profile/afdEndpoint/route/main.json | 8 ++++---- avm/res/cdn/profile/customdomain/main.json | 4 ++-- avm/res/cdn/profile/endpoint/main.json | 8 ++++---- avm/res/cdn/profile/endpoint/origin/main.json | 4 ++-- avm/res/cdn/profile/origingroup/main.json | 8 ++++---- avm/res/cdn/profile/origingroup/origin/main.json | 4 ++-- avm/res/cdn/profile/ruleset/main.json | 8 ++++---- avm/res/cdn/profile/ruleset/rule/main.json | 4 ++-- avm/res/cdn/profile/secret/main.json | 4 ++-- avm/res/cdn/profile/securityPolicies/main.json | 4 ++-- 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/avm/res/cdn/profile/afdEndpoint/main.json b/avm/res/cdn/profile/afdEndpoint/main.json index 72c91e3d9c..4488626a0a 100644 --- a/avm/res/cdn/profile/afdEndpoint/main.json +++ b/avm/res/cdn/profile/afdEndpoint/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13135731354374453249" + "version": "0.33.13.18514", + "templateHash": "8177824551774407436" }, "name": "CDN Profiles AFD Endpoints", "description": "This module deploys a CDN Profile AFD Endpoint." @@ -379,8 +379,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14731142764965944373" + "version": "0.33.13.18514", + "templateHash": "5263422487313973220" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route." @@ -676,7 +676,7 @@ }, "profile::customDomains": { "copy": { - "name": "customDomains", + "name": "profile::customDomains", "count": "[length(coalesce(parameters('customDomainNames'), createArray()))]" }, "existing": true, @@ -692,7 +692,7 @@ }, "profile::ruleSet": { "copy": { - "name": "ruleSet", + "name": "profile::ruleSet", "count": "[length(parameters('ruleSets'))]" }, "existing": true, diff --git a/avm/res/cdn/profile/afdEndpoint/route/main.json b/avm/res/cdn/profile/afdEndpoint/route/main.json index 12e7f0fd39..4e74441ce2 100644 --- a/avm/res/cdn/profile/afdEndpoint/route/main.json +++ b/avm/res/cdn/profile/afdEndpoint/route/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14731142764965944373" + "version": "0.33.13.18514", + "templateHash": "5263422487313973220" }, "name": "CDN Profiles AFD Endpoint Route", "description": "This module deploys a CDN Profile AFD Endpoint route." @@ -302,7 +302,7 @@ }, "profile::customDomains": { "copy": { - "name": "customDomains", + "name": "profile::customDomains", "count": "[length(coalesce(parameters('customDomainNames'), createArray()))]" }, "existing": true, @@ -318,7 +318,7 @@ }, "profile::ruleSet": { "copy": { - "name": "ruleSet", + "name": "profile::ruleSet", "count": "[length(parameters('ruleSets'))]" }, "existing": true, diff --git a/avm/res/cdn/profile/customdomain/main.json b/avm/res/cdn/profile/customdomain/main.json index b67a95697c..e01089b617 100644 --- a/avm/res/cdn/profile/customdomain/main.json +++ b/avm/res/cdn/profile/customdomain/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "10872254821030072983" + "version": "0.33.13.18514", + "templateHash": "13058047826352389276" }, "name": "CDN Profiles Custom Domains", "description": "This module deploys a CDN Profile Custom Domains." diff --git a/avm/res/cdn/profile/endpoint/main.json b/avm/res/cdn/profile/endpoint/main.json index 39625fe6cf..0b018844c8 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.32.4.45862", - "templateHash": "9549854961484064285" + "version": "0.33.13.18514", + "templateHash": "9667828946590224838" }, "name": "CDN Profiles Endpoints", "description": "This module deploys a CDN Profile Endpoint." @@ -121,8 +121,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13720707069401173773" + "version": "0.33.13.18514", + "templateHash": "14207274905612158052" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin." diff --git a/avm/res/cdn/profile/endpoint/origin/main.json b/avm/res/cdn/profile/endpoint/origin/main.json index 8ef6b9b8de..8bc265c6d1 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.32.4.45862", - "templateHash": "13720707069401173773" + "version": "0.33.13.18514", + "templateHash": "14207274905612158052" }, "name": "CDN Profiles Endpoints Origins", "description": "This module deploys a CDN Profile Endpoint Origin." diff --git a/avm/res/cdn/profile/origingroup/main.json b/avm/res/cdn/profile/origingroup/main.json index 9eb9c10590..41d03567cc 100644 --- a/avm/res/cdn/profile/origingroup/main.json +++ b/avm/res/cdn/profile/origingroup/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2255246560564651285" + "version": "0.33.13.18514", + "templateHash": "2309166106272805364" }, "name": "CDN Profiles Origin Group", "description": "This module deploys a CDN Profile Origin Group." @@ -348,8 +348,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12548128435491978362" + "version": "0.33.13.18514", + "templateHash": "4615820934914726240" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin." diff --git a/avm/res/cdn/profile/origingroup/origin/main.json b/avm/res/cdn/profile/origingroup/origin/main.json index a9fa5174b7..b29157deac 100644 --- a/avm/res/cdn/profile/origingroup/origin/main.json +++ b/avm/res/cdn/profile/origingroup/origin/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12548128435491978362" + "version": "0.33.13.18514", + "templateHash": "4615820934914726240" }, "name": "CDN Profiles Origin", "description": "This module deploys a CDN Profile Origin." diff --git a/avm/res/cdn/profile/ruleset/main.json b/avm/res/cdn/profile/ruleset/main.json index b054deabe1..ee63159840 100644 --- a/avm/res/cdn/profile/ruleset/main.json +++ b/avm/res/cdn/profile/ruleset/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16187656524256202445" + "version": "0.33.13.18514", + "templateHash": "832720268679200418" }, "name": "CDN Profiles Rule Sets", "description": "This module deploys a CDN Profile rule set." @@ -163,8 +163,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5126669469544382460" + "version": "0.33.13.18514", + "templateHash": "4778641008462766741" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule." diff --git a/avm/res/cdn/profile/ruleset/rule/main.json b/avm/res/cdn/profile/ruleset/rule/main.json index 033b5142b0..f25b854d45 100644 --- a/avm/res/cdn/profile/ruleset/rule/main.json +++ b/avm/res/cdn/profile/ruleset/rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5126669469544382460" + "version": "0.33.13.18514", + "templateHash": "4778641008462766741" }, "name": "CDN Profiles Rules", "description": "This module deploys a CDN Profile rule." diff --git a/avm/res/cdn/profile/secret/main.json b/avm/res/cdn/profile/secret/main.json index d8b71fd8f7..15711095a9 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.32.4.45862", - "templateHash": "8122410068056305563" + "version": "0.33.13.18514", + "templateHash": "6185880578813937844" }, "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 564f7be3be..ba9e21e315 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.32.4.45862", - "templateHash": "11785514765749998247" + "version": "0.33.13.18514", + "templateHash": "9521724516599685420" }, "name": "CDN Profiles Security Policy", "description": "This module deploys a CDN Profile Security Policy." From f836d252b9268eb8b7a484b7d83c1f8bf05db6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Pei=C3=9Fker?= <30857628+JPEasier@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:35:50 +0100 Subject: [PATCH 02/31] feat: Add NginxIngressController configuration for web application routing (#4362) --- .../managed-cluster/README.md | 29 +++++++++++++++---- .../managed-cluster/main.bicep | 16 +++++++++- .../managed-cluster/main.json | 24 +++++++++++---- .../tests/e2e/automatic/main.test.bicep | 2 +- .../managed-cluster/version.json | 2 +- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/avm/res/container-service/managed-cluster/README.md b/avm/res/container-service/managed-cluster/README.md index ae2c4fa7f7..23210a0d1b 100644 --- a/avm/res/container-service/managed-cluster/README.md +++ b/avm/res/container-service/managed-cluster/README.md @@ -17,7 +17,7 @@ This module deploys an Azure Kubernetes Service (AKS) Managed Cluster. | :-- | :-- | | `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.ContainerService/managedClusters` | [2024-03-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerService/2024-03-02-preview/managedClusters) | +| `Microsoft.ContainerService/managedClusters` | [2024-09-02-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerService/2024-09-02-preview/managedClusters) | | `Microsoft.ContainerService/managedClusters/agentPools` | [2024-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerService/2024-08-01/managedClusters/agentPools) | | `Microsoft.ContainerService/managedClusters/maintenanceConfigurations` | [2023-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerService/2023-10-01/managedClusters/maintenanceConfigurations) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | @@ -76,11 +76,11 @@ module managedCluster 'br/public:avm/res/container-service/managed-cluster: Date: Tue, 4 Feb 2025 21:34:20 +0100 Subject: [PATCH 03/31] fix: Update `avm/res/container-service/managed-cluster` - Latest cross-referenced modules (#4372) ## Description Common types update Cross reference to latest kubernetes-configuration resources ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.container-service.managed-cluster](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-service.managed-cluster.yml/badge.svg?branch=users%2Ferikag%2Faks_types_kube&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-service.managed-cluster.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [ ] I'm sure there are no other open Pull Requests for the same update/change - [ ] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../managed-cluster/README.md | 21 ++++++-- .../managed-cluster/agent-pool/main.json | 4 +- .../managed-cluster/main.bicep | 10 ++-- .../managed-cluster/main.json | 49 +++++++++---------- .../maintenance-configurations/main.json | 4 +- .../tests/e2e/azure/main.test.bicep | 5 ++ .../managed-cluster/version.json | 2 +- 7 files changed, 55 insertions(+), 40 deletions(-) diff --git a/avm/res/container-service/managed-cluster/README.md b/avm/res/container-service/managed-cluster/README.md index 23210a0d1b..10bcd4bb73 100644 --- a/avm/res/container-service/managed-cluster/README.md +++ b/avm/res/container-service/managed-cluster/README.md @@ -22,7 +22,7 @@ This module deploys an Azure Kubernetes Service (AKS) Managed Cluster. | `Microsoft.ContainerService/managedClusters/maintenanceConfigurations` | [2023-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ContainerService/2023-10-01/managedClusters/maintenanceConfigurations) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.KubernetesConfiguration/extensions` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KubernetesConfiguration/2022-03-01/extensions) | -| `Microsoft.KubernetesConfiguration/fluxConfigurations` | [2022-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KubernetesConfiguration/2022-03-01/fluxConfigurations) | +| `Microsoft.KubernetesConfiguration/fluxConfigurations` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KubernetesConfiguration/2023-05-01/fluxConfigurations) | ## Usage examples @@ -416,6 +416,11 @@ module managedCluster 'br/public:avm/res/container-service/managed-cluster: Date: Tue, 4 Feb 2025 23:46:50 +0100 Subject: [PATCH 04/31] fix: NetApp - Added missing param passthru (#4365) ## Description Added missing param passthru Updated API version RemotePath property added for migration cc: @Salima-90 (thanks for raising the issue) ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.net-app.net-app-account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.net-app.net-app-account.yml/badge.svg?branch=users%2Falsehr%2FnetAppMissingVolumeType&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.net-app.net-app-account.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [x] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/net-app/net-app-account/README.md | 60 ++++++- .../net-app-account/backup-policies/README.md | 2 +- .../backup-policies/main.bicep | 4 +- .../net-app-account/backup-policies/main.json | 4 +- .../net-app-account/backup-vault/README.md | 4 +- .../backup-vault/backup/README.md | 2 +- .../backup-vault/backup/main.bicep | 8 +- .../backup-vault/backup/main.json | 10 +- .../net-app-account/backup-vault/main.bicep | 4 +- .../net-app-account/backup-vault/main.json | 18 +- .../net-app-account/capacity-pool/README.md | 52 +++++- .../net-app-account/capacity-pool/main.bicep | 8 + .../net-app-account/capacity-pool/main.json | 86 ++++++++- .../capacity-pool/volume/README.md | 44 ++++- .../capacity-pool/volume/main.bicep | 15 +- .../capacity-pool/volume/main.json | 35 +++- avm/res/net-app/net-app-account/main.bicep | 2 +- avm/res/net-app/net-app-account/main.json | 166 +++++++++++++++--- 18 files changed, 450 insertions(+), 74 deletions(-) diff --git a/avm/res/net-app/net-app-account/README.md b/avm/res/net-app/net-app-account/README.md index ced70ad857..514345e5bc 100644 --- a/avm/res/net-app/net-app-account/README.md +++ b/avm/res/net-app/net-app-account/README.md @@ -17,12 +17,12 @@ This module deploys an Azure NetApp File. | :-- | :-- | | `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.NetApp/netAppAccounts` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts) | -| `Microsoft.NetApp/netAppAccounts/backupPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupPolicies) | -| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults) | -| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | +| `Microsoft.NetApp/netAppAccounts` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts) | +| `Microsoft.NetApp/netAppAccounts/backupPolicies` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupPolicies) | +| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupVaults) | +| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupVaults/backups) | | `Microsoft.NetApp/netAppAccounts/capacityPools` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools) | -| `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools/volumes) | +| `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/capacityPools/volumes) | | `Microsoft.NetApp/netAppAccounts/snapshotPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/snapshotPolicies) | ## Usage examples @@ -1633,6 +1633,7 @@ List of volumes to create in the capacity pool. | [`smbContinuouslyAvailable`](#parameter-capacitypoolsvolumessmbcontinuouslyavailable) | bool | Enables continuously available share property for SMB volume. Only applicable for SMB volume. | | [`smbEncryption`](#parameter-capacitypoolsvolumessmbencryption) | bool | Enables SMB encryption. Only applicable for SMB/DualProtocol volume. | | [`smbNonBrowsable`](#parameter-capacitypoolsvolumessmbnonbrowsable) | string | Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. | +| [`volumeType`](#parameter-capacitypoolsvolumesvolumetype) | string | The type of the volume. DataProtection volumes are used for replication. | | [`zones`](#parameter-capacitypoolsvolumeszones) | array | Zone where the volume will be placed. | ### Parameter: `capacityPools.volumes.name` @@ -1751,6 +1752,12 @@ Replication properties. | [`remoteVolumeResourceId`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | | [`replicationSchedule`](#parameter-capacitypoolsvolumesdataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`remotePath`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotepath) | object | The full path to a volume that is to be migrated into ANF. Required for Migration volumes. | + ### Parameter: `capacityPools.volumes.dataProtection.replication.endpointType` Indicates whether the local volume is the source or destination for the Volume Replication. @@ -1794,6 +1801,42 @@ The replication schedule for the volume. ] ``` +### Parameter: `capacityPools.volumes.dataProtection.replication.remotePath` + +The full path to a volume that is to be migrated into ANF. Required for Migration volumes. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`externalHostName`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotepathexternalhostname) | string | The Path to a ONTAP Host. | +| [`serverName`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotepathservername) | string | The name of a server on the ONTAP Host. | +| [`volumeName`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotepathvolumename) | string | The name of a volume on the server. | + +### Parameter: `capacityPools.volumes.dataProtection.replication.remotePath.externalHostName` + +The Path to a ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.replication.remotePath.serverName` + +The name of a server on the ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.replication.remotePath.volumeName` + +The name of a volume on the server. + +- Required: Yes +- Type: string + ### Parameter: `capacityPools.volumes.dataProtection.snapshot` Snapshot properties. @@ -2169,6 +2212,13 @@ Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProto ] ``` +### Parameter: `capacityPools.volumes.volumeType` + +The type of the volume. DataProtection volumes are used for replication. + +- Required: No +- Type: string + ### Parameter: `capacityPools.volumes.zones` Zone where the volume will be placed. diff --git a/avm/res/net-app/net-app-account/backup-policies/README.md b/avm/res/net-app/net-app-account/backup-policies/README.md index f575f4f788..a4a644ab10 100644 --- a/avm/res/net-app/net-app-account/backup-policies/README.md +++ b/avm/res/net-app/net-app-account/backup-policies/README.md @@ -12,7 +12,7 @@ This module deploys a Backup Policy for Azure NetApp File. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.NetApp/netAppAccounts/backupPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupPolicies) | +| `Microsoft.NetApp/netAppAccounts/backupPolicies` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupPolicies) | ## Parameters diff --git a/avm/res/net-app/net-app-account/backup-policies/main.bicep b/avm/res/net-app/net-app-account/backup-policies/main.bicep index 561876f59f..61e25a4721 100644 --- a/avm/res/net-app/net-app-account/backup-policies/main.bicep +++ b/avm/res/net-app/net-app-account/backup-policies/main.bicep @@ -24,11 +24,11 @@ param weeklyBackupsToKeep int = 0 @description('Optional. Indicates whether the backup policy is enabled.') param enabled bool = true -resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-07-01' existing = { name: netAppAccountName } -resource backupPolicies 'Microsoft.NetApp/netAppAccounts/backupPolicies@2024-03-01' = { +resource backupPolicies 'Microsoft.NetApp/netAppAccounts/backupPolicies@2024-07-01' = { name: name parent: netAppAccount location: location diff --git a/avm/res/net-app/net-app-account/backup-policies/main.json b/avm/res/net-app/net-app-account/backup-policies/main.json index 2b6c463c6b..a77278bec5 100644 --- a/avm/res/net-app/net-app-account/backup-policies/main.json +++ b/avm/res/net-app/net-app-account/backup-policies/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1799863578493793686" + "templateHash": "7141176618644423280" }, "name": "Azure NetApp Files Backup Policy", "description": "This module deploys a Backup Policy for Azure NetApp File." @@ -65,7 +65,7 @@ "resources": [ { "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", "properties": { diff --git a/avm/res/net-app/net-app-account/backup-vault/README.md b/avm/res/net-app/net-app-account/backup-vault/README.md index 1a2fe38075..b800706df3 100644 --- a/avm/res/net-app/net-app-account/backup-vault/README.md +++ b/avm/res/net-app/net-app-account/backup-vault/README.md @@ -12,8 +12,8 @@ This module deploys a NetApp Files Backup Vault. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults) | -| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | +| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupVaults) | +| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupVaults/backups) | ## Parameters diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/README.md b/avm/res/net-app/net-app-account/backup-vault/backup/README.md index 5769fd7385..05f791c950 100644 --- a/avm/res/net-app/net-app-account/backup-vault/backup/README.md +++ b/avm/res/net-app/net-app-account/backup-vault/backup/README.md @@ -12,7 +12,7 @@ This module deploys a backup of a NetApp Files Volume. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | +| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/backupVaults/backups) | ## Parameters diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep b/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep index accde9c313..4532249c51 100644 --- a/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep +++ b/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep @@ -22,14 +22,14 @@ param volumeName string @description('Required. The name of the capacity pool containing the volume.') param capacityPoolName string -resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-07-01' existing = { name: netAppAccountName - resource backupVault 'backupVaults@2024-03-01' existing = { + resource backupVault 'backupVaults@2024-07-01' existing = { name: backupVaultName } - resource remoteCapacityPool 'capacityPools@2024-03-01' existing = { + resource remoteCapacityPool 'capacityPools@2024-07-01' existing = { name: capacityPoolName resource volume 'volumes@2024-07-01' existing = { @@ -38,7 +38,7 @@ resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { } } -resource backup 'Microsoft.NetApp/netAppAccounts/backupVaults/backups@2024-03-01' = { +resource backup 'Microsoft.NetApp/netAppAccounts/backupVaults/backups@2024-07-01' = { name: name parent: netAppAccount::backupVault properties: { diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/main.json b/avm/res/net-app/net-app-account/backup-vault/backup/main.json index fa434a3da1..5257b0d5ab 100644 --- a/avm/res/net-app/net-app-account/backup-vault/backup/main.json +++ b/avm/res/net-app/net-app-account/backup-vault/backup/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10519572323483923146" + "templateHash": "3948084235912412629" }, "name": "Azure NetApp Files Volume Backup", "description": "This module deploys a backup of a NetApp Files Volume." @@ -68,24 +68,24 @@ "netAppAccount::backupVault": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" }, "netAppAccount::remoteCapacityPool": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/capacityPools", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backup": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", "properties": { "label": "[parameters('label')]", diff --git a/avm/res/net-app/net-app-account/backup-vault/main.bicep b/avm/res/net-app/net-app-account/backup-vault/main.bicep index 7ad087ceb6..bf683b0690 100644 --- a/avm/res/net-app/net-app-account/backup-vault/main.bicep +++ b/avm/res/net-app/net-app-account/backup-vault/main.bicep @@ -13,11 +13,11 @@ param netAppAccountName string @description('Optional. The list of backups to create.') param backups backupType[]? -resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-07-01' existing = { name: netAppAccountName } -resource backupVault 'Microsoft.NetApp/netAppAccounts/backupVaults@2024-03-01' = { +resource backupVault 'Microsoft.NetApp/netAppAccounts/backupVaults@2024-07-01' = { name: name parent: netAppAccount location: location diff --git a/avm/res/net-app/net-app-account/backup-vault/main.json b/avm/res/net-app/net-app-account/backup-vault/main.json index 20b96fb9a2..7a827614d8 100644 --- a/avm/res/net-app/net-app-account/backup-vault/main.json +++ b/avm/res/net-app/net-app-account/backup-vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1432647773332765235" + "templateHash": "9738469557677047438" }, "name": "Azure NetApp Files Volume Backup Vault", "description": "This module deploys a NetApp Files Backup Vault." @@ -91,12 +91,12 @@ "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backupVault": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", "properties": {} @@ -145,7 +145,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10519572323483923146" + "templateHash": "3948084235912412629" }, "name": "Azure NetApp Files Volume Backup", "description": "This module deploys a backup of a NetApp Files Volume." @@ -207,24 +207,24 @@ "netAppAccount::backupVault": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" }, "netAppAccount::remoteCapacityPool": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/capacityPools", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backup": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", "properties": { "label": "[parameters('label')]", @@ -290,7 +290,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('backupVault', '2024-03-01', 'full').location]" + "value": "[reference('backupVault', '2024-07-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/capacity-pool/README.md b/avm/res/net-app/net-app-account/capacity-pool/README.md index 120723a2df..2d5f2b7bd1 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/README.md +++ b/avm/res/net-app/net-app-account/capacity-pool/README.md @@ -15,7 +15,7 @@ This module deploys an Azure NetApp Files Capacity Pool. | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.NetApp/netAppAccounts/capacityPools` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools) | -| `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools/volumes) | +| `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/capacityPools/volumes) | ## Parameters @@ -275,6 +275,7 @@ List of volumes to create in the capacity pool. | [`smbContinuouslyAvailable`](#parameter-volumessmbcontinuouslyavailable) | bool | Enables continuously available share property for SMB volume. Only applicable for SMB volume. | | [`smbEncryption`](#parameter-volumessmbencryption) | bool | Enables SMB encryption. Only applicable for SMB/DualProtocol volume. | | [`smbNonBrowsable`](#parameter-volumessmbnonbrowsable) | string | Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. | +| [`volumeType`](#parameter-volumesvolumetype) | string | The type of the volume. DataProtection volumes are used for replication. | | [`zones`](#parameter-volumeszones) | array | Zone where the volume will be placed. | ### Parameter: `volumes.name` @@ -393,6 +394,12 @@ Replication properties. | [`remoteVolumeResourceId`](#parameter-volumesdataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | | [`replicationSchedule`](#parameter-volumesdataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`remotePath`](#parameter-volumesdataprotectionreplicationremotepath) | object | The full path to a volume that is to be migrated into ANF. Required for Migration volumes. | + ### Parameter: `volumes.dataProtection.replication.endpointType` Indicates whether the local volume is the source or destination for the Volume Replication. @@ -436,6 +443,42 @@ The replication schedule for the volume. ] ``` +### Parameter: `volumes.dataProtection.replication.remotePath` + +The full path to a volume that is to be migrated into ANF. Required for Migration volumes. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`externalHostName`](#parameter-volumesdataprotectionreplicationremotepathexternalhostname) | string | The Path to a ONTAP Host. | +| [`serverName`](#parameter-volumesdataprotectionreplicationremotepathservername) | string | The name of a server on the ONTAP Host. | +| [`volumeName`](#parameter-volumesdataprotectionreplicationremotepathvolumename) | string | The name of a volume on the server. | + +### Parameter: `volumes.dataProtection.replication.remotePath.externalHostName` + +The Path to a ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.replication.remotePath.serverName` + +The name of a server on the ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.replication.remotePath.volumeName` + +The name of a volume on the server. + +- Required: Yes +- Type: string + ### Parameter: `volumes.dataProtection.snapshot` Snapshot properties. @@ -811,6 +854,13 @@ Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProto ] ``` +### Parameter: `volumes.volumeType` + +The type of the volume. DataProtection volumes are used for replication. + +- Required: No +- Type: string + ### Parameter: `volumes.zones` Zone where the volume will be placed. diff --git a/avm/res/net-app/net-app-account/capacity-pool/main.bicep b/avm/res/net-app/net-app-account/capacity-pool/main.bicep index 216cf0e333..69d3185518 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/main.bicep +++ b/avm/res/net-app/net-app-account/capacity-pool/main.bicep @@ -116,6 +116,11 @@ module capacityPool_volumes 'volume/main.bicep' = [ encryptionKeySource: volume.?encryptionKeySource ?? 'Microsoft.NetApp' keyVaultPrivateEndpointResourceId: volume.?keyVaultPrivateEndpointResourceId dataProtection: volume.?dataProtection + kerberosEnabled: volume.?kerberosEnabled + smbContinuouslyAvailable: volume.?smbContinuouslyAvailable + smbEncryption: volume.?smbEncryption + smbNonBrowsable: volume.?smbNonBrowsable + volumeType: volume.?volumeType } } ] @@ -223,4 +228,7 @@ type volumeType = { @description('Optional. Define if a volume is KerberosEnabled.') kerberosEnabled: bool? + + @description('Optional. The type of the volume. DataProtection volumes are used for replication.') + volumeType: string? } diff --git a/avm/res/net-app/net-app-account/capacity-pool/main.json b/avm/res/net-app/net-app-account/capacity-pool/main.json index 24da0da165..1baa0db593 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "2539920372355196545" + "templateHash": "10620001426687567729" }, "name": "Azure NetApp Files Capacity Pools", "description": "This module deploys an Azure NetApp Files Capacity Pool." @@ -183,6 +183,13 @@ "metadata": { "description": "Optional. Define if a volume is KerberosEnabled." } + }, + "volumeType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." + } } }, "metadata": { @@ -254,6 +261,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -735,6 +769,21 @@ }, "dataProtection": { "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'dataProtection')]" + }, + "kerberosEnabled": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'kerberosEnabled')]" + }, + "smbContinuouslyAvailable": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbContinuouslyAvailable')]" + }, + "smbEncryption": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbEncryption')]" + }, + "smbNonBrowsable": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbNonBrowsable')]" + }, + "volumeType": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'volumeType')]" } }, "template": { @@ -745,7 +794,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "8045934107791458590" + "templateHash": "14921990871750776609" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." @@ -816,6 +865,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -1348,10 +1424,10 @@ }, "volume": { "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule'), 'remotePath', tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remotePath')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" }, "volume_roleAssignments": { @@ -1404,7 +1480,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('volume', '2024-03-01', 'full').location]" + "value": "[reference('volume', '2024-07-01', 'full').location]" } } } diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/README.md b/avm/res/net-app/net-app-account/capacity-pool/volume/README.md index c6cc4dd229..2b4a0116b2 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/README.md +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/README.md @@ -14,7 +14,7 @@ This module deploys an Azure NetApp Files Capacity Pool Volume. | 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.NetApp/netAppAccounts/capacityPools/volumes` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools/volumes) | +| `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-07-01/netAppAccounts/capacityPools/volumes) | ## Parameters @@ -196,6 +196,12 @@ Replication properties. | [`remoteVolumeResourceId`](#parameter-dataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | | [`replicationSchedule`](#parameter-dataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`remotePath`](#parameter-dataprotectionreplicationremotepath) | object | The full path to a volume that is to be migrated into ANF. Required for Migration volumes. | + ### Parameter: `dataProtection.replication.endpointType` Indicates whether the local volume is the source or destination for the Volume Replication. @@ -239,6 +245,42 @@ The replication schedule for the volume. ] ``` +### Parameter: `dataProtection.replication.remotePath` + +The full path to a volume that is to be migrated into ANF. Required for Migration volumes. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`externalHostName`](#parameter-dataprotectionreplicationremotepathexternalhostname) | string | The Path to a ONTAP Host. | +| [`serverName`](#parameter-dataprotectionreplicationremotepathservername) | string | The name of a server on the ONTAP Host. | +| [`volumeName`](#parameter-dataprotectionreplicationremotepathvolumename) | string | The name of a volume on the server. | + +### Parameter: `dataProtection.replication.remotePath.externalHostName` + +The Path to a ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `dataProtection.replication.remotePath.serverName` + +The name of a server on the ONTAP Host. + +- Required: Yes +- Type: string + +### Parameter: `dataProtection.replication.remotePath.volumeName` + +The name of a volume on the server. + +- Required: Yes +- Type: string + ### Parameter: `dataProtection.snapshot` Snapshot properties. diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep b/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep index 8d8b520830..ae948d7639 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep @@ -168,7 +168,7 @@ resource vnet 'Microsoft.Network/virtualNetworks@2024-03-01' existing = { } } -resource volume 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes@2024-03-01' = { +resource volume 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes@2024-07-01' = { name: name parent: netAppAccount::capacityPool location: location @@ -195,6 +195,7 @@ resource volume 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes@2024-03-0 remoteVolumeRegion: remoteNetAppAccount::remoteCapacityPool::remoteVolume.id remoteVolumeResourceId: dataProtection.?replication!.remoteVolumeResourceId replicationSchedule: dataProtection.?replication!.replicationSchedule + remotePath: dataProtection.?replication!.?remotePath } : {} backup: !empty(dataProtection.?backup) @@ -283,6 +284,18 @@ type replicationType = { @description('Required. The replication schedule for the volume.') replicationSchedule: ('_10minutely' | 'daily' | 'hourly') + + @description('Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes.') + remotePath: { + @description('Required. The Path to a ONTAP Host.') + externalHostName: string + + @description('Required. The name of a server on the ONTAP Host.') + serverName: string + + @description('Required. The name of a volume on the server.') + volumeName: string + }? } @description('The type for the backup properties.') diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json index fbc1d6f298..d68b83a31c 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "8045934107791458590" + "templateHash": "14921990871750776609" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." @@ -77,6 +77,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -609,10 +636,10 @@ }, "volume": { "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule'), 'remotePath', tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remotePath')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" }, "volume_roleAssignments": { @@ -665,7 +692,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('volume', '2024-03-01', 'full').location]" + "value": "[reference('volume', '2024-07-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/main.bicep b/avm/res/net-app/net-app-account/main.bicep index d6be205c6e..0830edb906 100644 --- a/avm/res/net-app/net-app-account/main.bicep +++ b/avm/res/net-app/net-app-account/main.bicep @@ -176,7 +176,7 @@ resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentiti ) } -resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' = { +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-07-01' = { name: name tags: tags identity: identity diff --git a/avm/res/net-app/net-app-account/main.json b/avm/res/net-app/net-app-account/main.json index c22e363075..3d2ef51806 100644 --- a/avm/res/net-app/net-app-account/main.json +++ b/avm/res/net-app/net-app-account/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "6509519164461633683" + "templateHash": "15376852435816415720" }, "name": "Azure NetApp Files", "description": "This module deploys an Azure NetApp File." @@ -461,6 +461,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -989,6 +1016,13 @@ "metadata": { "description": "Optional. Define if a volume is KerberosEnabled." } + }, + "volumeType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." + } } }, "metadata": { @@ -1329,7 +1363,7 @@ }, "netAppAccount": { "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('name')]", "tags": "[parameters('tags')]", "identity": "[variables('identity')]", @@ -1421,7 +1455,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1799863578493793686" + "templateHash": "7141176618644423280" }, "name": "Azure NetApp Files Backup Policy", "description": "This module deploys a Backup Policy for Azure NetApp File." @@ -1481,7 +1515,7 @@ "resources": [ { "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", "properties": { @@ -1884,7 +1918,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1432647773332765235" + "templateHash": "9738469557677047438" }, "name": "Azure NetApp Files Volume Backup Vault", "description": "This module deploys a NetApp Files Backup Vault." @@ -1969,12 +2003,12 @@ "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backupVault": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", "properties": {} @@ -2023,7 +2057,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10519572323483923146" + "templateHash": "3948084235912412629" }, "name": "Azure NetApp Files Volume Backup", "description": "This module deploys a backup of a NetApp Files Volume." @@ -2085,24 +2119,24 @@ "netAppAccount::backupVault": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" }, "netAppAccount::remoteCapacityPool": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/capacityPools", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backup": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", "properties": { "label": "[parameters('label')]", @@ -2168,7 +2202,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('backupVault', '2024-03-01', 'full').location]" + "value": "[reference('backupVault', '2024-07-01', 'full').location]" } } } @@ -2233,7 +2267,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "2539920372355196545" + "templateHash": "10620001426687567729" }, "name": "Azure NetApp Files Capacity Pools", "description": "This module deploys an Azure NetApp Files Capacity Pool." @@ -2410,6 +2444,13 @@ "metadata": { "description": "Optional. Define if a volume is KerberosEnabled." } + }, + "volumeType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." + } } }, "metadata": { @@ -2481,6 +2522,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -2962,6 +3030,21 @@ }, "dataProtection": { "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'dataProtection')]" + }, + "kerberosEnabled": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'kerberosEnabled')]" + }, + "smbContinuouslyAvailable": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbContinuouslyAvailable')]" + }, + "smbEncryption": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbEncryption')]" + }, + "smbNonBrowsable": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'smbNonBrowsable')]" + }, + "volumeType": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'volumeType')]" } }, "template": { @@ -2972,7 +3055,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "8045934107791458590" + "templateHash": "14921990871750776609" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." @@ -3043,6 +3126,33 @@ "metadata": { "description": "Required. The replication schedule for the volume." } + }, + "remotePath": { + "type": "object", + "properties": { + "externalHostName": { + "type": "string", + "metadata": { + "description": "Required. The Path to a ONTAP Host." + } + }, + "serverName": { + "type": "string", + "metadata": { + "description": "Required. The name of a server on the ONTAP Host." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of a volume on the server." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The full path to a volume that is to be migrated into ANF. Required for Migration volumes." + } } }, "metadata": { @@ -3575,10 +3685,10 @@ }, "volume": { "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule'), 'remotePath', tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remotePath')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" }, "volume_roleAssignments": { @@ -3631,7 +3741,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('volume', '2024-03-01', 'full').location]" + "value": "[reference('volume', '2024-07-01', 'full').location]" } } } @@ -3725,7 +3835,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1432647773332765235" + "templateHash": "9738469557677047438" }, "name": "Azure NetApp Files Volume Backup Vault", "description": "This module deploys a NetApp Files Backup Vault." @@ -3810,12 +3920,12 @@ "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backupVault": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", "properties": {} @@ -3864,7 +3974,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10519572323483923146" + "templateHash": "3948084235912412629" }, "name": "Azure NetApp Files Volume Backup", "description": "This module deploys a backup of a NetApp Files Volume." @@ -3926,24 +4036,24 @@ "netAppAccount::backupVault": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" }, "netAppAccount::remoteCapacityPool": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/capacityPools", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[parameters('netAppAccountName')]" }, "backup": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", - "apiVersion": "2024-03-01", + "apiVersion": "2024-07-01", "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", "properties": { "label": "[parameters('label')]", @@ -4009,7 +4119,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('backupVault', '2024-03-01', 'full').location]" + "value": "[reference('backupVault', '2024-07-01', 'full').location]" } } } @@ -4047,7 +4157,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('netAppAccount', '2024-03-01', 'full').location]" + "value": "[reference('netAppAccount', '2024-07-01', 'full').location]" }, "capacityPoolResourceIds": { "type": "array", From 9ed7020deef3aa2b7c31a7c9d1d942cc2727c9e8 Mon Sep 17 00:00:00 2001 From: Erika Gressi <56914614+eriqua@users.noreply.github.com> Date: Wed, 5 Feb 2025 16:34:40 +0100 Subject: [PATCH 05/31] feat: Remove `'avm/ptn/lz/sub-vending` from OIDC exeption list (#4304) ## Description Removing `'avm/ptn/lz/sub-vending` from the list of modules requiring service principal + secret authentication (OIDC exception) ## Pipeline Reference | Pipeline | | -------- | | [![avm.ptn.lz.sub-vending](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml/badge.svg?branch=users%2Ferikag%2Foidc_sub&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [ ] I'm sure there are no other open Pull Requests for the same update/change - [ ] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../actions/templates/avm-validateModuleDeployment/action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index dc2b3ff5a4..c26b7137e9 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -70,10 +70,9 @@ runs: # Grouping task logs Write-Output '::group::Set OIDC exception' - # List of modules requiring more that 1 hour to deploy and delete resources + # List of modules requiring service principal + secret authentication $modulePath = "${{ inputs.modulePath }}" $exceptionModulePaths = @( - 'avm/ptn/lz/sub-vending' # Requires additional OIDC MSI permissions 'avm/res/compute/image' # Failing on resource deletion when trying to delete RBAC at subscription level 'avm/res/compute/disk' # Failing on resource deletion when trying to delete RBAC at subscription level 'avm/ptn/virtual-machine-images/azure-image-builder' # Failing on resource deletion when trying to delete RBAC at subscription level From 972b730dfc0f5e77a28e3ada3bc57b1c11184388 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 6 Feb 2025 07:53:33 +0200 Subject: [PATCH 06/31] fix: Update `avm/ptn/lz/sub-vending` -- Bug fixes and improvements (#4274) ## Description - Update modules versions - Switch to private endpoints for the deployment script instead of service endpoints - Added `PublicnetworkAccess:Disabled` to the storage account due to a recent change in policy - Update CI pipeline to pin Az.Accounts and Az,Subscription modules' versions due to a recent bug - Update deployment script naming to avoid duplicate names ## Pipeline Reference | Pipeline | | -------- | | [![avm.ptn.lz.sub-vending](https://github.com/sebassem/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml/badge.svg?branch=avm-lz-subvending-policy-refresh)](https://github.com/sebassem/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml) | ## Type of Change - [X] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [X] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [X] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [X] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --------- Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- avm/ptn/lz/sub-vending/README.md | 34 +- avm/ptn/lz/sub-vending/main.bicep | 4 +- avm/ptn/lz/sub-vending/main.json | 8730 ++++++++++++----- .../modules/subResourceWrapper.bicep | 90 +- 4 files changed, 6457 insertions(+), 2401 deletions(-) diff --git a/avm/ptn/lz/sub-vending/README.md b/avm/ptn/lz/sub-vending/README.md index b1d81bc858..df28881931 100644 --- a/avm/ptn/lz/sub-vending/README.md +++ b/avm/ptn/lz/sub-vending/README.md @@ -18,12 +18,23 @@ This module deploys a subscription to accelerate deployment of landing zones. Fo | `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.KeyVault/vaults/secrets` | [2023-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2023-07-01/vaults/secrets) | | `Microsoft.ManagedIdentity/userAssignedIdentities` | [2023-01-31](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ManagedIdentity/2023-01-31/userAssignedIdentities) | | `Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials` | [2023-01-31](https://learn.microsoft.com/en-us/azure/templates/Microsoft.ManagedIdentity/2023-01-31/userAssignedIdentities/federatedIdentityCredentials) | | `Microsoft.Management/managementGroups/subscriptions` | [2021-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Management/2021-04-01/managementGroups/subscriptions) | | `Microsoft.Network/networkSecurityGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/networkSecurityGroups) | -| `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/privateDnsZones` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones) | +| `Microsoft.Network/privateDnsZones/A` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/A) | +| `Microsoft.Network/privateDnsZones/AAAA` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/AAAA) | +| `Microsoft.Network/privateDnsZones/CNAME` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/CNAME) | +| `Microsoft.Network/privateDnsZones/MX` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/MX) | +| `Microsoft.Network/privateDnsZones/PTR` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/PTR) | +| `Microsoft.Network/privateDnsZones/SOA` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/SOA) | +| `Microsoft.Network/privateDnsZones/SRV` | [2020-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-06-01/privateDnsZones/SRV) | +| `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` | [2024-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-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/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | | `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs/hubVirtualNetworkConnections) | | `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) | @@ -31,7 +42,7 @@ This module deploys a subscription to accelerate deployment of landing zones. Fo | `Microsoft.Resources/deploymentScripts` | [2023-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Resources/2023-08-01/deploymentScripts) | | `Microsoft.Resources/resourceGroups` | [2021-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Resources/2021-04-01/resourceGroups) | | `Microsoft.Resources/tags` | [2019-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Resources/2019-10-01/tags) | -| `Microsoft.Storage/storageAccounts` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts) | +| `Microsoft.Storage/storageAccounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-05-01/storageAccounts) | | `Microsoft.Storage/storageAccounts/blobServices` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices) | | `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers/immutabilityPolicies) | @@ -869,7 +880,7 @@ The name of the storage account for the deployment script. - Required: No - Type: string -- Default: `[format('stgds{0}', substring(uniqueString(deployment().name, parameters('virtualNetworkLocation')), 0, 10))]` +- Default: `[format('stgds{0}', substring(uniqueString(deployment().name, parameters('existingSubscriptionId'), parameters('subscriptionAliasName'), parameters('subscriptionDisplayName'), parameters('virtualNetworkLocation')), 0, 10))]` ### Parameter: `deploymentScriptVirtualNetworkName` @@ -877,7 +888,7 @@ The name of the private virtual network for the deployment script. The string mu - Required: No - Type: string -- Default: `[format('vnet-{0}', deployment().location)]` +- Default: `[format('vnet-ds-{0}', deployment().location)]` ### Parameter: `enableTelemetry` @@ -1344,13 +1355,14 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/ptn/authorization/role-assignment:0.1.1` | Remote reference | -| `br/public:avm/res/managed-identity/user-assigned-identity:0.2.2` | Remote reference | -| `br/public:avm/res/network/network-security-group:0.3.0` | Remote reference | -| `br/public:avm/res/network/virtual-network:0.5.0` | Remote reference | +| `br/public:avm/ptn/authorization/role-assignment:0.2.1` | Remote reference | +| `br/public:avm/res/managed-identity/user-assigned-identity:0.4.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.7.0` | Remote reference | +| `br/public:avm/res/network/virtual-network:0.5.2` | Remote reference | | `br/public:avm/res/resources/deployment-script:0.2.3` | Remote reference | -| `br/public:avm/res/resources/resource-group:0.2.4` | Remote reference | -| `br/public:avm/res/storage/storage-account:0.9.1` | Remote reference | +| `br/public:avm/res/resources/resource-group:0.4.1` | Remote reference | +| `br/public:avm/res/storage/storage-account:0.15.0` | Remote reference | ## Data Collection diff --git a/avm/ptn/lz/sub-vending/main.bicep b/avm/ptn/lz/sub-vending/main.bicep index 5127335a15..1a0a9ba20c 100644 --- a/avm/ptn/lz/sub-vending/main.bicep +++ b/avm/ptn/lz/sub-vending/main.bicep @@ -233,7 +233,7 @@ param deploymentScriptManagedIdentityName string = 'id-${deployment().location}' @maxLength(64) @description('Optional. The name of the private virtual network for the deployment script. The string must consist of a-z, A-Z, 0-9, -, _, and . (period) and be between 2 and 64 characters in length.') -param deploymentScriptVirtualNetworkName string = 'vnet-${deployment().location}' +param deploymentScriptVirtualNetworkName string = 'vnet-ds-${deployment().location}' @description('Optional. The name of the network security group for the deployment script private subnet.') param deploymentScriptNetworkSecurityGroupName string = 'nsg-${deployment().location}' @@ -242,7 +242,7 @@ param deploymentScriptNetworkSecurityGroupName string = 'nsg-${deployment().loca param virtualNetworkDeploymentScriptAddressPrefix string = '192.168.0.0/24' @description('Optional. The name of the storage account for the deployment script.') -param deploymentScriptStorageAccountName string = 'stgds${substring(uniqueString(deployment().name, virtualNetworkLocation), 0, 10)}' +param deploymentScriptStorageAccountName string = 'stgds${substring(uniqueString(deployment().name,existingSubscriptionId,subscriptionAliasName,subscriptionDisplayName, virtualNetworkLocation), 0, 10)}' @description('Optional. The location of the deployment script. Use region shortnames e.g. uksouth, eastus, etc.') param deploymentScriptLocation string = deployment().location diff --git a/avm/ptn/lz/sub-vending/main.json b/avm/ptn/lz/sub-vending/main.json index 6260281b89..2421387f0d 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.32.4.45862", - "templateHash": "9419179474284257467" + "version": "0.33.13.18514", + "templateHash": "16856855794906870670" }, "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).", @@ -489,7 +489,7 @@ }, "deploymentScriptVirtualNetworkName": { "type": "string", - "defaultValue": "[format('vnet-{0}', deployment().location)]", + "defaultValue": "[format('vnet-ds-{0}', deployment().location)]", "maxLength": 64, "metadata": { "description": "Optional. The name of the private virtual network for the deployment script. The string must consist of a-z, A-Z, 0-9, -, _, and . (period) and be between 2 and 64 characters in length." @@ -511,7 +511,7 @@ }, "deploymentScriptStorageAccountName": { "type": "string", - "defaultValue": "[format('stgds{0}', substring(uniqueString(deployment().name, parameters('virtualNetworkLocation')), 0, 10))]", + "defaultValue": "[format('stgds{0}', substring(uniqueString(deployment().name, parameters('existingSubscriptionId'), parameters('subscriptionAliasName'), parameters('subscriptionDisplayName'), parameters('virtualNetworkLocation')), 0, 10))]", "metadata": { "description": "Optional. The name of the storage account for the deployment script." } @@ -669,8 +669,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7356007681287188316" + "version": "0.33.13.18514", + "templateHash": "2801471703151139948" } }, "parameters": { @@ -880,8 +880,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12148543777890725773" + "version": "0.33.13.18514", + "templateHash": "250791371811352682" }, "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", @@ -1519,7 +1519,8 @@ "createRoleAssignmentsDeploymentScriptStorageAccount": "[take(format('lz-vend-stg-rbac-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptManagedIdentityName'), deployment().name)), 64)]", "createdsVnet": "[take(format('lz-vend-ds-vnet-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptLocation'), parameters('deploymentScriptVirtualNetworkName'), deployment().name)), 64)]", "createDsNsg": "[take(format('lz-vend-ds-nsg-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptLocation'), parameters('deploymentScriptNetworkSecurityGroupName'), deployment().name)), 64)]", - "createDsStorageAccount": "[take(format('lz-vend-ds-stg-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptLocation'), parameters('deploymentScriptStorageAccountName'), deployment().name)), 64)]" + "createDsStorageAccount": "[take(format('lz-vend-ds-stg-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptLocation'), parameters('deploymentScriptStorageAccountName'), deployment().name)), 64)]", + "createDsFilePrivateDnsZone": "[take(format('lz-vend-ds-pdns-create-{0}', uniqueString(parameters('subscriptionId'), parameters('deploymentScriptResourceGroupName'), parameters('deploymentScriptLocation'), parameters('deploymentScriptStorageAccountName'), parameters('deploymentScriptVirtualNetworkName'), deployment().name)), 64)]" }, "roleAssignmentsSubscription": "[filter(parameters('roleAssignments'), lambda('assignment', not(contains(lambdaVariables('assignment').relativeScope, '/resourceGroups/'))))]", "roleAssignmentsResourceGroups": "[filter(parameters('roleAssignments'), lambda('assignment', contains(lambdaVariables('assignment').relativeScope, '/resourceGroups/')))]", @@ -1587,8 +1588,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9408299259331736286" + "version": "0.33.13.18514", + "templateHash": "12834168093418139358" } }, "parameters": { @@ -1648,8 +1649,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9163659201609152701" + "version": "0.33.13.18514", + "templateHash": "15508893729756562690" } }, "parameters": { @@ -1708,8 +1709,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5714244397683720323" + "version": "0.33.13.18514", + "templateHash": "2541836993831686925" } }, "parameters": { @@ -1764,8 +1765,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "172844993812654627" + "version": "0.33.13.18514", + "templateHash": "7264500549088500335" } }, "parameters": { @@ -1842,8 +1843,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16527701492743422825" + "version": "0.33.13.18514", + "templateHash": "9459644647794329484" } }, "parameters": { @@ -1897,8 +1898,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15954838648223112192" + "version": "0.33.13.18514", + "templateHash": "8593973730489733307" } }, "parameters": { @@ -2015,8 +2016,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "15569531708310544555" + "version": "0.32.4.45862", + "templateHash": "15010504026239849745" }, "name": "Resource Groups", "description": "This module deploys a Resource Group.", @@ -2046,73 +2047,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.4.1" + } + } }, "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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.4.1" + } + } } }, "parameters": { @@ -2131,12 +2146,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." } @@ -2161,7 +2181,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.resources-resourcegroup.{0}.{1}', replace('0.2.4', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.resources-resourcegroup.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "location": "[parameters('location')]", "properties": { "mode": "Incremental", @@ -2212,8 +2232,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3101694150158706009" + "version": "0.32.4.45862", + "templateHash": "1203907446887412297" } }, "definitions": { @@ -2298,8 +2318,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8717205010771951354" + "version": "0.32.4.45862", + "templateHash": "6029968255804453751" } }, "definitions": { @@ -2308,6 +2328,13 @@ "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": { @@ -2379,13 +2406,20 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Quota Request Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0e5f05e5-9ab9-446b-b98d-1e2157c94125')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "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')]", "Tag Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4a9ae827-6dc8-4573-8ac7-8239d42aa03f')]", "Template Spec Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c9b6475-caf0-4164-b5a1-2142a7116f4b')]", "Template Spec Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '392ae280-861d-42bd-9ea5-08ee6d83b80e')]", @@ -2396,19 +2430,19 @@ "resourceGroup_roleAssignments": { "copy": { "name": "resourceGroup_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "name": "[guid(resourceGroup().id, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceGroup().id, 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')]" } } } @@ -2477,8 +2511,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9163659201609152701" + "version": "0.33.13.18514", + "templateHash": "15508893729756562690" } }, "parameters": { @@ -2537,8 +2571,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5714244397683720323" + "version": "0.33.13.18514", + "templateHash": "2541836993831686925" } }, "parameters": { @@ -2593,8 +2627,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "172844993812654627" + "version": "0.33.13.18514", + "templateHash": "7264500549088500335" } }, "parameters": { @@ -2671,8 +2705,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16527701492743422825" + "version": "0.33.13.18514", + "templateHash": "9459644647794329484" } }, "parameters": { @@ -2726,8 +2760,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15954838648223112192" + "version": "0.33.13.18514", + "templateHash": "8593973730489733307" } }, "parameters": { @@ -2859,8 +2893,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12023193036665775110" + "version": "0.32.4.45862", + "templateHash": "12002509614878477054" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", @@ -3225,7 +3259,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" } } }, @@ -3255,7 +3289,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" } } }, @@ -3330,7 +3364,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" } } } @@ -3496,7 +3530,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.5.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3680,8 +3714,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6411714881793832751" + "version": "0.32.4.45862", + "templateHash": "16307553544578422105" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -3759,7 +3793,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" } } } @@ -3768,7 +3802,7 @@ "name": { "type": "string", "metadata": { - "description": "Requird. The Name of the subnet resource." + "description": "Required. The Name of the subnet resource." } }, "virtualNetworkName": { @@ -3949,10 +3983,7 @@ "serviceEndpointPolicies": "[parameters('serviceEndpointPolicies')]", "defaultOutboundAccess": "[parameters('defaultOutboundAccess')]", "sharingScope": "[parameters('sharingScope')]" - }, - "dependsOn": [ - "virtualNetwork" - ] + } }, "subnet_roleAssignments": { "copy": { @@ -4065,8 +4096,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "345394220621166229" + "version": "0.32.4.45862", + "templateHash": "8973052275744789294" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -4223,8 +4254,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "345394220621166229" + "version": "0.32.4.45862", + "templateHash": "8973052275744789294" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -4423,8 +4454,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7399666879098691062" + "version": "0.33.13.18514", + "templateHash": "4537798139153123030" } }, "parameters": { @@ -4542,8 +4573,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4097241605548087035" + "version": "0.32.4.45862", + "templateHash": "10577398607850158081" }, "name": "Role Assignments (All scopes)", "description": "This module deploys a Role Assignment at a Management Group, Subscription or Resource Group scope.", @@ -4649,7 +4680,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -4702,8 +4733,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8906093264527258150" + "version": "0.32.4.45862", + "templateHash": "11820021262934304865" }, "name": "Role Assignments (Management Group scope)", "description": "This module deploys a Role Assignment at a Management Group scope.", @@ -4779,14 +4810,14 @@ "variables": { "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "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')]", "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -4866,8 +4897,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "707244099707019442" + "version": "0.32.4.45862", + "templateHash": "13566197367730692489" }, "name": "Role Assignments (Subscription scope)", "description": "This module deploys a Role Assignment at a Subscription scope.", @@ -4945,10 +4976,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -5038,8 +5069,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14591941439222880522" + "version": "0.32.4.45862", + "templateHash": "9586692955250077335" }, "name": "Role Assignments (Resource Group scope)", "description": "This module deploys a Role Assignment at a Resource Group scope.", @@ -5123,10 +5154,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -5244,8 +5275,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4097241605548087035" + "version": "0.32.4.45862", + "templateHash": "10577398607850158081" }, "name": "Role Assignments (All scopes)", "description": "This module deploys a Role Assignment at a Management Group, Subscription or Resource Group scope.", @@ -5351,7 +5382,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -5404,8 +5435,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8906093264527258150" + "version": "0.32.4.45862", + "templateHash": "11820021262934304865" }, "name": "Role Assignments (Management Group scope)", "description": "This module deploys a Role Assignment at a Management Group scope.", @@ -5481,14 +5512,14 @@ "variables": { "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "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')]", "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -5568,8 +5599,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "707244099707019442" + "version": "0.32.4.45862", + "templateHash": "13566197367730692489" }, "name": "Role Assignments (Subscription scope)", "description": "This module deploys a Role Assignment at a Subscription scope.", @@ -5647,10 +5678,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -5740,8 +5771,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14591941439222880522" + "version": "0.32.4.45862", + "templateHash": "9586692955250077335" }, "name": "Role Assignments (Resource Group scope)", "description": "This module deploys a Role Assignment at a Resource Group scope.", @@ -5825,10 +5856,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -5949,8 +5980,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4097241605548087035" + "version": "0.32.4.45862", + "templateHash": "10577398607850158081" }, "name": "Role Assignments (All scopes)", "description": "This module deploys a Role Assignment at a Management Group, Subscription or Resource Group scope.", @@ -6056,7 +6087,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -6109,8 +6140,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8906093264527258150" + "version": "0.32.4.45862", + "templateHash": "11820021262934304865" }, "name": "Role Assignments (Management Group scope)", "description": "This module deploys a Role Assignment at a Management Group scope.", @@ -6186,14 +6217,14 @@ "variables": { "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "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')]", "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -6273,8 +6304,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "707244099707019442" + "version": "0.32.4.45862", + "templateHash": "13566197367730692489" }, "name": "Role Assignments (Subscription scope)", "description": "This module deploys a Role Assignment at a Subscription scope.", @@ -6352,10 +6383,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -6445,8 +6476,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14591941439222880522" + "version": "0.32.4.45862", + "templateHash": "9586692955250077335" }, "name": "Role Assignments (Resource Group scope)", "description": "This module deploys a Role Assignment at a Resource Group scope.", @@ -6530,10 +6561,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -6641,8 +6672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "15569531708310544555" + "version": "0.32.4.45862", + "templateHash": "15010504026239849745" }, "name": "Resource Groups", "description": "This module deploys a Resource Group.", @@ -6672,73 +6703,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.4.1" + } + } }, "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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.4.1" + } + } } }, "parameters": { @@ -6757,12 +6802,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." } @@ -6787,7 +6837,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.resources-resourcegroup.{0}.{1}', replace('0.2.4', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.resources-resourcegroup.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "location": "[parameters('location')]", "properties": { "mode": "Incremental", @@ -6838,8 +6888,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3101694150158706009" + "version": "0.32.4.45862", + "templateHash": "1203907446887412297" } }, "definitions": { @@ -6924,8 +6974,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8717205010771951354" + "version": "0.32.4.45862", + "templateHash": "6029968255804453751" } }, "definitions": { @@ -6934,6 +6984,13 @@ "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": { @@ -7005,13 +7062,20 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Quota Request Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0e5f05e5-9ab9-446b-b98d-1e2157c94125')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "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')]", "Tag Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4a9ae827-6dc8-4573-8ac7-8239d42aa03f')]", "Template Spec Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c9b6475-caf0-4164-b5a1-2142a7116f4b')]", "Template Spec Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '392ae280-861d-42bd-9ea5-08ee6d83b80e')]", @@ -7022,19 +7086,19 @@ "resourceGroup_roleAssignments": { "copy": { "name": "resourceGroup_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "name": "[guid(resourceGroup().id, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceGroup().id, 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')]" } } } @@ -7101,8 +7165,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8316967256052237432" + "version": "0.29.47.4906", + "templateHash": "10609859695208799167" }, "name": "User Assigned Identities", "description": "This module deploys a User Assigned Identity.", @@ -7139,6 +7203,13 @@ "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": { @@ -7285,13 +7356,20 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Managed Identity Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e40ec5ca-96e0-45a2-b4ff-59039f2c2b59')]", "Managed Identity Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f1a07417-d97a-45cb-824c-7a7467783830')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (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')]" } }, @@ -7300,7 +7378,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.managedidentity-userassignedidentity.{0}.{1}', replace('0.2.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.managedidentity-userassignedidentity.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -7340,20 +7418,20 @@ "userAssignedIdentity_roleAssignments": { "copy": { "name": "userAssignedIdentity_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", "scope": "[format('Microsoft.ManagedIdentity/userAssignedIdentities/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 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.ManagedIdentity/userAssignedIdentities', 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": [ "userAssignedIdentity" @@ -7397,8 +7475,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "663270811232806628" + "version": "0.29.47.4906", + "templateHash": "3716898257490923786" }, "name": "User Assigned Identity Federated Identity Credential", "description": "This module deploys a User Assigned Identity Federated Identity Credential.", @@ -7560,8 +7638,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4097241605548087035" + "version": "0.32.4.45862", + "templateHash": "10577398607850158081" }, "name": "Role Assignments (All scopes)", "description": "This module deploys a Role Assignment at a Management Group, Subscription or Resource Group scope.", @@ -7667,7 +7745,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -7720,8 +7798,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8906093264527258150" + "version": "0.32.4.45862", + "templateHash": "11820021262934304865" }, "name": "Role Assignments (Management Group scope)", "description": "This module deploys a Role Assignment at a Management Group scope.", @@ -7797,14 +7875,14 @@ "variables": { "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "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')]", "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -7884,8 +7962,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "707244099707019442" + "version": "0.32.4.45862", + "templateHash": "13566197367730692489" }, "name": "Role Assignments (Subscription scope)", "description": "This module deploys a Role Assignment at a Subscription scope.", @@ -7963,10 +8041,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -8056,8 +8134,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14591941439222880522" + "version": "0.32.4.45862", + "templateHash": "9586692955250077335" }, "name": "Role Assignments (Resource Group scope)", "description": "This module deploys a Role Assignment at a Resource Group scope.", @@ -8141,10 +8219,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -8252,6 +8330,9 @@ }, "principalType": { "value": "ServicePrincipal" + }, + "description": { + "value": "Storage File Data Privileged Contributor" } }, "template": { @@ -8260,8 +8341,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4097241605548087035" + "version": "0.32.4.45862", + "templateHash": "10577398607850158081" }, "name": "Role Assignments (All scopes)", "description": "This module deploys a Role Assignment at a Management Group, Subscription or Resource Group scope.", @@ -8367,7 +8448,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-roleassignment.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -8420,8 +8501,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8906093264527258150" + "version": "0.32.4.45862", + "templateHash": "11820021262934304865" }, "name": "Role Assignments (Management Group scope)", "description": "This module deploys a Role Assignment at a Management Group scope.", @@ -8497,14 +8578,14 @@ "variables": { "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "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')]", "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -8584,8 +8665,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "707244099707019442" + "version": "0.32.4.45862", + "templateHash": "13566197367730692489" }, "name": "Role Assignments (Subscription scope)", "description": "This module deploys a Role Assignment at a Subscription scope.", @@ -8663,10 +8744,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -8756,8 +8837,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14591941439222880522" + "version": "0.32.4.45862", + "templateHash": "9586692955250077335" }, "name": "Role Assignments (Resource Group scope)", "description": "This module deploys a Role Assignment at a Resource Group scope.", @@ -8841,10 +8922,10 @@ "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')]" }, - "roleDefinitionIdVar": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]" + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": [ { @@ -8955,8 +9036,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "6301580350266878984" + "version": "0.29.47.4906", + "templateHash": "32550557190395602" }, "name": "Network Security Groups", "description": "This module deploys a Network security Group (NSG).", @@ -8993,6 +9074,13 @@ "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": { @@ -9371,12 +9459,19 @@ } }, "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')]", "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')]" } }, @@ -9384,8 +9479,8 @@ "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.3.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-networksecuritygroup.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -9486,20 +9581,20 @@ "networkSecurityGroup_roleAssignments": { "copy": { "name": "networkSecurityGroup_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/networkSecurityGroups/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Network/networkSecurityGroups', 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/networkSecurityGroups', 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": [ "networkSecurityGroup" @@ -9567,16 +9662,32 @@ "skuName": { "value": "Standard_LRS" }, + "publicNetworkAccess": { + "value": "Disabled" + }, + "allowSharedKeyAccess": { + "value": true + }, + "privateEndpoints": { + "value": [ + { + "service": "file", + "subnetResourceId": "[filter(reference('createDsVnet').outputs.subnetResourceIds.value, lambda('subnetResourceId', contains(lambdaVariables('subnetResourceId'), 'ds-pe-subnet')))[0]]", + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "[reference('dsFilePrivateDNSZone').outputs.resourceId.value]" + } + ] + }, + "name": "ds-file-pe" + } + ] + }, "networkAcls": { "value": { "bypass": "AzureServices", - "defaultAction": "Deny", - "virtualNetworkRules": [ - { - "action": "Allow", - "id": "[if(not(empty(parameters('resourceProviders'))), reference('createDsVnet').outputs.subnetResourceIds.value[0], null())]" - } - ] + "defaultAction": "Deny" } }, "enableTelemetry": { @@ -9590,127 +9701,76 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3958760216991467865" + "version": "0.32.4.45862", + "templateHash": "13064222201859168087" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "privateEndpointOutputType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", - "nullable": true, + "name": { + "type": "string", "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "The name of the private endpoint." } }, - "userAssignedResourceIds": { - "type": "array", - "items": { - "type": "string" - }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + } + }, + "groupId": { + "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." + "description": "The group Id for the private endpoint Group." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "A list of private IP addresses of the private endpoint." + } + } } }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + } + }, + "networkInterfaceResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "networkAclsType": { "type": "object", @@ -9781,278 +9841,251 @@ "description": "Optional. Specifies the default action of allow or deny when no other rules match." } } + }, + "metadata": { + "__bicep_export!": 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." - } - }, - "service": { - "type": "string", - "metadata": { - "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "privateDnsZoneGroupName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." - } + "secretsExportConfigurationType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The key vault name where to store the keys and connection strings generated by the modules." + } + }, + "accessKey1": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The accessKey1 secret name to create." + } + }, + "connectionString1": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The connectionString1 secret name to create." + } + }, + "accessKey2": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The accessKey2 secret name to create." + } + }, + "connectionString2": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The connectionString2 secret name to create." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "localUserType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the local user used for SFTP Authentication." + } + }, + "hasSharedKey": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether shared key exists. Set it to false to remove existing shared key." + } + }, + "hasSshKey": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether SSH key exists. Set it to false to remove existing SSH key." + } + }, + "hasSshPassword": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether SSH password exists. Set it to false to remove existing SSH password." + } + }, + "homeDirectory": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The local user home directory." + } + }, + "permissionScopes": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionScopeType" }, - "privateDnsZoneResourceIds": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." - } + "metadata": { + "description": "Required. The permission scopes of the local user." + } + }, + "sshAuthorizedKeys": { + "type": "array", + "items": { + "$ref": "#/definitions/sshAuthorizedKeyType" }, - "isManualConnection": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Manual PrivateLink Service Connections." - } + "nullable": true, + "metadata": { + "description": "Optional. The local user SSH authorized keys for SFTP." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_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" + } + } + }, + "_2.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" }, - "manualConnectionRequestMessage": { - "type": "string", - "nullable": true, - "maxLength": 140, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." - } - }, - "customDnsConfigs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint ip address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private ip addresses of the private endpoint." - } - } + "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.4.0" + } + } + }, + "_2.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." } }, - "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." - } - } + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect 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" - }, - "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." + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } } }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "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.4.0" + } + } }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } + "_2.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." } } - }, - "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." - } + "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.4.0" + } + } }, - "customerManagedKeyType": { + "customerManagedKeyWithAutoRotateType": { "type": "object", "properties": { "keyVaultResourceId": { @@ -10071,201 +10104,686 @@ "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, using version as per 'autoRotationEnabled' setting." + } + }, + "autoRotationEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable auto-rotating to the latest key version. Default is `true`. If set to `false`, 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. If used must also be specified in `managedIdentities.userAssignedResourceIds`. Required if no system assigned identity is available for use." + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." } } }, - "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", - "maxLength": 24, - "metadata": { - "description": "Required. Name of the Storage Account. Must be lower-case." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Location for all resources." + "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.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", - "metadata": { - "description": "Optional. The managed identity definition for this resource." - } - }, - "kind": { - "type": "string", - "defaultValue": "StorageV2", - "allowedValues": [ - "Storage", - "StorageV2", - "BlobStorage", - "FileStorage", - "BlockBlobStorage" - ], - "metadata": { - "description": "Optional. Type of Storage Account to create." - } - }, - "skuName": { - "type": "string", - "defaultValue": "Standard_GRS", - "allowedValues": [ - "Standard_LRS", - "Standard_GRS", - "Standard_RAGRS", - "Standard_ZRS", - "Premium_LRS", - "Premium_ZRS", - "Standard_GZRS", - "Standard_RAGZRS" - ], - "metadata": { - "description": "Optional. Storage Account Sku Name." - } - }, - "accessTier": { - "type": "string", - "defaultValue": "Hot", - "allowedValues": [ - "Premium", - "Hot", - "Cool" - ], - "metadata": { - "description": "Conditional. Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The \"Premium\" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type." - } - }, - "largeFileSharesState": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "Optional. Allow large file shares if sets to 'Enabled'. It cannot be disabled once it is enabled. Only supported on locally redundant and zone redundant file shares. It cannot be set on FileStorage storage accounts (storage accounts for premium file shares)." - } - }, - "azureFilesIdentityBasedAuthentication": { + "diagnosticSettingFullType": { "type": "object", - "defaultValue": {}, + "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": "Optional. Provides the identity based authentication settings for Azure Files." + "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.4.0" + } } }, - "defaultToOAuthAuthentication": { - "type": "bool", - "defaultValue": false, + "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": "Optional. A boolean flag which indicates whether the default authentication is OAuth or not." + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "allowSharedKeyAccess": { - "type": "bool", - "defaultValue": true, + "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": "Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true." + "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.4.0" + } } }, - "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "permissionScopeType": { + "type": "object", + "properties": { + "permissions": { + "type": "string", + "metadata": { + "description": "Required. The permissions for the local user. Possible values include: Read (r), Write (w), Delete (d), List (l), and Create (c)." + } + }, + "resourceName": { + "type": "string", + "metadata": { + "description": "Required. The name of resource, normally the container name or the file share name, used by the local user." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service used by the local user, e.g. blob, file." + } + } + }, "metadata": { - "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + "__bicep_imported_from!": { + "sourceTemplate": "local-user/main.bicep" + } } }, - "managementPolicyRules": { - "type": "array", - "nullable": true, + "privateEndpointMultiServiceType": { + "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", + "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/_2.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/_2.privateEndpointCustomDnsConfigType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_2.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": "Optional. The Storage Account ManagementPolicies Rules." + "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.4.0" + } } }, - "networkAcls": { - "$ref": "#/definitions/networkAclsType", - "nullable": true, + "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": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." + "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.4.0" + } } }, - "requireInfrastructureEncryption": { - "type": "bool", - "defaultValue": true, + "secretsOutputType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "$ref": "#/definitions/_1.secretSetOutputType", + "metadata": { + "description": "An exported secret's references." + } + }, "metadata": { - "description": "Optional. A Boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest. For security reasons, it is recommended to set it to true." + "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" + } } }, - "allowCrossTenantReplication": { - "type": "bool", - "defaultValue": true, + "sshAuthorizedKeyType": { + "type": "object", + "properties": { + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Description used to store the function/usage of the key." + } + }, + "key": { + "type": "securestring", + "metadata": { + "description": "Required. SSH public key base64 encoded. The format should be: '{keyType} {keyData}', e.g. ssh-rsa AAAABBBB." + } + } + }, "metadata": { - "description": "Optional. Allow or disallow cross AAD tenant object replication." + "__bicep_imported_from!": { + "sourceTemplate": "local-user/main.bicep" + } } - }, - "customDomainName": { + } + }, + "parameters": { + "name": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Sets the custom domain name assigned to the storage account. Name is the CNAME source." - } - }, - "customDomainUseSubDomainName": { - "type": "bool", - "defaultValue": false, + "maxLength": 24, "metadata": { - "description": "Optional. Indicates whether indirect CName validation is enabled. This should only be set on updates." + "description": "Required. Name of the Storage Account. Must be lower-case." } }, - "dnsEndpointType": { + "location": { "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "AzureDnsZone", - "Standard" - ], + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier." + "description": "Optional. Location for all resources." } }, - "blobServices": { - "type": "object", - "defaultValue": "[if(not(equals(parameters('kind'), 'FileStorage')), createObject('containerDeleteRetentionPolicyEnabled', true(), 'containerDeleteRetentionPolicyDays', 7, 'deleteRetentionPolicyEnabled', true(), 'deleteRetentionPolicyDays', 6), createObject())]", + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { - "description": "Optional. Blob service and containers to deploy." + "description": "Optional. Array of role assignments to create." } }, - "fileServices": { - "type": "object", - "defaultValue": {}, + "managedIdentities": { + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "metadata": { - "description": "Optional. File service and shares to deploy." + "description": "Optional. The managed identity definition for this resource." } }, - "queueServices": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Queue service and queues to create." + "kind": { + "type": "string", + "defaultValue": "StorageV2", + "allowedValues": [ + "Storage", + "StorageV2", + "BlobStorage", + "FileStorage", + "BlockBlobStorage" + ], + "metadata": { + "description": "Optional. Type of Storage Account to create." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Standard_GRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_RAGRS", + "Standard_ZRS", + "Premium_LRS", + "Premium_ZRS", + "Standard_GZRS", + "Standard_RAGZRS" + ], + "metadata": { + "description": "Optional. Storage Account Sku Name." + } + }, + "accessTier": { + "type": "string", + "defaultValue": "Hot", + "allowedValues": [ + "Premium", + "Hot", + "Cool", + "Cold" + ], + "metadata": { + "description": "Conditional. Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The \"Premium\" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type." + } + }, + "largeFileSharesState": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Allow large file shares if sets to 'Enabled'. It cannot be disabled once it is enabled. Only supported on locally redundant and zone redundant file shares. It cannot be set on FileStorage storage accounts (storage accounts for premium file shares)." + } + }, + "azureFilesIdentityBasedAuthentication": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Provides the identity based authentication settings for Azure Files." + } + }, + "defaultToOAuthAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A boolean flag which indicates whether the default authentication is OAuth or not." + } + }, + "allowSharedKeyAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true." + } + }, + "privateEndpoints": { + "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." + } + }, + "managementPolicyRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The Storage Account ManagementPolicies Rules." + } + }, + "networkAcls": { + "$ref": "#/definitions/networkAclsType", + "nullable": true, + "metadata": { + "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." + } + }, + "requireInfrastructureEncryption": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. A Boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest. For security reasons, it is recommended to set it to true." + } + }, + "allowCrossTenantReplication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Allow or disallow cross AAD tenant object replication." + } + }, + "customDomainName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Sets the custom domain name assigned to the storage account. Name is the CNAME source." + } + }, + "customDomainUseSubDomainName": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether indirect CName validation is enabled. This should only be set on updates." + } + }, + "dnsEndpointType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "AzureDnsZone", + "Standard" + ], + "metadata": { + "description": "Optional. Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier." + } + }, + "blobServices": { + "type": "object", + "defaultValue": "[if(not(equals(parameters('kind'), 'FileStorage')), createObject('containerDeleteRetentionPolicyEnabled', true(), 'containerDeleteRetentionPolicyDays', 7, 'deleteRetentionPolicyEnabled', true(), 'deleteRetentionPolicyDays', 6), createObject())]", + "metadata": { + "description": "Optional. Blob service and containers to deploy." + } + }, + "fileServices": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. File service and shares to deploy." + } + }, + "queueServices": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Queue service and queues to create." } }, "tableServices": { @@ -10286,12 +10804,11 @@ "type": "string", "defaultValue": "TLS1_2", "allowedValues": [ - "TLS1_0", - "TLS1_1", - "TLS1_2" + "TLS1_2", + "TLS1_3" ], "metadata": { - "description": "Optional. Set the minimum TLS version on request to storage." + "description": "Optional. Set the minimum TLS version on request to storage. The TLS versions 1.0 and 1.1 are deprecated and not supported anymore." } }, "enableHierarchicalNamespace": { @@ -10310,7 +10827,10 @@ }, "localUsers": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/localUserType" + }, + "nullable": true, "metadata": { "description": "Optional. Local users to deploy for SFTP authentication." } @@ -10330,13 +10850,18 @@ } }, "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." } @@ -10387,7 +10912,8 @@ } }, "customerManagedKey": { - "$ref": "#/definitions/customerManagedKeyType", + "$ref": "#/definitions/customerManagedKeyWithAutoRotateType", + "nullable": true, "metadata": { "description": "Optional. The customer managed key definition." } @@ -10409,9 +10935,23 @@ "metadata": { "description": "Optional. The keyType to use with Queue & Table services." } + }, + "secretsExportConfiguration": { + "$ref": "#/definitions/secretsExportConfigurationType", + "nullable": true, + "metadata": { + "description": "Optional. Key vault reference and secret settings for the module's secrets export." + } } }, "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)))))]" + } + ], "supportsBlobService": "[or(or(or(equals(parameters('kind'), 'BlockBlobStorage'), equals(parameters('kind'), 'BlobStorage')), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]", "supportsFileService": "[or(or(equals(parameters('kind'), 'FileStorage'), equals(parameters('kind'), 'StorageV2')), equals(parameters('kind'), 'Storage'))]", "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", @@ -10421,7 +10961,7 @@ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", @@ -10429,6 +10969,8 @@ "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]", "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]", + "Storage File Data Privileged Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69566ab7-960f-475b-8e7c-b3118f30c6bd')]", + "Storage File Data Privileged Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b8eda974-7b85-4f76-af95-65846b26df6d')]", "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]", "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]", "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]", @@ -10449,16 +10991,13 @@ "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')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.storage-storageaccount.{0}.{1}', replace('0.9.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.storage-storageaccount.{0}.{1}', replace('0.15.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -10494,7 +11033,7 @@ }, "storageAccount": { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2022-09-01", + "apiVersion": "2023-05-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "kind": "[parameters('kind')]", @@ -10514,11 +11053,11 @@ }, "dnsEndpointType": "[if(not(empty(parameters('dnsEndpointType'))), parameters('dnsEndpointType'), null())]", "isLocalUserEnabled": "[parameters('isLocalUserEnabled')]", - "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true(), 'keyType', parameters('keyType')), 'queue', createObject('enabled', true(), 'keyType', parameters('keyType'))), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", + "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true(), 'keyType', parameters('keyType')), 'queue', createObject('enabled', true(), 'keyType', parameters('keyType'))), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), parameters('customerManagedKey').keyVersion, if(coalesce(tryGet(parameters('customerManagedKey'), 'autoRotationEnabled'), true()), null(), last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", "accessTier": "[if(and(not(equals(parameters('kind'), 'Storage')), not(equals(parameters('kind'), 'BlockBlobStorage'))), parameters('accessTier'), null())]", "sasPolicy": "[if(not(empty(parameters('sasExpirationPeriod'))), createObject('expirationAction', 'Log', 'sasExpirationPeriod', parameters('sasExpirationPeriod')), null())]", "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]", - "isHnsEnabled": "[if(parameters('enableHierarchicalNamespace'), parameters('enableHierarchicalNamespace'), null())]", + "isHnsEnabled": "[parameters('enableHierarchicalNamespace')]", "isSftpEnabled": "[parameters('enableSftp')]", "isNfsV3Enabled": "[if(parameters('enableNfsV3'), parameters('enableNfsV3'), '')]", "largeFileSharesState": "[if(or(equals(parameters('skuName'), 'Standard_LRS'), equals(parameters('skuName'), 'Standard_ZRS')), parameters('largeFileSharesState'), null())]", @@ -10529,8 +11068,8 @@ "azureFilesIdentityBasedAuthentication": "[if(not(empty(parameters('azureFilesIdentityBasedAuthentication'))), parameters('azureFilesIdentityBasedAuthentication'), null())]" }, "dependsOn": [ - "cMKKeyVault", - "cMKUserAssignedIdentity" + "cMKKeyVault::cMKKey", + "cMKKeyVault" ] }, "storageAccount_diagnosticSettings": { @@ -10582,20 +11121,20 @@ "storageAccount_roleAssignments": { "copy": { "name": "storageAccount_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts', 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": [ "storageAccount" @@ -10608,7 +11147,8 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-StorageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-storageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -10618,8 +11158,8 @@ "name": { "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex()))]" }, - "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]", - "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", "subnetResourceId": { "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" }, @@ -10632,11 +11172,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')]" @@ -10664,299 +11201,364 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4120048060064073955" + "version": "0.30.23.60470", + "templateHash": "6724714132049298262" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "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." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "ipConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } } }, - "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": "Required. Properties of private endpoint IP configurations." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, - "lockType": { + "manualPrivateLinkServiceConnectionType": { "type": "object", "properties": { "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Required. The name of the private link service connection." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, + "type": "object", "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." - } + "groupIds": { + "type": "array", + "items": { + "type": "string" }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } - } - }, - "nullable": true - }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." } }, - "metadata": { - "description": "Required. Properties of private link service connection." + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } + }, + "metadata": { + "description": "Required. Properties of private link service connection." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", + "privateLinkServiceConnectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, + "type": "object", "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } + "groupIds": { + "type": "array", + "items": { + "type": "string" }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } + "metadata": { + "description": "Required. 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 `[]`." } }, - "metadata": { - "description": "Required. Properties of private link service connection." + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } + }, + "metadata": { + "description": "Required. Properties of private link service connection." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } + "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" }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", "metadata": { - "description": "Required. Name of the private endpoint resource to create." + "__bicep_export!": true } }, - "subnetResourceId": { - "type": "string", + "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": "Required. Resource ID of the subnet where the endpoint needs to be created." + "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" + } } }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "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": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } } }, - "customNetworkInterfaceName": { + "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": { + "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." + "description": "Required. Name of the private endpoint resource to create." } }, - "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", + "subnetResourceId": { + "type": "string", "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, - "privateDnsZoneGroupName": { + "customNetworkInterfaceName": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, - "privateDnsZoneResourceIds": { + "ipConfigurations": { "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "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." + } + }, + "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": { @@ -10968,12 +11570,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." } @@ -10986,19 +11593,31 @@ } }, "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." } }, "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { "description": "Optional. A grouping of information about the connection to the remote resource." } @@ -11012,6 +11631,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')]", @@ -11022,15 +11648,15 @@ "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": { "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.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -11048,7 +11674,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -11089,27 +11715,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))]", @@ -11120,28 +11746,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.30.23.60470", + "templateHash": "12329174801198479603" }, "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", @@ -11149,12 +11799,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": { @@ -11168,27 +11821,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", @@ -11246,14 +11908,35 @@ "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": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The resource IDs of the network interfaces associated with the private endpoint." + }, + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" }, "groupId": { "type": "string", + "nullable": true, "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": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" } } } @@ -11286,8 +11969,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "9473195527943694039" + "version": "0.32.4.45862", + "templateHash": "13043152240974749163" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", @@ -11353,7 +12036,7 @@ "storageAccount_localUsers": { "copy": { "name": "storageAccount_localUsers", - "count": "[length(parameters('localUsers'))]" + "count": "[length(coalesce(parameters('localUsers'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -11368,25 +12051,25 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('localUsers')[copyIndex()].name]" + "value": "[coalesce(parameters('localUsers'), createArray())[copyIndex()].name]" }, "hasSshKey": { - "value": "[parameters('localUsers')[copyIndex()].hasSshKey]" + "value": "[coalesce(parameters('localUsers'), createArray())[copyIndex()].hasSshKey]" }, "hasSshPassword": { - "value": "[parameters('localUsers')[copyIndex()].hasSshPassword]" + "value": "[coalesce(parameters('localUsers'), createArray())[copyIndex()].hasSshPassword]" }, "permissionScopes": { - "value": "[parameters('localUsers')[copyIndex()].permissionScopes]" + "value": "[coalesce(parameters('localUsers'), createArray())[copyIndex()].permissionScopes]" }, "hasSharedKey": { - "value": "[tryGet(parameters('localUsers')[copyIndex()], 'hasSharedKey')]" + "value": "[tryGet(coalesce(parameters('localUsers'), createArray())[copyIndex()], 'hasSharedKey')]" }, "homeDirectory": { - "value": "[tryGet(parameters('localUsers')[copyIndex()], 'homeDirectory')]" + "value": "[tryGet(coalesce(parameters('localUsers'), createArray())[copyIndex()], 'homeDirectory')]" }, "sshAuthorizedKeys": { - "value": "[tryGet(parameters('localUsers')[copyIndex()], 'sshAuthorizedKeys')]" + "value": "[tryGet(coalesce(parameters('localUsers'), createArray())[copyIndex()], 'sshAuthorizedKeys')]" } }, "template": { @@ -11396,43 +12079,60 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "14968464858285923305" + "version": "0.32.4.45862", + "templateHash": "10324618530995904011" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", "owner": "Azure/module-maintainers" }, "definitions": { - "sshAuthorizedKeysType": { - "type": "secureObject", + "sshAuthorizedKeyType": { + "type": "object", "properties": { - "secureList": { - "type": "array", - "items": { - "type": "object", - "properties": { - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Description used to store the function/usage of the key." - } - }, - "key": { - "type": "string", - "metadata": { - "description": "Required. SSH public key base64 encoded. The format should be: '{keyType} {keyData}', e.g. ssh-rsa AAAABBBB." - } - } - } - }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Description used to store the function/usage of the key." + } + }, + "key": { + "type": "securestring", "metadata": { - "description": "Optional. The list of SSH authorized keys." + "description": "Required. SSH public key base64 encoded. The format should be: '{keyType} {keyData}', e.g. ssh-rsa AAAABBBB." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } + }, + "permissionScopeType": { + "type": "object", + "properties": { + "permissions": { + "type": "string", + "metadata": { + "description": "Required. The permissions for the local user. Possible values include: Read (r), Write (w), Delete (d), List (l), and Create (c)." + } + }, + "resourceName": { + "type": "string", + "metadata": { + "description": "Required. The name of resource, normally the container name or the file share name, used by the local user." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service used by the local user, e.g. blob, file." + } + } + }, + "metadata": { + "__bicep_export!": true + } } }, "parameters": { @@ -11477,12 +12177,19 @@ }, "permissionScopes": { "type": "array", + "items": { + "$ref": "#/definitions/permissionScopeType" + }, "metadata": { "description": "Required. The permission scopes of the local user." } }, "sshAuthorizedKeys": { - "$ref": "#/definitions/sshAuthorizedKeysType", + "type": "array", + "items": { + "$ref": "#/definitions/sshAuthorizedKeyType" + }, + "nullable": true, "metadata": { "description": "Optional. The local user SSH authorized keys for SFTP." } @@ -11505,11 +12212,8 @@ "hasSshPassword": "[parameters('hasSshPassword')]", "homeDirectory": "[parameters('homeDirectory')]", "permissionScopes": "[parameters('permissionScopes')]", - "sshAuthorizedKeys": "[tryGet(parameters('sshAuthorizedKeys'), 'secureList')]" - }, - "dependsOn": [ - "storageAccount" - ] + "sshAuthorizedKeys": "[parameters('sshAuthorizedKeys')]" + } } }, "outputs": { @@ -11614,133 +12318,135 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "2306287879023715578" + "version": "0.32.4.45862", + "templateHash": "17622492193190468017" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", "owner": "Azure/module-maintainers" }, "definitions": { - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } + "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 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": "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.4.0" + } + } } }, "parameters": { @@ -11871,7 +12577,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -11974,6 +12684,9 @@ "storageAccountName": { "value": "[parameters('storageAccountName')]" }, + "blobServiceName": { + "value": "[variables('name')]" + }, "name": { "value": "[coalesce(parameters('containers'), createArray())[copyIndex()].name]" }, @@ -12012,8 +12725,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7045309160947869799" + "version": "0.32.4.45862", + "templateHash": "8294501714202659478" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -12021,70 +12734,79 @@ }, "definitions": { "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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.4.0" + } + } } }, "parameters": { @@ -12095,6 +12817,13 @@ "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." } }, + "blobServiceName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the parent Blob Service. Required if the template is used in a standalone deployment." + } + }, "name": { "type": "string", "metadata": { @@ -12170,19 +12899,30 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", @@ -12198,10 +12938,7 @@ "existing": true, "type": "Microsoft.Storage/storageAccounts/blobServices", "apiVersion": "2022-09-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", - "dependsOn": [ - "storageAccount" - ] + "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('blobServiceName'))]" }, "storageAccount": { "existing": true, @@ -12212,7 +12949,7 @@ "container": { "type": "Microsoft.Storage/storageAccounts/blobServices/containers", "apiVersion": "2022-09-01", - "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]", "properties": { "defaultEncryptionScope": "[if(not(empty(parameters('defaultEncryptionScope'))), parameters('defaultEncryptionScope'), null())]", "denyEncryptionScopeOverride": "[if(equals(parameters('denyEncryptionScopeOverride'), true()), parameters('denyEncryptionScopeOverride'), null())]", @@ -12221,28 +12958,25 @@ "immutableStorageWithVersioning": "[if(equals(parameters('immutableStorageWithVersioningEnabled'), true()), createObject('enabled', parameters('immutableStorageWithVersioningEnabled')), null())]", "metadata": "[parameters('metadata')]", "publicAccess": "[parameters('publicAccess')]" - }, - "dependsOn": [ - "storageAccount::blobServices" - ] + } }, "container_roleAssignments": { "copy": { "name": "container_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}/containers/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}/containers/{2}', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), parameters('blobServiceName'), 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": [ "container" @@ -12281,8 +13015,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "2543276032744560941" + "version": "0.32.4.45862", + "templateHash": "13544771409253577128" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", @@ -12362,8 +13096,7 @@ } }, "dependsOn": [ - "container", - "storageAccount" + "container" ] } }, @@ -12380,7 +13113,7 @@ "metadata": { "description": "The resource ID of the deployed container." }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), 'default', parameters('name'))]" + "value": "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('storageAccountName'), parameters('blobServiceName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -12393,7 +13126,7 @@ } }, "dependsOn": [ - "storageAccount" + "blobServices" ] } }, @@ -12460,133 +13193,135 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7463227074634701879" + "version": "0.32.4.45862", + "templateHash": "16770140342047484752" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", "owner": "Azure/module-maintainers" }, "definitions": { - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } + "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." - } - }, - "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." + "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`." + } + } } }, - "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.4.0" + } + } } }, "parameters": { @@ -12622,7 +13357,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -12649,10 +13388,7 @@ "properties": { "protocolSettings": "[parameters('protocolSettings')]", "shareDeleteRetentionPolicy": "[parameters('shareDeleteRetentionPolicy')]" - }, - "dependsOn": [ - "storageAccount" - ] + } }, "fileServices_diagnosticSettings": { "copy": { @@ -12741,8 +13477,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "1342480740201032357" + "version": "0.32.4.45862", + "templateHash": "14754019327939013287" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -12750,70 +13486,79 @@ }, "definitions": { "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "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.4.0" + } + } } }, "parameters": { @@ -12881,7 +13626,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -12892,10 +13641,7 @@ "existing": true, "type": "Microsoft.Storage/storageAccounts/fileServices", "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]", - "dependsOn": [ - "storageAccount" - ] + "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]" }, "storageAccount": { "existing": true, @@ -12912,10 +13658,7 @@ "shareQuota": "[parameters('shareQuota')]", "rootSquash": "[if(equals(parameters('enabledProtocols'), 'NFS'), parameters('rootSquash'), null())]", "enabledProtocols": "[parameters('enabledProtocols')]" - }, - "dependsOn": [ - "storageAccount::fileService" - ] + } }, "fileShare_roleAssignments": { "condition": "[not(empty(parameters('roleAssignments')))]", @@ -12941,8 +13684,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "8779226603522513073" + "version": "0.32.4.45862", + "templateHash": "15649989472241817249" } }, "parameters": { @@ -12960,6 +13703,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)))))]" + } + ], "$fxv#0": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", @@ -13058,7 +13808,7 @@ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", @@ -13072,7 +13822,7 @@ { "copy": { "name": "fileShare_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -13088,28 +13838,28 @@ "value": "[replace(parameters('fileShareResourceId'), '/shares/', '/fileShares/')]" }, "name": { - "value": "[guid(parameters('fileShareResourceId'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, 'tyfa')]" + "value": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(parameters('fileShareResourceId'), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId, 'tyfa'))]" }, "roleDefinitionId": { - "value": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]" + "value": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]" }, "principalId": { - "value": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]" + "value": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]" }, "principalType": { - "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]" + "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]" }, "description": { - "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]" + "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]" }, "condition": { - "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]" + "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]" }, "conditionVersion": { - "value": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]" + "value": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]" }, "delegatedManagedIdentityResourceId": { - "value": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "value": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" } } } @@ -13148,8 +13898,3114 @@ } }, "dependsOn": [ - "fileServices", - "storageAccount" + "fileServices", + "storageAccount" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('storageAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_queueServices": { + "condition": "[not(empty(parameters('queueServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-QueueServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('queueServices'), 'diagnosticSettings')]" + }, + "queues": { + "value": "[tryGet(parameters('queueServices'), 'queues')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "15558678445347429038" + }, + "name": "Storage Account Queue Services", + "description": "This module deploys a Storage Account Queue Service.", + "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" + } + } + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "queues": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Queues to create." + } + }, + "diagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "name": "default" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "queueServices": { + "type": "Microsoft.Storage/storageAccounts/queueServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", + "properties": {} + }, + "queueServices_diagnosticSettings": { + "copy": { + "name": "queueServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "queueServices" + ] + }, + "queueServices_queues": { + "copy": { + "name": "queueServices_queues", + "count": "[length(coalesce(parameters('queues'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Queue-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "name": { + "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'metadata')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "11255566639202978270" + }, + "name": "Storage Account Queues", + "description": "This module deploys a Storage Account Queue.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "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": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the storage queue to deploy." + } + }, + "metadata": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. A name-value pair that represents queue metadata." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", + "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", + "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", + "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "storageAccount::queueServices": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/queueServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]" + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "queue": { + "type": "Microsoft.Storage/storageAccounts/queueServices/queues", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]" + } + }, + "queue_roleAssignments": { + "copy": { + "name": "queue_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}/queues/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "queue" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed queue." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed queue." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed queue." + }, + "value": "[resourceGroup().name]" + } + } + } + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[variables('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccountName'), variables('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "storageAccount_tableServices": { + "condition": "[not(empty(parameters('tableServices')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Storage-TableServices', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[parameters('name')]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('tableServices'), 'diagnosticSettings')]" + }, + "tables": { + "value": "[tryGet(parameters('tableServices'), 'tables')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "3329223749131374550" + }, + "name": "Storage Account Table Services", + "description": "This module deploys a Storage Account Table Service.", + "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" + } + } + } + }, + "parameters": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "tables": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. tables to create." + } + }, + "diagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "name": "default" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "tableServices": { + "type": "Microsoft.Storage/storageAccounts/tableServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", + "properties": {} + }, + "tableServices_diagnosticSettings": { + "copy": { + "name": "tableServices_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "tableServices" + ] + }, + "tableServices_tables": { + "copy": { + "name": "tableServices_tables", + "count": "[length(parameters('tables'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Table-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('tables')[copyIndex()].name]" + }, + "storageAccountName": { + "value": "[parameters('storageAccountName')]" + }, + "roleAssignments": { + "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "10161610446497418516" + }, + "name": "Storage Account Table", + "description": "This module deploys a Storage Account Table.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "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": { + "storageAccountName": { + "type": "string", + "maxLength": 24, + "metadata": { + "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the table." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", + "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "storageAccount::tableServices": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts/tableServices", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]" + }, + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-04-01", + "name": "[parameters('storageAccountName')]" + }, + "table": { + "type": "Microsoft.Storage/storageAccounts/tableServices/tables", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "table_roleAssignments": { + "copy": { + "name": "table_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}/tables/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "table" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed file share service." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed file share service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed file share service." + }, + "value": "[resourceGroup().name]" + } + } + } + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed table service." + }, + "value": "[variables('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed table service." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccountName'), variables('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed table service." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + }, + "secretsExport": { + "condition": "[not(equals(parameters('secretsExportConfiguration'), null()))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secrets-kv', uniqueString(deployment().name, parameters('location')))]", + "subscriptionId": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '////'), '/')[4]]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[last(split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/'))]" + }, + "secretsToSet": { + "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'accessKey1'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey1, 'value', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[0].value)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'connectionString1'), createArray(createObject('name', parameters('secretsExportConfiguration').connectionString1, 'value', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix=core.windows.net', parameters('name'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[0].value))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'accessKey2'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey2, 'value', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[1].value)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'connectionString2'), createArray(createObject('name', parameters('secretsExportConfiguration').connectionString2, 'value', format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix=core.windows.net', parameters('name'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '2023-05-01').keys[1].value))), createArray()))]" + } + }, + "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.32.4.45862", + "templateHash": "7228569789039191996" + } + }, + "definitions": { + "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" + } + } + }, + "secretToSetType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret to set." + } + }, + "value": { + "type": "securestring", + "metadata": { + "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" + } + } + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Key Vault to set the ecrets in." + } + }, + "secretsToSet": { + "type": "array", + "items": { + "$ref": "#/definitions/secretToSetType" + }, + "metadata": { + "description": "Required. The secrets to set in the Key Vault." + } + } + }, + "resources": { + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[parameters('keyVaultName')]" + }, + "secrets": { + "copy": { + "name": "secrets", + "count": "[length(parameters('secretsToSet'))]" + }, + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]", + "properties": { + "value": "[parameters('secretsToSet')[copyIndex()].value]" + } + } + }, + "outputs": { + "secretsSet": { + "type": "array", + "items": { + "$ref": "#/definitions/secretSetOutputType" + }, + "metadata": { + "description": "The references to the secrets exported to the provided Key Vault." + }, + "copy": { + "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]", + "secretUriWithVersion": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUriWithVersion]" + } + } + } + } + } + }, + "dependsOn": [ + "storageAccount" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed storage account." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed storage account." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed storage account." + }, + "value": "[resourceGroup().name]" + }, + "primaryBlobEndpoint": { + "type": "string", + "metadata": { + "description": "The primary blob endpoint reference if blob services are deployed." + }, + "value": "[if(and(not(empty(parameters('blobServices'))), contains(parameters('blobServices'), 'containers')), reference(format('Microsoft.Storage/storageAccounts/{0}', parameters('name')), '2019-04-01').primaryEndpoints.blob, '')]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[tryGet(tryGet(reference('storageAccount', '2023-05-01', 'full'), 'identity'), 'principalId')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('storageAccount', '2023-05-01', 'full').location]" + }, + "serviceEndpoints": { + "type": "object", + "metadata": { + "description": "All service endpoints of the deployed storage account, Note Standard_LRS and Standard_ZRS accounts only have a blob service endpoint." + }, + "value": "[reference('storageAccount').primaryEndpoints]" + }, + "privateEndpoints": { + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointOutputType" + }, + "metadata": { + "description": "The private endpoints of the Storage Account." + }, + "copy": { + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]", + "input": { + "name": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfigs": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceResourceIds": "[reference(format('storageAccount_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" + } + } + }, + "exportedSecrets": { + "$ref": "#/definitions/secretsOutputType", + "metadata": { + "description": "A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name." + }, + "value": "[if(not(equals(parameters('secretsExportConfiguration'), null())), toObject(reference('secretsExport').outputs.secretsSet.value, lambda('secret', last(split(lambdaVariables('secret').secretResourceId, '/'))), lambda('secret', lambdaVariables('secret'))), createObject())]" + } + } + } + }, + "dependsOn": [ + "createDsVnet", + "createRoleAssignmentsDeploymentScriptStorageAccount", + "dsFilePrivateDNSZone" + ] + }, + "dsFilePrivateDNSZone": { + "condition": "[not(empty(parameters('resourceProviders')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[variables('deploymentNames').createDsFilePrivateDnsZone]", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('deploymentScriptResourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('privatelink.file.{0}', environment().suffixes.storage)]" + }, + "location": { + "value": "global" + }, + "virtualNetworkLinks": { + "value": [ + { + "registrationEnabled": false, + "virtualNetworkResourceId": "[reference('createDsVnet').outputs.resourceId.value]" + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "83178825086050429" + }, + "name": "Private DNS Zones", + "description": "This module deploys a Private DNS zone.", + "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 + }, + "aType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "aRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ipv4Address": { + "type": "string", + "metadata": { + "description": "Required. The IPv4 address of this A record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of A records in the record set." + } + } + } + }, + "nullable": true + }, + "aaaaType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "aaaaRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ipv6Address": { + "type": "string", + "metadata": { + "description": "Required. The IPv6 address of this AAAA record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of AAAA records in the record set." + } + } + } + }, + "nullable": true + }, + "cnameType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "cnameRecord": { + "type": "object", + "properties": { + "cname": { + "type": "string", + "metadata": { + "description": "Required. The canonical name of the CNAME record." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The CNAME record in the record set." + } + } + } + }, + "nullable": true + }, + "mxType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "mxRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "exchange": { + "type": "string", + "metadata": { + "description": "Required. The domain name of the mail host for this MX record." + } + }, + "preference": { + "type": "int", + "metadata": { + "description": "Required. The preference value for this MX record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of MX records in the record set." + } + } + } + }, + "nullable": true + }, + "ptrType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "ptrRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ptrdname": { + "type": "string", + "metadata": { + "description": "Required. The PTR target domain name for this PTR record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of PTR records in the record set." + } + } + } + }, + "nullable": true + }, + "soaType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "soaRecord": { + "type": "object", + "properties": { + "email": { + "type": "string", + "metadata": { + "description": "Required. The email contact for this SOA record." + } + }, + "expireTime": { + "type": "int", + "metadata": { + "description": "Required. The expire time for this SOA record." + } + }, + "host": { + "type": "string", + "metadata": { + "description": "Required. The domain name of the authoritative name server for this SOA record." + } + }, + "minimumTtl": { + "type": "int", + "metadata": { + "description": "Required. The minimum value for this SOA record. By convention this is used to determine the negative caching duration." + } + }, + "refreshTime": { + "type": "int", + "metadata": { + "description": "Required. The refresh value for this SOA record." + } + }, + "retryTime": { + "type": "int", + "metadata": { + "description": "Required. The retry time for this SOA record." + } + }, + "serialNumber": { + "type": "int", + "metadata": { + "description": "Required. The serial number for this SOA record." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The SOA record in the record set." + } + } + } + }, + "nullable": true + }, + "srvType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "srvRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "priority": { + "type": "int", + "metadata": { + "description": "Required. The priority value for this SRV record." + } + }, + "weight": { + "type": "int", + "metadata": { + "description": "Required. The weight value for this SRV record." + } + }, + "port": { + "type": "int", + "metadata": { + "description": "Required. The port value for this SRV record." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Required. The target domain name for this SRV record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of SRV records in the record set." + } + } + } + }, + "nullable": true + }, + "txtType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata of the record." + } + }, + "ttl": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The TTL of the record." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "txtRecords": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The text value of this TXT record." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of TXT records in the record set." + } + } + } + }, + "nullable": true + }, + "virtualNetworkLinkType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "minLength": 1, + "maxLength": 80, + "metadata": { + "description": "Optional. The resource name." + } + }, + "virtualNetworkResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the virtual network to link." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Azure Region where the resource lives." + } + }, + "registrationEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled?." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "resolutionPolicy": { + "type": "string", + "allowedValues": [ + "Default", + "NxDomainRedirect" + ], + "nullable": true, + "metadata": { + "description": "Optional. The resolution type of the private-dns-zone fallback machanism." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Private DNS zone name." + } + }, + "a": { + "$ref": "#/definitions/aType", + "metadata": { + "description": "Optional. Array of A records." + } + }, + "aaaa": { + "$ref": "#/definitions/aaaaType", + "metadata": { + "description": "Optional. Array of AAAA records." + } + }, + "cname": { + "$ref": "#/definitions/cnameType", + "metadata": { + "description": "Optional. Array of CNAME records." + } + }, + "mx": { + "$ref": "#/definitions/mxType", + "metadata": { + "description": "Optional. Array of MX records." + } + }, + "ptr": { + "$ref": "#/definitions/ptrType", + "metadata": { + "description": "Optional. Array of PTR records." + } + }, + "soa": { + "$ref": "#/definitions/soaType", + "metadata": { + "description": "Optional. Array of SOA records." + } + }, + "srv": { + "$ref": "#/definitions/srvType", + "metadata": { + "description": "Optional. Array of SRV records." + } + }, + "txt": { + "$ref": "#/definitions/txtType", + "metadata": { + "description": "Optional. Array of TXT records." + } + }, + "virtualNetworkLinks": { + "$ref": "#/definitions/virtualNetworkLinkType", + "metadata": { + "description": "Optional. Array of custom objects describing vNet links of the DNS zone. Each object should contain properties 'virtualNetworkResourceId' and 'registrationEnabled'. The 'vnetResourceId' is a resource ID of a vNet to link, 'registrationEnabled' (bool) enables automatic DNS registration in the zone for the linked vNet." + } + }, + "location": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Optional. The location of the PrivateDNSZone. Should be global." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privatednszone.{0}.{1}', replace('0.7.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateDnsZone": { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]" + }, + "privateDnsZone_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{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": [ + "privateDnsZone" + ] + }, + "privateDnsZone_roleAssignments": { + "copy": { + "name": "privateDnsZone_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_A": { + "copy": { + "name": "privateDnsZone_A", + "count": "[length(coalesce(parameters('a'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-ARecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('a'), createArray())[copyIndex()].name]" + }, + "aRecords": { + "value": "[tryGet(coalesce(parameters('a'), createArray())[copyIndex()], 'aRecords')]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('a'), createArray())[copyIndex()], 'metadata')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('a'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('a'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "2531120132215940282" + }, + "name": "Private DNS Zone A record", + "description": "This module deploys a Private DNS Zone A record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the A record." + } + }, + "aRecords": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of A records in the record set." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "A": { + "type": "Microsoft.Network/privateDnsZones/A", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "aRecords": "[parameters('aRecords')]", + "metadata": "[parameters('metadata')]", + "ttl": "[parameters('ttl')]" + } + }, + "A_roleAssignments": { + "copy": { + "name": "A_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/A/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/A', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "A" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed A record." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed A record." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/A', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed A record." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_AAAA": { + "copy": { + "name": "privateDnsZone_AAAA", + "count": "[length(coalesce(parameters('aaaa'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-AAAARecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('aaaa'), createArray())[copyIndex()].name]" + }, + "aaaaRecords": { + "value": "[tryGet(coalesce(parameters('aaaa'), createArray())[copyIndex()], 'aaaaRecords')]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('aaaa'), createArray())[copyIndex()], 'metadata')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('aaaa'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('aaaa'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "16709340450244912125" + }, + "name": "Private DNS Zone AAAA record", + "description": "This module deploys a Private DNS Zone AAAA record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the AAAA record." + } + }, + "aaaaRecords": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of AAAA records in the record set." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "AAAA": { + "type": "Microsoft.Network/privateDnsZones/AAAA", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "aaaaRecords": "[parameters('aaaaRecords')]", + "metadata": "[parameters('metadata')]", + "ttl": "[parameters('ttl')]" + } + }, + "AAAA_roleAssignments": { + "copy": { + "name": "AAAA_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/AAAA/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/AAAA', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "AAAA" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed AAAA record." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed AAAA record." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/AAAA', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed AAAA record." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_CNAME": { + "copy": { + "name": "privateDnsZone_CNAME", + "count": "[length(coalesce(parameters('cname'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-CNAMERecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('cname'), createArray())[copyIndex()].name]" + }, + "cnameRecord": { + "value": "[tryGet(coalesce(parameters('cname'), createArray())[copyIndex()], 'cnameRecord')]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('cname'), createArray())[copyIndex()], 'metadata')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('cname'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('cname'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "9976020649752073181" + }, + "name": "Private DNS Zone CNAME record", + "description": "This module deploys a Private DNS Zone CNAME record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the CNAME record." + } + }, + "cnameRecord": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. A CNAME record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "CNAME": { + "type": "Microsoft.Network/privateDnsZones/CNAME", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "cnameRecord": "[parameters('cnameRecord')]", + "metadata": "[parameters('metadata')]", + "ttl": "[parameters('ttl')]" + } + }, + "CNAME_roleAssignments": { + "copy": { + "name": "CNAME_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/CNAME/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/CNAME', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "CNAME" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed CNAME record." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed CNAME record." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/CNAME', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed CNAME record." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_MX": { + "copy": { + "name": "privateDnsZone_MX", + "count": "[length(coalesce(parameters('mx'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-MXRecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('mx'), createArray())[copyIndex()].name]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('mx'), createArray())[copyIndex()], 'metadata')]" + }, + "mxRecords": { + "value": "[tryGet(coalesce(parameters('mx'), createArray())[copyIndex()], 'mxRecords')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('mx'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('mx'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "2520323624213076361" + }, + "name": "Private DNS Zone MX record", + "description": "This module deploys a Private DNS Zone MX record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the MX record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "mxRecords": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of MX records in the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "MX": { + "type": "Microsoft.Network/privateDnsZones/MX", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]", + "mxRecords": "[parameters('mxRecords')]", + "ttl": "[parameters('ttl')]" + } + }, + "MX_roleAssignments": { + "copy": { + "name": "MX_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/MX/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/MX', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "MX" ] } }, @@ -13157,21 +17013,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the deployed file share service." + "description": "The name of the deployed MX record." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the deployed file share service." + "description": "The resource ID of the deployed MX record." }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('storageAccountName'), parameters('name'))]" + "value": "[resourceId('Microsoft.Network/privateDnsZones/MX', parameters('privateDnsZoneName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group of the deployed file share service." + "description": "The resource group of the deployed MX record." }, "value": "[resourceGroup().name]" } @@ -13179,28 +17035,40 @@ } }, "dependsOn": [ - "storageAccount" + "privateDnsZone" ] }, - "storageAccount_queueServices": { - "condition": "[not(empty(parameters('queueServices')))]", + "privateDnsZone_PTR": { + "copy": { + "name": "privateDnsZone_PTR", + "count": "[length(coalesce(parameters('ptr'), createArray()))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Storage-QueueServices', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('{0}-PrivateDnsZone-PTRRecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "storageAccountName": { + "privateDnsZoneName": { "value": "[parameters('name')]" }, - "diagnosticSettings": { - "value": "[tryGet(parameters('queueServices'), 'diagnosticSettings')]" + "name": { + "value": "[coalesce(parameters('ptr'), createArray())[copyIndex()].name]" }, - "queues": { - "value": "[tryGet(parameters('queueServices'), 'queues')]" + "metadata": { + "value": "[tryGet(coalesce(parameters('ptr'), createArray())[copyIndex()], 'metadata')]" + }, + "ptrRecords": { + "value": "[tryGet(coalesce(parameters('ptr'), createArray())[copyIndex()], 'ptrRecords')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('ptr'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('ptr'), createArray())[copyIndex()], 'roleAssignments')]" } }, "template": { @@ -13210,15 +17078,15 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "10678250016540336570" + "version": "0.32.4.45862", + "templateHash": "3080404733048745471" }, - "name": "Storage Account Queue Services", - "description": "This module deploys a Storage Account Queue Service.", + "name": "Private DNS Zone PTR record", + "description": "This module deploys a Private DNS Zone PTR record.", "owner": "Azure/module-maintainers" }, "definitions": { - "diagnosticSettingType": { + "roleAssignmentType": { "type": "array", "items": { "type": "object", @@ -13227,111 +17095,64 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of diagnostic setting." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "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, + "roleDefinitionIdOrName": { + "type": "string", "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." + "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'." } }, - "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, + "principalId": { + "type": "string", "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." + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." } }, - "logAnalyticsDestinationType": { + "principalType": { "type": "string", "allowedValues": [ - "AzureDiagnostics", - "Dedicated" + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" ], "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." + "description": "Optional. The principal type of the assigned principal ID." } }, - "storageAccountResourceId": { + "description": { "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." + "description": "Optional. The description of the role assignment." } }, - "eventHubAuthorizationRuleResourceId": { + "condition": { "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." + "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\"." } }, - "eventHubName": { + "conditionVersion": { "type": "string", + "allowedValues": [ + "2.0" + ], "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." + "description": "Optional. Version of the condition." } }, - "marketplacePartnerResourceId": { + "delegatedManagedIdentityResourceId": { "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." + "description": "Optional. The Resource Id of the delegated managed identity resource." } } } @@ -13340,318 +17161,351 @@ } }, "parameters": { - "storageAccountName": { + "privateDnsZoneName": { "type": "string", - "maxLength": 24, "metadata": { - "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." } }, - "queues": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the PTR record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "ptrRecords": { "type": "array", "nullable": true, "metadata": { - "description": "Optional. Queues to create." + "description": "Optional. The list of PTR records in the record set." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "ttl": { + "type": "int", + "defaultValue": 3600, "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." } } }, "variables": { - "name": "default" + "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')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } }, "resources": { - "storageAccount": { + "privateDnsZone": { "existing": true, - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-04-01", - "name": "[parameters('storageAccountName')]" - }, - "queueServices": { - "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", - "properties": {}, - "dependsOn": [ - "storageAccount" - ] + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "PTR": { + "type": "Microsoft.Network/privateDnsZones/PTR", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]", + "ptrRecords": "[parameters('ptrRecords')]", + "ttl": "[parameters('ttl')]" + } }, - "queueServices_diagnosticSettings": { + "PTR_roleAssignments": { "copy": { - "name": "queueServices_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + "name": "PTR_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}', parameters('storageAccountName'), variables('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/PTR/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/PTR', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "properties": { - "copy": [ - { - "name": "metrics", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", - "input": { - "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", - "timeGrain": null - } - }, - { - "name": "logs", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", - "input": { - "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", - "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" - } - } - ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + "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": [ - "queueServices" + "PTR" ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed PTR record." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed PTR record." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/PTR', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed PTR record." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_SOA": { + "copy": { + "name": "privateDnsZone_SOA", + "count": "[length(coalesce(parameters('soa'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-SOARecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('soa'), createArray())[copyIndex()].name]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('soa'), createArray())[copyIndex()], 'metadata')]" + }, + "soaRecord": { + "value": "[tryGet(coalesce(parameters('soa'), createArray())[copyIndex()], 'soaRecord')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('soa'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('soa'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "6653951445614700931" }, - "queueServices_queues": { - "copy": { - "name": "queueServices_queues", - "count": "[length(coalesce(parameters('queues'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Queue-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "storageAccountName": { - "value": "[parameters('storageAccountName')]" - }, + "name": "Private DNS Zone SOA record", + "description": "This module deploys a Private DNS Zone SOA record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { "name": { - "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]" + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } }, - "metadata": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'metadata')]" + "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'." + } }, - "roleAssignments": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "13487964166280180730" - }, - "name": "Storage Account Queues", - "description": "This module deploys a Storage Account Queue.", - "owner": "Azure/module-maintainers" + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } }, - "definitions": { - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." } }, - "parameters": { - "storageAccountName": { - "type": "string", - "maxLength": 24, - "metadata": { - "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the storage queue to deploy." - } - }, + "description": { + "type": "string", + "nullable": true, "metadata": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Required. A name-value pair that represents queue metadata." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } + "description": "Optional. The description of the role assignment." } }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", - "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", - "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", - "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", - "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + "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\"." } }, - "resources": { - "storageAccount::queueServices": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", - "dependsOn": [ - "storageAccount" - ] - }, - "storageAccount": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-04-01", - "name": "[parameters('storageAccountName')]" - }, - "queue": { - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", - "properties": { - "metadata": "[parameters('metadata')]" - }, - "dependsOn": [ - "storageAccount::queueServices" - ] - }, - "queue_roleAssignments": { - "copy": { - "name": "queue_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/queueServices/{1}/queues/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "queue" - ] + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." } }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed queue." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed queue." - }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices/queues', parameters('storageAccountName'), 'default', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed queue." - }, - "value": "[resourceGroup().name]" + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } } }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the SOA record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "soaRecord": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. A SOA record." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "SOA": { + "type": "Microsoft.Network/privateDnsZones/SOA", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]", + "soaRecord": "[parameters('soaRecord')]", + "ttl": "[parameters('ttl')]" + } + }, + "SOA_roleAssignments": { + "copy": { + "name": "SOA_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/SOA/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/SOA', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, "dependsOn": [ - "storageAccount" + "SOA" ] } }, @@ -13659,21 +17513,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the deployed file share service." + "description": "The name of the deployed SOA record." }, - "value": "[variables('name')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the deployed file share service." + "description": "The resource ID of the deployed SOA record." }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccountName'), variables('name'))]" + "value": "[resourceId('Microsoft.Network/privateDnsZones/SOA', parameters('privateDnsZoneName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group of the deployed file share service." + "description": "The resource group of the deployed SOA record." }, "value": "[resourceGroup().name]" } @@ -13681,28 +17535,40 @@ } }, "dependsOn": [ - "storageAccount" + "privateDnsZone" ] }, - "storageAccount_tableServices": { - "condition": "[not(empty(parameters('tableServices')))]", + "privateDnsZone_SRV": { + "copy": { + "name": "privateDnsZone_SRV", + "count": "[length(coalesce(parameters('srv'), createArray()))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Storage-TableServices', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('{0}-PrivateDnsZone-SRVRecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "storageAccountName": { + "privateDnsZoneName": { "value": "[parameters('name')]" }, - "diagnosticSettings": { - "value": "[tryGet(parameters('tableServices'), 'diagnosticSettings')]" + "name": { + "value": "[coalesce(parameters('srv'), createArray())[copyIndex()].name]" }, - "tables": { - "value": "[tryGet(parameters('tableServices'), 'tables')]" + "metadata": { + "value": "[tryGet(coalesce(parameters('srv'), createArray())[copyIndex()], 'metadata')]" + }, + "srvRecords": { + "value": "[tryGet(coalesce(parameters('srv'), createArray())[copyIndex()], 'srvRecords')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('srv'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('srv'), createArray())[copyIndex()], 'roleAssignments')]" } }, "template": { @@ -13712,15 +17578,15 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "16839054392438941735" + "version": "0.32.4.45862", + "templateHash": "5790774778713328446" }, - "name": "Storage Account Table Services", - "description": "This module deploys a Storage Account Table Service.", + "name": "Private DNS Zone SRV record", + "description": "This module deploys a Private DNS Zone SRV record.", "owner": "Azure/module-maintainers" }, "definitions": { - "diagnosticSettingType": { + "roleAssignmentType": { "type": "array", "items": { "type": "object", @@ -13729,416 +17595,417 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of diagnostic setting." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "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`." - } - } - } - }, + "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 name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + "description": "Optional. The principal type of the assigned principal ID." } }, - "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`." - } - } - } - }, + "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. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + "description": "Optional. Version of the condition." } }, - "logAnalyticsDestinationType": { + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the SRV record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "srvRecords": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of SRV records in the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "SRV": { + "type": "Microsoft.Network/privateDnsZones/SRV", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]", + "srvRecords": "[parameters('srvRecords')]", + "ttl": "[parameters('ttl')]" + } + }, + "SRV_roleAssignments": { + "copy": { + "name": "SRV_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/SRV/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/SRV', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "SRV" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed SRV record." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed SRV record." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/SRV', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed SRV record." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" + ] + }, + "privateDnsZone_TXT": { + "copy": { + "name": "privateDnsZone_TXT", + "count": "[length(coalesce(parameters('txt'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-TXTRecord-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('txt'), createArray())[copyIndex()].name]" + }, + "metadata": { + "value": "[tryGet(coalesce(parameters('txt'), createArray())[copyIndex()], 'metadata')]" + }, + "txtRecords": { + "value": "[tryGet(coalesce(parameters('txt'), createArray())[copyIndex()], 'txtRecords')]" + }, + "ttl": { + "value": "[coalesce(tryGet(coalesce(parameters('txt'), createArray())[copyIndex()], 'ttl'), 3600)]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('txt'), createArray())[copyIndex()], 'roleAssignments')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "1855369119498044639" + }, + "name": "Private DNS Zone TXT record", + "description": "This module deploys a Private DNS Zone TXT record.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "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." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "workspaceResourceId": { + "roleDefinitionIdOrName": { "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." + "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'." } }, - "storageAccountResourceId": { + "principalId": { "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." + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." } }, - "eventHubAuthorizationRuleResourceId": { + "principalType": { "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], "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." + "description": "Optional. The principal type of the assigned principal ID." } }, - "eventHubName": { + "description": { "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." + "description": "Optional. The description of the role assignment." } }, - "marketplacePartnerResourceId": { + "condition": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "storageAccountName": { - "type": "string", - "maxLength": 24, - "metadata": { - "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." - } - }, - "tables": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. tables to create." - } - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } - } - }, - "variables": { - "name": "default" - }, - "resources": { - "storageAccount": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-04-01", - "name": "[parameters('storageAccountName')]" - }, - "tableServices": { - "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", - "properties": {}, - "dependsOn": [ - "storageAccount" - ] - }, - "tableServices_diagnosticSettings": { - "copy": { - "name": "tableServices_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}', parameters('storageAccountName'), variables('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', variables('name')))]", - "properties": { - "copy": [ - { - "name": "metrics", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", - "input": { - "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", - "timeGrain": null - } - }, - { - "name": "logs", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", - "input": { - "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", - "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" - } - } - ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "tableServices" - ] - }, - "tableServices_tables": { - "copy": { - "name": "tableServices_tables", - "count": "[length(parameters('tables'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Table-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('tables')[copyIndex()].name]" - }, - "storageAccountName": { - "value": "[parameters('storageAccountName')]" - }, - "roleAssignments": { - "value": "[tryGet(parameters('tables')[copyIndex()], 'roleAssignments')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3177845984945141330" - }, - "name": "Storage Account Table", - "description": "This module deploys a Storage Account Table.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "storageAccountName": { - "type": "string", - "maxLength": 24, - "metadata": { - "description": "Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the table." - } - } - }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", - "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", - "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + "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\"." } }, - "resources": { - "storageAccount::tableServices": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", - "dependsOn": [ - "storageAccount" - ] - }, - "storageAccount": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-04-01", - "name": "[parameters('storageAccountName')]" - }, - "table": { - "type": "Microsoft.Storage/storageAccounts/tableServices/tables", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", - "dependsOn": [ - "storageAccount::tableServices" - ] - }, - "table_roleAssignments": { - "copy": { - "name": "table_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/tableServices/{1}/tables/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "table" - ] + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." } }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed file share service." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed file share service." - }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices/tables', parameters('storageAccountName'), 'default', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed file share service." - }, - "value": "[resourceGroup().name]" + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } } }, + "nullable": true + } + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the TXT record." + } + }, + "metadata": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The metadata attached to the record set." + } + }, + "ttl": { + "type": "int", + "defaultValue": 3600, + "metadata": { + "description": "Optional. The TTL (time-to-live) of the records in the record set." + } + }, + "txtRecords": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of TXT records in the record set." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "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": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "TXT": { + "type": "Microsoft.Network/privateDnsZones/TXT", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "properties": { + "metadata": "[parameters('metadata')]", + "ttl": "[parameters('ttl')]", + "txtRecords": "[parameters('txtRecords')]" + } + }, + "TXT_roleAssignments": { + "copy": { + "name": "TXT_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateDnsZones/{0}/TXT/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, "dependsOn": [ - "storageAccount" + "TXT" ] } }, @@ -14146,21 +18013,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the deployed table service." + "description": "The name of the deployed TXT record." }, - "value": "[variables('name')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the deployed table service." + "description": "The resource ID of the deployed TXT record." }, - "value": "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccountName'), variables('name'))]" + "value": "[resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group of the deployed table service." + "description": "The resource group of the deployed TXT record." }, "value": "[resourceGroup().name]" } @@ -14168,59 +18035,201 @@ } }, "dependsOn": [ - "storageAccount" + "privateDnsZone" + ] + }, + "privateDnsZone_virtualNetworkLinks": { + "copy": { + "name": "privateDnsZone_virtualNetworkLinks", + "count": "[length(coalesce(parameters('virtualNetworkLinks'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateDnsZone-VirtualNetworkLink-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'name'), format('{0}-vnetlink', last(split(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId, '/'))))]" + }, + "virtualNetworkResourceId": { + "value": "[coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'location'), 'global')]" + }, + "registrationEnabled": { + "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'registrationEnabled'), false())]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "resolutionPolicy": { + "value": "[tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'resolutionPolicy')]" + } + }, + "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.32.4.45862", + "templateHash": "15326596012552051215" + }, + "name": "Private DNS Zone Virtual Network Link", + "description": "This module deploys a Private DNS Zone Virtual Network Link.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateDnsZoneName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[format('{0}-vnetlink', last(split(parameters('virtualNetworkResourceId'), '/')))]", + "metadata": { + "description": "Optional. The name of the virtual network link." + } + }, + "location": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Optional. The location of the PrivateDNSZone. Should be global." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "registrationEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled?." + } + }, + "virtualNetworkResourceId": { + "type": "string", + "metadata": { + "description": "Required. Link to another virtual network resource ID." + } + }, + "resolutionPolicy": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resolution policy on the virtual network link. Only applicable for virtual network links to privatelink zones, and for A,AAAA,CNAME queries. When set to `NxDomainRedirect`, Azure DNS resolver falls back to public resolution if private dns query resolution results in non-existent domain response. `Default` is configured as the default option." + } + } + }, + "resources": { + "privateDnsZone": { + "existing": true, + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[parameters('privateDnsZoneName')]" + }, + "virtualNetworkLink": { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "registrationEnabled": "[parameters('registrationEnabled')]", + "virtualNetwork": { + "id": "[parameters('virtualNetworkResourceId')]" + }, + "resolutionPolicy": "[parameters('resolutionPolicy')]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed virtual network link." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed virtual network link." + }, + "value": "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', parameters('privateDnsZoneName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed virtual network link." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('virtualNetworkLink', '2024-06-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "privateDnsZone" ] } }, "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed storage account." - }, - "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('name'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed storage account." - }, - "value": "[parameters('name')]" - }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group of the deployed storage account." + "description": "The resource group the private DNS zone was deployed into." }, "value": "[resourceGroup().name]" }, - "primaryBlobEndpoint": { + "name": { "type": "string", "metadata": { - "description": "The primary blob endpoint reference if blob services are deployed." + "description": "The name of the private DNS zone." }, - "value": "[if(and(not(empty(parameters('blobServices'))), contains(parameters('blobServices'), 'containers')), reference(format('Microsoft.Storage/storageAccounts/{0}', parameters('name')), '2019-04-01').primaryEndpoints.blob, '')]" + "value": "[parameters('name')]" }, - "systemAssignedMIPrincipalId": { + "resourceId": { "type": "string", "metadata": { - "description": "The principal ID of the system assigned identity." + "description": "The resource ID of the private DNS zone." }, - "value": "[coalesce(tryGet(tryGet(reference('storageAccount', '2022-09-01', 'full'), 'identity'), 'principalId'), '')]" + "value": "[resourceId('Microsoft.Network/privateDnsZones', parameters('name'))]" }, "location": { "type": "string", "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('storageAccount', '2022-09-01', 'full').location]" + "value": "[reference('privateDnsZone', '2020-06-01', 'full').location]" } } } }, "dependsOn": [ - "createDsVnet", - "createRoleAssignmentsDeploymentScriptStorageAccount" + "createDsVnet" ] }, "createDsVnet": { @@ -14247,7 +18256,7 @@ "[parameters('virtualNetworkDeploymentScriptAddressPrefix')]" ] }, - "subnets": "[if(not(empty(parameters('resourceProviders'))), createObject('value', createArray(createObject('addressPrefix', if(not(empty(parameters('resourceProviders'))), cidrSubnet(parameters('virtualNetworkDeploymentScriptAddressPrefix'), 24, 0), null()), 'name', 'ds-subnet-001', 'networkSecurityGroupResourceId', if(not(empty(parameters('resourceProviders'))), reference('createDsNsg').outputs.resourceId.value, null()), 'serviceEndpoints', createArray('Microsoft.Storage'), 'delegation', 'Microsoft.ContainerInstance/containerGroups'))), createObject('value', null()))]", + "subnets": "[if(not(empty(parameters('resourceProviders'))), createObject('value', createArray(createObject('addressPrefix', if(not(empty(parameters('resourceProviders'))), cidrSubnet(parameters('virtualNetworkDeploymentScriptAddressPrefix'), 25, 0), null()), 'name', 'ds-subnet', 'networkSecurityGroupResourceId', if(not(empty(parameters('resourceProviders'))), reference('createDsNsg').outputs.resourceId.value, null()), 'delegation', 'Microsoft.ContainerInstance/containerGroups'), createObject('name', 'ds-pe-subnet', 'addressPrefix', if(not(empty(parameters('resourceProviders'))), cidrSubnet(parameters('virtualNetworkDeploymentScriptAddressPrefix'), 25, 1), null()), 'networkSecurityGroupResourceId', if(not(empty(parameters('resourceProviders'))), reference('createDsNsg').outputs.resourceId.value, null())))), createObject('value', null()))]", "enableTelemetry": { "value": "[parameters('enableTelemetry')]" } @@ -14259,8 +18268,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12023193036665775110" + "version": "0.32.4.45862", + "templateHash": "12002509614878477054" }, "name": "Virtual Networks", "description": "This module deploys a Virtual Network (vNet).", @@ -14625,7 +18634,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" } } }, @@ -14655,7 +18664,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" } } }, @@ -14730,7 +18739,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" } } } @@ -14896,7 +18905,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-virtualnetwork.{0}.{1}', replace('0.5.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -15080,8 +19089,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6411714881793832751" + "version": "0.32.4.45862", + "templateHash": "16307553544578422105" }, "name": "Virtual Network Subnets", "description": "This module deploys a Virtual Network Subnet.", @@ -15159,7 +19168,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" } } } @@ -15168,7 +19177,7 @@ "name": { "type": "string", "metadata": { - "description": "Requird. The Name of the subnet resource." + "description": "Required. The Name of the subnet resource." } }, "virtualNetworkName": { @@ -15349,10 +19358,7 @@ "serviceEndpointPolicies": "[parameters('serviceEndpointPolicies')]", "defaultOutboundAccess": "[parameters('defaultOutboundAccess')]", "sharingScope": "[parameters('sharingScope')]" - }, - "dependsOn": [ - "virtualNetwork" - ] + } }, "subnet_roleAssignments": { "copy": { @@ -15465,8 +19471,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "345394220621166229" + "version": "0.32.4.45862", + "templateHash": "8973052275744789294" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -15623,8 +19629,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "345394220621166229" + "version": "0.32.4.45862", + "templateHash": "8973052275744789294" }, "name": "Virtual Network Peerings", "description": "This module deploys a Virtual Network Peering.", @@ -15810,7 +19816,7 @@ "value": "AzurePowerShell" }, "azPowerShellVersion": { - "value": "3.0" + "value": "12.3" }, "cleanupPreference": { "value": "Always" @@ -15832,7 +19838,7 @@ }, "managedIdentities": "[if(not(empty(parameters('resourceProviders'))), createObject('value', createObject('userAssignedResourcesIds', createArray(reference('createManagedIdentityForDeploymentScript').outputs.resourceId.value))), createObject('value', null()))]", "storageAccountResourceId": "[if(not(empty(parameters('resourceProviders'))), createObject('value', reference('createDsStorageAccount').outputs.resourceId.value), createObject('value', null()))]", - "subnetResourceIds": "[if(not(empty(parameters('resourceProviders'))), createObject('value', reference('createDsVnet').outputs.subnetResourceIds.value), createObject('value', null()))]", + "subnetResourceIds": "[if(not(empty(parameters('resourceProviders'))), createObject('value', createArray(filter(reference('createDsVnet').outputs.subnetResourceIds.value, lambda('subnetResourceId', contains(lambdaVariables('subnetResourceId'), 'ds-subnet')))[0])), createObject('value', null()))]", "arguments": { "value": "[format('-resourceProviders ''{0}'' -resourceProvidersFeatures -subscriptionId {1}', variables('resourceProvidersFormatted'), parameters('subscriptionId'))]" }, diff --git a/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep b/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep index 068205a588..9b945cd645 100644 --- a/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep +++ b/avm/ptn/lz/sub-vending/modules/subResourceWrapper.bicep @@ -261,6 +261,10 @@ var deploymentNames = { 'lz-vend-ds-stg-create-${uniqueString(subscriptionId, deploymentScriptResourceGroupName, deploymentScriptLocation, deploymentScriptStorageAccountName, deployment().name)}', 64 ) + createDsFilePrivateDnsZone: take( + 'lz-vend-ds-pdns-create-${uniqueString(subscriptionId, deploymentScriptResourceGroupName,deploymentScriptLocation,deploymentScriptStorageAccountName, deploymentScriptVirtualNetworkName, deployment().name)}', + 64 + ) } // Role Assignments filtering and splitting @@ -357,7 +361,7 @@ module tagSubscription 'tags.bicep' = if (!empty(subscriptionTags)) { tags: subscriptionTags } } -module createResourceGroupForLzNetworking 'br/public:avm/res/resources/resource-group:0.2.4' = if (virtualNetworkEnabled && !empty(virtualNetworkLocation) && !empty(virtualNetworkResourceGroupName)) { +module createResourceGroupForLzNetworking 'br/public:avm/res/resources/resource-group:0.4.1' = if (virtualNetworkEnabled && !empty(virtualNetworkLocation) && !empty(virtualNetworkResourceGroupName)) { scope: subscription(subscriptionId) name: deploymentNames.createResourceGroupForLzNetworking params: { @@ -387,7 +391,7 @@ module tagResourceGroup 'tags.bicep' = if (virtualNetworkEnabled && !empty(virtu } } -module createLzVnet 'br/public:avm/res/network/virtual-network:0.5.0' = if (virtualNetworkEnabled && !empty(virtualNetworkName) && !empty(virtualNetworkAddressSpace) && !empty(virtualNetworkLocation) && !empty(virtualNetworkResourceGroupName)) { +module createLzVnet 'br/public:avm/res/network/virtual-network:0.5.2' = if (virtualNetworkEnabled && !empty(virtualNetworkName) && !empty(virtualNetworkAddressSpace) && !empty(virtualNetworkLocation) && !empty(virtualNetworkResourceGroupName)) { dependsOn: [ createResourceGroupForLzNetworking ] @@ -446,7 +450,7 @@ module createLzVirtualWanConnection 'hubVirtualNetworkConnections.bicep' = if (v } } -module createLzRoleAssignmentsSub 'br/public:avm/ptn/authorization/role-assignment:0.1.1' = [ +module createLzRoleAssignmentsSub 'br/public:avm/ptn/authorization/role-assignment:0.2.1' = [ for assignment in roleAssignmentsSubscription: if (roleAssignmentEnabled && !empty(roleAssignmentsSubscription)) { name: take( '${deploymentNames.createLzRoleAssignmentsSub}-${uniqueString(assignment.principalId, assignment.definition, assignment.relativeScope)}', @@ -477,7 +481,7 @@ module createLzRoleAssignmentsSub 'br/public:avm/ptn/authorization/role-assignme } ] -module createLzRoleAssignmentsRsgsSelf 'br/public:avm/ptn/authorization/role-assignment:0.1.1' = [ +module createLzRoleAssignmentsRsgsSelf 'br/public:avm/ptn/authorization/role-assignment:0.2.1' = [ for assignment in roleAssignmentsResourceGroupSelf: if (roleAssignmentEnabled && !empty(roleAssignmentsResourceGroupSelf)) { dependsOn: [ createResourceGroupForLzNetworking @@ -512,7 +516,7 @@ module createLzRoleAssignmentsRsgsSelf 'br/public:avm/ptn/authorization/role-ass } ] -module createLzRoleAssignmentsRsgsNotSelf 'br/public:avm/ptn/authorization/role-assignment:0.1.1' = [ +module createLzRoleAssignmentsRsgsNotSelf 'br/public:avm/ptn/authorization/role-assignment:0.2.1' = [ for assignment in roleAssignmentsResourceGroupNotSelf: if (roleAssignmentEnabled && !empty(roleAssignmentsResourceGroupNotSelf)) { name: take( '${deploymentNames.createLzRoleAssignmentsRsgsNotSelf}-${uniqueString(assignment.principalId, assignment.definition, assignment.relativeScope)}', @@ -544,7 +548,7 @@ module createLzRoleAssignmentsRsgsNotSelf 'br/public:avm/ptn/authorization/role- } ] -module createResourceGroupForDeploymentScript 'br/public:avm/res/resources/resource-group:0.2.4' = if (!empty(resourceProviders)) { +module createResourceGroupForDeploymentScript 'br/public:avm/res/resources/resource-group:0.4.1' = if (!empty(resourceProviders)) { scope: subscription(subscriptionId) name: deploymentNames.createResourceGroupForDeploymentScript params: { @@ -554,7 +558,7 @@ module createResourceGroupForDeploymentScript 'br/public:avm/res/resources/resou } } -module createManagedIdentityForDeploymentScript 'br/public:avm/res/managed-identity/user-assigned-identity:0.2.2' = if (!empty(resourceProviders)) { +module createManagedIdentityForDeploymentScript 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = if (!empty(resourceProviders)) { scope: resourceGroup(subscriptionId, deploymentScriptResourceGroupName) name: deploymentNames.createDeploymentScriptManagedIdentity dependsOn: [ @@ -567,7 +571,7 @@ module createManagedIdentityForDeploymentScript 'br/public:avm/res/managed-ident } } -module createRoleAssignmentsDeploymentScript 'br/public:avm/ptn/authorization/role-assignment:0.1.1' = if (!empty(resourceProviders)) { +module createRoleAssignmentsDeploymentScript 'br/public:avm/ptn/authorization/role-assignment:0.2.1' = if (!empty(resourceProviders)) { name: take('${deploymentNames.createRoleAssignmentsDeploymentScript}', 64) params: { location: deploymentScriptLocation @@ -578,7 +582,7 @@ module createRoleAssignmentsDeploymentScript 'br/public:avm/ptn/authorization/ro } } -module createRoleAssignmentsDeploymentScriptStorageAccount 'br/public:avm/ptn/authorization/role-assignment:0.1.1' = if (!empty(resourceProviders)) { +module createRoleAssignmentsDeploymentScriptStorageAccount 'br/public:avm/ptn/authorization/role-assignment:0.2.1' = if (!empty(resourceProviders)) { name: take('${deploymentNames.createRoleAssignmentsDeploymentScriptStorageAccount}', 64) params: { location: deploymentScriptLocation @@ -587,10 +591,11 @@ module createRoleAssignmentsDeploymentScriptStorageAccount 'br/public:avm/ptn/au subscriptionId: subscriptionId resourceGroupName: deploymentScriptResourceGroupName principalType: 'ServicePrincipal' + description: 'Storage File Data Privileged Contributor' } } -module createDsNsg 'br/public:avm/res/network/network-security-group:0.3.0' = if (!empty(resourceProviders)) { +module createDsNsg 'br/public:avm/res/network/network-security-group:0.5.0' = if (!empty(resourceProviders)) { scope: resourceGroup(subscriptionId, deploymentScriptResourceGroupName) dependsOn: [ createResourceGroupForDeploymentScript @@ -603,7 +608,7 @@ module createDsNsg 'br/public:avm/res/network/network-security-group:0.3.0' = if } } -module createDsStorageAccount 'br/public:avm/res/storage/storage-account:0.9.1' = if (!empty(resourceProviders)) { +module createDsStorageAccount 'br/public:avm/res/storage/storage-account:0.15.0' = if (!empty(resourceProviders)) { dependsOn: [ createRoleAssignmentsDeploymentScriptStorageAccount ] @@ -614,21 +619,49 @@ module createDsStorageAccount 'br/public:avm/res/storage/storage-account:0.9.1' name: deploymentScriptStorageAccountName kind: 'StorageV2' skuName: 'Standard_LRS' + publicNetworkAccess: 'Disabled' + allowSharedKeyAccess: true + privateEndpoints: [ + { + service: 'file' + subnetResourceId: filter( + createDsVnet.outputs.subnetResourceIds, + subnetResourceId => contains(subnetResourceId, 'ds-pe-subnet') + )[0] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: dsFilePrivateDNSZone.outputs.resourceId + } + ] + } + name: 'ds-file-pe' + } + ] networkAcls: { bypass: 'AzureServices' defaultAction: 'Deny' - virtualNetworkRules: [ - { - action: 'Allow' - id: !empty(resourceProviders) ? createDsVnet.outputs.subnetResourceIds[0] : null - } - ] } enableTelemetry: enableTelemetry } } -module createDsVnet 'br/public:avm/res/network/virtual-network:0.5.0' = if (!empty(resourceProviders)) { +module dsFilePrivateDNSZone 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (!empty(resourceProviders)) { + name: deploymentNames.createDsFilePrivateDnsZone + scope: resourceGroup(subscriptionId, deploymentScriptResourceGroupName) + params: { + name: 'privatelink.file.${environment().suffixes.storage}' + location: 'global' + virtualNetworkLinks: [ + { + registrationEnabled: false + virtualNetworkResourceId: createDsVnet.outputs.resourceId + } + ] + } +} + +module createDsVnet 'br/public:avm/res/network/virtual-network:0.5.2' = if (!empty(resourceProviders)) { scope: resourceGroup(subscriptionId, deploymentScriptResourceGroupName) name: deploymentNames.createdsVnet params: { @@ -641,28 +674,31 @@ module createDsVnet 'br/public:avm/res/network/virtual-network:0.5.0' = if (!emp ? [ { addressPrefix: !empty(resourceProviders) - ? cidrSubnet(virtualNetworkDeploymentScriptAddressPrefix, 24, 0) + ? cidrSubnet(virtualNetworkDeploymentScriptAddressPrefix, 25, 0) : null - name: 'ds-subnet-001' + name: 'ds-subnet' networkSecurityGroupResourceId: !empty(resourceProviders) ? createDsNsg.outputs.resourceId : null - serviceEndpoints: [ - 'Microsoft.Storage' - ] delegation: 'Microsoft.ContainerInstance/containerGroups' } + { + name: 'ds-pe-subnet' + addressPrefix: !empty(resourceProviders) + ? cidrSubnet(virtualNetworkDeploymentScriptAddressPrefix, 25, 1) + : null + networkSecurityGroupResourceId: !empty(resourceProviders) ? createDsNsg.outputs.resourceId : null + } ] : null enableTelemetry: enableTelemetry } } - module registerResourceProviders 'br/public:avm/res/resources/deployment-script:0.2.3' = if (!empty(resourceProviders)) { scope: resourceGroup(subscriptionId, deploymentScriptResourceGroupName) name: deploymentNames.registerResourceProviders params: { name: deploymentScriptName kind: 'AzurePowerShell' - azPowerShellVersion: '3.0' + azPowerShellVersion: '12.3' cleanupPreference: 'Always' enableTelemetry: enableTelemetry location: deploymentScriptLocation @@ -677,7 +713,9 @@ module registerResourceProviders 'br/public:avm/res/resources/deployment-script: } : null storageAccountResourceId: !(empty(resourceProviders)) ? createDsStorageAccount.outputs.resourceId : null - subnetResourceIds: !(empty(resourceProviders)) ? createDsVnet.outputs.subnetResourceIds : null + subnetResourceIds: !(empty(resourceProviders)) + ? [filter(createDsVnet.outputs.subnetResourceIds, subnetResourceId => contains(subnetResourceId, 'ds-subnet'))[0]] + : null arguments: '-resourceProviders \'${resourceProvidersFormatted}\' -resourceProvidersFeatures -subscriptionId ${subscriptionId}' scriptContent: loadTextContent('../scripts/Register-SubscriptionResourceProviderList.ps1') } From 0c33ee92a4498fb379bfed3d944430433ea35150 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Thu, 6 Feb 2025 14:32:01 +0100 Subject: [PATCH 07/31] feat: Portal Dashboard - Updated to latest UDTs (#4335) ## Description Updated to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.portal.dashboard](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.portal.dashboard.yml/badge.svg?branch=users%2Falsehr%2Fdashboardudt&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.portal.dashboard.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/portal/dashboard/README.md | 20 +-- avm/res/portal/dashboard/main.bicep | 44 +---- avm/res/portal/dashboard/main.json | 166 ++++++++++-------- .../tests/e2e/defaults/main.test.bicep | 1 - 4 files changed, 102 insertions(+), 129 deletions(-) diff --git a/avm/res/portal/dashboard/README.md b/avm/res/portal/dashboard/README.md index 63cc4e5a9b..17892ee07c 100644 --- a/avm/res/portal/dashboard/README.md +++ b/avm/res/portal/dashboard/README.md @@ -8,6 +8,7 @@ This module deploys a Portal Dashboard. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -43,10 +44,7 @@ This instance deploys the module with the minimum set of required parameters. module dashboard 'br/public:avm/res/portal/dashboard:' = { name: 'dashboardDeployment' params: { - // Required parameters name: 'pdmin001' - // Non-required parameters - location: '' } } ``` @@ -63,13 +61,8 @@ module dashboard 'br/public:avm/res/portal/dashboard:' = { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - // Required parameters "name": { "value": "pdmin001" - }, - // Non-required parameters - "location": { - "value": "" } } } @@ -85,10 +78,7 @@ module dashboard 'br/public:avm/res/portal/dashboard:' = { ```bicep-params using 'br/public:avm/res/portal/dashboard:' -// Required parameters param name = 'pdmin001' -// Non-required parameters -param location = '' ``` @@ -1210,6 +1200,14 @@ Tags of the resource. | `resourceGroupName` | string | The name of the resource group the dashboard was created in. | | `resourceId` | string | The resource ID of the dashboard. | +## 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.5.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/portal/dashboard/main.bicep b/avm/res/portal/dashboard/main.bicep index 8c2c74e0cf..067027ed42 100644 --- a/avm/res/portal/dashboard/main.bicep +++ b/avm/res/portal/dashboard/main.bicep @@ -13,11 +13,13 @@ param enableTelemetry bool = true @description('Optional. Tags of the resource.') param tags object? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @description('Optional. The dashboard lenses.') param lenses object[] = [] @@ -126,41 +128,3 @@ output name string = dashboard.name @description('The location the dashboard was deployed into.') output location string = dashboard.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')? -}? diff --git a/avm/res/portal/dashboard/main.json b/avm/res/portal/dashboard/main.json index 23af559768..da6a8ec429 100644 --- a/avm/res/portal/dashboard/main.json +++ b/avm/res/portal/dashboard/main.json @@ -5,86 +5,13 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9079804815412233513" + "version": "0.33.13.18514", + "templateHash": "15740229336702318485" }, "name": "Portal Dashboards", "description": "This module deploys a Portal Dashboard." }, "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": { @@ -108,7 +35,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.5.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.5.1" + } + } } }, "parameters": { @@ -140,13 +147,18 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } diff --git a/avm/res/portal/dashboard/tests/e2e/defaults/main.test.bicep b/avm/res/portal/dashboard/tests/e2e/defaults/main.test.bicep index 9b7189a800..0aac5f4332 100644 --- a/avm/res/portal/dashboard/tests/e2e/defaults/main.test.bicep +++ b/avm/res/portal/dashboard/tests/e2e/defaults/main.test.bicep @@ -42,7 +42,6 @@ module testDeployment '../../../main.bicep' = [ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: resourceLocation } } ] From 3f909897b257ce7f27e49e9460d43d69e6e34481 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:51:34 +0100 Subject: [PATCH 08/31] feat: Add new params to `avm/res/insights/component` (#4388) ## Description Add new parameters to the `avm/res/insights/component` module to support the `Flow_Type` and `Request_Source` properties. Resolves #4383 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.component](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.component.yml/badge.svg?branch=users%2Fkrbar%2FappInsightsParams)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.component.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/component/README.md | 26 +++++++++++++++++++ .../component/linkedStorageAccounts/main.json | 4 +-- avm/res/insights/component/main.bicep | 8 ++++++ avm/res/insights/component/main.json | 26 +++++++++++++++---- .../component/tests/e2e/max/main.test.bicep | 2 ++ avm/res/insights/component/version.json | 2 +- 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/avm/res/insights/component/README.md b/avm/res/insights/component/README.md index cbae0e0677..438d8a2edd 100644 --- a/avm/res/insights/component/README.md +++ b/avm/res/insights/component/README.md @@ -135,6 +135,7 @@ module component 'br/public:avm/res/insights/component:' = { ] disableIpMasking: false disableLocalAuth: true + flowType: 'Redfield' forceCustomerStorageForProfiler: true linkedStorageAccountResourceId: '' location: '' @@ -142,6 +143,7 @@ module component 'br/public:avm/res/insights/component:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } + requestSource: 'Azure' roleAssignments: [ { name: '8aacced3-3fce-41bc-a416-959df1acec57' @@ -212,6 +214,9 @@ module component 'br/public:avm/res/insights/component:' = { "disableLocalAuth": { "value": true }, + "flowType": { + "value": "Redfield" + }, "forceCustomerStorageForProfiler": { "value": true }, @@ -227,6 +232,9 @@ module component 'br/public:avm/res/insights/component:' = { "name": "myCustomLockName" } }, + "requestSource": { + "value": "Azure" + }, "roleAssignments": { "value": [ { @@ -289,6 +297,7 @@ param diagnosticSettings = [ ] param disableIpMasking = false param disableLocalAuth = true +param flowType = 'Redfield' param forceCustomerStorageForProfiler = true param linkedStorageAccountResourceId = '' param location = '' @@ -296,6 +305,7 @@ param lock = { kind: 'CanNotDelete' name: 'myCustomLockName' } +param requestSource = 'Azure' param roleAssignments = [ { name: '8aacced3-3fce-41bc-a416-959df1acec57' @@ -473,6 +483,7 @@ param tags = { | [`disableIpMasking`](#parameter-disableipmasking) | bool | Disable IP masking. Default value is set to true. | | [`disableLocalAuth`](#parameter-disablelocalauth) | bool | Disable Non-AAD based Auth. Default value is set to false. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`flowType`](#parameter-flowtype) | string | Used by the Application Insights system to determine what kind of flow this component was created by. This is to be set to 'Bluefield' when creating/updating a component via the REST API. | | [`forceCustomerStorageForProfiler`](#parameter-forcecustomerstorageforprofiler) | bool | Force users to create their own storage account for profiler and debugger. | | [`kind`](#parameter-kind) | string | The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone. | | [`linkedStorageAccountResourceId`](#parameter-linkedstorageaccountresourceid) | string | Linked storage account resource ID. | @@ -480,6 +491,7 @@ param tags = { | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`publicNetworkAccessForIngestion`](#parameter-publicnetworkaccessforingestion) | string | The network access type for accessing Application Insights ingestion. - Enabled or Disabled. | | [`publicNetworkAccessForQuery`](#parameter-publicnetworkaccessforquery) | string | The network access type for accessing Application Insights query. - Enabled or Disabled. | +| [`requestSource`](#parameter-requestsource) | string | Describes what tool created this Application Insights component. Customers using this API should set this to the default 'rest'. | | [`retentionInDays`](#parameter-retentionindays) | int | Retention period in days. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`samplingPercentage`](#parameter-samplingpercentage) | int | Percentage of the data produced by the application being monitored that is being sampled for Application Insights telemetry. | @@ -684,6 +696,13 @@ Enable/Disable usage telemetry for module. - Type: bool - Default: `True` +### Parameter: `flowType` + +Used by the Application Insights system to determine what kind of flow this component was created by. This is to be set to 'Bluefield' when creating/updating a component via the REST API. + +- Required: No +- Type: string + ### Parameter: `forceCustomerStorageForProfiler` Force users to create their own storage account for profiler and debugger. @@ -781,6 +800,13 @@ The network access type for accessing Application Insights query. - Enabled or D ] ``` +### Parameter: `requestSource` + +Describes what tool created this Application Insights component. Customers using this API should set this to the default 'rest'. + +- Required: No +- Type: string + ### Parameter: `retentionInDays` Retention period in days. diff --git a/avm/res/insights/component/linkedStorageAccounts/main.json b/avm/res/insights/component/linkedStorageAccounts/main.json index 35b60ac3b1..6e9338590b 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.32.4.45862", - "templateHash": "3603934328068593686" + "version": "0.33.93.31351", + "templateHash": "10861379689695100897" }, "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 c5e52fe4d2..f08d7d312a 100644 --- a/avm/res/insights/component/main.bicep +++ b/avm/res/insights/component/main.bicep @@ -59,6 +59,12 @@ param retentionInDays int = 365 @maxValue(100) param samplingPercentage int = 100 +@description('Optional. Used by the Application Insights system to determine what kind of flow this component was created by. This is to be set to \'Bluefield\' when creating/updating a component via the REST API.') +param flowType string? + +@description('Optional. Describes what tool created this Application Insights component. Customers using this API should set this to the default \'rest\'.') +param requestSource string? + @description('Optional. The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone.') param kind string = '' @@ -158,6 +164,8 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { publicNetworkAccessForQuery: publicNetworkAccessForQuery RetentionInDays: retentionInDays SamplingPercentage: samplingPercentage + Flow_Type: flowType + Request_Source: requestSource } } diff --git a/avm/res/insights/component/main.json b/avm/res/insights/component/main.json index 677006001c..e61ab6ae20 100644 --- a/avm/res/insights/component/main.json +++ b/avm/res/insights/component/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8234774084915355769" + "version": "0.33.93.31351", + "templateHash": "10160470062491934963" }, "name": "Application Insights", "description": "This component deploys an Application Insights instance." @@ -341,6 +341,20 @@ "description": "Optional. Percentage of the data produced by the application being monitored that is being sampled for Application Insights telemetry." } }, + "flowType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Used by the Application Insights system to determine what kind of flow this component was created by. This is to be set to 'Bluefield' when creating/updating a component via the REST API." + } + }, + "requestSource": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Describes what tool created this Application Insights component. Customers using this API should set this to the default 'rest'." + } + }, "kind": { "type": "string", "defaultValue": "", @@ -454,7 +468,9 @@ "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]", "RetentionInDays": "[parameters('retentionInDays')]", - "SamplingPercentage": "[parameters('samplingPercentage')]" + "SamplingPercentage": "[parameters('samplingPercentage')]", + "Flow_Type": "[parameters('flowType')]", + "Request_Source": "[parameters('requestSource')]" } }, "appInsights_roleAssignments": { @@ -558,8 +574,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3603934328068593686" + "version": "0.33.93.31351", + "templateHash": "10861379689695100897" }, "name": "Application Insights Linked Storage Account", "description": "This component deploys an Application Insights Linked Storage Account." diff --git a/avm/res/insights/component/tests/e2e/max/main.test.bicep b/avm/res/insights/component/tests/e2e/max/main.test.bicep index 8292a09dab..1fa9477266 100644 --- a/avm/res/insights/component/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/component/tests/e2e/max/main.test.bicep @@ -70,6 +70,8 @@ module testDeployment '../../../main.bicep' = { forceCustomerStorageForProfiler: true linkedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + flowType: 'Redfield' + requestSource: 'Azure' diagnosticSettings: [ { name: 'customSetting' diff --git a/avm/res/insights/component/version.json b/avm/res/insights/component/version.json index ea4f3b6e67..21226dd43f 100644 --- a/avm/res/insights/component/version.json +++ b/avm/res/insights/component/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] From f336c469c9630b754550a571698c6e1a267952e2 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:23:37 +0100 Subject: [PATCH 09/31] feat: Updated `avm/res/insights/diagnostic-setting` to latest UDT specs (#4390) Update to latest UDT specs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.diagnostic-setting](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.diagnostic-setting.yml/badge.svg?branch=users%2Fkrbar%2FdiagUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.diagnostic-setting.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [x] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../insights/diagnostic-setting/main.bicep | 8 +- avm/res/insights/diagnostic-setting/main.json | 91 +++++++++---------- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/avm/res/insights/diagnostic-setting/main.bicep b/avm/res/insights/diagnostic-setting/main.bicep index 550bce7219..2bcff0d23a 100644 --- a/avm/res/insights/diagnostic-setting/main.bicep +++ b/avm/res/insights/diagnostic-setting/main.bicep @@ -21,10 +21,10 @@ param eventHubAuthorizationRuleResourceId string? param eventHubName 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.') -param logCategoriesAndGroups logCategoriesAndGroupsType +param logCategoriesAndGroups logCategoriesAndGroupsType[]? @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') -param metricCategories metricCategoriesType? +param metricCategories metricCategoriesType[]? @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.') @allowed([ @@ -112,7 +112,7 @@ type logCategoriesAndGroupsType = { @description('Optional. Enable or disable the category explicitly. Default is `true`.') enabled: bool? -}[]? +} @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') type metricCategoriesType = { @@ -121,4 +121,4 @@ type metricCategoriesType = { @description('Optional. Enable or disable the category explicitly. Default is `true`.') enabled: bool? -}[]? +} diff --git a/avm/res/insights/diagnostic-setting/main.json b/avm/res/insights/diagnostic-setting/main.json index ecd36c943f..3363cf662f 100644 --- a/avm/res/insights/diagnostic-setting/main.json +++ b/avm/res/insights/diagnostic-setting/main.json @@ -5,67 +5,59 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16751842426340241931" + "version": "0.33.93.31351", + "templateHash": "4069661147816092581" }, "name": "Diagnostic Settings (Activity Logs) for Azure Subscriptions", "description": "This module deploys a Subscription wide export of the Activity Log." }, "definitions": { "logCategoriesAndGroupsType": { - "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`." - } + "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." } }, "metricCategoriesType": { - "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`." - } + "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." } @@ -110,13 +102,20 @@ } }, "logCategoriesAndGroups": { - "$ref": "#/definitions/logCategoriesAndGroupsType", + "type": "array", + "items": { + "$ref": "#/definitions/logCategoriesAndGroupsType" + }, + "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": { - "$ref": "#/definitions/metricCategoriesType", + "type": "array", + "items": { + "$ref": "#/definitions/metricCategoriesType" + }, "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." From 4f17e15be203b46aae59dc12c52aa7f4605028b1 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Fri, 7 Feb 2025 08:04:02 +0000 Subject: [PATCH 10/31] fix: Update avm/res/container-registry/registry - Param typo fix (#4375) --- avm/res/container-registry/registry/README.md | 4 +-- .../registry/cache-rule/main.json | 4 +-- .../registry/credential-set/main.json | 4 +-- .../container-registry/registry/main.bicep | 2 +- avm/res/container-registry/registry/main.json | 26 +++++++++---------- .../registry/replication/main.json | 4 +-- .../registry/scope-map/main.json | 4 +-- .../registry/webhook/main.json | 4 +-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/avm/res/container-registry/registry/README.md b/avm/res/container-registry/registry/README.md index 73b862ec30..fa70d39ffe 100644 --- a/avm/res/container-registry/registry/README.md +++ b/avm/res/container-registry/registry/README.md @@ -937,7 +937,7 @@ param trustPolicyStatus = 'enabled' | [`acrAdminUserEnabled`](#parameter-acradminuserenabled) | bool | Enable admin user that have push / pull permission to the registry. | | [`acrSku`](#parameter-acrsku) | string | Tier of your Azure container registry. | | [`anonymousPullEnabled`](#parameter-anonymouspullenabled) | bool | Enables registry-wide pull from unauthenticated clients. It's in preview and available in the Standard and Premium service tiers. | -| [`azureADAuthenticationAsArmPolicyStatus`](#parameter-azureadauthenticationasarmpolicystatus) | string | The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled. | +| [`azureADAuthenticationAsArmPolicyStatus`](#parameter-azureadauthenticationasarmpolicystatus) | string | The value that indicates whether the policy for using ARM audience token for a container registry is enabled or not. Default is enabled. | | [`cacheRules`](#parameter-cacherules) | array | Array of Cache Rules. | | [`credentialSets`](#parameter-credentialsets) | array | Array of Credential Sets. | | [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | @@ -1007,7 +1007,7 @@ Enables registry-wide pull from unauthenticated clients. It's in preview and ava ### Parameter: `azureADAuthenticationAsArmPolicyStatus` -The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled. +The value that indicates whether the policy for using ARM audience token for a container registry is enabled or not. Default is enabled. - Required: No - Type: string diff --git a/avm/res/container-registry/registry/cache-rule/main.json b/avm/res/container-registry/registry/cache-rule/main.json index 6579708c5a..a13292c7a1 100644 --- a/avm/res/container-registry/registry/cache-rule/main.json +++ b/avm/res/container-registry/registry/cache-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "13450234979206794925" + "version": "0.33.93.31351", + "templateHash": "3783697279882479947" }, "name": "Container Registries Cache", "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache))." diff --git a/avm/res/container-registry/registry/credential-set/main.json b/avm/res/container-registry/registry/credential-set/main.json index 34247710a3..feff9de1e7 100644 --- a/avm/res/container-registry/registry/credential-set/main.json +++ b/avm/res/container-registry/registry/credential-set/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16839288679507454258" + "version": "0.33.93.31351", + "templateHash": "15848218260506856293" }, "name": "Container Registries Credential Sets", "description": "This module deploys an ACR Credential Set." diff --git a/avm/res/container-registry/registry/main.bicep b/avm/res/container-registry/registry/main.bicep index 0c3e371764..7b7670fd32 100644 --- a/avm/res/container-registry/registry/main.bicep +++ b/avm/res/container-registry/registry/main.bicep @@ -59,7 +59,7 @@ param retentionPolicyDays int = 15 'disabled' 'enabled' ]) -@description('Optional. The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled.') +@description('Optional. The value that indicates whether the policy for using ARM audience token for a container registry is enabled or not. Default is enabled.') param azureADAuthenticationAsArmPolicyStatus string = 'enabled' @allowed([ diff --git a/avm/res/container-registry/registry/main.json b/avm/res/container-registry/registry/main.json index 590026207f..a125c7727e 100644 --- a/avm/res/container-registry/registry/main.json +++ b/avm/res/container-registry/registry/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "15303055419647729010" + "version": "0.33.93.31351", + "templateHash": "7811628046063994725" }, "name": "Azure Container Registries (ACR)", "description": "This module deploys an Azure Container Registry (ACR)." @@ -1002,7 +1002,7 @@ "enabled" ], "metadata": { - "description": "Optional. The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled." + "description": "Optional. The value that indicates whether the policy for using ARM audience token for a container registry is enabled or not. Default is enabled." } }, "softDeletePolicyStatus": { @@ -1415,8 +1415,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "8957375042269792339" + "version": "0.33.93.31351", + "templateHash": "11112300500664950599" }, "name": "Container Registries scopeMaps", "description": "This module deploys an Azure Container Registry (ACR) scopeMap." @@ -1538,8 +1538,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2771208879484692364" + "version": "0.33.93.31351", + "templateHash": "6036875058945996178" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication." @@ -1682,8 +1682,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16839288679507454258" + "version": "0.33.93.31351", + "templateHash": "15848218260506856293" }, "name": "Container Registries Credential Sets", "description": "This module deploys an ACR Credential Set." @@ -1866,8 +1866,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "13450234979206794925" + "version": "0.33.93.31351", + "templateHash": "3783697279882479947" }, "name": "Container Registries Cache", "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache))." @@ -2004,8 +2004,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "14557981877826360902" + "version": "0.33.93.31351", + "templateHash": "10084997815751263562" }, "name": "Azure Container Registry (ACR) Webhooks", "description": "This module deploys an Azure Container Registry (ACR) Webhook." diff --git a/avm/res/container-registry/registry/replication/main.json b/avm/res/container-registry/registry/replication/main.json index 9badf5a5aa..e3fd79ab49 100644 --- a/avm/res/container-registry/registry/replication/main.json +++ b/avm/res/container-registry/registry/replication/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2771208879484692364" + "version": "0.33.93.31351", + "templateHash": "6036875058945996178" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication." diff --git a/avm/res/container-registry/registry/scope-map/main.json b/avm/res/container-registry/registry/scope-map/main.json index ed203ced74..370ea96784 100644 --- a/avm/res/container-registry/registry/scope-map/main.json +++ b/avm/res/container-registry/registry/scope-map/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "8957375042269792339" + "version": "0.33.93.31351", + "templateHash": "11112300500664950599" }, "name": "Container Registries scopeMaps", "description": "This module deploys an Azure Container Registry (ACR) scopeMap." diff --git a/avm/res/container-registry/registry/webhook/main.json b/avm/res/container-registry/registry/webhook/main.json index cbb4e22ae0..035dcd3f6c 100644 --- a/avm/res/container-registry/registry/webhook/main.json +++ b/avm/res/container-registry/registry/webhook/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "14557981877826360902" + "version": "0.33.93.31351", + "templateHash": "10084997815751263562" }, "name": "Azure Container Registry (ACR) Webhooks", "description": "This module deploys an Azure Container Registry (ACR) Webhook." From 5cef7141be37a5456834c2003bc5b3e9b072f011 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:09:38 +0100 Subject: [PATCH 11/31] feat: Activity Log Alert - Update to latest UDTs (#4397) ## Description Update to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.activity-log-alert](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.activity-log-alert.yml/badge.svg?branch=users%2Fkrbar%2FactLogUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.activity-log-alert.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/activity-log-alert/README.md | 9 ++ .../insights/activity-log-alert/main.bicep | 37 +---- avm/res/insights/activity-log-alert/main.json | 152 +++++++++--------- 3 files changed, 92 insertions(+), 106 deletions(-) diff --git a/avm/res/insights/activity-log-alert/README.md b/avm/res/insights/activity-log-alert/README.md index 8a307f678d..d8a2bb4dd5 100644 --- a/avm/res/insights/activity-log-alert/README.md +++ b/avm/res/insights/activity-log-alert/README.md @@ -8,6 +8,7 @@ This module deploys an Activity Log Alert. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -866,6 +867,14 @@ Tags of the resource. | `resourceGroupName` | string | The resource group the activity log alert was deployed into. | | `resourceId` | string | The resource ID of the activity log alert. | +## 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.5.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/insights/activity-log-alert/main.bicep b/avm/res/insights/activity-log-alert/main.bicep index 9951e646dd..2401ab1567 100644 --- a/avm/res/insights/activity-log-alert/main.bicep +++ b/avm/res/insights/activity-log-alert/main.bicep @@ -24,8 +24,9 @@ param actions array = [] @description('Required. An Array of objects containing conditions that will cause this alert to activate. Conditions can also be combined with logical operators `allOf` and `anyOf`. Each condition can specify only one field between `equals` and `containsAny`. An alert rule condition must have exactly one category (Administrative, ServiceHealth, ResourceHealth, Alert, Autoscale, Recommendation, Security, or Policy).') param conditions array +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -35,8 +36,8 @@ param enableTelemetry bool = true var actionGroups = [ for action in actions: { - actionGroupId: contains(action, 'actionGroupId') ? action.actionGroupId : action - webhookProperties: contains(action, 'webhookProperties') ? action.webhookProperties : null + actionGroupId: action.?actionGroupId ?? action + webhookProperties: action.?webhookProperties } ] @@ -128,33 +129,3 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = activityLogAlert.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? -}[]? diff --git a/avm/res/insights/activity-log-alert/main.json b/avm/res/insights/activity-log-alert/main.json index bbd41cb8a9..b9334b0a7c 100644 --- a/avm/res/insights/activity-log-alert/main.json +++ b/avm/res/insights/activity-log-alert/main.json @@ -5,85 +5,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12218331407041412114" + "version": "0.33.93.31351", + "templateHash": "3537417410371628791" }, "name": "Activity Log Alerts", "description": "This module deploys an Activity Log Alert." }, "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.5.1" + } + } } }, "parameters": { @@ -137,7 +139,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -163,8 +169,8 @@ "name": "actionGroups", "count": "[length(parameters('actions'))]", "input": { - "actionGroupId": "[if(contains(parameters('actions')[copyIndex('actionGroups')], 'actionGroupId'), parameters('actions')[copyIndex('actionGroups')].actionGroupId, parameters('actions')[copyIndex('actionGroups')])]", - "webhookProperties": "[if(contains(parameters('actions')[copyIndex('actionGroups')], 'webhookProperties'), parameters('actions')[copyIndex('actionGroups')].webhookProperties, null())]" + "actionGroupId": "[coalesce(tryGet(parameters('actions')[copyIndex('actionGroups')], 'actionGroupId'), parameters('actions')[copyIndex('actionGroups')])]", + "webhookProperties": "[tryGet(parameters('actions')[copyIndex('actionGroups')], 'webhookProperties')]" } }, { From 48a4012ea98bfded8a3469ccc2923eedb4f659e0 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:10:23 +0100 Subject: [PATCH 12/31] feat: Action Group - Update to latest UDTs (#4396) ## Description Update to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.action-group](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.action-group.yml/badge.svg?branch=users%2Fkrbar%2FagrUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.action-group.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/action-group/README.md | 9 ++ avm/res/insights/action-group/main.bicep | 33 +---- avm/res/insights/action-group/main.json | 148 ++++++++++++----------- 3 files changed, 88 insertions(+), 102 deletions(-) diff --git a/avm/res/insights/action-group/README.md b/avm/res/insights/action-group/README.md index 6d443eba38..a198ad9860 100644 --- a/avm/res/insights/action-group/README.md +++ b/avm/res/insights/action-group/README.md @@ -8,6 +8,7 @@ This module deploys an Action Group. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -646,6 +647,14 @@ The list of webhook receivers that are part of this action group. | `resourceGroupName` | string | The resource group the action group was deployed into. | | `resourceId` | string | The resource ID of the action group. | +## 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.5.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/insights/action-group/main.bicep b/avm/res/insights/action-group/main.bicep index e4d7e83e0e..bad8c54172 100644 --- a/avm/res/insights/action-group/main.bicep +++ b/avm/res/insights/action-group/main.bicep @@ -10,8 +10,9 @@ param groupShortName string @description('Optional. Indicates whether this action group is enabled. If an action group is not enabled, then none of its receivers will receive communications.') param enabled bool = true +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. The list of email receivers that are part of this action group.') param emailReceivers array? @@ -143,33 +144,3 @@ output resourceId string = actionGroup.id @description('The location the resource was deployed into.') output location string = actionGroup.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? -}[]? diff --git a/avm/res/insights/action-group/main.json b/avm/res/insights/action-group/main.json index 88c6d133ae..e30d03815e 100644 --- a/avm/res/insights/action-group/main.json +++ b/avm/res/insights/action-group/main.json @@ -5,85 +5,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8879119685728165969" + "version": "0.33.93.31351", + "templateHash": "1390192729878803338" }, "name": "Action Groups", "description": "This module deploys an Action Group." }, "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.5.1" + } + } } }, "parameters": { @@ -107,7 +109,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } From d942e87576512b3e5fe7a3fc1d4cd669d1b0ea27 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Fri, 7 Feb 2025 13:18:11 +0100 Subject: [PATCH 13/31] feat: Databricks Workspace - Updated to latest UDTs & renamed test instances (#4401) ## Description - Renamed databricks instances to workaround error `BAD_REQUEST: Cannot create 1 Storage Credential(s) in Metastore 11cefb12-29fd-4843-8c14-ca73ebc67fda (estimated count: 205, limit: 200)`. This is **NOT** a solution, but the support did not offer one, so it's the best we can do at this time - Updated to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.databricks.workspace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml/badge.svg?branch=users%2Falsehr%2FdatabricksStorageCredentialRename&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/databricks/workspace/README.md | 74 +- avm/res/databricks/workspace/main.bicep | 82 +- avm/res/databricks/workspace/main.json | 1165 +++++++++-------- .../tests/e2e/defaults/main.test.bicep | 3 +- .../workspace/tests/e2e/max/main.test.bicep | 8 +- .../tests/e2e/waf-aligned/main.test.bicep | 11 +- avm/res/databricks/workspace/version.json | 12 +- 7 files changed, 701 insertions(+), 654 deletions(-) diff --git a/avm/res/databricks/workspace/README.md b/avm/res/databricks/workspace/README.md index 3d46594eed..857acbed83 100644 --- a/avm/res/databricks/workspace/README.md +++ b/avm/res/databricks/workspace/README.md @@ -48,10 +48,7 @@ This instance deploys the module with the minimum set of required parameters. module workspace 'br/public:avm/res/databricks/workspace:' = { name: 'workspaceDeployment' params: { - // Required parameters - name: 'dwmin001' - // Non-required parameters - location: '' + name: 'dwmin002' } } ``` @@ -68,13 +65,8 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - // Required parameters "name": { - "value": "dwmin001" - }, - // Non-required parameters - "location": { - "value": "" + "value": "dwmin002" } } } @@ -90,10 +82,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { ```bicep-params using 'br/public:avm/res/databricks/workspace:' -// Required parameters -param name = 'dwmin001' -// Non-required parameters -param location = '' +param name = 'dwmin002' ``` @@ -113,7 +102,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { name: 'workspaceDeployment' params: { // Required parameters - name: 'dwmax002' + name: 'dwmax003' // Non-required parameters amlWorkspaceResourceId: '' automaticClusterUpdate: 'Enabled' @@ -127,7 +116,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { keyVaultResourceId: '' } customerManagedKeyManagedDisk: { - autoRotationDisabled: true + autoRotationEnabled: false keyName: '' keyVaultResourceId: '' } @@ -244,7 +233,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { "parameters": { // Required parameters "name": { - "value": "dwmax002" + "value": "dwmax003" }, // Non-required parameters "amlWorkspaceResourceId": { @@ -270,7 +259,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { }, "customerManagedKeyManagedDisk": { "value": { - "autoRotationDisabled": true, + "autoRotationEnabled": false, "keyName": "", "keyVaultResourceId": "" } @@ -435,7 +424,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { using 'br/public:avm/res/databricks/workspace:' // Required parameters -param name = 'dwmax002' +param name = 'dwmax003' // Non-required parameters param amlWorkspaceResourceId = '' param automaticClusterUpdate = 'Enabled' @@ -449,7 +438,7 @@ param customerManagedKey = { keyVaultResourceId: '' } param customerManagedKeyManagedDisk = { - autoRotationDisabled: true + autoRotationEnabled: false keyName: '' keyVaultResourceId: '' } @@ -567,7 +556,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { name: 'workspaceDeployment' params: { // Required parameters - name: 'dwwaf001' + name: 'dwwaf002' // Non-required parameters accessConnectorResourceId: '' amlWorkspaceResourceId: '' @@ -605,11 +594,6 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { enhancedSecurityMonitoring: 'Enabled' loadBalancerBackendPoolName: '' loadBalancerResourceId: '' - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } managedResourceGroupResourceId: '' natGatewayName: 'nat-gateway' prepareEncryption: true @@ -679,7 +663,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { "parameters": { // Required parameters "name": { - "value": "dwwaf001" + "value": "dwwaf002" }, // Non-required parameters "accessConnectorResourceId": { @@ -746,15 +730,6 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { "loadBalancerResourceId": { "value": "" }, - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, "managedResourceGroupResourceId": { "value": "" }, @@ -851,7 +826,7 @@ module workspace 'br/public:avm/res/databricks/workspace:' = { using 'br/public:avm/res/databricks/workspace:' // Required parameters -param name = 'dwwaf001' +param name = 'dwwaf002' // Non-required parameters param accessConnectorResourceId = '' param amlWorkspaceResourceId = '' @@ -889,11 +864,6 @@ param disablePublicIp = true param enhancedSecurityMonitoring = 'Enabled' param loadBalancerBackendPoolName = '' param loadBalancerResourceId = '' -param location = '' -param lock = { - kind: 'CanNotDelete' - name: 'myCustomLockName' -} param managedResourceGroupResourceId = '' param natGatewayName = 'nat-gateway' param prepareEncryption = true @@ -1481,7 +1451,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`resourceGroupResourceId`](#parameter-privateendpointsresourcegroupresourceid) | string | The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | | [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | @@ -1740,9 +1710,9 @@ The name of the private link connection to create. - Required: No - Type: string -### Parameter: `privateEndpoints.resourceGroupName` +### Parameter: `privateEndpoints.resourceGroupResourceId` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. - Required: No - Type: string @@ -1763,7 +1733,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** @@ -2081,7 +2051,7 @@ Configuration details for private endpoints for the managed workspace storage ac | [`name`](#parameter-storageaccountprivateendpointsname) | string | The name of the private endpoint. | | [`privateDnsZoneGroup`](#parameter-storageaccountprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-storageaccountprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | -| [`resourceGroupName`](#parameter-storageaccountprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | +| [`resourceGroupResourceId`](#parameter-storageaccountprivateendpointsresourcegroupresourceid) | string | The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. | | [`roleAssignments`](#parameter-storageaccountprivateendpointsroleassignments) | array | Array of role assignments to create. | | [`tags`](#parameter-storageaccountprivateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | @@ -2340,9 +2310,9 @@ The name of the private link connection to create. - Required: No - Type: string -### Parameter: `storageAccountPrivateEndpoints.resourceGroupName` +### Parameter: `storageAccountPrivateEndpoints.resourceGroupResourceId` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. - Required: No - Type: string @@ -2363,7 +2333,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** @@ -2508,8 +2478,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/utl/types/avm-common-types:0.4.0` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.10.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.5.1` | Remote reference | ## Notes diff --git a/avm/res/databricks/workspace/main.bicep b/avm/res/databricks/workspace/main.bicep index bc02c279a3..b75702d2f7 100644 --- a/avm/res/databricks/workspace/main.bicep +++ b/avm/res/databricks/workspace/main.bicep @@ -18,15 +18,15 @@ param skuName string = 'premium' @description('Optional. Location for all Resources.') param location string = resourceGroup().location -import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? -import { diagnosticSettingLogsOnlyType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { diagnosticSettingLogsOnlyType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingLogsOnlyType[]? -import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') param lock lockType? @@ -51,11 +51,11 @@ param customPublicSubnetName string = '' @description('Optional. Disable Public IP.') param disablePublicIp bool = false -import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { customerManagedKeyType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The customer managed key definition to use for the managed service.') param customerManagedKey customerManagedKeyType? -import { customerManagedKeyWithAutoRotateType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { customerManagedKeyWithAutoRotateType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The customer managed key definition to use for the managed disk.') param customerManagedKeyManagedDisk customerManagedKeyWithAutoRotateType? @@ -108,7 +108,7 @@ param requiredNsgRules string = 'AllRules' ]) param privateStorageAccount string = '' -import { privateEndpointMultiServiceType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +import { privateEndpointMultiServiceType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') param privateEndpoints privateEndpointMultiServiceType[]? @@ -327,7 +327,7 @@ resource workspace 'Microsoft.Databricks/workspaces@2024-05-01' = { keyVaultUri: cMKKeyVault.properties.vaultUri keyName: customerManagedKey!.keyName keyVersion: !empty(customerManagedKey.?keyVersion ?? '') - ? customerManagedKey!.keyVersion! + ? customerManagedKey!.?keyVersion! : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) } } @@ -339,7 +339,7 @@ resource workspace 'Microsoft.Databricks/workspaces@2024-05-01' = { keyVaultUri: cMKManagedDiskKeyVault.properties.vaultUri keyName: customerManagedKeyManagedDisk!.keyName keyVersion: !empty(customerManagedKeyManagedDisk.?keyVersion ?? '') - ? customerManagedKeyManagedDisk!.keyVersion! + ? customerManagedKeyManagedDisk!.?keyVersion! : last(split(cMKManagedDiskKeyVault::cMKKey.properties.keyUriWithVersion, '/')) } rotationToLatestKeyVersionEnabled: (customerManagedKeyManagedDisk.?autoRotationEnabled ?? true == true) ?? false @@ -435,10 +435,18 @@ resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022 ] @batchSize(1) -module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' - scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') + scope: !empty(privateEndpoint.?resourceGroupResourceId) + ? resourceGroup( + split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], + split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] + ) + : resourceGroup( + split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], + split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -496,10 +504,18 @@ var _storageAccountId = resourceId( ) @batchSize(1) -module storageAccount_storageAccountPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ +module storageAccount_storageAccountPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (storageAccountPrivateEndpoints ?? []): if (privateStorageAccount == 'Enabled') { name: '${uniqueString(deployment().name, location)}-workspacestorage-PrivateEndpoint-${index}' - scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') + scope: !empty(privateEndpoint.?resourceGroupResourceId) + ? resourceGroup( + split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], + split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] + ) + : resourceGroup( + split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], + split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${_storageAccountName}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -579,26 +595,26 @@ output workspaceUrl string = workspace.properties.workspaceUrl output workspaceResourceId string = workspace.properties.workspaceId @description('The private endpoints of the Databricks Workspace.') -output privateEndpoints array = [ +output privateEndpoints privateEndpointOutputType[] = [ for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { name: workspace_privateEndpoints[i].outputs.name resourceId: workspace_privateEndpoints[i].outputs.resourceId - groupId: workspace_privateEndpoints[i].outputs.groupId - customDnsConfig: workspace_privateEndpoints[i].outputs.customDnsConfig - networkInterfaceIds: workspace_privateEndpoints[i].outputs.networkInterfaceIds + groupId: workspace_privateEndpoints[i].outputs.?groupId! + customDnsConfigs: workspace_privateEndpoints[i].outputs.customDnsConfigs + networkInterfaceResourceIds: workspace_privateEndpoints[i].outputs.networkInterfaceResourceIds } ] @description('The private endpoints of the Databricks Workspace Storage.') -output storagePrivateEndpoints array = [ +output storagePrivateEndpoints privateEndpointOutputType[] = [ for (pe, i) in ((!empty(storageAccountPrivateEndpoints) && privateStorageAccount == 'Enabled') ? array(storageAccountPrivateEndpoints) : []): { name: storageAccount_storageAccountPrivateEndpoints[i].outputs.name resourceId: storageAccount_storageAccountPrivateEndpoints[i].outputs.resourceId - groupId: storageAccount_storageAccountPrivateEndpoints[i].outputs.groupId - customDnsConfig: storageAccount_storageAccountPrivateEndpoints[i].outputs.customDnsConfig - networkInterfaceIds: storageAccount_storageAccountPrivateEndpoints[i].outputs.networkInterfaceIds + groupId: storageAccount_storageAccountPrivateEndpoints[i].outputs.?groupId! + customDnsConfigs: storageAccount_storageAccountPrivateEndpoints[i].outputs.customDnsConfigs + networkInterfaceResourceIds: storageAccount_storageAccountPrivateEndpoints[i].outputs.networkInterfaceResourceIds } ] @@ -607,6 +623,32 @@ output storagePrivateEndpoints array = [ // =============== // @export() +@description('The type for a private endpoint output.') +type privateEndpointOutputType = { + @description('The name of the private endpoint.') + name: string + + @description('The resource ID of the private endpoint.') + resourceId: string + + @description('The group Id for the private endpoint Group.') + groupId: string? + + @description('The custom DNS configurations of the private endpoint.') + customDnsConfigs: { + @description('FQDN that resolves to private endpoint IP address.') + fqdn: string? + + @description('A list of private IP addresses of the private endpoint.') + ipAddresses: string[] + }[] + + @description('The IDs of the network interfaces associated with the private endpoint.') + networkInterfaceResourceIds: string[] +} + +@export() +@description('The type for a default catalog configuration.') type defaultCatalogType = { //This value cannot be set to a custom value. Reason --> 'InvalidInitialCatalogName' message: 'Currently custom initial catalog name is not supported. This capability will be added in future.' //@description('Optional. Set the name of the Catalog.') diff --git a/avm/res/databricks/workspace/main.json b/avm/res/databricks/workspace/main.json index a9d725328e..fc365caa58 100644 --- a/avm/res/databricks/workspace/main.json +++ b/avm/res/databricks/workspace/main.json @@ -5,13 +5,77 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9456807081929487353" + "version": "0.33.13.18514", + "templateHash": "5589679396689290907" }, "name": "Azure Databricks Workspaces", "description": "This module deploys an Azure Databricks Workspace." }, "definitions": { + "privateEndpointOutputType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + } + }, + "groupId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The group Id for the private endpoint Group." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "A list of private IP addresses of the private endpoint." + } + } + } + }, + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + } + }, + "networkInterfaceResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a private endpoint output." + } + }, "defaultCatalogType": { "type": "object", "properties": { @@ -27,7 +91,8 @@ } }, "metadata": { - "__bicep_export!": true + "__bicep_export!": true, + "description": "The type for a default catalog configuration." } }, "_1.privateEndpointCustomDnsConfigType": { @@ -52,7 +117,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -94,7 +159,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -135,7 +200,7 @@ }, "metadata": { "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -172,7 +237,7 @@ "metadata": { "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.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -216,7 +281,7 @@ "metadata": { "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.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -313,7 +378,7 @@ "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.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -343,7 +408,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.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -383,6 +448,13 @@ "description": "Required. Resource ID of the subnet where the endpoint needs to be created." } }, + "resourceGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used." + } + }, "privateDnsZoneGroup": { "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", "nullable": true, @@ -472,19 +544,12 @@ "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 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.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -559,7 +624,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.4.0" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } } @@ -944,7 +1009,7 @@ "sku": { "name": "[parameters('skuName')]" }, - "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(coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'autoRotationEnabled'), equals(true(), true())), false())), 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())))]", + "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'), ''))), tryGet(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'), ''))), tryGet(parameters('customerManagedKeyManagedDisk'), 'keyVersion'), last(split(reference('cMKManagedDiskKeyVault::cMKKey').keyUriWithVersion, '/')))), 'rotationToLatestKeyVersionEnabled', coalesce(coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'autoRotationEnabled'), equals(true(), true())), false())), 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": [ "cMKManagedDiskKeyVault::cMKKey", "cMKKeyVault::cMKKey", @@ -1030,7 +1095,6 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1083,12 +1147,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1277254088602407590" + "version": "0.33.13.18514", + "templateHash": "15954548978129725136" }, "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint." }, "definitions": { "privateDnsZoneGroupType": { @@ -1110,259 +1173,148 @@ "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } } - } - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, - "lockType": { + "ipConfigurationType": { "type": "object", "properties": { "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Required. The name of the resource that is unique within a resource group." } }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, + "type": "object", "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." + "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": { + "__bicep_export!": true + } }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", + "privateLinkServiceConnectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, + "type": "object", "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } + "groupIds": { + "type": "array", + "items": { + "type": "string" }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." } }, - "metadata": { - "description": "Required. Properties of private link service connection." + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } + }, + "metadata": { + "description": "Required. Properties of private link service connection." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } + "customDnsConfigType": { + "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" }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } + "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.5.1" + } + } }, "privateDnsZoneGroupConfigType": { "type": "object", @@ -1386,63 +1338,150 @@ "sourceTemplate": "private-dns-zone-group/main.bicep" } } - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the private endpoint resource to create." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "nullable": true, - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "privateDnsZoneGroup": { - "$ref": "#/definitions/privateDnsZoneGroupType", - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone group to configure for the private endpoint." - } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", + "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.5.1" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "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." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "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." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { "description": "Optional. Location for all Resources." } }, "lock": { "$ref": "#/definitions/lockType", + "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." } @@ -1455,21 +1494,33 @@ } }, "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty." } }, "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty." } }, "enableTelemetry": { @@ -1498,7 +1549,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": { @@ -1506,7 +1557,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.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1612,12 +1663,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5805178546717255803" + "version": "0.33.13.18514", + "templateHash": "5440815542537978381" }, "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint Private DNS Zone Group." }, "definitions": { "privateDnsZoneGroupConfigType": { @@ -1695,10 +1745,7 @@ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] + } } }, "outputs": { @@ -1760,26 +1807,33 @@ }, "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" }, - "customDnsConfig": { - "$ref": "#/definitions/customDnsConfigType", + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, "metadata": { "description": "The custom DNS configurations of the private endpoint." }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, - "networkInterfaceIds": { + "networkInterfaceResourceIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "The IDs of the network interfaces associated with the private endpoint." + "description": "The resource IDs of the network interfaces associated with the private endpoint." }, - "value": "[reference('privateEndpoint').networkInterfaces]" + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" }, "groupId": { "type": "string", + "nullable": true, "metadata": { "description": "The group Id for the private endpoint Group." }, - "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" } } } @@ -1799,7 +1853,6 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-workspacestorage-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "resourceGroup": "[coalesce(tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1852,12 +1905,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1277254088602407590" + "version": "0.33.13.18514", + "templateHash": "15954548978129725136" }, "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint." }, "definitions": { "privateDnsZoneGroupType": { @@ -1879,80 +1931,118 @@ "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_export!": true } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "ipConfigurationType": { + "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." + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } } }, - "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\"." + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "privateLinkServiceConnectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "customDnsConfigType": { + "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_export!": true + } }, "lockType": { "type": "object", @@ -1977,182 +2067,108 @@ } } }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } + "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.5.1" } - }, - "nullable": true + } }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." } - } - }, - "nullable": true - }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." } } }, - "nullable": true - }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" } - }, - "nullable": true + } }, - "privateDnsZoneGroupConfigType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group config." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "privateDnsZoneResourceId": { + "roleDefinitionIdOrName": { "type": "string", "metadata": { - "description": "Required. The resource id of the private DNS zone." + "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": "private-dns-zone-group/main.bicep" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } } @@ -2172,6 +2188,9 @@ }, "applicationSecurityGroupResourceIds": { "type": "array", + "items": { + "type": "string" + }, "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." @@ -2185,7 +2204,11 @@ } }, "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", + "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "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." } @@ -2206,12 +2229,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." } @@ -2224,21 +2252,33 @@ } }, "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty." } }, "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty." } }, "enableTelemetry": { @@ -2267,7 +2307,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": { @@ -2275,7 +2315,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.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2381,12 +2421,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5805178546717255803" + "version": "0.33.13.18514", + "templateHash": "5440815542537978381" }, "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint Private DNS Zone Group." }, "definitions": { "privateDnsZoneGroupConfigType": { @@ -2464,10 +2503,7 @@ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] + } } }, "outputs": { @@ -2529,26 +2565,33 @@ }, "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" }, - "customDnsConfig": { - "$ref": "#/definitions/customDnsConfigType", + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, "metadata": { "description": "The custom DNS configurations of the private endpoint." }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, - "networkInterfaceIds": { + "networkInterfaceResourceIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "The IDs of the network interfaces associated with the private endpoint." + "description": "The resource IDs of the network interfaces associated with the private endpoint." }, - "value": "[reference('privateEndpoint').networkInterfaces]" + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" }, "groupId": { "type": "string", + "nullable": true, "metadata": { "description": "The group Id for the private endpoint Group." }, - "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" } } } @@ -2631,6 +2674,9 @@ }, "privateEndpoints": { "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointOutputType" + }, "metadata": { "description": "The private endpoints of the Databricks Workspace." }, @@ -2639,14 +2685,17 @@ "input": { "name": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.name.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]" + "groupId": "[tryGet(tryGet(reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]", + "customDnsConfigs": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]", + "networkInterfaceResourceIds": "[reference(format('workspace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" } } }, "storagePrivateEndpoints": { "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointOutputType" + }, "metadata": { "description": "The private endpoints of the Databricks Workspace Storage." }, @@ -2655,9 +2704,9 @@ "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]" + "groupId": "[tryGet(tryGet(reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]", + "customDnsConfigs": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]", + "networkInterfaceResourceIds": "[reference(format('storageAccount_storageAccountPrivateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" } } } diff --git a/avm/res/databricks/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/databricks/workspace/tests/e2e/defaults/main.test.bicep index d7b8b471c1..e5fba9e022 100644 --- a/avm/res/databricks/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/defaults/main.test.bicep @@ -41,8 +41,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' - location: resourceLocation + name: '${namePrefix}${serviceShort}002' } } ] diff --git a/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep b/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep index 6ccaa9f548..3647c97b80 100644 --- a/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/max/main.test.bicep @@ -82,7 +82,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}002' + name: '${namePrefix}${serviceShort}003' location: resourceLocation diagnosticSettings: [ { @@ -139,7 +139,7 @@ module testDeployment '../../../main.bicep' = [ customerManagedKeyManagedDisk: { keyName: nestedDependencies.outputs.keyVaultDiskKeyName keyVaultResourceId: nestedDependencies.outputs.keyVaultDiskResourceId - autoRotationDisabled: true + autoRotationEnabled: false } storageAccountName: 'sa${namePrefix}${serviceShort}001' storageAccountSkuName: 'Standard_ZRS' @@ -197,9 +197,5 @@ module testDeployment '../../../main.bicep' = [ enhancedSecurityMonitoring: 'Enabled' // This can be set to 'Enabled' without the complianceSecurityProfileValue being set to 'Enabled' automaticClusterUpdate: 'Enabled' // This can be set to 'Enabled' without the complianceSecurityProfileValue being set to 'Enabled' } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep index 65bc856e21..34cc2a2553 100644 --- a/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/databricks/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -83,8 +83,7 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - name: '${namePrefix}${serviceShort}001' - location: resourceLocation + name: '${namePrefix}${serviceShort}002' diagnosticSettings: [ { name: 'customSetting' @@ -102,10 +101,6 @@ module testDeployment '../../../main.bicep' = [ ] } ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -178,9 +173,5 @@ module testDeployment '../../../main.bicep' = [ enhancedSecurityMonitoring: 'Enabled' // This can be set to 'Enabled' without the complianceSecurityProfileValue being set to 'Enabled' automaticClusterUpdate: 'Enabled' // This can be set to 'Enabled' without the complianceSecurityProfileValue being set to 'Enabled' } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/databricks/workspace/version.json b/avm/res/databricks/workspace/version.json index b8b30a0125..d96f771b50 100644 --- a/avm/res/databricks/workspace/version.json +++ b/avm/res/databricks/workspace/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.9", - "pathFilters": [ - "./main.json" - ] -} \ No newline at end of file + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.10", + "pathFilters": [ + "./main.json" + ] +} From ffa7a7bb95ca740617c473272858c8f04eed9949 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:15:13 +0100 Subject: [PATCH 14/31] feat: API versions update of `avm/res/network/public-ip-adress` (#4395) ## Description - updated API version, which addresses a static validation warning `API version tests / In [res/network/public-ip-address] used resource type [publicIPAddresses] should use one of the recent API version(s). Currently using [2023-09-01].` - updated the `domainNameLabelScope` UDT to address a Bicep warning complaining about the expected value type. ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.network.public-ip-address](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.network.public-ip-address.yml/badge.svg?branch=users%2Fkrbar%2FpipUpdate)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.network.public-ip-address.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [x] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/network/public-ip-address/README.md | 7 +++---- avm/res/network/public-ip-address/main.bicep | 6 +++--- avm/res/network/public-ip-address/main.json | 12 ++++++------ .../tests/e2e/defaults/main.test.bicep | 2 +- .../public-ip-address/tests/e2e/max/main.test.bicep | 2 +- .../tests/e2e/waf-aligned/main.test.bicep | 2 +- avm/res/network/public-ip-address/version.json | 2 +- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/avm/res/network/public-ip-address/README.md b/avm/res/network/public-ip-address/README.md index b392a84ddd..1674ff5afd 100644 --- a/avm/res/network/public-ip-address/README.md +++ b/avm/res/network/public-ip-address/README.md @@ -18,7 +18,7 @@ This module deploys a Public IP Address. | `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/publicIPAddresses` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-09-01/publicIPAddresses) | +| `Microsoft.Network/publicIPAddresses` | [2024-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-05-01/publicIPAddresses) | ## Usage examples @@ -826,12 +826,12 @@ The DNS settings of the public IP address. | Parameter | Type | Description | | :-- | :-- | :-- | | [`domainNameLabel`](#parameter-dnssettingsdomainnamelabel) | string | 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. | -| [`domainNameLabelScope`](#parameter-dnssettingsdomainnamelabelscope) | string | The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | +| [`domainNameLabelScope`](#parameter-dnssettingsdomainnamelabelscope) | string | The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN. | | [`fqdn`](#parameter-dnssettingsfqdn) | string | The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone. | | [`reverseFqdn`](#parameter-dnssettingsreversefqdn) | string | 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. | @@ -846,12 +846,11 @@ The domain name label. The concatenation of the domain name label and the region The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN. -- Required: Yes +- Required: No - Type: string - Allowed: ```Bicep [ - '' 'NoReuse' 'ResourceGroupReuse' 'SubscriptionReuse' diff --git a/avm/res/network/public-ip-address/main.bicep b/avm/res/network/public-ip-address/main.bicep index 57e1e6cf1b..7294fe5e4c 100644 --- a/avm/res/network/public-ip-address/main.bicep +++ b/avm/res/network/public-ip-address/main.bicep @@ -144,7 +144,7 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = { +resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2024-05-01' = { name: name location: location tags: tags @@ -248,8 +248,8 @@ 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 - @description('Required. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN.') - domainNameLabelScope: ('' | 'NoReuse' | 'ResourceGroupReuse' | 'SubscriptionReuse' | 'TenantReuse') + @description('Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN.') + domainNameLabelScope: ('NoReuse' | 'ResourceGroupReuse' | 'SubscriptionReuse' | 'TenantReuse')? @description('Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone.') fqdn: string? diff --git a/avm/res/network/public-ip-address/main.json b/avm/res/network/public-ip-address/main.json index d311be8a5f..8d53c2edb3 100644 --- a/avm/res/network/public-ip-address/main.json +++ b/avm/res/network/public-ip-address/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3357602174596763976" + "version": "0.33.93.31351", + "templateHash": "11118459859179868367" }, "name": "Public IP Addresses", "description": "This module deploys a Public IP Address." @@ -24,14 +24,14 @@ "domainNameLabelScope": { "type": "string", "allowedValues": [ - "", "NoReuse", "ResourceGroupReuse", "SubscriptionReuse", "TenantReuse" ], + "nullable": true, "metadata": { - "description": "Required. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." + "description": "Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." } }, "fqdn": { @@ -534,7 +534,7 @@ }, "publicIpAddress": { "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-09-01", + "apiVersion": "2024-05-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -665,7 +665,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('publicIpAddress', '2023-09-01', 'full').location]" + "value": "[reference('publicIpAddress', '2024-05-01', 'full').location]" } } } \ No newline at end of file diff --git a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep index fa38cabbae..1fd4157d2a 100644 --- a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/public-ip-address/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-11-01' = { name: resourceGroupName location: resourceLocation } 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 950083f7f0..85db1a32cf 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 @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep index 827c783ef4..bcab1fc980 100644 --- a/avm/res/network/public-ip-address/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/public-ip-address/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-11-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/public-ip-address/version.json b/avm/res/network/public-ip-address/version.json index 09c3664cec..9a9a06e897 100644 --- a/avm/res/network/public-ip-address/version.json +++ b/avm/res/network/public-ip-address/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", + "version": "0.8", "pathFilters": [ "./main.json" ] From 40cd90e5a2b1b818981c7a1d5ea01d6fb06a29eb Mon Sep 17 00:00:00 2001 From: Peter Sandberg Brun Date: Fri, 7 Feb 2025 17:54:50 +0100 Subject: [PATCH 15/31] feat: Add support for managed identity authentication in OMS agent configuration (#4360) ## Description - Added a new parameter omsAgentUseAADAuth to specify whether the OMS agent should use managed identity authentication. Documentation: https://learn.microsoft.com/en-us/azure/azure-monitor/containers/kubernetes-monitoring-enable?tabs=arm#enable-container-insights https://raw.githubusercontent.com/microsoft/Docker-Provider/ci_prod/scripts/onboarding/aks/onboarding-msi-bicep/existingClusterOnboarding.bicep - Updated the omsagent configuration to include the useAADAuth property if the new parameter is set to true. ## Pipeline Reference | Pipeline | | -------- | | | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../managed-cluster/README.md | 10 +++++++++ .../managed-cluster/agent-pool/main.json | 4 ++-- .../managed-cluster/main.bicep | 8 +++++++ .../managed-cluster/main.json | 21 ++++++++++++------- .../maintenance-configurations/main.json | 4 ++-- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/avm/res/container-service/managed-cluster/README.md b/avm/res/container-service/managed-cluster/README.md index 10bcd4bb73..d42773ac42 100644 --- a/avm/res/container-service/managed-cluster/README.md +++ b/avm/res/container-service/managed-cluster/README.md @@ -2785,6 +2785,7 @@ param tags = { | [`nodeResourceGroup`](#parameter-noderesourcegroup) | string | Name of the resource group containing agent pool nodes. | | [`nodeResourceGroupProfile`](#parameter-noderesourcegroupprofile) | object | The node resource group configuration profile. | | [`omsAgentEnabled`](#parameter-omsagentenabled) | bool | Specifies whether the OMS agent is enabled. | +| [`omsAgentUseAADAuth`](#parameter-omsagentuseaadauth) | bool | Specifies whether the OMS agent is using managed identity authentication. | | [`openServiceMeshEnabled`](#parameter-openservicemeshenabled) | bool | Specifies whether the openServiceMesh add-on is enabled or not. | | [`outboundType`](#parameter-outboundtype) | string | Specifies outbound (egress) routing method. | | [`podCidr`](#parameter-podcidr) | string | Specifies the CIDR notation IP range from which to assign pod IPs when kubenet is used. | @@ -4757,6 +4758,15 @@ Specifies whether the OMS agent is enabled. - Default: `True` - MinValue: 24 +### Parameter: `omsAgentUseAADAuth` + +Specifies whether the OMS agent is using managed identity authentication. + +- Required: No +- Type: bool +- Default: `False` +- MinValue: 24 + ### Parameter: `openServiceMeshEnabled` Specifies whether the openServiceMesh add-on is enabled or not. 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 f060d4cfee..997d0b4670 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.33.13.18514", - "templateHash": "3772142304849625200" + "version": "0.33.93.31351", + "templateHash": "3323013309772683046" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool." diff --git a/avm/res/container-service/managed-cluster/main.bicep b/avm/res/container-service/managed-cluster/main.bicep index b1fb466143..b781128a02 100644 --- a/avm/res/container-service/managed-cluster/main.bicep +++ b/avm/res/container-service/managed-cluster/main.bicep @@ -344,6 +344,9 @@ param diagnosticSettings diagnosticSettingFullType[]? @description('Optional. Specifies whether the OMS agent is enabled.') param omsAgentEnabled bool = true +@description('Optional. Specifies whether the OMS agent is using managed identity authentication.') +param omsAgentUseAADAuth bool = false + @description('Optional. Resource ID of the monitoring log analytics workspace.') param monitoringWorkspaceResourceId string? @@ -657,6 +660,11 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2024-09-02-p config: omsAgentEnabled && !empty(monitoringWorkspaceResourceId) ? { logAnalyticsWorkspaceResourceID: monitoringWorkspaceResourceId! + ...(omsAgentUseAADAuth + ? { + useAADAuth: 'true' + } + : {}) } : null } diff --git a/avm/res/container-service/managed-cluster/main.json b/avm/res/container-service/managed-cluster/main.json index cb74fda14c..5d5b313589 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.33.13.18514", - "templateHash": "12618640856903207312" + "version": "0.33.93.31351", + "templateHash": "5916819919470014658" }, "name": "Azure Kubernetes Service (AKS) Managed Clusters", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster." @@ -1478,6 +1478,13 @@ "description": "Optional. Specifies whether the OMS agent is enabled." } }, + "omsAgentUseAADAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the OMS agent is using managed identity authentication." + } + }, "monitoringWorkspaceResourceId": { "type": "string", "nullable": true, @@ -1738,7 +1745,7 @@ }, "omsagent": { "enabled": "[and(parameters('omsAgentEnabled'), not(empty(parameters('monitoringWorkspaceResourceId'))))]", - "config": "[if(and(parameters('omsAgentEnabled'), not(empty(parameters('monitoringWorkspaceResourceId')))), createObject('logAnalyticsWorkspaceResourceID', parameters('monitoringWorkspaceResourceId')), null())]" + "config": "[if(and(parameters('omsAgentEnabled'), not(empty(parameters('monitoringWorkspaceResourceId')))), shallowMerge(createArray(createObject('logAnalyticsWorkspaceResourceID', parameters('monitoringWorkspaceResourceId')), if(parameters('omsAgentUseAADAuth'), createObject('useAADAuth', 'true'), createObject()))), null())]" }, "aciConnectorLinux": { "enabled": "[parameters('aciConnectorLinuxEnabled')]" @@ -1984,8 +1991,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "8370238557121472803" + "version": "0.33.93.31351", + "templateHash": "17573192747850353863" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations." @@ -2180,8 +2187,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "3772142304849625200" + "version": "0.33.93.31351", + "templateHash": "3323013309772683046" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool." 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 370698ec8b..4a41bfaa00 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.33.13.18514", - "templateHash": "8370238557121472803" + "version": "0.33.93.31351", + "templateHash": "17573192747850353863" }, "name": "Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations." From 3c4b14873c9f819127f2e41a4ae1c182f3c68cfc Mon Sep 17 00:00:00 2001 From: Sandy <16922860+thecsw@users.noreply.github.com> Date: Sat, 8 Feb 2025 03:50:21 -0600 Subject: [PATCH 16/31] feat: update `avm/res/storage/storage-account` - Added Defender Plan (Advanced Threat Prodection) (#4379) ## Description Similar to #4363 to enable Microsoft Defender's Advanced Threat Protection plan on storage accounts. ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.storage.storage-account](https://github.com/thecsw/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg)](https://github.com/thecsw/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [X] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [X] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [X] I'm sure there are no other open Pull Requests for the same update/change - [X] I have run `Set-AVMModule` locally to generate the supporting module files. - [X] My corresponding pipelines / checks run clean and green without any errors or warnings --------- Signed-off-by: Sandy Urazayev --- avm/res/storage/storage-account/README.md | 10 +++ .../container/immutability-policy/main.json | 4 +- .../blob-service/container/main.json | 8 +-- .../storage-account/blob-service/main.json | 12 ++-- .../storage-account/file-service/main.json | 8 +-- .../file-service/share/main.json | 4 +- .../storage-account/local-user/main.json | 4 +- avm/res/storage/storage-account/main.bicep | 12 ++++ avm/res/storage/storage-account/main.json | 72 ++++++++++++------- .../management-policy/main.json | 4 +- .../storage-account/queue-service/main.json | 8 +-- .../queue-service/queue/main.json | 4 +- .../storage-account/table-service/main.json | 8 +-- .../table-service/table/main.json | 4 +- avm/res/storage/storage-account/version.json | 4 +- 15 files changed, 104 insertions(+), 62 deletions(-) diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md index 82b01bb576..94e576af3b 100644 --- a/avm/res/storage/storage-account/README.md +++ b/avm/res/storage/storage-account/README.md @@ -22,6 +22,7 @@ This module deploys a Storage Account. | `Microsoft.KeyVault/vaults/secrets` | [2023-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2023-07-01/vaults/secrets) | | `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.Security/advancedThreatProtectionSettings` | [2019-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Security/2019-01-01/advancedThreatProtectionSettings) | | `Microsoft.Storage/storageAccounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-05-01/storageAccounts) | | `Microsoft.Storage/storageAccounts/blobServices` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices) | | `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | @@ -3428,6 +3429,7 @@ param tags = { | [`defaultToOAuthAuthentication`](#parameter-defaulttooauthauthentication) | bool | A boolean flag which indicates whether the default authentication is OAuth or not. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`dnsEndpointType`](#parameter-dnsendpointtype) | string | Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier. | +| [`enableAdvancedThreatProtection`](#parameter-enableadvancedthreatprotection) | bool | Enables Advanced Threat Protection on the storage account. | | [`enableNfsV3`](#parameter-enablenfsv3) | bool | If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true. | | [`enableSftp`](#parameter-enablesftp) | bool | If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | @@ -3786,6 +3788,14 @@ Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a ] ``` +### Parameter: `enableAdvancedThreatProtection` + +Enables Advanced Threat Protection on the storage account. + +- Required: No +- Type: bool +- Default: `True` + ### Parameter: `enableNfsV3` If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true. diff --git a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json index dbbe33ca7c..3e1f62c7b5 100644 --- a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json +++ b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/container/main.json b/avm/res/storage/storage-account/blob-service/container/main.json index 49e3b47170..df35c3db1f 100644 --- a/avm/res/storage/storage-account/blob-service/container/main.json +++ b/avm/res/storage/storage-account/blob-service/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -294,8 +294,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/main.json b/avm/res/storage/storage-account/blob-service/main.json index b37a944429..23d1aadc51 100644 --- a/avm/res/storage/storage-account/blob-service/main.json +++ b/avm/res/storage/storage-account/blob-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7416701536235015086" + "version": "0.33.93.31351", + "templateHash": "7588078546699808778" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -472,8 +472,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -761,8 +761,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/file-service/main.json b/avm/res/storage/storage-account/file-service/main.json index 95c9c54fe5..8e27cf79fc 100644 --- a/avm/res/storage/storage-account/file-service/main.json +++ b/avm/res/storage/storage-account/file-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16196407713115246323" + "version": "0.33.93.31351", + "templateHash": "3168394810831105529" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -359,8 +359,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5204319087439022536" + "version": "0.33.93.31351", + "templateHash": "12044655551245282190" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." diff --git a/avm/res/storage/storage-account/file-service/share/main.json b/avm/res/storage/storage-account/file-service/share/main.json index a95097e146..0144ab364d 100644 --- a/avm/res/storage/storage-account/file-service/share/main.json +++ b/avm/res/storage/storage-account/file-service/share/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5204319087439022536" + "version": "0.33.93.31351", + "templateHash": "12044655551245282190" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." diff --git a/avm/res/storage/storage-account/local-user/main.json b/avm/res/storage/storage-account/local-user/main.json index dac871c0e5..7be0e3b8da 100644 --- a/avm/res/storage/storage-account/local-user/main.json +++ b/avm/res/storage/storage-account/local-user/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16427795222629898111" + "version": "0.33.93.31351", + "templateHash": "5655292159520921149" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep index 91ee043a7e..8ee2ba44da 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -188,6 +188,9 @@ param keyType string? @description('Optional. Key vault reference and secret settings for the module\'s secrets export.') param secretsExportConfiguration secretsExportConfigurationType? +@description('Optional. Enables Advanced Threat Protection on the storage account.') +param enableAdvancedThreatProtection bool = true + var supportsBlobService = kind == 'BlockBlobStorage' || kind == 'BlobStorage' || kind == 'StorageV2' || kind == 'Storage' var supportsFileService = kind == 'FileStorage' || kind == 'StorageV2' || kind == 'Storage' @@ -694,6 +697,15 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura } } +// Microsoft Defender plan +resource storageAccount_atp 'Microsoft.Security/advancedThreatProtectionSettings@2019-01-01' = if (enableAdvancedThreatProtection) { + name: 'current' + scope: storageAccount + properties: { + isEnabled: true + } +} + @description('The resource ID of the deployed storage account.') output resourceId string = storageAccount.id diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index a6425011ad..a154a8304e 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9739064632358098891" + "version": "0.33.93.31351", + "templateHash": "9582256320776207177" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account." @@ -1245,6 +1245,13 @@ "metadata": { "description": "Optional. Key vault reference and secret settings for the module's secrets export." } + }, + "enableAdvancedThreatProtection": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enables Advanced Threat Protection on the storage account." + } } }, "variables": { @@ -1443,6 +1450,19 @@ "storageAccount" ] }, + "storageAccount_atp": { + "condition": "[parameters('enableAdvancedThreatProtection')]", + "type": "Microsoft.Security/advancedThreatProtectionSettings", + "apiVersion": "2019-01-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", + "name": "current", + "properties": { + "isEnabled": true + }, + "dependsOn": [ + "storageAccount" + ] + }, "storageAccount_privateEndpoints": { "copy": { "name": "storageAccount_privateEndpoints", @@ -2222,8 +2242,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4014848332192190169" + "version": "0.33.93.31351", + "templateHash": "10504956743360699891" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." @@ -2331,8 +2351,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16427795222629898111" + "version": "0.33.93.31351", + "templateHash": "5655292159520921149" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." @@ -2569,8 +2589,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7416701536235015086" + "version": "0.33.93.31351", + "templateHash": "7588078546699808778" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -3036,8 +3056,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -3325,8 +3345,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." @@ -3505,8 +3525,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16196407713115246323" + "version": "0.33.93.31351", + "templateHash": "3168394810831105529" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -3859,8 +3879,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5204319087439022536" + "version": "0.33.93.31351", + "templateHash": "12044655551245282190" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." @@ -4294,8 +4314,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14497929042813606497" + "version": "0.33.93.31351", + "templateHash": "1736438454543575457" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -4613,8 +4633,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9969689246600110741" + "version": "0.33.93.31351", + "templateHash": "6383154227554431205" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." @@ -4883,8 +4903,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4194630585059896468" + "version": "0.33.93.31351", + "templateHash": "12583903411447171294" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -5199,8 +5219,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4457939127962832961" + "version": "0.33.93.31351", + "templateHash": "1369356397929898951" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." @@ -5453,8 +5473,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9771994149501143078" + "version": "0.33.93.31351", + "templateHash": "2275047425860597278" } }, "definitions": { diff --git a/avm/res/storage/storage-account/management-policy/main.json b/avm/res/storage/storage-account/management-policy/main.json index bc2c2530f7..38c4ba5749 100644 --- a/avm/res/storage/storage-account/management-policy/main.json +++ b/avm/res/storage/storage-account/management-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4014848332192190169" + "version": "0.33.93.31351", + "templateHash": "10504956743360699891" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." diff --git a/avm/res/storage/storage-account/queue-service/main.json b/avm/res/storage/storage-account/queue-service/main.json index fa4e1c19d4..58b8972173 100644 --- a/avm/res/storage/storage-account/queue-service/main.json +++ b/avm/res/storage/storage-account/queue-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14497929042813606497" + "version": "0.33.93.31351", + "templateHash": "1736438454543575457" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -324,8 +324,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9969689246600110741" + "version": "0.33.93.31351", + "templateHash": "6383154227554431205" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." diff --git a/avm/res/storage/storage-account/queue-service/queue/main.json b/avm/res/storage/storage-account/queue-service/queue/main.json index 19308bf371..dfd0124351 100644 --- a/avm/res/storage/storage-account/queue-service/queue/main.json +++ b/avm/res/storage/storage-account/queue-service/queue/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9969689246600110741" + "version": "0.33.93.31351", + "templateHash": "6383154227554431205" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." diff --git a/avm/res/storage/storage-account/table-service/main.json b/avm/res/storage/storage-account/table-service/main.json index c336dcaed3..791d9ecdc8 100644 --- a/avm/res/storage/storage-account/table-service/main.json +++ b/avm/res/storage/storage-account/table-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4194630585059896468" + "version": "0.33.93.31351", + "templateHash": "12583903411447171294" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -321,8 +321,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4457939127962832961" + "version": "0.33.93.31351", + "templateHash": "1369356397929898951" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." diff --git a/avm/res/storage/storage-account/table-service/table/main.json b/avm/res/storage/storage-account/table-service/table/main.json index f9e2ac6377..d97ce4a5f1 100644 --- a/avm/res/storage/storage-account/table-service/table/main.json +++ b/avm/res/storage/storage-account/table-service/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4457939127962832961" + "version": "0.33.93.31351", + "templateHash": "1369356397929898951" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." diff --git a/avm/res/storage/storage-account/version.json b/avm/res/storage/storage-account/version.json index 8f0ecca899..77443210ac 100644 --- a/avm/res/storage/storage-account/version.json +++ b/avm/res/storage/storage-account/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.17", + "version": "0.18", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +} From e0dbcc4e37c300cf3323cd49f968f9230c5f2181 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Sat, 8 Feb 2025 18:04:13 +0100 Subject: [PATCH 17/31] feat: Updates of `avm/res/network/bastion-host` (#4394) ## Description - added support for the `Developer` SKU - leveraging AVM Common Types - updated cross module reference to the newest version of the Public IP module - updated api versions Resolves #4129 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.network.bastion-host](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.network.bastion-host.yml/badge.svg?branch=users%2Fkrbar%2FbastionUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.network.bastion-host.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [x] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/network/bastion-host/README.md | 123 ++- avm/res/network/bastion-host/main.bicep | 159 +--- avm/res/network/bastion-host/main.json | 870 ++++++++++-------- .../tests/e2e/custompip/dependencies.bicep | 2 +- .../tests/e2e/custompip/main.test.bicep | 6 +- .../tests/e2e/defaults/dependencies.bicep | 2 +- .../tests/e2e/defaults/main.test.bicep | 5 +- .../tests/e2e/developer/dependencies.bicep | 30 + .../tests/e2e/developer/main.test.bicep | 59 ++ .../tests/e2e/max/dependencies.bicep | 4 +- .../tests/e2e/max/main.test.bicep | 6 +- .../tests/e2e/private/dependencies.bicep | 2 +- .../tests/e2e/private/main.test.bicep | 2 +- .../tests/e2e/waf-aligned/dependencies.bicep | 4 +- .../tests/e2e/waf-aligned/main.test.bicep | 6 +- avm/res/network/bastion-host/version.json | 2 +- 16 files changed, 723 insertions(+), 559 deletions(-) create mode 100644 avm/res/network/bastion-host/tests/e2e/developer/dependencies.bicep create mode 100644 avm/res/network/bastion-host/tests/e2e/developer/main.test.bicep diff --git a/avm/res/network/bastion-host/README.md b/avm/res/network/bastion-host/README.md index d0358319a5..5f23a61e2c 100644 --- a/avm/res/network/bastion-host/README.md +++ b/avm/res/network/bastion-host/README.md @@ -18,8 +18,8 @@ This module deploys a Bastion Host. | `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/bastionHosts` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-01-01/bastionHosts) | -| `Microsoft.Network/publicIPAddresses` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-09-01/publicIPAddresses) | +| `Microsoft.Network/bastionHosts` | [2024-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-05-01/bastionHosts) | +| `Microsoft.Network/publicIPAddresses` | [2024-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2024-05-01/publicIPAddresses) | ## Usage examples @@ -31,9 +31,10 @@ The following section provides usage examples for the module, which were used to - [With a custom public IP address deployed by the module](#example-1-with-a-custom-public-ip-address-deployed-by-the-module) - [Using only defaults](#example-2-using-only-defaults) -- [Using large parameter set](#example-3-using-large-parameter-set) -- [Private-only deployment](#example-4-private-only-deployment) -- [WAF-aligned](#example-5-waf-aligned) +- [Using Developer SKU](#example-3-using-developer-sku) +- [Using large parameter set](#example-4-using-large-parameter-set) +- [Private-only deployment](#example-5-private-only-deployment) +- [WAF-aligned](#example-6-waf-aligned) ### Example 1: _With a custom public IP address deployed by the module_ @@ -289,7 +290,81 @@ param location = ''

-### Example 3: _Using large parameter set_ +### Example 3: _Using Developer SKU_ + +This instance deploys the module with the Developer SKU. + + +

+ +via Bicep module + +```bicep +module bastionHost 'br/public:avm/res/network/bastion-host:' = { + name: 'bastionHostDeployment' + params: { + // Required parameters + name: 'nbhdev001' + virtualNetworkResourceId: '' + // Non-required parameters + location: '' + skuName: 'Developer' + } +} +``` + +
+

+ +

+ +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": "nbhdev001" + }, + "virtualNetworkResourceId": { + "value": "" + }, + // Non-required parameters + "location": { + "value": "" + }, + "skuName": { + "value": "Developer" + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/network/bastion-host:' + +// Required parameters +param name = 'nbhdev001' +param virtualNetworkResourceId = '' +// Non-required parameters +param location = '' +param skuName = 'Developer' +``` + +
+

+ +### Example 4: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -529,7 +604,7 @@ param zones = [

-### Example 4: _Private-only deployment_ +### Example 5: _Private-only deployment_ This instance deploys the module as private-only Bastion deployment. @@ -613,7 +688,7 @@ param skuName = 'Premium'

-### Example 5: _WAF-aligned_ +### Example 6: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -778,22 +853,22 @@ param tags = { | :-- | :-- | :-- | | [`bastionSubnetPublicIpResourceId`](#parameter-bastionsubnetpublicipresourceid) | string | The Public IP resource ID to associate to the azureBastionSubnet. If empty, then the Public IP that is created as part of this module will be applied to the azureBastionSubnet. This parameter is ignored when enablePrivateOnlyBastion is true. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | -| [`disableCopyPaste`](#parameter-disablecopypaste) | bool | Choose to disable or enable Copy Paste. For Basic SKU Copy/Paste is always enabled. | -| [`enableFileCopy`](#parameter-enablefilecopy) | bool | Choose to disable or enable File Copy. Not supported for Basic SKU. | -| [`enableIpConnect`](#parameter-enableipconnect) | bool | Choose to disable or enable IP Connect. Not supported for Basic SKU. | -| [`enableKerberos`](#parameter-enablekerberos) | bool | Choose to disable or enable Kerberos authentication. | +| [`disableCopyPaste`](#parameter-disablecopypaste) | bool | Choose to disable or enable Copy Paste. For Basic and Developer SKU Copy/Paste is always enabled. | +| [`enableFileCopy`](#parameter-enablefilecopy) | bool | Choose to disable or enable File Copy. Not supported for Basic and Developer SKU. | +| [`enableIpConnect`](#parameter-enableipconnect) | bool | Choose to disable or enable IP Connect. Not supported for Basic and Developer SKU. | +| [`enableKerberos`](#parameter-enablekerberos) | bool | Choose to disable or enable Kerberos authentication. Not supported for Developer SKU. | | [`enablePrivateOnlyBastion`](#parameter-enableprivateonlybastion) | bool | Choose to disable or enable Private-only Bastion deployment. The Premium SKU is required for this feature. | | [`enableSessionRecording`](#parameter-enablesessionrecording) | bool | Choose to disable or enable Session Recording feature. The Premium SKU is required for this feature. If Session Recording is enabled, the Native client support will be disabled. | -| [`enableShareableLink`](#parameter-enableshareablelink) | bool | Choose to disable or enable Shareable Link. Not supported for Basic SKU. | +| [`enableShareableLink`](#parameter-enableshareablelink) | bool | Choose to disable or enable Shareable Link. Not supported for Basic and Developer SKU. | | [`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. | | [`publicIPAddressObject`](#parameter-publicipaddressobject) | object | Specifies the properties of the Public IP to create and be used by Azure Bastion, if no existing public IP was provided. This parameter is ignored when enablePrivateOnlyBastion is true. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | -| [`scaleUnits`](#parameter-scaleunits) | int | The scale units for the Bastion Host resource. The Basic SKU only supports 2 scale units. | +| [`scaleUnits`](#parameter-scaleunits) | int | The scale units for the Bastion Host resource. The Basic and Developer SKU only support 2 scale units. | | [`skuName`](#parameter-skuname) | string | The SKU of this Bastion Host. | | [`tags`](#parameter-tags) | object | Tags of the resource. | -| [`zones`](#parameter-zones) | array | A list of availability zones denoting where the Bastion Host resource needs to come from. | +| [`zones`](#parameter-zones) | array | A list of availability zones denoting where the Bastion Host resource needs to come from. This is not supported for the Developer SKU. | ### Parameter: `name` @@ -931,7 +1006,7 @@ Resource ID of the diagnostic log analytics workspace. For security reasons, it ### Parameter: `disableCopyPaste` -Choose to disable or enable Copy Paste. For Basic SKU Copy/Paste is always enabled. +Choose to disable or enable Copy Paste. For Basic and Developer SKU Copy/Paste is always enabled. - Required: No - Type: bool @@ -939,7 +1014,7 @@ Choose to disable or enable Copy Paste. For Basic SKU Copy/Paste is always enabl ### Parameter: `enableFileCopy` -Choose to disable or enable File Copy. Not supported for Basic SKU. +Choose to disable or enable File Copy. Not supported for Basic and Developer SKU. - Required: No - Type: bool @@ -947,7 +1022,7 @@ Choose to disable or enable File Copy. Not supported for Basic SKU. ### Parameter: `enableIpConnect` -Choose to disable or enable IP Connect. Not supported for Basic SKU. +Choose to disable or enable IP Connect. Not supported for Basic and Developer SKU. - Required: No - Type: bool @@ -955,7 +1030,7 @@ Choose to disable or enable IP Connect. Not supported for Basic SKU. ### Parameter: `enableKerberos` -Choose to disable or enable Kerberos authentication. +Choose to disable or enable Kerberos authentication. Not supported for Developer SKU. - Required: No - Type: bool @@ -979,7 +1054,7 @@ Choose to disable or enable Session Recording feature. The Premium SKU is requir ### Parameter: `enableShareableLink` -Choose to disable or enable Shareable Link. Not supported for Basic SKU. +Choose to disable or enable Shareable Link. Not supported for Basic and Developer SKU. - Required: No - Type: bool @@ -1155,7 +1230,7 @@ The principal type of the assigned principal ID. ### Parameter: `scaleUnits` -The scale units for the Bastion Host resource. The Basic SKU only supports 2 scale units. +The scale units for the Bastion Host resource. The Basic and Developer SKU only support 2 scale units. - Required: No - Type: int @@ -1172,6 +1247,7 @@ The SKU of this Bastion Host. ```Bicep [ 'Basic' + 'Developer' 'Premium' 'Standard' ] @@ -1186,7 +1262,7 @@ Tags of the resource. ### Parameter: `zones` -A list of availability zones denoting where the Bastion Host resource needs to come from. +A list of availability zones denoting where the Bastion Host resource needs to come from. This is not supported for the Developer SKU. - Required: No - Type: array @@ -1216,7 +1292,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/public-ip-address:0.6.0` | Remote reference | +| `br/public:avm/res/network/public-ip-address:0.8.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.5.1` | Remote reference | ## Data Collection diff --git a/avm/res/network/bastion-host/main.bicep b/avm/res/network/bastion-host/main.bicep index 3048d66789..70c415b18b 100644 --- a/avm/res/network/bastion-host/main.bicep +++ b/avm/res/network/bastion-host/main.bicep @@ -18,33 +18,36 @@ param publicIPAddressObject object = { name: '${name}-pip' } +import { diagnosticSettingLogsOnlyType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingLogsOnlyType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @allowed([ 'Basic' + 'Developer' 'Premium' 'Standard' ]) @description('Optional. The SKU of this Bastion Host.') param skuName string = 'Basic' -@description('Optional. Choose to disable or enable Copy Paste. For Basic SKU Copy/Paste is always enabled.') +@description('Optional. Choose to disable or enable Copy Paste. For Basic and Developer SKU Copy/Paste is always enabled.') param disableCopyPaste bool = false -@description('Optional. Choose to disable or enable File Copy. Not supported for Basic SKU.') +@description('Optional. Choose to disable or enable File Copy. Not supported for Basic and Developer SKU.') param enableFileCopy bool = true -@description('Optional. Choose to disable or enable IP Connect. Not supported for Basic SKU.') +@description('Optional. Choose to disable or enable IP Connect. Not supported for Basic and Developer SKU.') param enableIpConnect bool = false -@description('Optional. Choose to disable or enable Kerberos authentication.') +@description('Optional. Choose to disable or enable Kerberos authentication. Not supported for Developer SKU.') param enableKerberos bool = false -@description('Optional. Choose to disable or enable Shareable Link. Not supported for Basic SKU.') +@description('Optional. Choose to disable or enable Shareable Link. Not supported for Basic and Developer SKU.') param enableShareableLink bool = false @description('Optional. Choose to disable or enable Session Recording feature. The Premium SKU is required for this feature. If Session Recording is enabled, the Native client support will be disabled.') @@ -53,11 +56,12 @@ param enableSessionRecording bool = false @description('Optional. Choose to disable or enable Private-only Bastion deployment. The Premium SKU is required for this feature.') param enablePrivateOnlyBastion bool = false -@description('Optional. The scale units for the Bastion Host resource. The Basic SKU only supports 2 scale units.') +@description('Optional. The scale units for the Bastion Host resource. The Basic and Developer SKU only support 2 scale units.') param scaleUnits int = 2 +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -65,7 +69,7 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true -@description('Optional. A list of availability zones denoting where the Bastion Host resource needs to come from.') +@description('Optional. A list of availability zones denoting where the Bastion Host resource needs to come from. This is not supported for the Developer SKU.') @allowed([ 1 2 @@ -77,28 +81,31 @@ param zones int[] = [] // Availability Zones are currently in preview and only a // Prep ipConfigurations object AzureBastionSubnet for different uses cases: // 1. Use existing Public IP // 2. Use new Public IP created in this module -var ipConfigurations = [ - { - name: 'IpConfAzureBastionSubnet' - properties: union( +// (skuName == 'Developer' is a special case where ipConfigurations is empty) +var ipConfigurations = skuName == 'Developer' + ? [] + : [ { - subnet: { - id: '${virtualNetworkResourceId}/subnets/AzureBastionSubnet' // The subnet name must be AzureBastionSubnet - } - }, - (!enablePrivateOnlyBastion - ? { - //Use existing Public IP, new Public IP created in this module - publicIPAddress: { - id: !empty(bastionSubnetPublicIpResourceId) - ? bastionSubnetPublicIpResourceId - : publicIPAddress.outputs.resourceId + name: 'IpConfAzureBastionSubnet' + properties: union( + { + subnet: { + id: '${virtualNetworkResourceId}/subnets/AzureBastionSubnet' // The subnet name must be AzureBastionSubnet } - } - : {}) - ) - } -] + }, + (!enablePrivateOnlyBastion + ? { + //Use existing Public IP, new Public IP created in this module + publicIPAddress: { + id: !empty(bastionSubnetPublicIpResourceId) + ? bastionSubnetPublicIpResourceId + : publicIPAddress.outputs.resourceId + } + } + : {}) + ) + } + ] // ---------------------------------------------------------------------------- @@ -146,7 +153,7 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.6.0' = if (empty(bastionSubnetPublicIpResourceId) && (!enablePrivateOnlyBastion)) { +module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.8.0' = if (empty(bastionSubnetPublicIpResourceId) && (skuName != 'Developer') && (!enablePrivateOnlyBastion)) { name: '${uniqueString(deployment().name, location)}-Bastion-PIP' params: { name: publicIPAddressObject.name @@ -167,9 +174,16 @@ module publicIPAddress 'br/public:avm/res/network/public-ip-address:0.6.0' = if var bastionpropertiesVar = union( { - scaleUnits: skuName == 'Basic' ? 2 : scaleUnits + scaleUnits: (skuName == 'Basic' || skuName == 'Developer') ? 2 : scaleUnits ipConfigurations: ipConfigurations }, + (skuName == 'Developer' + ? { + virtualNetwork: { + id: virtualNetworkResourceId + } + } + : {}), ((skuName == 'Basic' || skuName == 'Standard' || skuName == 'Premium') ? { enableKerberos: enableKerberos @@ -192,14 +206,14 @@ var bastionpropertiesVar = union( : {}) ) -resource azureBastion 'Microsoft.Network/bastionHosts@2024-01-01' = { +resource azureBastion 'Microsoft.Network/bastionHosts@2024-05-01' = { name: name location: location - tags: tags + tags: tags ?? {} // The empty object is a workaround for error when deploying with the Developer SKU. The error seems unrelated to the tags, but it is resolved by adding the empty object. sku: { name: skuName } - zones: map(zones, zone => string(zone)) + zones: skuName == 'Developer' ? [] : map(zones, zone => string(zone)) properties: bastionpropertiesVar } @@ -265,77 +279,4 @@ output resourceId string = azureBastion.id output location string = azureBastion.location @description('The Public IPconfiguration object for the AzureBastionSubnet.') -output ipConfAzureBastionSubnet object = azureBastion.properties.ipConfigurations[0] - -// =============== // -// 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. 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? -}[]? +output ipConfAzureBastionSubnet object = skuName == 'Developer' ? {} : azureBastion.properties.ipConfigurations[0] diff --git a/avm/res/network/bastion-host/main.json b/avm/res/network/bastion-host/main.json index ecfca15cc8..27dfd312d4 100644 --- a/avm/res/network/bastion-host/main.json +++ b/avm/res/network/bastion-host/main.json @@ -5,13 +5,110 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4032958951426322911" + "version": "0.33.93.31351", + "templateHash": "16499979971476585213" }, "name": "Bastion Hosts", "description": "This module deploys a Bastion Host." }, "definitions": { + "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." + } + }, + "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." + } + }, + "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 only logs are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, "lockType": { "type": "object", "properties": { @@ -35,175 +132,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.5.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." - } - }, - "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.5.1" + } + } } }, "parameters": { @@ -243,13 +252,18 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingLogsOnlyType" + }, + "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." } @@ -259,6 +273,7 @@ "defaultValue": "Basic", "allowedValues": [ "Basic", + "Developer", "Premium", "Standard" ], @@ -270,35 +285,35 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable Copy Paste. For Basic SKU Copy/Paste is always enabled." + "description": "Optional. Choose to disable or enable Copy Paste. For Basic and Developer SKU Copy/Paste is always enabled." } }, "enableFileCopy": { "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Choose to disable or enable File Copy. Not supported for Basic SKU." + "description": "Optional. Choose to disable or enable File Copy. Not supported for Basic and Developer SKU." } }, "enableIpConnect": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable IP Connect. Not supported for Basic SKU." + "description": "Optional. Choose to disable or enable IP Connect. Not supported for Basic and Developer SKU." } }, "enableKerberos": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable Kerberos authentication." + "description": "Optional. Choose to disable or enable Kerberos authentication. Not supported for Developer SKU." } }, "enableShareableLink": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable Shareable Link. Not supported for Basic SKU." + "description": "Optional. Choose to disable or enable Shareable Link. Not supported for Basic and Developer SKU." } }, "enableSessionRecording": { @@ -319,11 +334,15 @@ "type": "int", "defaultValue": 2, "metadata": { - "description": "Optional. The scale units for the Bastion Host resource. The Basic SKU only supports 2 scale units." + "description": "Optional. The scale units for the Bastion Host resource. The Basic and Developer SKU only support 2 scale units." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -354,7 +373,7 @@ 3 ], "metadata": { - "description": "Optional. A list of availability zones denoting where the Bastion Host resource needs to come from." + "description": "Optional. A list of availability zones denoting where the Bastion Host resource needs to come from. This is not supported for the Developer SKU." } } }, @@ -397,15 +416,15 @@ }, "azureBastion": { "type": "Microsoft.Network/bastionHosts", - "apiVersion": "2024-01-01", + "apiVersion": "2024-05-01", "name": "[parameters('name')]", "location": "[parameters('location')]", - "tags": "[parameters('tags')]", + "tags": "[coalesce(parameters('tags'), createObject())]", "sku": { "name": "[parameters('skuName')]" }, - "zones": "[map(parameters('zones'), lambda('zone', string(lambdaVariables('zone'))))]", - "properties": "[union(createObject('scaleUnits', if(equals(parameters('skuName'), 'Basic'), 2, parameters('scaleUnits')), 'ipConfigurations', createArray(createObject('name', 'IpConfAzureBastionSubnet', 'properties', union(createObject('subnet', createObject('id', format('{0}/subnets/AzureBastionSubnet', parameters('virtualNetworkResourceId')))), if(not(parameters('enablePrivateOnlyBastion')), createObject('publicIPAddress', createObject('id', if(not(empty(parameters('bastionSubnetPublicIpResourceId'))), parameters('bastionSubnetPublicIpResourceId'), reference('publicIPAddress').outputs.resourceId.value))), createObject()))))), if(or(or(equals(parameters('skuName'), 'Basic'), equals(parameters('skuName'), 'Standard')), equals(parameters('skuName'), 'Premium')), createObject('enableKerberos', parameters('enableKerberos')), createObject()), if(or(equals(parameters('skuName'), 'Standard'), equals(parameters('skuName'), 'Premium')), createObject('enableTunneling', if(equals(parameters('skuName'), 'Standard'), true(), if(parameters('enableSessionRecording'), false(), true())), 'disableCopyPaste', parameters('disableCopyPaste'), 'enableFileCopy', parameters('enableFileCopy'), 'enableIpConnect', parameters('enableIpConnect'), 'enableShareableLink', parameters('enableShareableLink')), createObject()), if(equals(parameters('skuName'), 'Premium'), createObject('enableSessionRecording', parameters('enableSessionRecording'), 'enablePrivateOnlyBastion', parameters('enablePrivateOnlyBastion')), createObject()))]", + "zones": "[if(equals(parameters('skuName'), 'Developer'), createArray(), map(parameters('zones'), lambda('zone', string(lambdaVariables('zone')))))]", + "properties": "[union(createObject('scaleUnits', if(or(equals(parameters('skuName'), 'Basic'), equals(parameters('skuName'), 'Developer')), 2, parameters('scaleUnits')), 'ipConfigurations', if(equals(parameters('skuName'), 'Developer'), createArray(), createArray(createObject('name', 'IpConfAzureBastionSubnet', 'properties', union(createObject('subnet', createObject('id', format('{0}/subnets/AzureBastionSubnet', parameters('virtualNetworkResourceId')))), if(not(parameters('enablePrivateOnlyBastion')), createObject('publicIPAddress', createObject('id', if(not(empty(parameters('bastionSubnetPublicIpResourceId'))), parameters('bastionSubnetPublicIpResourceId'), reference('publicIPAddress').outputs.resourceId.value))), createObject())))))), if(equals(parameters('skuName'), 'Developer'), createObject('virtualNetwork', createObject('id', parameters('virtualNetworkResourceId'))), createObject()), if(or(or(equals(parameters('skuName'), 'Basic'), equals(parameters('skuName'), 'Standard')), equals(parameters('skuName'), 'Premium')), createObject('enableKerberos', parameters('enableKerberos')), createObject()), if(or(equals(parameters('skuName'), 'Standard'), equals(parameters('skuName'), 'Premium')), createObject('enableTunneling', if(equals(parameters('skuName'), 'Standard'), true(), if(parameters('enableSessionRecording'), false(), true())), 'disableCopyPaste', parameters('disableCopyPaste'), 'enableFileCopy', parameters('enableFileCopy'), 'enableIpConnect', parameters('enableIpConnect'), 'enableShareableLink', parameters('enableShareableLink')), createObject()), if(equals(parameters('skuName'), 'Premium'), createObject('enableSessionRecording', parameters('enableSessionRecording'), 'enablePrivateOnlyBastion', parameters('enablePrivateOnlyBastion')), createObject()))]", "dependsOn": [ "publicIPAddress" ] @@ -479,7 +498,7 @@ ] }, "publicIPAddress": { - "condition": "[and(empty(parameters('bastionSubnetPublicIpResourceId')), not(parameters('enablePrivateOnlyBastion')))]", + "condition": "[and(and(empty(parameters('bastionSubnetPublicIpResourceId')), not(equals(parameters('skuName'), 'Developer'))), not(parameters('enablePrivateOnlyBastion')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-Bastion-PIP', uniqueString(deployment().name, parameters('location')))]", @@ -536,112 +555,13 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "16693645977675862540" + "version": "0.33.93.31351", + "templateHash": "5168739580767459761" }, "name": "Public IP Addresses", - "description": "This module deploys a Public IP Address.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Public IP Address." }, "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": { @@ -654,14 +574,14 @@ "domainNameLabelScope": { "type": "string", "allowedValues": [ - "", "NoReuse", "ResourceGroupReuse", "SubscriptionReuse", "TenantReuse" ], + "nullable": true, "metadata": { - "description": "Required. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." + "description": "Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." } }, "fqdn": { @@ -678,6 +598,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": { @@ -707,127 +630,257 @@ "description": "Required. The DDoS protection policy customizations." } } + }, + "metadata": { + "__bicep_export!": 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 } }, - "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." + } + } + }, + "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": { @@ -892,8 +945,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." } @@ -935,7 +999,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -962,7 +1030,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingFullType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -994,7 +1066,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.6.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.8.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1012,7 +1084,7 @@ }, "publicIpAddress": { "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-09-01", + "apiVersion": "2024-05-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -1028,7 +1100,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": { @@ -1143,7 +1215,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('publicIpAddress', '2023-09-01', 'full').location]" + "value": "[reference('publicIpAddress', '2024-05-01', 'full').location]" } } } @@ -1177,14 +1249,14 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('azureBastion', '2024-01-01', 'full').location]" + "value": "[reference('azureBastion', '2024-05-01', 'full').location]" }, "ipConfAzureBastionSubnet": { "type": "object", "metadata": { "description": "The Public IPconfiguration object for the AzureBastionSubnet." }, - "value": "[reference('azureBastion').ipConfigurations[0]]" + "value": "[if(equals(parameters('skuName'), 'Developer'), createObject(), reference('azureBastion').ipConfigurations[0])]" } } } \ No newline at end of file diff --git a/avm/res/network/bastion-host/tests/e2e/custompip/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/custompip/dependencies.bicep index 4166c9be72..e4b1080880 100644 --- a/avm/res/network/bastion-host/tests/e2e/custompip/dependencies.bicep +++ b/avm/res/network/bastion-host/tests/e2e/custompip/dependencies.bicep @@ -9,7 +9,7 @@ param managedIdentityName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: virtualNetworkName location: location properties: { diff --git a/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep index ca63db4a59..13e17f8de0 100644 --- a/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/custompip/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: resourceLocation } @@ -107,9 +107,5 @@ module testDeployment '../../../main.bicep' = [ } } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/network/bastion-host/tests/e2e/defaults/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/defaults/dependencies.bicep index 7aada15d55..e7f1953da8 100644 --- a/avm/res/network/bastion-host/tests/e2e/defaults/dependencies.bicep +++ b/avm/res/network/bastion-host/tests/e2e/defaults/dependencies.bicep @@ -6,7 +6,7 @@ param virtualNetworkName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: virtualNetworkName location: location properties: { diff --git a/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep index 19706f01fd..b87f5575f8 100644 --- a/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/defaults/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: resourceLocation } @@ -54,8 +54,5 @@ module testDeployment '../../../main.bicep' = [ location: resourceLocation virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/bastion-host/tests/e2e/developer/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/developer/dependencies.bicep new file mode 100644 index 0000000000..e7f1953da8 --- /dev/null +++ b/avm/res/network/bastion-host/tests/e2e/developer/dependencies.bicep @@ -0,0 +1,30 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'AzureBastionSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network.') +output virtualNetworkResourceId string = virtualNetwork.id diff --git a/avm/res/network/bastion-host/tests/e2e/developer/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/developer/main.test.bicep new file mode 100644 index 0000000000..a62c4e437b --- /dev/null +++ b/avm/res/network/bastion-host/tests/e2e/developer/main.test.bicep @@ -0,0 +1,59 @@ +targetScope = 'subscription' + +metadata name = 'Using Developer SKU' +metadata description = 'This instance deploys the module with the Developer SKU.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.bastionhosts-${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 = 'nbhdev' + +@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-11-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + 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' + skuName: 'Developer' + location: resourceLocation + virtualNetworkResourceId: nestedDependencies.outputs.virtualNetworkResourceId + } + } +] diff --git a/avm/res/network/bastion-host/tests/e2e/max/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/max/dependencies.bicep index 1ff59b7834..d5fdc86712 100644 --- a/avm/res/network/bastion-host/tests/e2e/max/dependencies.bicep +++ b/avm/res/network/bastion-host/tests/e2e/max/dependencies.bicep @@ -12,7 +12,7 @@ param managedIdentityName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: virtualNetworkName location: location properties: { @@ -32,7 +32,7 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { } } -resource publicIP 'Microsoft.Network/publicIPAddresses@2024-01-01' = { +resource publicIP 'Microsoft.Network/publicIPAddresses@2024-05-01' = { name: publicIPName location: location sku: { diff --git a/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep index 2b78c0cf46..10ede671ff 100644 --- a/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/max/main.test.bicep @@ -27,7 +27,7 @@ var enforcedLocation = 'northeurope' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: enforcedLocation } @@ -123,9 +123,5 @@ module testDeployment '../../../main.bicep' = [ 3 ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/network/bastion-host/tests/e2e/private/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/private/dependencies.bicep index 7aada15d55..e7f1953da8 100644 --- a/avm/res/network/bastion-host/tests/e2e/private/dependencies.bicep +++ b/avm/res/network/bastion-host/tests/e2e/private/dependencies.bicep @@ -6,7 +6,7 @@ param virtualNetworkName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: virtualNetworkName location: location properties: { diff --git a/avm/res/network/bastion-host/tests/e2e/private/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/private/main.test.bicep index b35c9f07a9..eee5592b8c 100644 --- a/avm/res/network/bastion-host/tests/e2e/private/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/private/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: resourceLocation } diff --git a/avm/res/network/bastion-host/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/bastion-host/tests/e2e/waf-aligned/dependencies.bicep index 8027783d25..4691026fae 100644 --- a/avm/res/network/bastion-host/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/network/bastion-host/tests/e2e/waf-aligned/dependencies.bicep @@ -9,7 +9,7 @@ param publicIPName string var addressPrefix = '10.0.0.0/16' -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: virtualNetworkName location: location properties: { @@ -29,7 +29,7 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = { } } -resource publicIP 'Microsoft.Network/publicIPAddresses@2023-04-01' = { +resource publicIP 'Microsoft.Network/publicIPAddresses@2024-05-01' = { name: publicIPName location: location sku: { diff --git a/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep index 861b40da3d..a4b10faba8 100644 --- a/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/bastion-host/tests/e2e/waf-aligned/main.test.bicep @@ -26,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' // General resources // ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { name: resourceGroupName location: resourceLocation } @@ -90,9 +90,5 @@ module testDeployment '../../../main.bicep' = [ Role: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/network/bastion-host/version.json b/avm/res/network/bastion-host/version.json index ea4f3b6e67..21226dd43f 100644 --- a/avm/res/network/bastion-host/version.json +++ b/avm/res/network/bastion-host/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] From e5e810bdf72d3b63fabd790a8d4c98b511350da6 Mon Sep 17 00:00:00 2001 From: Sandy <16922860+thecsw@users.noreply.github.com> Date: Sun, 9 Feb 2025 06:40:45 -0600 Subject: [PATCH 18/31] fix: revert Defender updates to `avm/res/storage/storage-account` (#4414) This reverts PR #4379 due to deploy tests failing, > Failed to enable the Defender for Storage (classic) plan on the storage account '***ssablob001' - This plan is no longer available for new subscriptions and storage accounts, subscriptions already using the new or classic per storage account plans, or re-enabling. Please use the latest API to protect your storage account. If you have enabled the new plan, disable any policies attempting to re-enable the classic plan. Thanks to @AlexanderSehr for bringing it out. ## Description ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.storage.storage-account](https://github.com/thecsw/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg?branch=sandy%2Frevert-storage-atp)](https://github.com/thecsw/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [X] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [X] I'm sure there are no other open Pull Requests for the same update/change - [X] I have run `Set-AVMModule` locally to generate the supporting module files. - [X] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/storage/storage-account/README.md | 10 --- .../container/immutability-policy/main.json | 4 +- .../blob-service/container/main.json | 8 +-- .../storage-account/blob-service/main.json | 12 ++-- .../storage-account/file-service/main.json | 8 +-- .../file-service/share/main.json | 4 +- .../storage-account/local-user/main.json | 4 +- avm/res/storage/storage-account/main.bicep | 12 ---- avm/res/storage/storage-account/main.json | 72 +++++++------------ .../management-policy/main.json | 4 +- .../storage-account/queue-service/main.json | 8 +-- .../queue-service/queue/main.json | 4 +- .../storage-account/table-service/main.json | 8 +-- .../table-service/table/main.json | 4 +- avm/res/storage/storage-account/version.json | 4 +- 15 files changed, 62 insertions(+), 104 deletions(-) diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md index 94e576af3b..82b01bb576 100644 --- a/avm/res/storage/storage-account/README.md +++ b/avm/res/storage/storage-account/README.md @@ -22,7 +22,6 @@ This module deploys a Storage Account. | `Microsoft.KeyVault/vaults/secrets` | [2023-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2023-07-01/vaults/secrets) | | `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.Security/advancedThreatProtectionSettings` | [2019-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Security/2019-01-01/advancedThreatProtectionSettings) | | `Microsoft.Storage/storageAccounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-05-01/storageAccounts) | | `Microsoft.Storage/storageAccounts/blobServices` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices) | | `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | @@ -3429,7 +3428,6 @@ param tags = { | [`defaultToOAuthAuthentication`](#parameter-defaulttooauthauthentication) | bool | A boolean flag which indicates whether the default authentication is OAuth or not. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`dnsEndpointType`](#parameter-dnsendpointtype) | string | Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a large number of accounts in a single subscription, which creates accounts in an Azure DNS Zone and the endpoint URL will have an alphanumeric DNS Zone identifier. | -| [`enableAdvancedThreatProtection`](#parameter-enableadvancedthreatprotection) | bool | Enables Advanced Threat Protection on the storage account. | | [`enableNfsV3`](#parameter-enablenfsv3) | bool | If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true. | | [`enableSftp`](#parameter-enablesftp) | bool | If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | @@ -3788,14 +3786,6 @@ Allows you to specify the type of endpoint. Set this to AzureDNSZone to create a ] ``` -### Parameter: `enableAdvancedThreatProtection` - -Enables Advanced Threat Protection on the storage account. - -- Required: No -- Type: bool -- Default: `True` - ### Parameter: `enableNfsV3` If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true. diff --git a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json index 3e1f62c7b5..dbbe33ca7c 100644 --- a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json +++ b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "8061556339565534458" + "version": "0.32.4.45862", + "templateHash": "12930903258566593173" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/container/main.json b/avm/res/storage/storage-account/blob-service/container/main.json index df35c3db1f..49e3b47170 100644 --- a/avm/res/storage/storage-account/blob-service/container/main.json +++ b/avm/res/storage/storage-account/blob-service/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2991444340097371621" + "version": "0.32.4.45862", + "templateHash": "7180309977212880563" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -294,8 +294,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "8061556339565534458" + "version": "0.32.4.45862", + "templateHash": "12930903258566593173" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/main.json b/avm/res/storage/storage-account/blob-service/main.json index 23d1aadc51..b37a944429 100644 --- a/avm/res/storage/storage-account/blob-service/main.json +++ b/avm/res/storage/storage-account/blob-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "7588078546699808778" + "version": "0.32.4.45862", + "templateHash": "7416701536235015086" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -472,8 +472,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2991444340097371621" + "version": "0.32.4.45862", + "templateHash": "7180309977212880563" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -761,8 +761,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "8061556339565534458" + "version": "0.32.4.45862", + "templateHash": "12930903258566593173" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/file-service/main.json b/avm/res/storage/storage-account/file-service/main.json index 8e27cf79fc..95c9c54fe5 100644 --- a/avm/res/storage/storage-account/file-service/main.json +++ b/avm/res/storage/storage-account/file-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "3168394810831105529" + "version": "0.32.4.45862", + "templateHash": "16196407713115246323" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -359,8 +359,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12044655551245282190" + "version": "0.32.4.45862", + "templateHash": "5204319087439022536" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." diff --git a/avm/res/storage/storage-account/file-service/share/main.json b/avm/res/storage/storage-account/file-service/share/main.json index 0144ab364d..a95097e146 100644 --- a/avm/res/storage/storage-account/file-service/share/main.json +++ b/avm/res/storage/storage-account/file-service/share/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12044655551245282190" + "version": "0.32.4.45862", + "templateHash": "5204319087439022536" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." diff --git a/avm/res/storage/storage-account/local-user/main.json b/avm/res/storage/storage-account/local-user/main.json index 7be0e3b8da..dac871c0e5 100644 --- a/avm/res/storage/storage-account/local-user/main.json +++ b/avm/res/storage/storage-account/local-user/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "5655292159520921149" + "version": "0.32.4.45862", + "templateHash": "16427795222629898111" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep index 8ee2ba44da..91ee043a7e 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -188,9 +188,6 @@ param keyType string? @description('Optional. Key vault reference and secret settings for the module\'s secrets export.') param secretsExportConfiguration secretsExportConfigurationType? -@description('Optional. Enables Advanced Threat Protection on the storage account.') -param enableAdvancedThreatProtection bool = true - var supportsBlobService = kind == 'BlockBlobStorage' || kind == 'BlobStorage' || kind == 'StorageV2' || kind == 'Storage' var supportsFileService = kind == 'FileStorage' || kind == 'StorageV2' || kind == 'Storage' @@ -697,15 +694,6 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura } } -// Microsoft Defender plan -resource storageAccount_atp 'Microsoft.Security/advancedThreatProtectionSettings@2019-01-01' = if (enableAdvancedThreatProtection) { - name: 'current' - scope: storageAccount - properties: { - isEnabled: true - } -} - @description('The resource ID of the deployed storage account.') output resourceId string = storageAccount.id diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index a154a8304e..a6425011ad 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "9582256320776207177" + "version": "0.32.4.45862", + "templateHash": "9739064632358098891" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account." @@ -1245,13 +1245,6 @@ "metadata": { "description": "Optional. Key vault reference and secret settings for the module's secrets export." } - }, - "enableAdvancedThreatProtection": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enables Advanced Threat Protection on the storage account." - } } }, "variables": { @@ -1450,19 +1443,6 @@ "storageAccount" ] }, - "storageAccount_atp": { - "condition": "[parameters('enableAdvancedThreatProtection')]", - "type": "Microsoft.Security/advancedThreatProtectionSettings", - "apiVersion": "2019-01-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('name'))]", - "name": "current", - "properties": { - "isEnabled": true - }, - "dependsOn": [ - "storageAccount" - ] - }, "storageAccount_privateEndpoints": { "copy": { "name": "storageAccount_privateEndpoints", @@ -2242,8 +2222,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "10504956743360699891" + "version": "0.32.4.45862", + "templateHash": "4014848332192190169" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." @@ -2351,8 +2331,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "5655292159520921149" + "version": "0.32.4.45862", + "templateHash": "16427795222629898111" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." @@ -2589,8 +2569,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "7588078546699808778" + "version": "0.32.4.45862", + "templateHash": "7416701536235015086" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -3056,8 +3036,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2991444340097371621" + "version": "0.32.4.45862", + "templateHash": "7180309977212880563" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -3345,8 +3325,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "8061556339565534458" + "version": "0.32.4.45862", + "templateHash": "12930903258566593173" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." @@ -3525,8 +3505,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "3168394810831105529" + "version": "0.32.4.45862", + "templateHash": "16196407713115246323" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -3879,8 +3859,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12044655551245282190" + "version": "0.32.4.45862", + "templateHash": "5204319087439022536" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." @@ -4314,8 +4294,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1736438454543575457" + "version": "0.32.4.45862", + "templateHash": "14497929042813606497" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -4633,8 +4613,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "6383154227554431205" + "version": "0.32.4.45862", + "templateHash": "9969689246600110741" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." @@ -4903,8 +4883,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12583903411447171294" + "version": "0.32.4.45862", + "templateHash": "4194630585059896468" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -5219,8 +5199,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1369356397929898951" + "version": "0.32.4.45862", + "templateHash": "4457939127962832961" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." @@ -5473,8 +5453,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2275047425860597278" + "version": "0.32.4.45862", + "templateHash": "9771994149501143078" } }, "definitions": { diff --git a/avm/res/storage/storage-account/management-policy/main.json b/avm/res/storage/storage-account/management-policy/main.json index 38c4ba5749..bc2c2530f7 100644 --- a/avm/res/storage/storage-account/management-policy/main.json +++ b/avm/res/storage/storage-account/management-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "10504956743360699891" + "version": "0.32.4.45862", + "templateHash": "4014848332192190169" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." diff --git a/avm/res/storage/storage-account/queue-service/main.json b/avm/res/storage/storage-account/queue-service/main.json index 58b8972173..fa4e1c19d4 100644 --- a/avm/res/storage/storage-account/queue-service/main.json +++ b/avm/res/storage/storage-account/queue-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1736438454543575457" + "version": "0.32.4.45862", + "templateHash": "14497929042813606497" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -324,8 +324,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "6383154227554431205" + "version": "0.32.4.45862", + "templateHash": "9969689246600110741" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." diff --git a/avm/res/storage/storage-account/queue-service/queue/main.json b/avm/res/storage/storage-account/queue-service/queue/main.json index dfd0124351..19308bf371 100644 --- a/avm/res/storage/storage-account/queue-service/queue/main.json +++ b/avm/res/storage/storage-account/queue-service/queue/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "6383154227554431205" + "version": "0.32.4.45862", + "templateHash": "9969689246600110741" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." diff --git a/avm/res/storage/storage-account/table-service/main.json b/avm/res/storage/storage-account/table-service/main.json index 791d9ecdc8..c336dcaed3 100644 --- a/avm/res/storage/storage-account/table-service/main.json +++ b/avm/res/storage/storage-account/table-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12583903411447171294" + "version": "0.32.4.45862", + "templateHash": "4194630585059896468" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -321,8 +321,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1369356397929898951" + "version": "0.32.4.45862", + "templateHash": "4457939127962832961" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." diff --git a/avm/res/storage/storage-account/table-service/table/main.json b/avm/res/storage/storage-account/table-service/table/main.json index d97ce4a5f1..f9e2ac6377 100644 --- a/avm/res/storage/storage-account/table-service/table/main.json +++ b/avm/res/storage/storage-account/table-service/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1369356397929898951" + "version": "0.32.4.45862", + "templateHash": "4457939127962832961" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." diff --git a/avm/res/storage/storage-account/version.json b/avm/res/storage/storage-account/version.json index 77443210ac..8f0ecca899 100644 --- a/avm/res/storage/storage-account/version.json +++ b/avm/res/storage/storage-account/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.18", + "version": "0.17", "pathFilters": [ "./main.json" ] -} +} \ No newline at end of file From 6758137d0acae8bbf4e86e19e8d3db6fe2fbd296 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Sun, 9 Feb 2025 17:46:42 +0000 Subject: [PATCH 19/31] fix: avm/res/storage/storage-account blob soft delete days to 7 (#4411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description I flagged last year that the blob soft delete days for blob was only 6, but for containers it was 7. The module owner agreed for consistency it should be 7 also. Therefore, this PR bumps this in line as per #2707.  Closes #2707 to increase blob soft delete inline to 7 days with containers for consistency. ## Pipeline Reference [![avm.res.storage.storage-account](https://github.com/riosengineer/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg)](https://github.com/riosengineer/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [x] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../storage-account/blob-service/README.md | 2 +- .../container/immutability-policy/main.json | 4 +- .../blob-service/container/main.json | 8 +-- .../storage-account/blob-service/main.bicep | 2 +- .../storage-account/blob-service/main.json | 14 ++--- avm/res/storage/storage-account/main.json | 54 +++++++++---------- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/avm/res/storage/storage-account/blob-service/README.md b/avm/res/storage/storage-account/blob-service/README.md index 9d0866eeec..831df721ec 100644 --- a/avm/res/storage/storage-account/blob-service/README.md +++ b/avm/res/storage/storage-account/blob-service/README.md @@ -440,7 +440,7 @@ How long this blob can be restored. It should be less than DeleteRetentionPolicy - Required: No - Type: int -- Default: `6` +- Default: `7` - MinValue: 1 - MaxValue: 365 diff --git a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json index dbbe33ca7c..3e1f62c7b5 100644 --- a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json +++ b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/container/main.json b/avm/res/storage/storage-account/blob-service/container/main.json index 49e3b47170..df35c3db1f 100644 --- a/avm/res/storage/storage-account/blob-service/container/main.json +++ b/avm/res/storage/storage-account/blob-service/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -294,8 +294,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/blob-service/main.bicep b/avm/res/storage/storage-account/blob-service/main.bicep index e88a222172..3198c5f316 100644 --- a/avm/res/storage/storage-account/blob-service/main.bicep +++ b/avm/res/storage/storage-account/blob-service/main.bicep @@ -55,7 +55,7 @@ param restorePolicyEnabled bool = false @minValue(1) @description('Optional. How long this blob can be restored. It should be less than DeleteRetentionPolicy days.') -param restorePolicyDays int = 6 +param restorePolicyDays int = 7 @description('Optional. Blob containers to create.') param containers array? diff --git a/avm/res/storage/storage-account/blob-service/main.json b/avm/res/storage/storage-account/blob-service/main.json index b37a944429..4eacd0e9e2 100644 --- a/avm/res/storage/storage-account/blob-service/main.json +++ b/avm/res/storage/storage-account/blob-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7416701536235015086" + "version": "0.33.93.31351", + "templateHash": "2058460323623594433" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -312,7 +312,7 @@ }, "restorePolicyDays": { "type": "int", - "defaultValue": 6, + "defaultValue": 7, "minValue": 1, "metadata": { "description": "Optional. How long this blob can be restored. It should be less than DeleteRetentionPolicy days." @@ -472,8 +472,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -761,8 +761,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index a6425011ad..b3193cf49f 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9739064632358098891" + "version": "0.33.93.31351", + "templateHash": "17960260729884623690" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account." @@ -2222,8 +2222,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4014848332192190169" + "version": "0.33.93.31351", + "templateHash": "10504956743360699891" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." @@ -2331,8 +2331,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16427795222629898111" + "version": "0.33.93.31351", + "templateHash": "5655292159520921149" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." @@ -2569,8 +2569,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7416701536235015086" + "version": "0.33.93.31351", + "templateHash": "2058460323623594433" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -2876,7 +2876,7 @@ }, "restorePolicyDays": { "type": "int", - "defaultValue": 6, + "defaultValue": 7, "minValue": 1, "metadata": { "description": "Optional. How long this blob can be restored. It should be less than DeleteRetentionPolicy days." @@ -3036,8 +3036,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7180309977212880563" + "version": "0.33.93.31351", + "templateHash": "2991444340097371621" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -3325,8 +3325,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12930903258566593173" + "version": "0.33.93.31351", + "templateHash": "8061556339565534458" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." @@ -3505,8 +3505,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16196407713115246323" + "version": "0.33.93.31351", + "templateHash": "3168394810831105529" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -3859,8 +3859,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5204319087439022536" + "version": "0.33.93.31351", + "templateHash": "12044655551245282190" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." @@ -4294,8 +4294,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14497929042813606497" + "version": "0.33.93.31351", + "templateHash": "1736438454543575457" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -4613,8 +4613,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9969689246600110741" + "version": "0.33.93.31351", + "templateHash": "6383154227554431205" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." @@ -4883,8 +4883,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4194630585059896468" + "version": "0.33.93.31351", + "templateHash": "12583903411447171294" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -5199,8 +5199,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4457939127962832961" + "version": "0.33.93.31351", + "templateHash": "1369356397929898951" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." @@ -5453,8 +5453,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9771994149501143078" + "version": "0.33.93.31351", + "templateHash": "2275047425860597278" } }, "definitions": { From 2672fd488ae1553d7591b22752dab23a88884f5d Mon Sep 17 00:00:00 2001 From: Erika Gressi <56914614+eriqua@users.noreply.github.com> Date: Mon, 10 Feb 2025 19:49:09 +0100 Subject: [PATCH 20/31] ci: Add `avm/ptn/lz/sub-vending` and `avm/res/azure-stack-hci/cluster` to the list of OIDC exception list (#4393) ## Description hub-spoke test is failing on role assignment removal when leveraging OIDC. Adding it back to the exception list to fall back to SP+secret authentication method, while the issue is being troubleshooted. Same issue with the yet-to-be-published `avm/res/azure-stack-hci/cluster` module tests ## Pipeline Reference | Pipeline | | -------- | | [![avm.ptn.lz.sub-vending](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml/badge.svg?branch=users%2Ferikag%2Fsublz_oidc_exp&event=workflow_run)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml) | ## Type of Change - [x] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [ ] I'm sure there are no other open Pull Requests for the same update/change - [ ] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../actions/templates/avm-validateModuleDeployment/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index c26b7137e9..f127041711 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -73,6 +73,8 @@ runs: # List of modules requiring service principal + secret authentication $modulePath = "${{ inputs.modulePath }}" $exceptionModulePaths = @( + 'avm/ptn/lz/sub-vending' # Failing on resource deletion when trying to delete RBAC at subscription level (hub-spoke test) + 'avm/res/azure-stack-hci/cluster' # Failing on resource deletion when trying to delete RBAC at subscription level 'avm/res/compute/image' # Failing on resource deletion when trying to delete RBAC at subscription level 'avm/res/compute/disk' # Failing on resource deletion when trying to delete RBAC at subscription level 'avm/ptn/virtual-machine-images/azure-image-builder' # Failing on resource deletion when trying to delete RBAC at subscription level From 19db33d0b110fb175d4a124ec25c523ebc1326bf Mon Sep 17 00:00:00 2001 From: Adam Ricket <44428944+thecmdradama@users.noreply.github.com> Date: Tue, 11 Feb 2025 08:52:00 +0800 Subject: [PATCH 21/31] feat: Updates of `avm/res/network/express-route-circuits` (#4400) ## Description - Adds support for an optional list of authorizations. - Adds output for authorizations as a flattened map. - Adds output for the service provider provisioning state property. ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.network.express-route-circuit](https://github.com/thecmdradama/bicep-registry-modules/actions/workflows/avm.res.network.express-route-circuit.yml/badge.svg)](https://github.com/thecmdradama/bicep-registry-modules/actions/workflows/avm.res.network.express-route-circuit.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [x] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../network/express-route-circuit/README.md | 10 +++++++ .../network/express-route-circuit/main.bicep | 11 +++++++ .../network/express-route-circuit/main.json | 30 +++++++++++++++++-- .../express-route-circuit/version.json | 2 +- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/avm/res/network/express-route-circuit/README.md b/avm/res/network/express-route-circuit/README.md index 9f1ad4093b..c8972d64f7 100644 --- a/avm/res/network/express-route-circuit/README.md +++ b/avm/res/network/express-route-circuit/README.md @@ -523,6 +523,7 @@ param tags = { | Parameter | Type | Description | | :-- | :-- | :-- | | [`allowClassicOperations`](#parameter-allowclassicoperations) | bool | Allow classic operations. You can connect to virtual networks in the classic deployment model by setting allowClassicOperations to true. | +| [`authorizationNames`](#parameter-authorizationnames) | array | List of names for ExpressRoute circuit authorizations to create. To fetch the `authorizationKey` for the authorization, use the `existing` resource reference for `Microsoft.Network/expressRouteCircuits/authorizations`. | | [`bandwidthInGbps`](#parameter-bandwidthingbps) | int | The bandwidth of the circuit when the circuit is provisioned on an ExpressRoutePort resource. Available when configuring Express Route Direct. Default value of 0 will set the property to null. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | @@ -578,6 +579,14 @@ Allow classic operations. You can connect to virtual networks in the classic dep - Type: bool - Default: `False` +### Parameter: `authorizationNames` + +List of names for ExpressRoute circuit authorizations to create. To fetch the `authorizationKey` for the authorization, use the `existing` resource reference for `Microsoft.Network/expressRouteCircuits/authorizations`. + +- Required: No +- Type: array +- Default: `[]` + ### Parameter: `bandwidthInGbps` The bandwidth of the circuit when the circuit is provisioned on an ExpressRoutePort resource. Available when configuring Express Route Direct. Default value of 0 will set the property to null. @@ -1014,6 +1023,7 @@ Specifies the identifier that is used to identify the customer. | `resourceGroupName` | string | The resource group the express route curcuit was deployed into. | | `resourceId` | string | The resource ID of express route curcuit. | | `serviceKey` | string | The service key of the express route circuit. | +| `serviceProviderProvisioningState` | string | The service provider provisioning state of the express route circuit. | ## Data Collection diff --git a/avm/res/network/express-route-circuit/main.bicep b/avm/res/network/express-route-circuit/main.bicep index 70094abb9f..6e0332ae4f 100644 --- a/avm/res/network/express-route-circuit/main.bicep +++ b/avm/res/network/express-route-circuit/main.bicep @@ -60,6 +60,9 @@ param location string = resourceGroup().location @description('Optional. Allow classic operations. You can connect to virtual networks in the classic deployment model by setting allowClassicOperations to true.') param allowClassicOperations bool = false +@description('Optional. List of names for ExpressRoute circuit authorizations to create. To fetch the `authorizationKey` for the authorization, use the `existing` resource reference for `Microsoft.Network/expressRouteCircuits/authorizations`.') +param authorizationNames string[] = [] + @description('Optional. The bandwidth of the circuit when the circuit is provisioned on an ExpressRoutePort resource. Available when configuring Express Route Direct. Default value of 0 will set the property to null.') param bandwidthInGbps int = 0 @@ -143,6 +146,11 @@ resource expressRouteCircuit 'Microsoft.Network/expressRouteCircuits@2023-04-01' } properties: { allowClassicOperations: allowClassicOperations + authorizations: [ + for authorizationName in authorizationNames: { + name: authorizationName + } + ] globalReachEnabled: globalReachEnabled bandwidthInGbps: bandwidthInGbps != 0 ? bandwidthInGbps : null expressRoutePort: !empty(expressRoutePortResourceId) @@ -245,6 +253,9 @@ output name string = expressRouteCircuit.name @description('The service key of the express route circuit.') output serviceKey string = expressRouteCircuit.properties.serviceKey +@description('The service provider provisioning state of the express route circuit.') +output serviceProviderProvisioningState string = expressRouteCircuit.properties.serviceProviderProvisioningState + @description('The location the resource was deployed into.') output location string = expressRouteCircuit.location diff --git a/avm/res/network/express-route-circuit/main.json b/avm/res/network/express-route-circuit/main.json index db47e4afee..9029bd322a 100644 --- a/avm/res/network/express-route-circuit/main.json +++ b/avm/res/network/express-route-circuit/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17484476736436996858" + "version": "0.33.93.31351", + "templateHash": "8776591928362518786" }, "name": "ExpressRoute Circuits", "description": "This module deploys an Express Route Circuit." @@ -346,6 +346,16 @@ "description": "Optional. Allow classic operations. You can connect to virtual networks in the classic deployment model by setting allowClassicOperations to true." } }, + "authorizationNames": { + "type": "array", + "items": { + "type": "string" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. List of names for ExpressRoute circuit authorizations to create. To fetch the `authorizationKey` for the authorization, use the `existing` resource reference for `Microsoft.Network/expressRouteCircuits/authorizations`." + } + }, "bandwidthInGbps": { "type": "int", "defaultValue": 0, @@ -450,6 +460,15 @@ "family": "[if(equals(parameters('skuTier'), 'Local'), 'UnlimitedData', parameters('skuFamily'))]" }, "properties": { + "copy": [ + { + "name": "authorizations", + "count": "[length(parameters('authorizationNames'))]", + "input": { + "name": "[parameters('authorizationNames')[copyIndex('authorizations')]]" + } + } + ], "allowClassicOperations": "[parameters('allowClassicOperations')]", "globalReachEnabled": "[parameters('globalReachEnabled')]", "bandwidthInGbps": "[if(not(equals(parameters('bandwidthInGbps'), 0)), parameters('bandwidthInGbps'), null())]", @@ -569,6 +588,13 @@ }, "value": "[reference('expressRouteCircuit').serviceKey]" }, + "serviceProviderProvisioningState": { + "type": "string", + "metadata": { + "description": "The service provider provisioning state of the express route circuit." + }, + "value": "[reference('expressRouteCircuit').serviceProviderProvisioningState]" + }, "location": { "type": "string", "metadata": { diff --git a/avm/res/network/express-route-circuit/version.json b/avm/res/network/express-route-circuit/version.json index 76049e1c4a..13669e6601 100644 --- a/avm/res/network/express-route-circuit/version.json +++ b/avm/res/network/express-route-circuit/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" ] From 10886543a928f0a70389bf0cecdc1b94df265c9d Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 11 Feb 2025 08:32:25 +0100 Subject: [PATCH 22/31] feat: RSV - Addressed diverse tickets & refactored structure (#4361) ## Description > Rebased from #3821 - Updated CMK implementation to align with AVM & the [docs](https://learn.microsoft.com/en-us/azure/backup/encryption-at-rest-with-cmk?tabs=portal) - Added UDTs for all objects & arrays (exept one due to its complexity) - Updaetd protectedItem implementation & added test case - Regenerated all files - Tested different combinations of configurations: - `enableAutokeyRotation` disabled ![image](https://github.com/user-attachments/assets/c156987a-7a17-413c-a6e3-28dbda8092e3) - `enableAutokeyRotation` enabled ![image](https://github.com/user-attachments/assets/0c427cce-89f8-405d-8eeb-8934c0d05ef7) Closes #3746 Closes #3625 Closes #3591 Closes #3233 Closes #2541 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.recovery-services.vault](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml/badge.svg?branch=users%2Falsehr%2Falexanderojala_rsv_rebase&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [ ] I'm sure there are no other open Pull Requests for the same update/change - [ ] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --------- Co-authored-by: Alexander Ojala --- avm/res/recovery-services/vault/README.md | 1189 ++++++++++++-- .../vault/backup-config/main.json | 4 +- .../protection-container/README.md | 135 -- .../protection-container/main.bicep | 82 - .../protection-container/main.json | 275 ---- .../protected-item/README.md | 8 +- .../protected-item/main.bicep | 16 +- .../protected-item/main.json | 12 +- .../vault/backup-policy/README.md | 2 +- .../vault/backup-policy/main.bicep | 2 +- .../vault/backup-policy/main.json | 6 +- .../vault/backup-storage-config/main.json | 4 +- avm/res/recovery-services/vault/main.bicep | 373 ++++- avm/res/recovery-services/vault/main.json | 1439 +++++++++++++---- .../vault/replication-alert-setting/README.md | 5 +- .../replication-alert-setting/main.bicep | 6 +- .../vault/replication-alert-setting/main.json | 26 +- .../vault/replication-fabric/README.md | 80 +- .../vault/replication-fabric/main.bicep | 28 +- .../vault/replication-fabric/main.json | 282 +++- .../README.md | 58 +- .../main.bicep | 50 +- .../main.json | 164 +- .../README.md | 25 +- .../main.bicep | 39 +- .../main.json | 55 +- .../vault/replication-policy/main.json | 4 +- .../vault/tests/e2e/dr/main.test.bicep | 8 +- .../vault/tests/e2e/encr/dependencies.bicep | 61 + .../vault/tests/e2e/encr/main.test.bicep | 73 + .../vault/tests/e2e/max/dependencies.bicep | 110 +- .../vault/tests/e2e/max/main.test.bicep | 19 +- .../tests/e2e/waf-aligned/main.test.bicep | 7 +- avm/res/recovery-services/vault/version.json | 2 +- 34 files changed, 3395 insertions(+), 1254 deletions(-) delete mode 100644 avm/res/recovery-services/vault/backup-fabric/protection-container/README.md delete mode 100644 avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep delete mode 100644 avm/res/recovery-services/vault/backup-fabric/protection-container/main.json create mode 100644 avm/res/recovery-services/vault/tests/e2e/encr/dependencies.bicep create mode 100644 avm/res/recovery-services/vault/tests/e2e/encr/main.test.bicep diff --git a/avm/res/recovery-services/vault/README.md b/avm/res/recovery-services/vault/README.md index bb0a07fd8f..959ce67a48 100644 --- a/avm/res/recovery-services/vault/README.md +++ b/avm/res/recovery-services/vault/README.md @@ -20,11 +20,10 @@ This module deploys a Recovery Services Vault. | `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.RecoveryServices/vaults` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults) | +| `Microsoft.RecoveryServices/vaults` | [2024-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2024-04-01/vaults) | | `Microsoft.RecoveryServices/vaults/backupconfig` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupconfig) | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers) | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | -| `Microsoft.RecoveryServices/vaults/backupPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupPolicies) | +| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2024-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2024-10-01/vaults/backupFabrics/protectionContainers/protectedItems) | +| `Microsoft.RecoveryServices/vaults/backupPolicies` | [2024-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2024-10-01/vaults/backupPolicies) | | `Microsoft.RecoveryServices/vaults/backupstorageconfig` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupstorageconfig) | | `Microsoft.RecoveryServices/vaults/replicationAlertSettings` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2022-10-01/vaults/replicationAlertSettings) | | `Microsoft.RecoveryServices/vaults/replicationFabrics` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2022-10-01/vaults/replicationFabrics) | @@ -42,8 +41,9 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Test case for disaster recovery enabled](#example-2-test-case-for-disaster-recovery-enabled) -- [Using large parameter set](#example-3-using-large-parameter-set) -- [WAF-aligned](#example-4-waf-aligned) +- [Using encryption with Customer-Managed-Key](#example-3-using-encryption-with-customer-managed-key) +- [Using large parameter set](#example-4-using-large-parameter-set) +- [WAF-aligned](#example-5-waf-aligned) ### Example 1: _Using only defaults_ @@ -171,24 +171,24 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { location: 'NorthEurope' replicationContainers: [ { - name: 'ne-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerName: 'pluto' - targetProtectionContainerId: '' + targetProtectionContainerResourceId: '' } ] + name: 'ne-container1' } { - name: 'ne-container2' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'WE-2' targetContainerName: 'we-container1' } ] + name: 'ne-container2' } ] } @@ -197,14 +197,14 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { name: 'WE-2' replicationContainers: [ { - name: 'we-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'NorthEurope' targetContainerName: 'ne-container2' } ] + name: 'we-container1' } ] } @@ -256,24 +256,24 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { "location": "NorthEurope", "replicationContainers": [ { - "name": "ne-container1", - "replicationContainerMappings": [ + "mappings": [ { "policyName": "Default_values", "targetContainerName": "pluto", - "targetProtectionContainerId": "" + "targetProtectionContainerResourceId": "" } - ] + ], + "name": "ne-container1" }, { - "name": "ne-container2", - "replicationContainerMappings": [ + "mappings": [ { "policyName": "Default_values", "targetContainerFabricName": "WE-2", "targetContainerName": "we-container1" } - ] + ], + "name": "ne-container2" } ] }, @@ -282,14 +282,14 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { "name": "WE-2", "replicationContainers": [ { - "name": "we-container1", - "replicationContainerMappings": [ + "mappings": [ { "policyName": "Default_values", "targetContainerFabricName": "NorthEurope", "targetContainerName": "ne-container2" } - ] + ], + "name": "we-container1" } ] } @@ -339,24 +339,24 @@ param replicationFabrics = [ location: 'NorthEurope' replicationContainers: [ { - name: 'ne-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerName: 'pluto' - targetProtectionContainerId: '' + targetProtectionContainerResourceId: '' } ] + name: 'ne-container1' } { - name: 'ne-container2' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'WE-2' targetContainerName: 'we-container1' } ] + name: 'ne-container2' } ] } @@ -365,14 +365,14 @@ param replicationFabrics = [ name: 'WE-2' replicationContainers: [ { - name: 'we-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'NorthEurope' targetContainerName: 'ne-container2' } ] + name: 'we-container1' } ] } @@ -399,7 +399,108 @@ param tags = {

-### Example 3: _Using large parameter set_ +### Example 3: _Using encryption with Customer-Managed-Key_ + +This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. + + +

+ +via Bicep module + +```bicep +module vault 'br/public:avm/res/recovery-services/vault:' = { + name: 'vaultDeployment' + params: { + // Required parameters + name: 'rsvencr001' + // Non-required parameters + customerManagedKey: { + autoRotationEnabled: false + keyName: '' + keyVaultResourceId: '' + userAssignedIdentityResourceId: '' + } + location: '' + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + } +} +``` + +
+

+ +

+ +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": "rsvencr001" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "autoRotationEnabled": false, + "keyName": "", + "keyVaultResourceId": "", + "userAssignedIdentityResourceId": "" + } + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/res/recovery-services/vault:' + +// Required parameters +param name = 'rsvencr001' +// Non-required parameters +param customerManagedKey = { + autoRotationEnabled: false + keyName: '' + keyVaultResourceId: '' + userAssignedIdentityResourceId: '' +} +param location = '' +param managedIdentities = { + userAssignedResourceIds: [ + '' + ] +} +``` + +
+

+ +### Example 4: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -649,10 +750,6 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } diagnosticSettings: [ { eventHubAuthorizationRuleResourceId: '' @@ -680,10 +777,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } monitoringSettings: { azureMonitorAlertSettings: { + alertsForAllFailoverIssues: 'Enabled' alertsForAllJobFailures: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } privateEndpoints: [ @@ -745,6 +845,15 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ] + protectedItems: [ + { + name: '' + policyName: 'VMpolicy' + protectedItemType: 'Microsoft.Compute/virtualMachines' + protectionContainerName: '' + sourceResourceId: '' + } + ] replicationAlertSettings: { customEmailAddresses: [ 'test.user@testcompany.com' @@ -1040,12 +1149,6 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } ] }, - "backupStorageConfig": { - "value": { - "crossRegionRestoreFlag": true, - "storageModelType": "GeoRedundant" - } - }, "diagnosticSettings": { "value": [ { @@ -1082,10 +1185,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { "monitoringSettings": { "value": { "azureMonitorAlertSettings": { - "alertsForAllJobFailures": "Enabled" + "alertsForAllFailoverIssues": "Enabled", + "alertsForAllJobFailures": "Enabled", + "alertsForAllReplicationIssues": "Enabled" }, "classicAlertSettings": { - "alertsForCriticalOperations": "Enabled" + "alertsForCriticalOperations": "Enabled", + "emailNotificationsForSiteRecovery": "Enabled" } } }, @@ -1150,6 +1256,17 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } ] }, + "protectedItems": { + "value": [ + { + "name": "", + "policyName": "VMpolicy", + "protectedItemType": "Microsoft.Compute/virtualMachines", + "protectionContainerName": "", + "sourceResourceId": "" + } + ] + }, "replicationAlertSettings": { "value": { "customEmailAddresses": [ @@ -1445,10 +1562,6 @@ param backupPolicies = [ } } ] -param backupStorageConfig = { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' -} param diagnosticSettings = [ { eventHubAuthorizationRuleResourceId: '' @@ -1476,10 +1589,13 @@ param managedIdentities = { } param monitoringSettings = { azureMonitorAlertSettings: { + alertsForAllFailoverIssues: 'Enabled' alertsForAllJobFailures: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } param privateEndpoints = [ @@ -1541,6 +1657,15 @@ param privateEndpoints = [ } } ] +param protectedItems = [ + { + name: '' + policyName: 'VMpolicy' + protectedItemType: 'Microsoft.Compute/virtualMachines' + protectionContainerName: '' + sourceResourceId: '' + } +] param replicationAlertSettings = { customEmailAddresses: [ 'test.user@testcompany.com' @@ -1582,7 +1707,7 @@ param tags = {

-### Example 4: _WAF-aligned_ +### Example 5: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -1832,10 +1957,6 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } diagnosticSettings: [ { eventHubAuthorizationRuleResourceId: '' @@ -1863,10 +1984,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } monitoringSettings: { azureMonitorAlertSettings: { + alertsForAllFailoverIssues: 'Enabled' alertsForAllJobFailures: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } privateEndpoints: [ @@ -2204,12 +2328,6 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } ] }, - "backupStorageConfig": { - "value": { - "crossRegionRestoreFlag": true, - "storageModelType": "GeoRedundant" - } - }, "diagnosticSettings": { "value": [ { @@ -2246,10 +2364,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { "monitoringSettings": { "value": { "azureMonitorAlertSettings": { - "alertsForAllJobFailures": "Enabled" + "alertsForAllFailoverIssues": "Enabled", + "alertsForAllJobFailures": "Enabled", + "alertsForAllReplicationIssues": "Enabled" }, "classicAlertSettings": { - "alertsForCriticalOperations": "Enabled" + "alertsForCriticalOperations": "Enabled", + "emailNotificationsForSiteRecovery": "Enabled" } } }, @@ -2588,10 +2709,6 @@ param backupPolicies = [ } } ] -param backupStorageConfig = { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' -} param diagnosticSettings = [ { eventHubAuthorizationRuleResourceId: '' @@ -2619,10 +2736,13 @@ param managedIdentities = { } param monitoringSettings = { azureMonitorAlertSettings: { + alertsForAllFailoverIssues: 'Enabled' alertsForAllJobFailures: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } param privateEndpoints = [ @@ -2721,6 +2841,7 @@ param tags = { | [`backupConfig`](#parameter-backupconfig) | object | The backup configuration. | | [`backupPolicies`](#parameter-backuppolicies) | array | List of all backup policies. | | [`backupStorageConfig`](#parameter-backupstorageconfig) | object | The storage configuration for the Azure Recovery Service Vault. | +| [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`location`](#parameter-location) | string | Location for all resources. | @@ -2728,11 +2849,13 @@ param tags = { | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | | [`monitoringSettings`](#parameter-monitoringsettings) | object | Monitoring Settings of the vault. | | [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | -| [`protectionContainers`](#parameter-protectioncontainers) | array | List of all protection containers. | +| [`protectedItems`](#parameter-protecteditems) | array | List of all protection containers. | | [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. | +| [`redundancySettings`](#parameter-redundancysettings) | object | The redundancy settings of the vault. | | [`replicationAlertSettings`](#parameter-replicationalertsettings) | object | Replication alert settings. | | [`replicationFabrics`](#parameter-replicationfabrics) | array | List of all replication fabrics. | | [`replicationPolicies`](#parameter-replicationpolicies) | array | List of all replication policies. | +| [`restoreSettings`](#parameter-restoresettings) | object | The restore settings of the vault. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`securitySettings`](#parameter-securitysettings) | object | Security Settings of the vault. | | [`tags`](#parameter-tags) | object | Tags of the Recovery Service Vault resource. | @@ -2750,166 +2873,387 @@ The backup configuration. - Required: No - Type: object -- Default: `{}` -### Parameter: `backupPolicies` +**Optional parameters** -List of all backup policies. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enhancedSecurityState`](#parameter-backupconfigenhancedsecuritystate) | string | Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations. | +| [`isSoftDeleteFeatureStateEditable`](#parameter-backupconfigissoftdeletefeaturestateeditable) | bool | Is soft delete feature state editable. | +| [`name`](#parameter-backupconfigname) | string | Name of the Azure Recovery Service Vault Backup Policy. | +| [`resourceGuardOperationRequests`](#parameter-backupconfigresourceguardoperationrequests) | array | ResourceGuard Operation Requests. | +| [`softDeleteFeatureState`](#parameter-backupconfigsoftdeletefeaturestate) | string | Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes. | +| [`storageModelType`](#parameter-backupconfigstoragemodeltype) | string | Storage type. | +| [`storageType`](#parameter-backupconfigstoragetype) | string | Storage type. | +| [`storageTypeState`](#parameter-backupconfigstoragetypestate) | string | Once a machine is registered against a resource, the storageTypeState is always Locked. | + +### Parameter: `backupConfig.enhancedSecurityState` + +Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations. - Required: No -- Type: array -- Default: `[]` +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` -### Parameter: `backupStorageConfig` +### Parameter: `backupConfig.isSoftDeleteFeatureStateEditable` -The storage configuration for the Azure Recovery Service Vault. +Is soft delete feature state editable. - Required: No -- Type: object -- Default: `{}` +- Type: bool -### Parameter: `diagnosticSettings` +### Parameter: `backupConfig.name` -The diagnostic settings of the service. +Name of the Azure Recovery Service Vault Backup Policy. + +- Required: No +- Type: string + +### Parameter: `backupConfig.resourceGuardOperationRequests` + +ResourceGuard Operation Requests. - Required: No - Type: array -**Optional parameters** +### Parameter: `backupConfig.softDeleteFeatureState` -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`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. | -| [`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 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. | +Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes. -### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` -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. +### Parameter: `backupConfig.storageModelType` + +Storage type. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'GeoRedundant' + 'LocallyRedundant' + 'ReadAccessGeoZoneRedundant' + 'ZoneRedundant' + ] + ``` -### Parameter: `diagnosticSettings.eventHubName` +### Parameter: `backupConfig.storageType` -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. +Storage type. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'GeoRedundant' + 'LocallyRedundant' + 'ReadAccessGeoZoneRedundant' + 'ZoneRedundant' + ] + ``` -### Parameter: `diagnosticSettings.logAnalyticsDestinationType` +### Parameter: `backupConfig.storageTypeState` -A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. +Once a machine is registered against a resource, the storageTypeState is always Locked. - Required: No - Type: string - Allowed: ```Bicep [ - 'AzureDiagnostics' - 'Dedicated' + 'Locked' + 'Unlocked' ] ``` -### Parameter: `diagnosticSettings.logCategoriesAndGroups` +### Parameter: `backupPolicies` -The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. +List of all backup policies. - Required: No - Type: array -**Optional parameters** +**Required parameters** | 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. | -| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | +| [`name`](#parameter-backuppoliciesname) | string | Name of the Azure Recovery Service Vault Backup Policy. | +| [`properties`](#parameter-backuppoliciesproperties) | object | Configuration of the Azure Recovery Service Vault Backup Policy. | -### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` +### Parameter: `backupPolicies.name` -Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. +Name of the Azure Recovery Service Vault Backup Policy. -- Required: No +- Required: Yes - Type: string -### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` +### Parameter: `backupPolicies.properties` -Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. +Configuration of the Azure Recovery Service Vault Backup Policy. + +- Required: Yes +- Type: object + +### Parameter: `backupStorageConfig` + +The storage configuration for the Azure Recovery Service Vault. - Required: No -- Type: string +- Type: object -### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` +**Optional parameters** -Enable or disable the category explicitly. Default is `true`. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`crossRegionRestoreFlag`](#parameter-backupstorageconfigcrossregionrestoreflag) | bool | Opt in details of Cross Region Restore feature. | +| [`name`](#parameter-backupstorageconfigname) | string | The name of the backup storage config. | +| [`storageModelType`](#parameter-backupstorageconfigstoragemodeltype) | string | Change Vault Storage Type (Works if vault has not registered any backup instance). | + +### Parameter: `backupStorageConfig.crossRegionRestoreFlag` + +Opt in details of Cross Region Restore feature. - Required: No - Type: bool -### Parameter: `diagnosticSettings.marketplacePartnerResourceId` +### Parameter: `backupStorageConfig.name` -The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. +The name of the backup storage config. - Required: No - Type: string -### Parameter: `diagnosticSettings.metricCategories` +### Parameter: `backupStorageConfig.storageModelType` -The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. +Change Vault Storage Type (Works if vault has not registered any backup instance). - Required: No -- Type: array +- Type: string +- Allowed: + ```Bicep + [ + 'GeoRedundant' + 'LocallyRedundant' + 'ReadAccessGeoZoneRedundant' + 'ZoneRedundant' + ] + ``` + +### Parameter: `customerManagedKey` + +The customer managed key definition. + +- Required: No +- Type: object **Required parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | +| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | +| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | +| [`autoRotationEnabled`](#parameter-customermanagedkeyautorotationenabled) | bool | Enable or disable auto-rotating to the latest key version. Default is `true`. If set to `false`, the latest key version at the time of the deployment is used. | +| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, using version as per 'autoRotationEnabled' setting. | +| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | -### Parameter: `diagnosticSettings.metricCategories.category` +### Parameter: `customerManagedKey.keyName` -Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. +The name of the customer managed key to use for encryption. - Required: Yes - Type: string -### Parameter: `diagnosticSettings.metricCategories.enabled` +### Parameter: `customerManagedKey.keyVaultResourceId` -Enable or disable the category explicitly. Default is `true`. +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.autoRotationEnabled` + +Enable or disable auto-rotating to the latest key version. Default is `true`. If set to `false`, the latest key version at the time of the deployment is used. - Required: No - Type: bool -### Parameter: `diagnosticSettings.name` +### Parameter: `customerManagedKey.keyVersion` -The name of the diagnostic setting. +The version of the customer managed key to reference for encryption. If not provided, using version as per 'autoRotationEnabled' setting. - Required: No - Type: string -### Parameter: `diagnosticSettings.storageAccountResourceId` +### Parameter: `customerManagedKey.userAssignedIdentityResourceId` -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. +User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. - Required: No - Type: string -### Parameter: `diagnosticSettings.workspaceResourceId` +### Parameter: `diagnosticSettings` -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. +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`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. | +| [`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 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. | + +### Parameter: `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: `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: `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: `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-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. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `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: `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: `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. + +- Required: No +- Type: string + +### Parameter: `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-diagnosticsettingsmetriccategoriescategory) | 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-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `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: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `diagnosticSettings.name` + +The name of the diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `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: `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 @@ -3000,7 +3344,112 @@ Monitoring Settings of the vault. - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`azureMonitorAlertSettings`](#parameter-monitoringsettingsazuremonitoralertsettings) | object | The alert settings. | +| [`classicAlertSettings`](#parameter-monitoringsettingsclassicalertsettings) | object | The classic alert settings. | + +### Parameter: `monitoringSettings.azureMonitorAlertSettings` + +The alert settings. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`alertsForAllFailoverIssues`](#parameter-monitoringsettingsazuremonitoralertsettingsalertsforallfailoverissues) | string | Enable / disable alerts for all failover issues. | +| [`alertsForAllJobFailures`](#parameter-monitoringsettingsazuremonitoralertsettingsalertsforalljobfailures) | string | Enable / disable alerts for all job failures. | +| [`alertsForAllReplicationIssues`](#parameter-monitoringsettingsazuremonitoralertsettingsalertsforallreplicationissues) | string | Enable / disable alerts for all replication issues. | + +### Parameter: `monitoringSettings.azureMonitorAlertSettings.alertsForAllFailoverIssues` + +Enable / disable alerts for all failover issues. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `monitoringSettings.azureMonitorAlertSettings.alertsForAllJobFailures` + +Enable / disable alerts for all job failures. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `monitoringSettings.azureMonitorAlertSettings.alertsForAllReplicationIssues` + +Enable / disable alerts for all replication issues. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `monitoringSettings.classicAlertSettings` + +The classic alert settings. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`alertsForCriticalOperations`](#parameter-monitoringsettingsclassicalertsettingsalertsforcriticaloperations) | string | Enable / disable alerts for critical operations. | +| [`emailNotificationsForSiteRecovery`](#parameter-monitoringsettingsclassicalertsettingsemailnotificationsforsiterecovery) | string | Enable / disable email notifications for site recovery. | + +### Parameter: `monitoringSettings.classicAlertSettings.alertsForCriticalOperations` + +Enable / disable alerts for critical operations. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `monitoringSettings.classicAlertSettings.emailNotificationsForSiteRecovery` + +Enable / disable email notifications for site recovery. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` ### Parameter: `privateEndpoints` @@ -3413,52 +3862,391 @@ Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object -### Parameter: `protectionContainers` +### Parameter: `protectedItems` List of all protection containers. - Required: No - Type: array -- Default: `[]` -### Parameter: `publicNetworkAccess` +**Required parameters** -Whether or not public network access is allowed for this resource. For security reasons it should be disabled. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-protecteditemsname) | string | Name of the resource. | +| [`policyName`](#parameter-protecteditemspolicyname) | string | The backup policy with which this item is backed up. | +| [`protectedItemType`](#parameter-protecteditemsprotecteditemtype) | string | The backup item type. | +| [`protectionContainerName`](#parameter-protecteditemsprotectioncontainername) | string | Name of the Azure Recovery Service Vault Protection Container. | +| [`sourceResourceId`](#parameter-protecteditemssourceresourceid) | string | Resource ID of the resource to back up. | -- Required: No -- Type: string -- Default: `'Disabled'` -- Allowed: - ```Bicep - [ - 'Disabled' - 'Enabled' - ] - ``` +**Optional parameters** -### Parameter: `replicationAlertSettings` +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`location`](#parameter-protecteditemslocation) | string | Location for all resources. | -Replication alert settings. +### Parameter: `protectedItems.name` -- Required: No -- Type: object -- Default: `{}` +Name of the resource. -### Parameter: `replicationFabrics` +- Required: Yes +- Type: string -List of all replication fabrics. +### Parameter: `protectedItems.policyName` -- Required: No -- Type: array -- Default: `[]` +The backup policy with which this item is backed up. -### Parameter: `replicationPolicies` +- Required: Yes +- Type: string -List of all replication policies. +### Parameter: `protectedItems.protectedItemType` + +The backup item type. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AzureFileShareProtectedItem' + 'AzureVmWorkloadSAPAseDatabase' + 'AzureVmWorkloadSAPHanaDatabase' + 'AzureVmWorkloadSQLDatabase' + 'DPMProtectedItem' + 'GenericProtectedItem' + 'MabFileFolderProtectedItem' + 'Microsoft.ClassicCompute/virtualMachines' + 'Microsoft.Compute/virtualMachines' + 'Microsoft.Sql/servers/databases' + ] + ``` + +### Parameter: `protectedItems.protectionContainerName` + +Name of the Azure Recovery Service Vault Protection Container. + +- Required: Yes +- Type: string + +### Parameter: `protectedItems.sourceResourceId` + +Resource ID of the resource to back up. + +- Required: Yes +- Type: string + +### Parameter: `protectedItems.location` + +Location for all resources. + +- Required: No +- Type: string + +### Parameter: `publicNetworkAccess` + +Whether or not public network access is allowed for this resource. For security reasons it should be disabled. + +- Required: No +- Type: string +- Default: `'Disabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `redundancySettings` + +The redundancy settings of the vault. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`crossRegionRestore`](#parameter-redundancysettingscrossregionrestore) | string | Flag to show if Cross Region Restore is enabled on the Vault or not. | +| [`standardTierStorageRedundancy`](#parameter-redundancysettingsstandardtierstorageredundancy) | string | The storage redundancy setting of a vault. | + +### Parameter: `redundancySettings.crossRegionRestore` + +Flag to show if Cross Region Restore is enabled on the Vault or not. + +- Required: No +- Type: string + +### Parameter: `redundancySettings.standardTierStorageRedundancy` + +The storage redundancy setting of a vault. + +- Required: No +- Type: string + +### Parameter: `replicationAlertSettings` + +Replication alert settings. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`customEmailAddresses`](#parameter-replicationalertsettingscustomemailaddresses) | array | The custom email address for sending emails. | +| [`locale`](#parameter-replicationalertsettingslocale) | string | The locale for the email notification. | +| [`name`](#parameter-replicationalertsettingsname) | string | The name of the replication Alert Setting. | +| [`sendToOwners`](#parameter-replicationalertsettingssendtoowners) | string | The value indicating whether to send email to subscription administrator. | + +### Parameter: `replicationAlertSettings.customEmailAddresses` + +The custom email address for sending emails. - Required: No - Type: array -- Default: `[]` + +### Parameter: `replicationAlertSettings.locale` + +The locale for the email notification. + +- Required: No +- Type: string + +### Parameter: `replicationAlertSettings.name` + +The name of the replication Alert Setting. + +- Required: No +- Type: string + +### Parameter: `replicationAlertSettings.sendToOwners` + +The value indicating whether to send email to subscription administrator. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'DoNotSend' + 'Send' + ] + ``` + +### Parameter: `replicationFabrics` + +List of all replication fabrics. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`location`](#parameter-replicationfabricslocation) | string | The recovery location the fabric represents. | +| [`name`](#parameter-replicationfabricsname) | string | The name of the fabric. | +| [`replicationContainers`](#parameter-replicationfabricsreplicationcontainers) | array | Replication containers to create. | + +### Parameter: `replicationFabrics.location` + +The recovery location the fabric represents. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.name` + +The name of the fabric. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers` + +Replication containers to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-replicationfabricsreplicationcontainersname) | string | The name of the replication container. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`mappings`](#parameter-replicationfabricsreplicationcontainersmappings) | array | Replication containers mappings to create. | + +### Parameter: `replicationFabrics.replicationContainers.name` + +The name of the replication container. + +- Required: Yes +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings` + +Replication containers mappings to create. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-replicationfabricsreplicationcontainersmappingsname) | string | The name of the replication container mapping. If not provided, it will be automatically generated as `-`. | +| [`policyName`](#parameter-replicationfabricsreplicationcontainersmappingspolicyname) | string | Name of the replication policy. Will be ignored if policyResourceId is also specified. | +| [`policyResourceId`](#parameter-replicationfabricsreplicationcontainersmappingspolicyresourceid) | string | Resource ID of the replication policy. If defined, policyName will be ignored. | +| [`targetContainerFabricName`](#parameter-replicationfabricsreplicationcontainersmappingstargetcontainerfabricname) | string | Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetContainerName`](#parameter-replicationfabricsreplicationcontainersmappingstargetcontainername) | string | Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetProtectionContainerResourceId`](#parameter-replicationfabricsreplicationcontainersmappingstargetprotectioncontainerresourceid) | string | Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. | + +### Parameter: `replicationFabrics.replicationContainers.mappings.name` + +The name of the replication container mapping. If not provided, it will be automatically generated as `-`. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings.policyName` + +Name of the replication policy. Will be ignored if policyResourceId is also specified. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings.policyResourceId` + +Resource ID of the replication policy. If defined, policyName will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings.targetContainerFabricName` + +Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings.targetContainerName` + +Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationFabrics.replicationContainers.mappings.targetProtectionContainerResourceId` + +Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationPolicies` + +List of all replication policies. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-replicationpoliciesname) | string | The name of the replication policy. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`appConsistentFrequencyInMinutes`](#parameter-replicationpoliciesappconsistentfrequencyinminutes) | int | The app consistent snapshot frequency (in minutes). | +| [`crashConsistentFrequencyInMinutes`](#parameter-replicationpoliciescrashconsistentfrequencyinminutes) | int | The crash consistent snapshot frequency (in minutes). | +| [`multiVmSyncStatus`](#parameter-replicationpoliciesmultivmsyncstatus) | string | A value indicating whether multi-VM sync has to be enabled. | +| [`recoveryPointHistory`](#parameter-replicationpoliciesrecoverypointhistory) | int | The duration in minutes until which the recovery points need to be stored. | + +### Parameter: `replicationPolicies.name` + +The name of the replication policy. + +- Required: Yes +- Type: string + +### Parameter: `replicationPolicies.appConsistentFrequencyInMinutes` + +The app consistent snapshot frequency (in minutes). + +- Required: No +- Type: int + +### Parameter: `replicationPolicies.crashConsistentFrequencyInMinutes` + +The crash consistent snapshot frequency (in minutes). + +- Required: No +- Type: int + +### Parameter: `replicationPolicies.multiVmSyncStatus` + +A value indicating whether multi-VM sync has to be enabled. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disable' + 'Enable' + ] + ``` + +### Parameter: `replicationPolicies.recoveryPointHistory` + +The duration in minutes until which the recovery points need to be stored. + +- Required: No +- Type: int + +### Parameter: `restoreSettings` + +The restore settings of the vault. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`crossSubscriptionRestoreSettings`](#parameter-restoresettingscrosssubscriptionrestoresettings) | object | The restore settings of the vault. | + +### Parameter: `restoreSettings.crossSubscriptionRestoreSettings` + +The restore settings of the vault. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`crossSubscriptionRestoreState`](#parameter-restoresettingscrosssubscriptionrestoresettingscrosssubscriptionrestorestate) | string | The restore settings of the vault. | + +### Parameter: `restoreSettings.crossSubscriptionRestoreSettings.crossSubscriptionRestoreState` + +The restore settings of the vault. + +- Required: Yes +- Type: string ### Parameter: `roleAssignments` @@ -3575,7 +4363,95 @@ Security Settings of the vault. - Required: No - Type: object -- Default: `{}` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`immutabilitySettings`](#parameter-securitysettingsimmutabilitysettings) | object | Immutability settings of a vault. | +| [`softDeleteSettings`](#parameter-securitysettingssoftdeletesettings) | object | Soft delete settings of a vault. | + +### Parameter: `securitySettings.immutabilitySettings` + +Immutability settings of a vault. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`state`](#parameter-securitysettingsimmutabilitysettingsstate) | string | The immmutability setting of the vault. | + +### Parameter: `securitySettings.immutabilitySettings.state` + +The immmutability setting of the vault. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Locked' + 'Unlocked' + ] + ``` + +### Parameter: `securitySettings.softDeleteSettings` + +Soft delete settings of a vault. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enhancedSecurityState`](#parameter-securitysettingssoftdeletesettingsenhancedsecuritystate) | string | The enhanced security state. | +| [`softDeleteRetentionPeriodInDays`](#parameter-securitysettingssoftdeletesettingssoftdeleteretentionperiodindays) | int | The soft delete retention period in days. | +| [`softDeleteState`](#parameter-securitysettingssoftdeletesettingssoftdeletestate) | string | The soft delete state. | + +### Parameter: `securitySettings.softDeleteSettings.enhancedSecurityState` + +The enhanced security state. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AlwaysON' + 'Disabled' + 'Enabled' + 'Invalid' + ] + ``` + +### Parameter: `securitySettings.softDeleteSettings.softDeleteRetentionPeriodInDays` + +The soft delete retention period in days. + +- Required: Yes +- Type: int + +### Parameter: `securitySettings.softDeleteSettings.softDeleteState` + +The soft delete state. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AlwaysON' + 'Disabled' + 'Enabled' + 'Invalid' + ] + ``` ### Parameter: `tags` @@ -3602,6 +4478,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.10.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.4.0` | Remote reference | | `br/public:avm/utl/types/avm-common-types:0.5.1` | Remote reference | ## Data Collection diff --git a/avm/res/recovery-services/vault/backup-config/main.json b/avm/res/recovery-services/vault/backup-config/main.json index 282e69a1d2..b855197f7c 100644 --- a/avm/res/recovery-services/vault/backup-config/main.json +++ b/avm/res/recovery-services/vault/backup-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "617152935951311267" + "version": "0.33.13.18514", + "templateHash": "1001038691929568740" }, "name": "Recovery Services Vault Backup Config", "description": "This module deploys a Recovery Services Vault Backup Config." diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/README.md b/avm/res/recovery-services/vault/backup-fabric/protection-container/README.md deleted file mode 100644 index 23baa4b6f9..0000000000 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# Recovery Services Vault Protection Container `[Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers]` - -This module deploys a Recovery Services Vault Protection Container. - -## Navigation - -- [Resource Types](#Resource-Types) -- [Parameters](#Parameters) -- [Outputs](#Outputs) - -## Resource Types - -| Resource Type | API Version | -| :-- | :-- | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers) | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | - -## Parameters - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`name`](#parameter-name) | string | Name of the Azure Recovery Service Vault Protection Container. | - -**Conditional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`recoveryVaultName`](#parameter-recoveryvaultname) | string | The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`backupManagementType`](#parameter-backupmanagementtype) | string | Backup management type to execute the current Protection Container job. | -| [`containerType`](#parameter-containertype) | string | Type of the container. | -| [`friendlyName`](#parameter-friendlyname) | string | Friendly name of the Protection Container. | -| [`location`](#parameter-location) | string | Location for all resources. | -| [`protectedItems`](#parameter-protecteditems) | array | Protected items to register in the container. | -| [`sourceResourceId`](#parameter-sourceresourceid) | string | Resource ID of the target resource for the Protection Container. | - -### Parameter: `name` - -Name of the Azure Recovery Service Vault Protection Container. - -- Required: Yes -- Type: string - -### Parameter: `recoveryVaultName` - -The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment. - -- Required: Yes -- Type: string - -### Parameter: `backupManagementType` - -Backup management type to execute the current Protection Container job. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'AzureBackupServer' - 'AzureIaasVM' - 'AzureSql' - 'AzureStorage' - 'AzureWorkload' - 'DefaultBackup' - 'DPM' - 'Invalid' - 'MAB' - ] - ``` - -### Parameter: `containerType` - -Type of the container. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'AzureBackupServerContainer' - 'AzureSqlContainer' - 'GenericContainer' - 'Microsoft.ClassicCompute/virtualMachines' - 'Microsoft.Compute/virtualMachines' - 'SQLAGWorkLoadContainer' - 'StorageContainer' - 'VMAppContainer' - 'Windows' - ] - ``` - -### Parameter: `friendlyName` - -Friendly name of the Protection Container. - -- Required: No -- Type: string - -### Parameter: `location` - -Location for all resources. - -- Required: No -- Type: string -- Default: `[resourceGroup().location]` - -### Parameter: `protectedItems` - -Protected items to register in the container. - -- Required: No -- Type: array -- Default: `[]` - -### Parameter: `sourceResourceId` - -Resource ID of the target resource for the Protection Container. - -- Required: No -- Type: string - -## Outputs - -| Output | Type | Description | -| :-- | :-- | :-- | -| `name` | string | The Name of the Protection Container. | -| `resourceGroupName` | string | The name of the Resource Group the Protection Container was created in. | -| `resourceId` | string | The resource ID of the Protection Container. | diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep deleted file mode 100644 index 46f5bedc9a..0000000000 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.bicep +++ /dev/null @@ -1,82 +0,0 @@ -metadata name = 'Recovery Services Vault Protection Container' -metadata description = 'This module deploys a Recovery Services Vault Protection Container.' - -@description('Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment.') -param recoveryVaultName string - -@description('Required. Name of the Azure Recovery Service Vault Protection Container.') -param name string - -@description('Optional. Location for all resources.') -param location string = resourceGroup().location - -@description('Optional. Backup management type to execute the current Protection Container job.') -@allowed([ - 'AzureBackupServer' - 'AzureIaasVM' - 'AzureSql' - 'AzureStorage' - 'AzureWorkload' - 'DPM' - 'DefaultBackup' - 'Invalid' - 'MAB' -]) -param backupManagementType string? - -@description('Optional. Resource ID of the target resource for the Protection Container.') -param sourceResourceId string? - -@description('Optional. Friendly name of the Protection Container.') -param friendlyName string? - -@description('Optional. Protected items to register in the container.') -param protectedItems array = [] - -@description('Optional. Type of the container.') -@allowed([ - 'AzureBackupServerContainer' - 'AzureSqlContainer' - 'GenericContainer' - 'Microsoft.ClassicCompute/virtualMachines' - 'Microsoft.Compute/virtualMachines' - 'SQLAGWorkLoadContainer' - 'StorageContainer' - 'VMAppContainer' - 'Windows' -]) -param containerType string? - -resource protectionContainer 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers@2023-01-01' = { - name: '${recoveryVaultName}/Azure/${name}' - properties: { - sourceResourceId: sourceResourceId - friendlyName: friendlyName - backupManagementType: backupManagementType - containerType: !empty(containerType) ? any(containerType) : null - } -} - -module protectionContainer_protectedItems 'protected-item/main.bicep' = [ - for (protectedItem, index) in protectedItems: { - name: '${uniqueString(deployment().name, location)}-ProtectedItem-${index}' - params: { - policyId: protectedItem.policyId - name: protectedItem.name - protectedItemType: protectedItem.protectedItemType - protectionContainerName: protectionContainer.name - recoveryVaultName: recoveryVaultName - sourceResourceId: protectedItem.sourceResourceId - location: location - } - } -] - -@description('The name of the Resource Group the Protection Container was created in.') -output resourceGroupName string = resourceGroup().name - -@description('The resource ID of the Protection Container.') -output resourceId string = protectionContainer.id - -@description('The Name of the Protection Container.') -output name string = protectionContainer.name diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json b/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json deleted file mode 100644 index 29fed457e4..0000000000 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/main.json +++ /dev/null @@ -1,275 +0,0 @@ -{ - "$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.32.4.45862", - "templateHash": "2342312580952650656" - }, - "name": "Recovery Services Vault Protection Container", - "description": "This module deploys a Recovery Services Vault Protection Container." - }, - "parameters": { - "recoveryVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the Azure Recovery Service Vault Protection Container." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "backupManagementType": { - "type": "string", - "nullable": true, - "allowedValues": [ - "AzureBackupServer", - "AzureIaasVM", - "AzureSql", - "AzureStorage", - "AzureWorkload", - "DPM", - "DefaultBackup", - "Invalid", - "MAB" - ], - "metadata": { - "description": "Optional. Backup management type to execute the current Protection Container job." - } - }, - "sourceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the target resource for the Protection Container." - } - }, - "friendlyName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Friendly name of the Protection Container." - } - }, - "protectedItems": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Protected items to register in the container." - } - }, - "containerType": { - "type": "string", - "nullable": true, - "allowedValues": [ - "AzureBackupServerContainer", - "AzureSqlContainer", - "GenericContainer", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "SQLAGWorkLoadContainer", - "StorageContainer", - "VMAppContainer", - "Windows" - ], - "metadata": { - "description": "Optional. Type of the container." - } - } - }, - "resources": { - "protectionContainer": { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]", - "properties": { - "sourceResourceId": "[parameters('sourceResourceId')]", - "friendlyName": "[parameters('friendlyName')]", - "backupManagementType": "[parameters('backupManagementType')]", - "containerType": "[if(not(empty(parameters('containerType'))), parameters('containerType'), null())]" - } - }, - "protectionContainer_protectedItems": { - "copy": { - "name": "protectionContainer_protectedItems", - "count": "[length(parameters('protectedItems'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-ProtectedItem-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "policyId": { - "value": "[parameters('protectedItems')[copyIndex()].policyId]" - }, - "name": { - "value": "[parameters('protectedItems')[copyIndex()].name]" - }, - "protectedItemType": { - "value": "[parameters('protectedItems')[copyIndex()].protectedItemType]" - }, - "protectionContainerName": { - "value": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]" - }, - "recoveryVaultName": { - "value": "[parameters('recoveryVaultName')]" - }, - "sourceResourceId": { - "value": "[parameters('protectedItems')[copyIndex()].sourceResourceId]" - }, - "location": { - "value": "[parameters('location')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "10896311401307689711" - }, - "name": "Recovery Service Vaults Protection Container Protected Item", - "description": "This module deploys a Recovery Services Vault Protection Container Protected Item." - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the resource." - } - }, - "protectionContainerName": { - "type": "string", - "metadata": { - "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." - } - }, - "recoveryVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "protectedItemType": { - "type": "string", - "allowedValues": [ - "AzureFileShareProtectedItem", - "AzureVmWorkloadSAPAseDatabase", - "AzureVmWorkloadSAPHanaDatabase", - "AzureVmWorkloadSQLDatabase", - "DPMProtectedItem", - "GenericProtectedItem", - "MabFileFolderProtectedItem", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "Microsoft.Sql/servers/databases" - ], - "metadata": { - "description": "Required. The backup item type." - } - }, - "policyId": { - "type": "string", - "metadata": { - "description": "Required. ID of the backup policy with which this item is backed up." - } - }, - "sourceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource to back up." - } - } - }, - "resources": [ - { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": { - "protectedItemType": "[parameters('protectedItemType')]", - "policyId": "[parameters('policyId')]", - "sourceResourceId": "[parameters('sourceResourceId')]" - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the protected item was created in." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the protected item." - }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The Name of the protected item." - }, - "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "protectionContainer" - ] - } - }, - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Protection Container was created in." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Protection Container." - }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers', split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[2])]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The Name of the Protection Container." - }, - "value": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]" - } - } -} \ No newline at end of file diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/README.md b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/README.md index c66a0ad665..d0a07999d8 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/README.md +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/README.md @@ -12,7 +12,7 @@ This module deploys a Recovery Services Vault Protection Container Protected Ite | Resource Type | API Version | | :-- | :-- | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | +| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2024-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2024-10-01/vaults/backupFabrics/protectionContainers/protectedItems) | ## Parameters @@ -21,7 +21,7 @@ This module deploys a Recovery Services Vault Protection Container Protected Ite | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | Name of the resource. | -| [`policyId`](#parameter-policyid) | string | ID of the backup policy with which this item is backed up. | +| [`policyName`](#parameter-policyname) | string | The backup policy with which this item is backed up. | | [`protectedItemType`](#parameter-protecteditemtype) | string | The backup item type. | | [`sourceResourceId`](#parameter-sourceresourceid) | string | Resource ID of the resource to back up. | @@ -45,9 +45,9 @@ Name of the resource. - Required: Yes - Type: string -### Parameter: `policyId` +### Parameter: `policyName` -ID of the backup policy with which this item is backed up. +The backup policy with which this item is backed up. - Required: Yes - Type: string diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep index 781a46df52..314684719e 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep @@ -28,18 +28,26 @@ param location string = resourceGroup().location @description('Required. The backup item type.') param protectedItemType string -@description('Required. ID of the backup policy with which this item is backed up.') -param policyId string +@description('Required. The backup policy with which this item is backed up.') +param policyName string @description('Required. Resource ID of the resource to back up.') param sourceResourceId string -resource protectedItem 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2023-01-01' = { +resource rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' existing = { + name: recoveryVaultName + + resource backupPolicy 'backupPolicies@2024-10-01' existing = { + name: policyName + } +} + +resource protectedItem 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2024-10-01' = { name: '${recoveryVaultName}/Azure/${protectionContainerName}/${name}' location: location properties: { protectedItemType: any(protectedItemType) - policyId: policyId + policyId: rsv::backupPolicy.id sourceResourceId: sourceResourceId } } diff --git a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json index 9bb32d1ceb..6abfc869ee 100644 --- a/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json +++ b/avm/res/recovery-services/vault/backup-fabric/protection-container/protected-item/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "10896311401307689711" + "version": "0.33.13.18514", + "templateHash": "14694277488209426813" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item." @@ -54,10 +54,10 @@ "description": "Required. The backup item type." } }, - "policyId": { + "policyName": { "type": "string", "metadata": { - "description": "Required. ID of the backup policy with which this item is backed up." + "description": "Required. The backup policy with which this item is backed up." } }, "sourceResourceId": { @@ -70,12 +70,12 @@ "resources": [ { "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", - "apiVersion": "2023-01-01", + "apiVersion": "2024-10-01", "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", "location": "[parameters('location')]", "properties": { "protectedItemType": "[parameters('protectedItemType')]", - "policyId": "[parameters('policyId')]", + "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVaultName'), parameters('policyName'))]", "sourceResourceId": "[parameters('sourceResourceId')]" } } diff --git a/avm/res/recovery-services/vault/backup-policy/README.md b/avm/res/recovery-services/vault/backup-policy/README.md index 7a222bdeb3..b05afe092c 100644 --- a/avm/res/recovery-services/vault/backup-policy/README.md +++ b/avm/res/recovery-services/vault/backup-policy/README.md @@ -12,7 +12,7 @@ This module deploys a Recovery Services Vault Backup Policy. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.RecoveryServices/vaults/backupPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupPolicies) | +| `Microsoft.RecoveryServices/vaults/backupPolicies` | [2024-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2024-10-01/vaults/backupPolicies) | ## Parameters diff --git a/avm/res/recovery-services/vault/backup-policy/main.bicep b/avm/res/recovery-services/vault/backup-policy/main.bicep index cedc1bc33f..3e182f8f59 100644 --- a/avm/res/recovery-services/vault/backup-policy/main.bicep +++ b/avm/res/recovery-services/vault/backup-policy/main.bicep @@ -14,7 +14,7 @@ resource rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' existing = { name: recoveryVaultName } -resource backupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2023-01-01' = { +resource backupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2024-10-01' = { name: name parent: rsv properties: properties diff --git a/avm/res/recovery-services/vault/backup-policy/main.json b/avm/res/recovery-services/vault/backup-policy/main.json index 45675065d7..aadb42246e 100644 --- a/avm/res/recovery-services/vault/backup-policy/main.json +++ b/avm/res/recovery-services/vault/backup-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8749531505758368980" + "version": "0.33.13.18514", + "templateHash": "18409788320626401161" }, "name": "Recovery Services Vault Backup Policies", "description": "This module deploys a Recovery Services Vault Backup Policy." @@ -33,7 +33,7 @@ "resources": [ { "type": "Microsoft.RecoveryServices/vaults/backupPolicies", - "apiVersion": "2023-01-01", + "apiVersion": "2024-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", "properties": "[parameters('properties')]" } diff --git a/avm/res/recovery-services/vault/backup-storage-config/main.json b/avm/res/recovery-services/vault/backup-storage-config/main.json index a1f71b911b..795ad5446f 100644 --- a/avm/res/recovery-services/vault/backup-storage-config/main.json +++ b/avm/res/recovery-services/vault/backup-storage-config/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5873261661461950688" + "version": "0.33.13.18514", + "templateHash": "17375948662410777678" }, "name": "Recovery Services Vault Backup Storage Config", "description": "This module deploys a Recovery Service Vault Backup Storage Configuration." diff --git a/avm/res/recovery-services/vault/main.bicep b/avm/res/recovery-services/vault/main.bicep index 10cffcdaf9..96e98b1f01 100644 --- a/avm/res/recovery-services/vault/main.bicep +++ b/avm/res/recovery-services/vault/main.bicep @@ -5,7 +5,7 @@ metadata description = 'This module deploys a Recovery Services Vault.' param name string @description('Optional. The storage configuration for the Azure Recovery Service Vault.') -param backupStorageConfig object = {} +param backupStorageConfig backupStorageConfigType? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -14,22 +14,22 @@ param enableTelemetry bool = true param location string = resourceGroup().location @description('Optional. List of all backup policies.') -param backupPolicies array = [] +param backupPolicies backupPolicyType[]? @description('Optional. The backup configuration.') -param backupConfig object = {} +param backupConfig backupConfigType? @description('Optional. List of all protection containers.') -param protectionContainers array = [] +param protectedItems protectedItemType[]? @description('Optional. List of all replication fabrics.') -param replicationFabrics array = [] +param replicationFabrics replicationFabricType[]? @description('Optional. List of all replication policies.') -param replicationPolicies array = [] +param replicationPolicies replicationPolicyType[]? @description('Optional. Replication alert settings.') -param replicationAlertSettings object = {} +param replicationAlertSettings replicationAlertSettingsType? import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The diagnostic settings of the service.') @@ -55,10 +55,10 @@ import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-co param privateEndpoints privateEndpointSingleServiceType[]? @description('Optional. Monitoring Settings of the vault.') -param monitoringSettings object = {} +param monitoringSettings monitoringSettingsType? @description('Optional. Security Settings of the vault.') -param securitySettings object = {} +param securitySettings securitySettingType? @description('Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled.') @allowed([ @@ -67,6 +67,16 @@ param securitySettings object = {} ]) param publicNetworkAccess string = 'Disabled' +@description('Optional. The redundancy settings of the vault.') +param redundancySettings redundancySettingsType? + +@description('Optional. The restore settings of the vault.') +param restoreSettings restoreSettingsType? + +import { customerManagedKeyWithAutoRotateType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' +@description('Optional. The customer managed key definition.') +param customerManagedKey customerManagedKeyWithAutoRotateType? + var formattedUserAssignedIdentities = reduce( map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, @@ -150,7 +160,27 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -resource rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' = { +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId)) { + name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup( + split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], + split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4] + ) + + resource cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { + name: customerManagedKey.?keyName ?? 'dummyKey' + } +} + +resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup( + split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], + split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4] + ) +} + +resource rsv 'Microsoft.RecoveryServices/vaults@2024-04-01' = { name: name location: location tags: tags @@ -160,22 +190,57 @@ resource rsv 'Microsoft.RecoveryServices/vaults@2023-01-01' = { tier: 'Standard' } properties: { - monitoringSettings: !empty(monitoringSettings) ? monitoringSettings : null - securitySettings: !empty(securitySettings) ? securitySettings : null + monitoringSettings: !empty(monitoringSettings) + ? { + azureMonitorAlertSettings: !empty(monitoringSettings.?azureMonitorAlertSettings) + ? { + alertsForAllFailoverIssues: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllFailoverIssues ?? 'Enabled' + alertsForAllJobFailures: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllJobFailures ?? 'Enabled' + alertsForAllReplicationIssues: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllReplicationIssues ?? 'Enabled' + } + : null + classicAlertSettings: !empty(monitoringSettings.?classicAlertSettings) + ? { + alertsForCriticalOperations: monitoringSettings!.classicAlertSettings.?alertsForCriticalOperations ?? 'Enabled' + emailNotificationsForSiteRecovery: monitoringSettings!.classicAlertSettings.?emailNotificationsForSiteRecovery ?? 'Enabled' + } + : null + } + : null + securitySettings: securitySettings publicNetworkAccess: publicNetworkAccess + redundancySettings: redundancySettings + restoreSettings: restoreSettings + encryption: !empty(customerManagedKey) + ? { + infrastructureEncryption: 'Enabled' + kekIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) + ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } + : { + useSystemAssignedIdentity: empty(customerManagedKey.?userAssignedIdentityResourceId) + } + keyVaultProperties: { + keyUri: !empty(customerManagedKey.?keyVersion) + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + : (customerManagedKey.?autoRotationEnabled ?? true) + ? cMKKeyVault::cMKKey.properties.keyUri + : cMKKeyVault::cMKKey.properties.keyUriWithVersion + } + } + : null } } module rsv_replicationFabrics 'replication-fabric/main.bicep' = [ - for (replicationFabric, index) in replicationFabrics: { + for (replicationFabric, index) in (replicationFabrics ?? []): { name: '${uniqueString(deployment().name, location)}-RSV-Fabric-${index}' params: { recoveryVaultName: rsv.name - name: contains(replicationFabric, 'name') ? replicationFabric.name : replicationFabric.location + name: replicationFabric.?name location: replicationFabric.location - replicationContainers: contains(replicationFabric, 'replicationContainers') - ? replicationFabric.replicationContainers - : [] + replicationContainers: replicationFabric.?replicationContainers } dependsOn: [ rsv_replicationPolicies @@ -184,23 +249,15 @@ module rsv_replicationFabrics 'replication-fabric/main.bicep' = [ ] module rsv_replicationPolicies 'replication-policy/main.bicep' = [ - for (replicationPolicy, index) in replicationPolicies: { + for (replicationPolicy, index) in (replicationPolicies ?? []): { name: '${uniqueString(deployment().name, location)}-RSV-Policy-${index}' params: { name: replicationPolicy.name recoveryVaultName: rsv.name - appConsistentFrequencyInMinutes: contains(replicationPolicy, 'appConsistentFrequencyInMinutes') - ? replicationPolicy.appConsistentFrequencyInMinutes - : 60 - crashConsistentFrequencyInMinutes: contains(replicationPolicy, 'crashConsistentFrequencyInMinutes') - ? replicationPolicy.crashConsistentFrequencyInMinutes - : 5 - multiVmSyncStatus: contains(replicationPolicy, 'multiVmSyncStatus') - ? replicationPolicy.multiVmSyncStatus - : 'Enable' - recoveryPointHistory: contains(replicationPolicy, 'recoveryPointHistory') - ? replicationPolicy.recoveryPointHistory - : 1440 + appConsistentFrequencyInMinutes: replicationPolicy.?appConsistentFrequencyInMinutes + crashConsistentFrequencyInMinutes: replicationPolicy.?crashConsistentFrequencyInMinutes + multiVmSyncStatus: replicationPolicy.?multiVmSyncStatus + recoveryPointHistory: replicationPolicy.?recoveryPointHistory } } ] @@ -209,29 +266,31 @@ module rsv_backupStorageConfiguration 'backup-storage-config/main.bicep' = if (! name: '${uniqueString(deployment().name, location)}-RSV-BackupStorageConfig' params: { recoveryVaultName: rsv.name - storageModelType: backupStorageConfig.storageModelType - crossRegionRestoreFlag: backupStorageConfig.crossRegionRestoreFlag + storageModelType: backupStorageConfig!.storageModelType + crossRegionRestoreFlag: backupStorageConfig!.crossRegionRestoreFlag } } -module rsv_backupFabric_protectionContainers 'backup-fabric/protection-container/main.bicep' = [ - for (protectionContainer, index) in protectionContainers: { - name: '${uniqueString(deployment().name, location)}-RSV-ProtectionContainers-${index}' +module rsv_backupFabric_protectionContainer_protectedItems 'backup-fabric/protection-container/protected-item/main.bicep' = [ + for (protectedItem, index) in (protectedItems ?? []): { + name: '${uniqueString(deployment().name, location)}-ProtectedItem-${index}' params: { recoveryVaultName: rsv.name - name: protectionContainer.name - sourceResourceId: protectionContainer.?sourceResourceId - friendlyName: protectionContainer.?friendlyName - backupManagementType: protectionContainer.?backupManagementType - containerType: protectionContainer.?containerType - protectedItems: contains(protectionContainer, 'protectedItems') ? protectionContainer.protectedItems : [] + name: protectedItem.name location: location + policyName: protectedItem.policyName + protectedItemType: protectedItem.protectedItemType + protectionContainerName: protectedItem.protectionContainerName + sourceResourceId: protectedItem.sourceResourceId } + dependsOn: [ + rsv_backupPolicies + ] } ] module rsv_backupPolicies 'backup-policy/main.bicep' = [ - for (backupPolicy, index) in backupPolicies: { + for (backupPolicy, index) in (backupPolicies ?? []): { name: '${uniqueString(deployment().name, location)}-RSV-BackupPolicy-${index}' params: { recoveryVaultName: rsv.name @@ -245,22 +304,14 @@ module rsv_backupConfig 'backup-config/main.bicep' = if (!empty(backupConfig)) { name: '${uniqueString(deployment().name, location)}-RSV-BackupConfig' params: { recoveryVaultName: rsv.name - name: contains(backupConfig, 'name') ? backupConfig.name : 'vaultconfig' - enhancedSecurityState: contains(backupConfig, 'enhancedSecurityState') - ? backupConfig.enhancedSecurityState - : 'Enabled' - resourceGuardOperationRequests: contains(backupConfig, 'resourceGuardOperationRequests') - ? backupConfig.resourceGuardOperationRequests - : [] - softDeleteFeatureState: contains(backupConfig, 'softDeleteFeatureState') - ? backupConfig.softDeleteFeatureState - : 'Enabled' - storageModelType: contains(backupConfig, 'storageModelType') ? backupConfig.storageModelType : 'GeoRedundant' - storageType: contains(backupConfig, 'storageType') ? backupConfig.storageType : 'GeoRedundant' - storageTypeState: contains(backupConfig, 'storageTypeState') ? backupConfig.storageTypeState : 'Locked' - isSoftDeleteFeatureStateEditable: contains(backupConfig, 'isSoftDeleteFeatureStateEditable') - ? backupConfig.isSoftDeleteFeatureStateEditable - : true + name: backupConfig.?name + enhancedSecurityState: backupConfig.?enhancedSecurityState + resourceGuardOperationRequests: backupConfig.?resourceGuardOperationRequests + softDeleteFeatureState: backupConfig.?softDeleteFeatureState + storageModelType: backupConfig.?storageModelType + storageType: backupConfig.?storageType + storageTypeState: backupConfig.?storageTypeState + isSoftDeleteFeatureStateEditable: backupConfig.?isSoftDeleteFeatureStateEditable } } @@ -269,11 +320,9 @@ module rsv_replicationAlertSettings 'replication-alert-setting/main.bicep' = if params: { name: 'defaultAlertSetting' recoveryVaultName: rsv.name - customEmailAddresses: contains(replicationAlertSettings, 'customEmailAddresses') - ? replicationAlertSettings.customEmailAddresses - : [] - locale: contains(replicationAlertSettings, 'locale') ? replicationAlertSettings.locale : '' - sendToOwners: contains(replicationAlertSettings, 'sendToOwners') ? replicationAlertSettings.sendToOwners : 'Send' + customEmailAddresses: replicationAlertSettings.?customEmailAddresses + locale: replicationAlertSettings.?locale + sendToOwners: replicationAlertSettings.?sendToOwners } } @@ -446,3 +495,201 @@ type privateEndpointOutputType = { @description('The IDs of the network interfaces associated with the private endpoint.') networkInterfaceResourceIds: string[] } + +@export() +@description('The type for redundancy settings.') +type redundancySettingsType = { + @description('Optional. Flag to show if Cross Region Restore is enabled on the Vault or not.') + crossRegionRestore: string? + + @description('Optional. The storage redundancy setting of a vault.') + standardTierStorageRedundancy: string? +} + +@export() +@description('The type for restore settings.') +type restoreSettingsType = { + @description('Required. The restore settings of the vault.') + crossSubscriptionRestoreSettings: { + @description('Required. The restore settings of the vault.') + crossSubscriptionRestoreState: string + } +} + +import { containerType } from 'replication-fabric/main.bicep' +@export() +@description('The type for replication fabrics.') +type replicationFabricType = { + @description('Optional. The name of the fabric.') + name: string? + + @description('Optional. The recovery location the fabric represents.') + location: string? + + @description('Optional. Replication containers to create.') + replicationContainers: containerType[]? +} + +@export() +@description('The type for replication policies.') +type replicationPolicyType = { + @description('Required. The name of the replication policy.') + name: string + + @description('Optional. The app consistent snapshot frequency (in minutes).') + appConsistentFrequencyInMinutes: int? + + @description('Optional. The crash consistent snapshot frequency (in minutes).') + crashConsistentFrequencyInMinutes: int? + + @description('Optional. A value indicating whether multi-VM sync has to be enabled.') + multiVmSyncStatus: ('Enable' | 'Disable')? + + @description('Optional. The duration in minutes until which the recovery points need to be stored.') + recoveryPointHistory: int? +} + +@export() +@description('The type for a backup storage config.') +type backupStorageConfigType = { + @description('Optional. The name of the backup storage config.') + name: string? + + @description('Optional. Change Vault Storage Type (Works if vault has not registered any backup instance).') + storageModelType: ('GeoRedundant' | 'LocallyRedundant' | 'ReadAccessGeoZoneRedundant' | 'ZoneRedundant')? + + @description('Optional. Opt in details of Cross Region Restore feature.') + crossRegionRestoreFlag: bool? +} + +@export() +@description('The type for a backup configuration.') +type backupConfigType = { + @description('Optional. Name of the Azure Recovery Service Vault Backup Policy.') + name: string? + + @description('Optional. Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations.') + enhancedSecurityState: ('Disabled' | 'Enabled')? + + @description('Optional. ResourceGuard Operation Requests.') + resourceGuardOperationRequests: object[]? + + @description('Optional. Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes.') + softDeleteFeatureState: ('Disabled' | 'Enabled')? + + @description('Optional. Storage type.') + storageModelType: ('GeoRedundant' | 'LocallyRedundant' | 'ReadAccessGeoZoneRedundant' | 'ZoneRedundant')? + + @description('Optional. Storage type.') + storageType: ('GeoRedundant' | 'LocallyRedundant' | 'ReadAccessGeoZoneRedundant' | 'ZoneRedundant')? + + @description('Optional. Once a machine is registered against a resource, the storageTypeState is always Locked.') + storageTypeState: ('Locked' | 'Unlocked')? + + @description('Optional. Is soft delete feature state editable.') + isSoftDeleteFeatureStateEditable: bool? +} + +@export() +@description('The type for replication alert settings') +type replicationAlertSettingsType = { + @description('Optional. The name of the replication Alert Setting.') + name: string? + + @description('Optional. The custom email address for sending emails.') + customEmailAddresses: string[]? + + @description('Optional. The locale for the email notification.') + locale: string? + + @description('Optional. The value indicating whether to send email to subscription administrator.') + sendToOwners: ('DoNotSend' | 'Send')? +} + +@export() +@description('The type for a protected item') +type protectedItemType = { + @description('Required. Name of the resource.') + name: string + + @description('Optional. Location for all resources.') + location: string? + + @description('Required. Name of the Azure Recovery Service Vault Protection Container.') + protectionContainerName: string + + @description('Required. The backup item type.') + protectedItemType: ( + | 'AzureFileShareProtectedItem' + | 'AzureVmWorkloadSAPAseDatabase' + | 'AzureVmWorkloadSAPHanaDatabase' + | 'AzureVmWorkloadSQLDatabase' + | 'DPMProtectedItem' + | 'GenericProtectedItem' + | 'MabFileFolderProtectedItem' + | 'Microsoft.ClassicCompute/virtualMachines' + | 'Microsoft.Compute/virtualMachines' + | 'Microsoft.Sql/servers/databases') + + @description('Required. The backup policy with which this item is backed up.') + policyName: string + + @description('Required. Resource ID of the resource to back up.') + sourceResourceId: string +} + +@export() +@description('The type of a backup policy.') +type backupPolicyType = { + @description('Required. Name of the Azure Recovery Service Vault Backup Policy.') + name: string + + @description('Required. Configuration of the Azure Recovery Service Vault Backup Policy.') + properties: object +} + +@export() +type monitoringSettingsType = { + @description('Optional. The alert settings.') + azureMonitorAlertSettings: { + @description('Optional. Enable / disable alerts for all failover issues.') + alertsForAllFailoverIssues: ('Enabled' | 'Disabled')? + + @description('Optional. Enable / disable alerts for all job failures.') + alertsForAllJobFailures: ('Enabled' | 'Disabled')? + + @description('Optional. Enable / disable alerts for all replication issues.') + alertsForAllReplicationIssues: ('Enabled' | 'Disabled')? + }? + + @description('Optional. The classic alert settings.') + classicAlertSettings: { + @description('Optional. Enable / disable alerts for critical operations.') + alertsForCriticalOperations: ('Enabled' | 'Disabled')? + + @description('Optional. Enable / disable email notifications for site recovery.') + emailNotificationsForSiteRecovery: ('Enabled' | 'Disabled')? + }? +} + +@export() +@description('The type for security settings.') +type securitySettingType = { + @description('Optional. Immutability settings of a vault.') + immutabilitySettings: { + @description('Required. The immmutability setting of the vault.') + state: ('Disabled' | 'Locked' | 'Unlocked') + }? + + @description('Optional. Soft delete settings of a vault.') + softDeleteSettings: { + @description('Required. The enhanced security state.') + enhancedSecurityState: ('AlwaysON' | 'Disabled' | 'Enabled' | 'Invalid') + + @description('Required. The soft delete retention period in days.') + softDeleteRetentionPeriodInDays: int + + @description('Required. The soft delete state.') + softDeleteState: ('AlwaysON' | 'Disabled' | 'Enabled' | 'Invalid') + }? +} diff --git a/avm/res/recovery-services/vault/main.json b/avm/res/recovery-services/vault/main.json index afcefb46ff..c162dc8dab 100644 --- a/avm/res/recovery-services/vault/main.json +++ b/avm/res/recovery-services/vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "6598977512480723703" + "templateHash": "1404292748211985740" }, "name": "Recovery Services Vaults", "description": "This module deploys a Recovery Services Vault." @@ -75,6 +75,532 @@ "__bicep_export!": true } }, + "redundancySettingsType": { + "type": "object", + "properties": { + "crossRegionRestore": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Flag to show if Cross Region Restore is enabled on the Vault or not." + } + }, + "standardTierStorageRedundancy": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The storage redundancy setting of a vault." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for redundancy settings." + } + }, + "restoreSettingsType": { + "type": "object", + "properties": { + "crossSubscriptionRestoreSettings": { + "type": "object", + "properties": { + "crossSubscriptionRestoreState": { + "type": "string", + "metadata": { + "description": "Required. The restore settings of the vault." + } + } + }, + "metadata": { + "description": "Required. The restore settings of the vault." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for restore settings." + } + }, + "replicationFabricType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the fabric." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The recovery location the fabric represents." + } + }, + "replicationContainers": { + "type": "array", + "items": { + "$ref": "#/definitions/containerType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Replication containers to create." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for replication fabrics." + } + }, + "replicationPolicyType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication policy." + } + }, + "appConsistentFrequencyInMinutes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The app consistent snapshot frequency (in minutes)." + } + }, + "crashConsistentFrequencyInMinutes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The crash consistent snapshot frequency (in minutes)." + } + }, + "multiVmSyncStatus": { + "type": "string", + "allowedValues": [ + "Disable", + "Enable" + ], + "nullable": true, + "metadata": { + "description": "Optional. A value indicating whether multi-VM sync has to be enabled." + } + }, + "recoveryPointHistory": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The duration in minutes until which the recovery points need to be stored." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for replication policies." + } + }, + "backupStorageConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the backup storage config." + } + }, + "storageModelType": { + "type": "string", + "allowedValues": [ + "GeoRedundant", + "LocallyRedundant", + "ReadAccessGeoZoneRedundant", + "ZoneRedundant" + ], + "nullable": true, + "metadata": { + "description": "Optional. Change Vault Storage Type (Works if vault has not registered any backup instance)." + } + }, + "crossRegionRestoreFlag": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Opt in details of Cross Region Restore feature." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup storage config." + } + }, + "backupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the Azure Recovery Service Vault Backup Policy." + } + }, + "enhancedSecurityState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations." + } + }, + "resourceGuardOperationRequests": { + "type": "array", + "items": { + "type": "object" + }, + "nullable": true, + "metadata": { + "description": "Optional. ResourceGuard Operation Requests." + } + }, + "softDeleteFeatureState": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes." + } + }, + "storageModelType": { + "type": "string", + "allowedValues": [ + "GeoRedundant", + "LocallyRedundant", + "ReadAccessGeoZoneRedundant", + "ZoneRedundant" + ], + "nullable": true, + "metadata": { + "description": "Optional. Storage type." + } + }, + "storageType": { + "type": "string", + "allowedValues": [ + "GeoRedundant", + "LocallyRedundant", + "ReadAccessGeoZoneRedundant", + "ZoneRedundant" + ], + "nullable": true, + "metadata": { + "description": "Optional. Storage type." + } + }, + "storageTypeState": { + "type": "string", + "allowedValues": [ + "Locked", + "Unlocked" + ], + "nullable": true, + "metadata": { + "description": "Optional. Once a machine is registered against a resource, the storageTypeState is always Locked." + } + }, + "isSoftDeleteFeatureStateEditable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Is soft delete feature state editable." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup configuration." + } + }, + "replicationAlertSettingsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication Alert Setting." + } + }, + "customEmailAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The custom email address for sending emails." + } + }, + "locale": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The locale for the email notification." + } + }, + "sendToOwners": { + "type": "string", + "allowedValues": [ + "DoNotSend", + "Send" + ], + "nullable": true, + "metadata": { + "description": "Optional. The value indicating whether to send email to subscription administrator." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for replication alert settings" + } + }, + "protectedItemType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the resource." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "protectionContainerName": { + "type": "string", + "metadata": { + "description": "Required. Name of the Azure Recovery Service Vault Protection Container." + } + }, + "protectedItemType": { + "type": "string", + "allowedValues": [ + "AzureFileShareProtectedItem", + "AzureVmWorkloadSAPAseDatabase", + "AzureVmWorkloadSAPHanaDatabase", + "AzureVmWorkloadSQLDatabase", + "DPMProtectedItem", + "GenericProtectedItem", + "MabFileFolderProtectedItem", + "Microsoft.ClassicCompute/virtualMachines", + "Microsoft.Compute/virtualMachines", + "Microsoft.Sql/servers/databases" + ], + "metadata": { + "description": "Required. The backup item type." + } + }, + "policyName": { + "type": "string", + "metadata": { + "description": "Required. The backup policy with which this item is backed up." + } + }, + "sourceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource to back up." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a protected item" + } + }, + "backupPolicyType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the Azure Recovery Service Vault Backup Policy." + } + }, + "properties": { + "type": "object", + "metadata": { + "description": "Required. Configuration of the Azure Recovery Service Vault Backup Policy." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type of a backup policy." + } + }, + "monitoringSettingsType": { + "type": "object", + "properties": { + "azureMonitorAlertSettings": { + "type": "object", + "properties": { + "alertsForAllFailoverIssues": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable / disable alerts for all failover issues." + } + }, + "alertsForAllJobFailures": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable / disable alerts for all job failures." + } + }, + "alertsForAllReplicationIssues": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable / disable alerts for all replication issues." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The alert settings." + } + }, + "classicAlertSettings": { + "type": "object", + "properties": { + "alertsForCriticalOperations": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable / disable alerts for critical operations." + } + }, + "emailNotificationsForSiteRecovery": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enable / disable email notifications for site recovery." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The classic alert settings." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "securitySettingType": { + "type": "object", + "properties": { + "immutabilitySettings": { + "type": "object", + "properties": { + "state": { + "type": "string", + "allowedValues": [ + "Disabled", + "Locked", + "Unlocked" + ], + "metadata": { + "description": "Required. The immmutability setting of the vault." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Immutability settings of a vault." + } + }, + "softDeleteSettings": { + "type": "object", + "properties": { + "enhancedSecurityState": { + "type": "string", + "allowedValues": [ + "AlwaysON", + "Disabled", + "Enabled", + "Invalid" + ], + "metadata": { + "description": "Required. The enhanced security state." + } + }, + "softDeleteRetentionPeriodInDays": { + "type": "int", + "metadata": { + "description": "Required. The soft delete retention period in days." + } + }, + "softDeleteState": { + "type": "string", + "allowedValues": [ + "AlwaysON", + "Disabled", + "Enabled", + "Invalid" + ], + "metadata": { + "description": "Required. The soft delete state." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Soft delete settings of a vault." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for security settings." + } + }, "_1.privateEndpointCustomDnsConfigType": { "type": "object", "properties": { @@ -184,6 +710,130 @@ } } }, + "_2.mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "description": "The type for protection container mappings.", + "__bicep_imported_from!": { + "sourceTemplate": "replication-fabric/replication-protection-container/main.bicep" + } + } + }, + "containerType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication container." + } + }, + "mappings": { + "type": "array", + "items": { + "$ref": "#/definitions/_2.mappingType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Replication containers mappings to create." + } + } + }, + "metadata": { + "description": "The type for a replication protection container.", + "__bicep_imported_from!": { + "sourceTemplate": "replication-fabric/main.bicep" + } + } + }, + "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 'autoRotationEnabled' setting." + } + }, + "autoRotationEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable auto-rotating to the latest key version. Default is `true`. If set to `false`, 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": { + "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.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } + } + }, "diagnosticSettingFullType": { "type": "object", "properties": { @@ -590,8 +1240,8 @@ } }, "backupStorageConfig": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/backupStorageConfigType", + "nullable": true, "metadata": { "description": "Optional. The storage configuration for the Azure Recovery Service Vault." } @@ -612,42 +1262,54 @@ }, "backupPolicies": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/backupPolicyType" + }, + "nullable": true, "metadata": { "description": "Optional. List of all backup policies." } }, "backupConfig": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/backupConfigType", + "nullable": true, "metadata": { "description": "Optional. The backup configuration." } }, - "protectionContainers": { + "protectedItems": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/protectedItemType" + }, + "nullable": true, "metadata": { "description": "Optional. List of all protection containers." } }, "replicationFabrics": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/replicationFabricType" + }, + "nullable": true, "metadata": { "description": "Optional. List of all replication fabrics." } }, "replicationPolicies": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/replicationPolicyType" + }, + "nullable": true, "metadata": { "description": "Optional. List of all replication policies." } }, "replicationAlertSettings": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/replicationAlertSettingsType", + "nullable": true, "metadata": { "description": "Optional. Replication alert settings." } @@ -704,15 +1366,15 @@ } }, "monitoringSettings": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/monitoringSettingsType", + "nullable": true, "metadata": { "description": "Optional. Monitoring Settings of the vault." } }, "securitySettings": { - "type": "object", - "defaultValue": {}, + "$ref": "#/definitions/securitySettingType", + "nullable": true, "metadata": { "description": "Optional. Security Settings of the vault." } @@ -727,6 +1389,27 @@ "metadata": { "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled." } + }, + "redundancySettings": { + "$ref": "#/definitions/redundancySettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The redundancy settings of the vault." + } + }, + "restoreSettings": { + "$ref": "#/definitions/restoreSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The restore settings of the vault." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyWithAutoRotateType", + "nullable": true, + "metadata": { + "description": "Optional. The customer managed key definition." + } } }, "variables": { @@ -754,6 +1437,15 @@ } }, "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]" + }, "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", @@ -774,9 +1466,27 @@ } } }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, "rsv": { "type": "Microsoft.RecoveryServices/vaults", - "apiVersion": "2023-01-01", + "apiVersion": "2024-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -786,10 +1496,16 @@ "tier": "Standard" }, "properties": { - "monitoringSettings": "[if(not(empty(parameters('monitoringSettings'))), parameters('monitoringSettings'), null())]", - "securitySettings": "[if(not(empty(parameters('securitySettings'))), parameters('securitySettings'), null())]", - "publicNetworkAccess": "[parameters('publicNetworkAccess')]" - } + "monitoringSettings": "[if(not(empty(parameters('monitoringSettings'))), createObject('azureMonitorAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'))), createObject('alertsForAllFailoverIssues', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllFailoverIssues'), 'Enabled'), 'alertsForAllJobFailures', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllJobFailures'), 'Enabled'), 'alertsForAllReplicationIssues', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllReplicationIssues'), 'Enabled')), null()), 'classicAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'classicAlertSettings'))), createObject('alertsForCriticalOperations', coalesce(tryGet(parameters('monitoringSettings').classicAlertSettings, 'alertsForCriticalOperations'), 'Enabled'), 'emailNotificationsForSiteRecovery', coalesce(tryGet(parameters('monitoringSettings').classicAlertSettings, 'emailNotificationsForSiteRecovery'), 'Enabled')), null())), null())]", + "securitySettings": "[parameters('securitySettings')]", + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "redundancySettings": "[parameters('redundancySettings')]", + "restoreSettings": "[parameters('restoreSettings')]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('infrastructureEncryption', 'Enabled', 'kekIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), createObject('useSystemAssignedIdentity', empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))), 'keyVaultProperties', createObject('keyUri', if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), if(coalesce(tryGet(parameters('customerManagedKey'), 'autoRotationEnabled'), true()), reference('cMKKeyVault::cMKKey').keyUri, reference('cMKKeyVault::cMKKey').keyUriWithVersion)))), null())]" + }, + "dependsOn": [ + "cMKKeyVault::cMKKey" + ] }, "rsv_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", @@ -871,7 +1587,7 @@ "rsv_replicationFabrics": { "copy": { "name": "rsv_replicationFabrics", - "count": "[length(parameters('replicationFabrics'))]" + "count": "[length(coalesce(parameters('replicationFabrics'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -885,24 +1601,109 @@ "recoveryVaultName": { "value": "[parameters('name')]" }, - "name": "[if(contains(parameters('replicationFabrics')[copyIndex()], 'name'), createObject('value', parameters('replicationFabrics')[copyIndex()].name), createObject('value', parameters('replicationFabrics')[copyIndex()].location))]", + "name": { + "value": "[tryGet(coalesce(parameters('replicationFabrics'), createArray())[copyIndex()], 'name')]" + }, "location": { - "value": "[parameters('replicationFabrics')[copyIndex()].location]" + "value": "[coalesce(parameters('replicationFabrics'), createArray())[copyIndex()].location]" }, - "replicationContainers": "[if(contains(parameters('replicationFabrics')[copyIndex()], 'replicationContainers'), createObject('value', parameters('replicationFabrics')[copyIndex()].replicationContainers), createObject('value', createArray()))]" + "replicationContainers": { + "value": "[tryGet(coalesce(parameters('replicationFabrics'), createArray())[copyIndex()], 'replicationContainers')]" + } }, "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.33.13.18514", - "templateHash": "16265039904717699288" + "templateHash": "8049192542960910465" }, "name": "Recovery Services Vault Replication Fabrics", "description": "This module deploys a Replication Fabric for Azure to Azure disaster recovery scenario of Azure Site Recovery.\n\n> Note: this module currently support only the `instanceType: 'Azure'` scenario." }, + "definitions": { + "containerType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication container." + } + }, + "mappings": { + "type": "array", + "items": { + "$ref": "#/definitions/mappingType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Replication containers mappings to create." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a replication protection container." + } + }, + "mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "description": "The type for protection container mappings.", + "__bicep_imported_from!": { + "sourceTemplate": "replication-protection-container/main.bicep" + } + } + } + }, "parameters": { "recoveryVaultName": { "type": "string", @@ -926,14 +1727,23 @@ }, "replicationContainers": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/containerType" + }, + "nullable": true, "metadata": { "description": "Optional. Replication containers to create." } } }, - "resources": [ - { + "resources": { + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationFabric": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", @@ -944,10 +1754,10 @@ } } }, - { + "fabric_replicationContainers": { "copy": { "name": "fabric_replicationContainers", - "count": "[length(parameters('replicationContainers'))]" + "count": "[length(coalesce(parameters('replicationContainers'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -959,7 +1769,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('replicationContainers')[copyIndex()].name]" + "value": "[coalesce(parameters('replicationContainers'), createArray())[copyIndex()].name]" }, "recoveryVaultName": { "value": "[parameters('recoveryVaultName')]" @@ -967,22 +1777,76 @@ "replicationFabricName": { "value": "[parameters('name')]" }, - "replicationContainerMappings": { - "value": "[tryGet(parameters('replicationContainers')[copyIndex()], 'replicationContainerMappings')]" + "mappings": { + "value": "[tryGet(coalesce(parameters('replicationContainers'), createArray())[copyIndex()], 'mappings')]" } }, "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.33.13.18514", - "templateHash": "3485070905266123603" + "templateHash": "852813454503469785" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." }, + "definitions": { + "mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for protection container mappings." + } + } + }, "parameters": { "recoveryVaultName": { "type": "string", @@ -1002,16 +1866,31 @@ "description": "Required. The name of the replication container." } }, - "replicationContainerMappings": { + "mappings": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/mappingType" + }, + "nullable": true, "metadata": { "description": "Optional. Replication containers mappings to create." } } }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]", @@ -1023,10 +1902,10 @@ ] } }, - { + "fabric_container_containerMappings": { "copy": { "name": "fabric_container_containerMappings", - "count": "[length(parameters('replicationContainerMappings'))]" + "count": "[length(coalesce(parameters('mappings'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -1038,13 +1917,13 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'name')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'name')]" }, - "policyId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyId')]" + "policyResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyResourceId')]" }, "policyName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyName')]" }, "recoveryVaultName": { "value": "[parameters('recoveryVaultName')]" @@ -1055,24 +1934,25 @@ "sourceProtectionContainerName": { "value": "[parameters('name')]" }, - "targetProtectionContainerId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetProtectionContainerId')]" + "targetProtectionContainerResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetProtectionContainerResourceId')]" }, "targetContainerFabricName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerFabricName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerFabricName')]" }, "targetContainerName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerName')]" } }, "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.33.13.18514", - "templateHash": "6423347652173335680" + "templateHash": "17160081039503517469" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." @@ -1096,9 +1976,9 @@ "description": "Conditional. The name of the parent source Replication container. Required if the template is used in a standalone deployment." } }, - "targetProtectionContainerId": { + "targetProtectionContainerResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." } @@ -1107,17 +1987,17 @@ "type": "string", "defaultValue": "[parameters('replicationFabricName')]", "metadata": { - "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, "targetContainerName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, - "policyId": { + "policyResourceId": { "type": "string", "defaultValue": "", "metadata": { @@ -1128,7 +2008,7 @@ "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the replication policy. Will be ignored if policyId is also specified." + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." } }, "name": { @@ -1140,38 +2020,56 @@ } }, "variables": { - "policyResourceId": "[if(not(equals(parameters('policyId'), '')), parameters('policyId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", - "targetProtectionContainerResourceId": "[if(not(equals(parameters('targetProtectionContainerId'), '')), parameters('targetProtectionContainerId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", - "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('targetProtectionContainerResourceId'), '/')[10]))]" + "calcPolicyResourceId": "[if(not(empty(parameters('policyResourceId'))), parameters('policyResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", + "calcTargetProtectionContainerResourceId": "[if(not(empty(parameters('targetProtectionContainerResourceId'))), parameters('targetProtectionContainerResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", + "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('calcTargetProtectionContainerResourceId'), '/')[10]))]" }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric::replicationContainer": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'))]" + }, + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]", "properties": { - "targetProtectionContainerId": "[variables('targetProtectionContainerResourceId')]", - "policyId": "[variables('policyResourceId')]", + "targetProtectionContainerId": "[variables('calcTargetProtectionContainerResourceId')]", + "policyId": "[variables('calcPolicyResourceId')]", "providerSpecificInput": { "instanceType": "A2A" } } } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" + "value": "[variables('mappingName')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[0], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[1], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[2], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[3])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" }, "resourceGroupName": { "type": "string", @@ -1184,24 +2082,24 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "replicationContainer" ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -1214,24 +2112,24 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1])]" + "replicationFabric" ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication fabric." }, - "value": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication fabric." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', parameters('recoveryVaultName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -1251,7 +2149,7 @@ "rsv_replicationPolicies": { "copy": { "name": "rsv_replicationPolicies", - "count": "[length(parameters('replicationPolicies'))]" + "count": "[length(coalesce(parameters('replicationPolicies'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -1263,15 +2161,23 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('replicationPolicies')[copyIndex()].name]" + "value": "[coalesce(parameters('replicationPolicies'), createArray())[copyIndex()].name]" }, "recoveryVaultName": { "value": "[parameters('name')]" }, - "appConsistentFrequencyInMinutes": "[if(contains(parameters('replicationPolicies')[copyIndex()], 'appConsistentFrequencyInMinutes'), createObject('value', parameters('replicationPolicies')[copyIndex()].appConsistentFrequencyInMinutes), createObject('value', 60))]", - "crashConsistentFrequencyInMinutes": "[if(contains(parameters('replicationPolicies')[copyIndex()], 'crashConsistentFrequencyInMinutes'), createObject('value', parameters('replicationPolicies')[copyIndex()].crashConsistentFrequencyInMinutes), createObject('value', 5))]", - "multiVmSyncStatus": "[if(contains(parameters('replicationPolicies')[copyIndex()], 'multiVmSyncStatus'), createObject('value', parameters('replicationPolicies')[copyIndex()].multiVmSyncStatus), createObject('value', 'Enable'))]", - "recoveryPointHistory": "[if(contains(parameters('replicationPolicies')[copyIndex()], 'recoveryPointHistory'), createObject('value', parameters('replicationPolicies')[copyIndex()].recoveryPointHistory), createObject('value', 1440))]" + "appConsistentFrequencyInMinutes": { + "value": "[tryGet(coalesce(parameters('replicationPolicies'), createArray())[copyIndex()], 'appConsistentFrequencyInMinutes')]" + }, + "crashConsistentFrequencyInMinutes": { + "value": "[tryGet(coalesce(parameters('replicationPolicies'), createArray())[copyIndex()], 'crashConsistentFrequencyInMinutes')]" + }, + "multiVmSyncStatus": { + "value": "[tryGet(coalesce(parameters('replicationPolicies'), createArray())[copyIndex()], 'multiVmSyncStatus')]" + }, + "recoveryPointHistory": { + "value": "[tryGet(coalesce(parameters('replicationPolicies'), createArray())[copyIndex()], 'recoveryPointHistory')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1484,14 +2390,14 @@ "rsv" ] }, - "rsv_backupFabric_protectionContainers": { + "rsv_backupFabric_protectionContainer_protectedItems": { "copy": { - "name": "rsv_backupFabric_protectionContainers", - "count": "[length(parameters('protectionContainers'))]" + "name": "rsv_backupFabric_protectionContainer_protectedItems", + "count": "[length(coalesce(parameters('protectedItems'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-RSV-ProtectionContainers-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-ProtectedItem-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1502,49 +2408,53 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('protectionContainers')[copyIndex()].name]" + "value": "[coalesce(parameters('protectedItems'), createArray())[copyIndex()].name]" }, - "sourceResourceId": { - "value": "[tryGet(parameters('protectionContainers')[copyIndex()], 'sourceResourceId')]" + "location": { + "value": "[parameters('location')]" }, - "friendlyName": { - "value": "[tryGet(parameters('protectionContainers')[copyIndex()], 'friendlyName')]" + "policyName": { + "value": "[coalesce(parameters('protectedItems'), createArray())[copyIndex()].policyName]" }, - "backupManagementType": { - "value": "[tryGet(parameters('protectionContainers')[copyIndex()], 'backupManagementType')]" + "protectedItemType": { + "value": "[coalesce(parameters('protectedItems'), createArray())[copyIndex()].protectedItemType]" }, - "containerType": { - "value": "[tryGet(parameters('protectionContainers')[copyIndex()], 'containerType')]" + "protectionContainerName": { + "value": "[coalesce(parameters('protectedItems'), createArray())[copyIndex()].protectionContainerName]" }, - "protectedItems": "[if(contains(parameters('protectionContainers')[copyIndex()], 'protectedItems'), createObject('value', parameters('protectionContainers')[copyIndex()].protectedItems), createObject('value', createArray()))]", - "location": { - "value": "[parameters('location')]" + "sourceResourceId": { + "value": "[coalesce(parameters('protectedItems'), createArray())[copyIndex()].sourceResourceId]" } }, "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.33.13.18514", - "templateHash": "11151484631677356109" + "templateHash": "14694277488209426813" }, - "name": "Recovery Services Vault Protection Container", - "description": "This module deploys a Recovery Services Vault Protection Container." + "name": "Recovery Service Vaults Protection Container Protected Item", + "description": "This module deploys a Recovery Services Vault Protection Container Protected Item." }, "parameters": { - "recoveryVaultName": { + "name": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." + "description": "Required. Name of the resource." } }, - "name": { + "protectionContainerName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." + } + }, + "recoveryVaultName": { "type": "string", "metadata": { - "description": "Required. Name of the Azure Recovery Service Vault Protection Container." + "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." } }, "location": { @@ -1554,257 +2464,84 @@ "description": "Optional. Location for all resources." } }, - "backupManagementType": { + "protectedItemType": { "type": "string", - "nullable": true, "allowedValues": [ - "AzureBackupServer", - "AzureIaasVM", - "AzureSql", - "AzureStorage", - "AzureWorkload", - "DPM", - "DefaultBackup", - "Invalid", - "MAB" + "AzureFileShareProtectedItem", + "AzureVmWorkloadSAPAseDatabase", + "AzureVmWorkloadSAPHanaDatabase", + "AzureVmWorkloadSQLDatabase", + "DPMProtectedItem", + "GenericProtectedItem", + "MabFileFolderProtectedItem", + "Microsoft.ClassicCompute/virtualMachines", + "Microsoft.Compute/virtualMachines", + "Microsoft.Sql/servers/databases" ], "metadata": { - "description": "Optional. Backup management type to execute the current Protection Container job." - } - }, - "sourceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the target resource for the Protection Container." + "description": "Required. The backup item type." } }, - "friendlyName": { + "policyName": { "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Friendly name of the Protection Container." - } - }, - "protectedItems": { - "type": "array", - "defaultValue": [], "metadata": { - "description": "Optional. Protected items to register in the container." + "description": "Required. The backup policy with which this item is backed up." } }, - "containerType": { + "sourceResourceId": { "type": "string", - "nullable": true, - "allowedValues": [ - "AzureBackupServerContainer", - "AzureSqlContainer", - "GenericContainer", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "SQLAGWorkLoadContainer", - "StorageContainer", - "VMAppContainer", - "Windows" - ], "metadata": { - "description": "Optional. Type of the container." + "description": "Required. Resource ID of the resource to back up." } } }, - "resources": { - "protectionContainer": { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]", + "resources": [ + { + "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", + "apiVersion": "2024-10-01", + "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", + "location": "[parameters('location')]", "properties": { - "sourceResourceId": "[parameters('sourceResourceId')]", - "friendlyName": "[parameters('friendlyName')]", - "backupManagementType": "[parameters('backupManagementType')]", - "containerType": "[if(not(empty(parameters('containerType'))), parameters('containerType'), null())]" + "protectedItemType": "[parameters('protectedItemType')]", + "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVaultName'), parameters('policyName'))]", + "sourceResourceId": "[parameters('sourceResourceId')]" } - }, - "protectionContainer_protectedItems": { - "copy": { - "name": "protectionContainer_protectedItems", - "count": "[length(parameters('protectedItems'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-ProtectedItem-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "policyId": { - "value": "[parameters('protectedItems')[copyIndex()].policyId]" - }, - "name": { - "value": "[parameters('protectedItems')[copyIndex()].name]" - }, - "protectedItemType": { - "value": "[parameters('protectedItems')[copyIndex()].protectedItemType]" - }, - "protectionContainerName": { - "value": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]" - }, - "recoveryVaultName": { - "value": "[parameters('recoveryVaultName')]" - }, - "sourceResourceId": { - "value": "[parameters('protectedItems')[copyIndex()].sourceResourceId]" - }, - "location": { - "value": "[parameters('location')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16309659094506585930" - }, - "name": "Recovery Service Vaults Protection Container Protected Item", - "description": "This module deploys a Recovery Services Vault Protection Container Protected Item." - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the resource." - } - }, - "protectionContainerName": { - "type": "string", - "metadata": { - "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." - } - }, - "recoveryVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "protectedItemType": { - "type": "string", - "allowedValues": [ - "AzureFileShareProtectedItem", - "AzureVmWorkloadSAPAseDatabase", - "AzureVmWorkloadSAPHanaDatabase", - "AzureVmWorkloadSQLDatabase", - "DPMProtectedItem", - "GenericProtectedItem", - "MabFileFolderProtectedItem", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "Microsoft.Sql/servers/databases" - ], - "metadata": { - "description": "Required. The backup item type." - } - }, - "policyId": { - "type": "string", - "metadata": { - "description": "Required. ID of the backup policy with which this item is backed up." - } - }, - "sourceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource to back up." - } - } - }, - "resources": [ - { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": { - "protectedItemType": "[parameters('protectedItemType')]", - "policyId": "[parameters('policyId')]", - "sourceResourceId": "[parameters('sourceResourceId')]" - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the protected item was created in." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the protected item." - }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The Name of the protected item." - }, - "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "protectionContainer" - ] } - }, + ], "outputs": { "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the Resource Group the Protection Container was created in." + "description": "The name of the Resource Group the protected item was created in." }, "value": "[resourceGroup().name]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the Protection Container." + "description": "The resource ID of the protected item." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers', split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[2])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" }, "name": { "type": "string", "metadata": { - "description": "The Name of the Protection Container." + "description": "The Name of the protected item." }, - "value": "[format('{0}/Azure/{1}', parameters('recoveryVaultName'), parameters('name'))]" + "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" } } } }, "dependsOn": [ - "rsv" + "rsv", + "rsv_backupPolicies" ] }, "rsv_backupPolicies": { "copy": { "name": "rsv_backupPolicies", - "count": "[length(parameters('backupPolicies'))]" + "count": "[length(coalesce(parameters('backupPolicies'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -1819,10 +2556,10 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('backupPolicies')[copyIndex()].name]" + "value": "[coalesce(parameters('backupPolicies'), createArray())[copyIndex()].name]" }, "properties": { - "value": "[parameters('backupPolicies')[copyIndex()].properties]" + "value": "[coalesce(parameters('backupPolicies'), createArray())[copyIndex()].properties]" } }, "template": { @@ -1832,7 +2569,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "992831565851796181" + "templateHash": "18409788320626401161" }, "name": "Recovery Services Vault Backup Policies", "description": "This module deploys a Recovery Services Vault Backup Policy." @@ -1860,7 +2597,7 @@ "resources": [ { "type": "Microsoft.RecoveryServices/vaults/backupPolicies", - "apiVersion": "2023-01-01", + "apiVersion": "2024-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", "properties": "[parameters('properties')]" } @@ -1908,14 +2645,30 @@ "recoveryVaultName": { "value": "[parameters('name')]" }, - "name": "[if(contains(parameters('backupConfig'), 'name'), createObject('value', parameters('backupConfig').name), createObject('value', 'vaultconfig'))]", - "enhancedSecurityState": "[if(contains(parameters('backupConfig'), 'enhancedSecurityState'), createObject('value', parameters('backupConfig').enhancedSecurityState), createObject('value', 'Enabled'))]", - "resourceGuardOperationRequests": "[if(contains(parameters('backupConfig'), 'resourceGuardOperationRequests'), createObject('value', parameters('backupConfig').resourceGuardOperationRequests), createObject('value', createArray()))]", - "softDeleteFeatureState": "[if(contains(parameters('backupConfig'), 'softDeleteFeatureState'), createObject('value', parameters('backupConfig').softDeleteFeatureState), createObject('value', 'Enabled'))]", - "storageModelType": "[if(contains(parameters('backupConfig'), 'storageModelType'), createObject('value', parameters('backupConfig').storageModelType), createObject('value', 'GeoRedundant'))]", - "storageType": "[if(contains(parameters('backupConfig'), 'storageType'), createObject('value', parameters('backupConfig').storageType), createObject('value', 'GeoRedundant'))]", - "storageTypeState": "[if(contains(parameters('backupConfig'), 'storageTypeState'), createObject('value', parameters('backupConfig').storageTypeState), createObject('value', 'Locked'))]", - "isSoftDeleteFeatureStateEditable": "[if(contains(parameters('backupConfig'), 'isSoftDeleteFeatureStateEditable'), createObject('value', parameters('backupConfig').isSoftDeleteFeatureStateEditable), createObject('value', true()))]" + "name": { + "value": "[tryGet(parameters('backupConfig'), 'name')]" + }, + "enhancedSecurityState": { + "value": "[tryGet(parameters('backupConfig'), 'enhancedSecurityState')]" + }, + "resourceGuardOperationRequests": { + "value": "[tryGet(parameters('backupConfig'), 'resourceGuardOperationRequests')]" + }, + "softDeleteFeatureState": { + "value": "[tryGet(parameters('backupConfig'), 'softDeleteFeatureState')]" + }, + "storageModelType": { + "value": "[tryGet(parameters('backupConfig'), 'storageModelType')]" + }, + "storageType": { + "value": "[tryGet(parameters('backupConfig'), 'storageType')]" + }, + "storageTypeState": { + "value": "[tryGet(parameters('backupConfig'), 'storageTypeState')]" + }, + "isSoftDeleteFeatureStateEditable": { + "value": "[tryGet(parameters('backupConfig'), 'isSoftDeleteFeatureStateEditable')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -2079,18 +2832,25 @@ "recoveryVaultName": { "value": "[parameters('name')]" }, - "customEmailAddresses": "[if(contains(parameters('replicationAlertSettings'), 'customEmailAddresses'), createObject('value', parameters('replicationAlertSettings').customEmailAddresses), createObject('value', createArray()))]", - "locale": "[if(contains(parameters('replicationAlertSettings'), 'locale'), createObject('value', parameters('replicationAlertSettings').locale), createObject('value', ''))]", - "sendToOwners": "[if(contains(parameters('replicationAlertSettings'), 'sendToOwners'), createObject('value', parameters('replicationAlertSettings').sendToOwners), createObject('value', 'Send'))]" + "customEmailAddresses": { + "value": "[tryGet(parameters('replicationAlertSettings'), 'customEmailAddresses')]" + }, + "locale": { + "value": "[tryGet(parameters('replicationAlertSettings'), 'locale')]" + }, + "sendToOwners": { + "value": "[tryGet(parameters('replicationAlertSettings'), 'sendToOwners')]" + } }, "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.33.13.18514", - "templateHash": "3897872700976586621" + "templateHash": "13714844551703046217" }, "name": "Recovery Services Vault Replication Alert Settings", "description": "This module deploys a Recovery Services Vault Replication Alert Settings." @@ -2111,9 +2871,12 @@ }, "customEmailAddresses": { "type": "array", - "defaultValue": [], + "items": { + "type": "string" + }, + "nullable": true, "metadata": { - "description": "Optional. Comma separated list of custom email address for sending alert emails." + "description": "Optional. The custom email address for sending emails." } }, "locale": { @@ -2135,18 +2898,24 @@ } } }, - "resources": [ - { + "resources": { + "recoveryVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2023-01-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationAlertSettings": { "type": "Microsoft.RecoveryServices/vaults/replicationAlertSettings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", "properties": { - "customEmailAddresses": "[if(not(empty(parameters('customEmailAddresses'))), parameters('customEmailAddresses'), null())]", + "customEmailAddresses": "[parameters('customEmailAddresses')]", "locale": "[parameters('locale')]", "sendToOwners": "[parameters('sendToOwners')]" } } - ], + }, "outputs": { "name": { "type": "string", @@ -2960,14 +3729,14 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[tryGet(tryGet(reference('rsv', '2023-01-01', 'full'), 'identity'), 'principalId')]" + "value": "[tryGet(tryGet(reference('rsv', '2024-04-01', 'full'), 'identity'), 'principalId')]" }, "location": { "type": "string", "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('rsv', '2023-01-01', 'full').location]" + "value": "[reference('rsv', '2024-04-01', 'full').location]" }, "privateEndpoints": { "type": "array", diff --git a/avm/res/recovery-services/vault/replication-alert-setting/README.md b/avm/res/recovery-services/vault/replication-alert-setting/README.md index 711a738ed4..5bceb91ca6 100644 --- a/avm/res/recovery-services/vault/replication-alert-setting/README.md +++ b/avm/res/recovery-services/vault/replication-alert-setting/README.md @@ -26,7 +26,7 @@ This module deploys a Recovery Services Vault Replication Alert Settings. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`customEmailAddresses`](#parameter-customemailaddresses) | array | Comma separated list of custom email address for sending alert emails. | +| [`customEmailAddresses`](#parameter-customemailaddresses) | array | The custom email address for sending emails. | | [`locale`](#parameter-locale) | string | The locale for the email notification. | | [`name`](#parameter-name) | string | The name of the replication Alert Setting. | | [`sendToOwners`](#parameter-sendtoowners) | string | The value indicating whether to send email to subscription administrator. | @@ -40,11 +40,10 @@ The name of the parent Azure Recovery Service Vault. Required if the template is ### Parameter: `customEmailAddresses` -Comma separated list of custom email address for sending alert emails. +The custom email address for sending emails. - Required: No - Type: array -- Default: `[]` ### Parameter: `locale` diff --git a/avm/res/recovery-services/vault/replication-alert-setting/main.bicep b/avm/res/recovery-services/vault/replication-alert-setting/main.bicep index a92f9ff0ca..33dfed3314 100644 --- a/avm/res/recovery-services/vault/replication-alert-setting/main.bicep +++ b/avm/res/recovery-services/vault/replication-alert-setting/main.bicep @@ -7,8 +7,8 @@ param recoveryVaultName string @description('Optional. The name of the replication Alert Setting.') param name string = 'defaultAlertSetting' -@description('Optional. Comma separated list of custom email address for sending alert emails.') -param customEmailAddresses array = [] +@description('Optional. The custom email address for sending emails.') +param customEmailAddresses string[]? @description('Optional. The locale for the email notification.') param locale string = '' @@ -28,7 +28,7 @@ resource replicationAlertSettings 'Microsoft.RecoveryServices/vaults/replication name: name parent: recoveryVault properties: { - customEmailAddresses: !empty(customEmailAddresses) ? customEmailAddresses : null + customEmailAddresses: customEmailAddresses locale: locale sendToOwners: sendToOwners } diff --git a/avm/res/recovery-services/vault/replication-alert-setting/main.json b/avm/res/recovery-services/vault/replication-alert-setting/main.json index 842682439c..8f3cc16a47 100644 --- a/avm/res/recovery-services/vault/replication-alert-setting/main.json +++ b/avm/res/recovery-services/vault/replication-alert-setting/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.32.4.45862", - "templateHash": "13751902698582597636" + "version": "0.33.13.18514", + "templateHash": "13714844551703046217" }, "name": "Recovery Services Vault Replication Alert Settings", "description": "This module deploys a Recovery Services Vault Replication Alert Settings." @@ -26,9 +27,12 @@ }, "customEmailAddresses": { "type": "array", - "defaultValue": [], + "items": { + "type": "string" + }, + "nullable": true, "metadata": { - "description": "Optional. Comma separated list of custom email address for sending alert emails." + "description": "Optional. The custom email address for sending emails." } }, "locale": { @@ -50,18 +54,24 @@ } } }, - "resources": [ - { + "resources": { + "recoveryVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2023-01-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationAlertSettings": { "type": "Microsoft.RecoveryServices/vaults/replicationAlertSettings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", "properties": { - "customEmailAddresses": "[if(not(empty(parameters('customEmailAddresses'))), parameters('customEmailAddresses'), null())]", + "customEmailAddresses": "[parameters('customEmailAddresses')]", "locale": "[parameters('locale')]", "sendToOwners": "[parameters('sendToOwners')]" } } - ], + }, "outputs": { "name": { "type": "string", diff --git a/avm/res/recovery-services/vault/replication-fabric/README.md b/avm/res/recovery-services/vault/replication-fabric/README.md index c363361733..1ddb4829bf 100644 --- a/avm/res/recovery-services/vault/replication-fabric/README.md +++ b/avm/res/recovery-services/vault/replication-fabric/README.md @@ -63,7 +63,85 @@ Replication containers to create. - Required: No - Type: array -- Default: `[]` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-replicationcontainersname) | string | The name of the replication container. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`mappings`](#parameter-replicationcontainersmappings) | array | Replication containers mappings to create. | + +### Parameter: `replicationContainers.name` + +The name of the replication container. + +- Required: Yes +- Type: string + +### Parameter: `replicationContainers.mappings` + +Replication containers mappings to create. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-replicationcontainersmappingsname) | string | The name of the replication container mapping. If not provided, it will be automatically generated as `-`. | +| [`policyName`](#parameter-replicationcontainersmappingspolicyname) | string | Name of the replication policy. Will be ignored if policyResourceId is also specified. | +| [`policyResourceId`](#parameter-replicationcontainersmappingspolicyresourceid) | string | Resource ID of the replication policy. If defined, policyName will be ignored. | +| [`targetContainerFabricName`](#parameter-replicationcontainersmappingstargetcontainerfabricname) | string | Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetContainerName`](#parameter-replicationcontainersmappingstargetcontainername) | string | Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetProtectionContainerResourceId`](#parameter-replicationcontainersmappingstargetprotectioncontainerresourceid) | string | Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. | + +### Parameter: `replicationContainers.mappings.name` + +The name of the replication container mapping. If not provided, it will be automatically generated as `-`. + +- Required: No +- Type: string + +### Parameter: `replicationContainers.mappings.policyName` + +Name of the replication policy. Will be ignored if policyResourceId is also specified. + +- Required: No +- Type: string + +### Parameter: `replicationContainers.mappings.policyResourceId` + +Resource ID of the replication policy. If defined, policyName will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationContainers.mappings.targetContainerFabricName` + +Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationContainers.mappings.targetContainerName` + +Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `replicationContainers.mappings.targetProtectionContainerResourceId` + +Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. + +- Required: No +- Type: string ## Outputs diff --git a/avm/res/recovery-services/vault/replication-fabric/main.bicep b/avm/res/recovery-services/vault/replication-fabric/main.bicep index 05ee580de4..19f5d6c3bc 100644 --- a/avm/res/recovery-services/vault/replication-fabric/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/main.bicep @@ -13,10 +13,15 @@ param location string = resourceGroup().location param name string = location @description('Optional. Replication containers to create.') -param replicationContainers array = [] +param replicationContainers containerType[]? + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2024-10-01' existing = { + name: recoveryVaultName +} resource replicationFabric 'Microsoft.RecoveryServices/vaults/replicationFabrics@2022-10-01' = { - name: '${recoveryVaultName}/${name}' + name: name + parent: recoveryServicesVault properties: { customDetails: { instanceType: 'Azure' @@ -26,13 +31,13 @@ resource replicationFabric 'Microsoft.RecoveryServices/vaults/replicationFabrics } module fabric_replicationContainers 'replication-protection-container/main.bicep' = [ - for (container, index) in replicationContainers: { + for (container, index) in (replicationContainers ?? []): { name: '${deployment().name}-RCont-${index}' params: { name: container.name recoveryVaultName: recoveryVaultName replicationFabricName: name - replicationContainerMappings: container.?replicationContainerMappings + mappings: container.?mappings } dependsOn: [ replicationFabric @@ -48,3 +53,18 @@ output resourceId string = replicationFabric.id @description('The name of the resource group the replication fabric was created in.') output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // + +import { mappingType } from 'replication-protection-container/main.bicep' +@export() +@description('The type for a replication protection container.') +type containerType = { + @description('Required. The name of the replication container.') + name: string + + @description('Optional. Replication containers mappings to create.') + mappings: mappingType[]? +} diff --git a/avm/res/recovery-services/vault/replication-fabric/main.json b/avm/res/recovery-services/vault/replication-fabric/main.json index fa8d97df0a..8869864c78 100644 --- a/avm/res/recovery-services/vault/replication-fabric/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/main.json @@ -1,15 +1,96 @@ { "$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.32.4.45862", - "templateHash": "10507112348892069298" + "version": "0.33.13.18514", + "templateHash": "8049192542960910465" }, "name": "Recovery Services Vault Replication Fabrics", "description": "This module deploys a Replication Fabric for Azure to Azure disaster recovery scenario of Azure Site Recovery.\n\n> Note: this module currently support only the `instanceType: 'Azure'` scenario." }, + "definitions": { + "containerType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication container." + } + }, + "mappings": { + "type": "array", + "items": { + "$ref": "#/definitions/mappingType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Replication containers mappings to create." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a replication protection container." + } + }, + "mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "description": "The type for protection container mappings.", + "__bicep_imported_from!": { + "sourceTemplate": "replication-protection-container/main.bicep" + } + } + } + }, "parameters": { "recoveryVaultName": { "type": "string", @@ -33,14 +114,23 @@ }, "replicationContainers": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/containerType" + }, + "nullable": true, "metadata": { "description": "Optional. Replication containers to create." } } }, - "resources": [ - { + "resources": { + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationFabric": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]", @@ -51,10 +141,10 @@ } } }, - { + "fabric_replicationContainers": { "copy": { "name": "fabric_replicationContainers", - "count": "[length(parameters('replicationContainers'))]" + "count": "[length(coalesce(parameters('replicationContainers'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -66,7 +156,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('replicationContainers')[copyIndex()].name]" + "value": "[coalesce(parameters('replicationContainers'), createArray())[copyIndex()].name]" }, "recoveryVaultName": { "value": "[parameters('recoveryVaultName')]" @@ -74,22 +164,76 @@ "replicationFabricName": { "value": "[parameters('name')]" }, - "replicationContainerMappings": { - "value": "[tryGet(parameters('replicationContainers')[copyIndex()], 'replicationContainerMappings')]" + "mappings": { + "value": "[tryGet(coalesce(parameters('replicationContainers'), createArray())[copyIndex()], 'mappings')]" } }, "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.32.4.45862", - "templateHash": "11569119002723688025" + "version": "0.33.13.18514", + "templateHash": "852813454503469785" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." }, + "definitions": { + "mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for protection container mappings." + } + } + }, "parameters": { "recoveryVaultName": { "type": "string", @@ -109,16 +253,31 @@ "description": "Required. The name of the replication container." } }, - "replicationContainerMappings": { + "mappings": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/mappingType" + }, + "nullable": true, "metadata": { "description": "Optional. Replication containers mappings to create." } } }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]", @@ -130,10 +289,10 @@ ] } }, - { + "fabric_container_containerMappings": { "copy": { "name": "fabric_container_containerMappings", - "count": "[length(parameters('replicationContainerMappings'))]" + "count": "[length(coalesce(parameters('mappings'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -145,13 +304,13 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'name')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'name')]" }, - "policyId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyId')]" + "policyResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyResourceId')]" }, "policyName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyName')]" }, "recoveryVaultName": { "value": "[parameters('recoveryVaultName')]" @@ -162,24 +321,25 @@ "sourceProtectionContainerName": { "value": "[parameters('name')]" }, - "targetProtectionContainerId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetProtectionContainerId')]" + "targetProtectionContainerResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetProtectionContainerResourceId')]" }, "targetContainerFabricName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerFabricName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerFabricName')]" }, "targetContainerName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerName')]" } }, "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.32.4.45862", - "templateHash": "9324067216015127289" + "version": "0.33.13.18514", + "templateHash": "17160081039503517469" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." @@ -203,9 +363,9 @@ "description": "Conditional. The name of the parent source Replication container. Required if the template is used in a standalone deployment." } }, - "targetProtectionContainerId": { + "targetProtectionContainerResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." } @@ -214,17 +374,17 @@ "type": "string", "defaultValue": "[parameters('replicationFabricName')]", "metadata": { - "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, "targetContainerName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, - "policyId": { + "policyResourceId": { "type": "string", "defaultValue": "", "metadata": { @@ -235,7 +395,7 @@ "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the replication policy. Will be ignored if policyId is also specified." + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." } }, "name": { @@ -247,38 +407,56 @@ } }, "variables": { - "policyResourceId": "[if(not(equals(parameters('policyId'), '')), parameters('policyId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", - "targetProtectionContainerResourceId": "[if(not(equals(parameters('targetProtectionContainerId'), '')), parameters('targetProtectionContainerId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", - "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('targetProtectionContainerResourceId'), '/')[10]))]" + "calcPolicyResourceId": "[if(not(empty(parameters('policyResourceId'))), parameters('policyResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", + "calcTargetProtectionContainerResourceId": "[if(not(empty(parameters('targetProtectionContainerResourceId'))), parameters('targetProtectionContainerResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", + "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('calcTargetProtectionContainerResourceId'), '/')[10]))]" }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric::replicationContainer": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'))]" + }, + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]", "properties": { - "targetProtectionContainerId": "[variables('targetProtectionContainerResourceId')]", - "policyId": "[variables('policyResourceId')]", + "targetProtectionContainerId": "[variables('calcTargetProtectionContainerResourceId')]", + "policyId": "[variables('calcPolicyResourceId')]", "providerSpecificInput": { "instanceType": "A2A" } } } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" + "value": "[variables('mappingName')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[0], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[1], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[2], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[3])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" }, "resourceGroupName": { "type": "string", @@ -291,24 +469,24 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "replicationContainer" ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -321,24 +499,24 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1])]" + "replicationFabric" ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication fabric." }, - "value": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication fabric." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[0], split(format('{0}/{1}', parameters('recoveryVaultName'), parameters('name')), '/')[1])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics', parameters('recoveryVaultName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/README.md b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/README.md index 76b8606ba1..c747eac6d0 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/README.md +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/README.md @@ -36,7 +36,7 @@ This module deploys a Recovery Services Vault Replication Protection Container. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`replicationContainerMappings`](#parameter-replicationcontainermappings) | array | Replication containers mappings to create. | +| [`mappings`](#parameter-mappings) | array | Replication containers mappings to create. | ### Parameter: `name` @@ -59,13 +59,65 @@ The name of the parent Replication Fabric. Required if the template is used in a - Required: Yes - Type: string -### Parameter: `replicationContainerMappings` +### Parameter: `mappings` Replication containers mappings to create. - Required: No - Type: array -- Default: `[]` + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-mappingsname) | string | The name of the replication container mapping. If not provided, it will be automatically generated as `-`. | +| [`policyName`](#parameter-mappingspolicyname) | string | Name of the replication policy. Will be ignored if policyResourceId is also specified. | +| [`policyResourceId`](#parameter-mappingspolicyresourceid) | string | Resource ID of the replication policy. If defined, policyName will be ignored. | +| [`targetContainerFabricName`](#parameter-mappingstargetcontainerfabricname) | string | Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetContainerName`](#parameter-mappingstargetcontainername) | string | Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetProtectionContainerResourceId`](#parameter-mappingstargetprotectioncontainerresourceid) | string | Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. | + +### Parameter: `mappings.name` + +The name of the replication container mapping. If not provided, it will be automatically generated as `-`. + +- Required: No +- Type: string + +### Parameter: `mappings.policyName` + +Name of the replication policy. Will be ignored if policyResourceId is also specified. + +- Required: No +- Type: string + +### Parameter: `mappings.policyResourceId` + +Resource ID of the replication policy. If defined, policyName will be ignored. + +- Required: No +- Type: string + +### Parameter: `mappings.targetContainerFabricName` + +Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `mappings.targetContainerName` + +Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. + +- Required: No +- Type: string + +### Parameter: `mappings.targetProtectionContainerResourceId` + +Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. + +- Required: No +- Type: string ## Outputs diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep index fbd8140aca..e9997a3938 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.bicep @@ -13,10 +13,19 @@ param replicationFabricName string param name string @description('Optional. Replication containers mappings to create.') -param replicationContainerMappings array = [] +param mappings mappingType[]? + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2024-10-01' existing = { + name: recoveryVaultName + + resource replicationFabric 'replicationFabrics@2022-10-01' existing = { + name: replicationFabricName + } +} resource replicationContainer 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers@2022-10-01' = { - name: '${recoveryVaultName}/${replicationFabricName}/${name}' + name: name + parent: recoveryServicesVault::replicationFabric properties: { providerSpecificInput: [ { @@ -27,22 +36,19 @@ resource replicationContainer 'Microsoft.RecoveryServices/vaults/replicationFabr } module fabric_container_containerMappings 'replication-protection-container-mapping/main.bicep' = [ - for (mapping, index) in replicationContainerMappings: { + for (mapping, index) in (mappings ?? []): { name: '${deployment().name}-Map-${index}' params: { name: mapping.?name - policyId: mapping.?policyId + policyResourceId: mapping.?policyResourceId policyName: mapping.?policyName recoveryVaultName: recoveryVaultName replicationFabricName: replicationFabricName - sourceProtectionContainerName: name - targetProtectionContainerId: mapping.?targetProtectionContainerId + sourceProtectionContainerName: replicationContainer.name + targetProtectionContainerResourceId: mapping.?targetProtectionContainerResourceId targetContainerFabricName: mapping.?targetContainerFabricName targetContainerName: mapping.?targetContainerName } - dependsOn: [ - replicationContainer - ] } ] @@ -54,3 +60,29 @@ output resourceId string = replicationContainer.id @description('The name of the resource group the replication container was created in.') output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // + +@export() +@description('The type for protection container mappings.') +type mappingType = { + @description('Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored.') + targetProtectionContainerResourceId: string? + + @description('Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored.') + targetContainerFabricName: string? + + @description('Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored.') + targetContainerName: string? + + @description('Optional. Resource ID of the replication policy. If defined, policyName will be ignored.') + policyResourceId: string? + + @description('Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified.') + policyName: string? + + @description('Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`.') + name: string? +} diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json index 574de7d536..cab7041379 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/main.json @@ -1,15 +1,69 @@ { "$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.32.4.45862", - "templateHash": "11569119002723688025" + "version": "0.33.13.18514", + "templateHash": "852813454503469785" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Containers", "description": "This module deploys a Recovery Services Vault Replication Protection Container.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." }, + "definitions": { + "mappingType": { + "type": "object", + "properties": { + "targetProtectionContainerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." + } + }, + "targetContainerFabricName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "targetContainerName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." + } + }, + "policyResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the replication policy. If defined, policyName will be ignored." + } + }, + "policyName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for protection container mappings." + } + } + }, "parameters": { "recoveryVaultName": { "type": "string", @@ -29,16 +83,31 @@ "description": "Required. The name of the replication container." } }, - "replicationContainerMappings": { + "mappings": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/mappingType" + }, + "nullable": true, "metadata": { "description": "Optional. Replication containers mappings to create." } } }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]", @@ -50,10 +119,10 @@ ] } }, - { + "fabric_container_containerMappings": { "copy": { "name": "fabric_container_containerMappings", - "count": "[length(parameters('replicationContainerMappings'))]" + "count": "[length(coalesce(parameters('mappings'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -65,13 +134,13 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'name')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'name')]" }, - "policyId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyId')]" + "policyResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyResourceId')]" }, "policyName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'policyName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'policyName')]" }, "recoveryVaultName": { "value": "[parameters('recoveryVaultName')]" @@ -82,24 +151,25 @@ "sourceProtectionContainerName": { "value": "[parameters('name')]" }, - "targetProtectionContainerId": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetProtectionContainerId')]" + "targetProtectionContainerResourceId": { + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetProtectionContainerResourceId')]" }, "targetContainerFabricName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerFabricName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerFabricName')]" }, "targetContainerName": { - "value": "[tryGet(parameters('replicationContainerMappings')[copyIndex()], 'targetContainerName')]" + "value": "[tryGet(coalesce(parameters('mappings'), createArray())[copyIndex()], 'targetContainerName')]" } }, "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.32.4.45862", - "templateHash": "9324067216015127289" + "version": "0.33.13.18514", + "templateHash": "17160081039503517469" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." @@ -123,9 +193,9 @@ "description": "Conditional. The name of the parent source Replication container. Required if the template is used in a standalone deployment." } }, - "targetProtectionContainerId": { + "targetProtectionContainerResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." } @@ -134,17 +204,17 @@ "type": "string", "defaultValue": "[parameters('replicationFabricName')]", "metadata": { - "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, "targetContainerName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, - "policyId": { + "policyResourceId": { "type": "string", "defaultValue": "", "metadata": { @@ -155,7 +225,7 @@ "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the replication policy. Will be ignored if policyId is also specified." + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." } }, "name": { @@ -167,38 +237,56 @@ } }, "variables": { - "policyResourceId": "[if(not(equals(parameters('policyId'), '')), parameters('policyId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", - "targetProtectionContainerResourceId": "[if(not(equals(parameters('targetProtectionContainerId'), '')), parameters('targetProtectionContainerId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", - "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('targetProtectionContainerResourceId'), '/')[10]))]" + "calcPolicyResourceId": "[if(not(empty(parameters('policyResourceId'))), parameters('policyResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", + "calcTargetProtectionContainerResourceId": "[if(not(empty(parameters('targetProtectionContainerResourceId'))), parameters('targetProtectionContainerResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", + "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('calcTargetProtectionContainerResourceId'), '/')[10]))]" }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric::replicationContainer": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'))]" + }, + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]", "properties": { - "targetProtectionContainerId": "[variables('targetProtectionContainerResourceId')]", - "policyId": "[variables('policyResourceId')]", + "targetProtectionContainerId": "[variables('calcTargetProtectionContainerResourceId')]", + "policyId": "[variables('calcPolicyResourceId')]", "providerSpecificInput": { "instanceType": "A2A" } } } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" + "value": "[variables('mappingName')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[0], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[1], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[2], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[3])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" }, "resourceGroupName": { "type": "string", @@ -211,24 +299,24 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "replicationContainer" ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[0], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[1], split(format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name')), '/')[2])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/README.md b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/README.md index 59d9063217..c4557fa801 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/README.md +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/README.md @@ -31,11 +31,11 @@ This module deploys a Recovery Services Vault (RSV) Replication Protection Conta | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | The name of the replication container mapping. If not provided, it will be automatically generated as `-`. | -| [`policyId`](#parameter-policyid) | string | Resource ID of the replication policy. If defined, policyName will be ignored. | -| [`policyName`](#parameter-policyname) | string | Name of the replication policy. Will be ignored if policyId is also specified. | -| [`targetContainerFabricName`](#parameter-targetcontainerfabricname) | string | Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored. | -| [`targetContainerName`](#parameter-targetcontainername) | string | Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored. | -| [`targetProtectionContainerId`](#parameter-targetprotectioncontainerid) | string | Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. | +| [`policyName`](#parameter-policyname) | string | Name of the replication policy. Will be ignored if policyResourceId is also specified. | +| [`policyResourceId`](#parameter-policyresourceid) | string | Resource ID of the replication policy. If defined, policyName will be ignored. | +| [`targetContainerFabricName`](#parameter-targetcontainerfabricname) | string | Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetContainerName`](#parameter-targetcontainername) | string | Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. | +| [`targetProtectionContainerResourceId`](#parameter-targetprotectioncontainerresourceid) | string | Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. | ### Parameter: `recoveryVaultName` @@ -66,17 +66,17 @@ The name of the replication container mapping. If not provided, it will be autom - Type: string - Default: `''` -### Parameter: `policyId` +### Parameter: `policyName` -Resource ID of the replication policy. If defined, policyName will be ignored. +Name of the replication policy. Will be ignored if policyResourceId is also specified. - Required: No - Type: string - Default: `''` -### Parameter: `policyName` +### Parameter: `policyResourceId` -Name of the replication policy. Will be ignored if policyId is also specified. +Resource ID of the replication policy. If defined, policyName will be ignored. - Required: No - Type: string @@ -84,7 +84,7 @@ Name of the replication policy. Will be ignored if policyId is also specified. ### Parameter: `targetContainerFabricName` -Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored. +Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored. - Required: No - Type: string @@ -92,19 +92,18 @@ Name of the fabric containing the target container. If targetProtectionContainer ### Parameter: `targetContainerName` -Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored. +Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored. - Required: No - Type: string - Default: `''` -### Parameter: `targetProtectionContainerId` +### Parameter: `targetProtectionContainerResourceId` Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored. - Required: No - Type: string -- Default: `''` ## Outputs diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep index 98b9ef47d1..19799272dd 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.bicep @@ -13,28 +13,28 @@ param replicationFabricName string param sourceProtectionContainerName string @description('Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored.') -param targetProtectionContainerId string = '' +param targetProtectionContainerResourceId string? -@description('Optional. Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored.') +@description('Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored.') param targetContainerFabricName string = replicationFabricName -@description('Optional. Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored.') +@description('Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored.') param targetContainerName string = '' @description('Optional. Resource ID of the replication policy. If defined, policyName will be ignored.') -param policyId string = '' +param policyResourceId string = '' -@description('Optional. Name of the replication policy. Will be ignored if policyId is also specified.') +@description('Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified.') param policyName string = '' @description('Optional. The name of the replication container mapping. If not provided, it will be automatically generated as `-`.') param name string = '' -var policyResourceId = policyId != '' - ? policyId +var calcPolicyResourceId = !empty(policyResourceId) + ? policyResourceId : subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', recoveryVaultName, policyName) -var targetProtectionContainerResourceId = targetProtectionContainerId != '' - ? targetProtectionContainerId +var calcTargetProtectionContainerResourceId = !empty(targetProtectionContainerResourceId) + ? targetProtectionContainerResourceId : subscriptionResourceId( 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', recoveryVaultName, @@ -43,13 +43,26 @@ var targetProtectionContainerResourceId = targetProtectionContainerId != '' ) var mappingName = !empty(name) ? name - : '${sourceProtectionContainerName}-${split(targetProtectionContainerResourceId, '/')[10]}' + : '${sourceProtectionContainerName}-${split(calcTargetProtectionContainerResourceId!, '/')[10]}' + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2024-10-01' existing = { + name: recoveryVaultName + + resource replicationFabric 'replicationFabrics@2022-10-01' existing = { + name: replicationFabricName + + resource replicationContainer 'replicationProtectionContainers@2022-10-01' existing = { + name: sourceProtectionContainerName + } + } +} resource replicationContainer 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings@2022-10-01' = { - name: '${recoveryVaultName}/${replicationFabricName}/${sourceProtectionContainerName}/${mappingName}' + name: mappingName + parent: recoveryServicesVault::replicationFabric::replicationContainer properties: { - targetProtectionContainerId: targetProtectionContainerResourceId - policyId: policyResourceId + targetProtectionContainerId: calcTargetProtectionContainerResourceId + policyId: calcPolicyResourceId providerSpecificInput: { instanceType: 'A2A' } diff --git a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json index b1dc3b51dc..4e34240f55 100644 --- a/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/main.json +++ b/avm/res/recovery-services/vault/replication-fabric/replication-protection-container/replication-protection-container-mapping/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.32.4.45862", - "templateHash": "9324067216015127289" + "version": "0.33.13.18514", + "templateHash": "17160081039503517469" }, "name": "Recovery Services Vault Replication Fabric Replication Protection Container Replication Protection Container Mappings", "description": "This module deploys a Recovery Services Vault (RSV) Replication Protection Container Mapping.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." @@ -29,9 +30,9 @@ "description": "Conditional. The name of the parent source Replication container. Required if the template is used in a standalone deployment." } }, - "targetProtectionContainerId": { + "targetProtectionContainerResourceId": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. Resource ID of the target Replication container. Must be specified if targetContainerName is not. If specified, targetContainerFabricName and targetContainerName will be ignored." } @@ -40,17 +41,17 @@ "type": "string", "defaultValue": "[parameters('replicationFabricName')]", "metadata": { - "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the fabric containing the target container. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, "targetContainerName": { "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerId is not. If targetProtectionContainerId is specified, this parameter will be ignored." + "description": "Optional. Name of the target container. Must be specified if targetProtectionContainerResourceId is not. If targetProtectionContainerResourceId is specified, this parameter will be ignored." } }, - "policyId": { + "policyResourceId": { "type": "string", "defaultValue": "", "metadata": { @@ -61,7 +62,7 @@ "type": "string", "defaultValue": "", "metadata": { - "description": "Optional. Name of the replication policy. Will be ignored if policyId is also specified." + "description": "Optional. Name of the replication policy. Will be ignored if policyResourceId is also specified." } }, "name": { @@ -73,38 +74,56 @@ } }, "variables": { - "policyResourceId": "[if(not(equals(parameters('policyId'), '')), parameters('policyId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", - "targetProtectionContainerResourceId": "[if(not(equals(parameters('targetProtectionContainerId'), '')), parameters('targetProtectionContainerId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", - "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('targetProtectionContainerResourceId'), '/')[10]))]" + "calcPolicyResourceId": "[if(not(empty(parameters('policyResourceId'))), parameters('policyResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationPolicies', parameters('recoveryVaultName'), parameters('policyName')))]", + "calcTargetProtectionContainerResourceId": "[if(not(empty(parameters('targetProtectionContainerResourceId'))), parameters('targetProtectionContainerResourceId'), subscriptionResourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers', parameters('recoveryVaultName'), parameters('targetContainerFabricName'), parameters('targetContainerName')))]", + "mappingName": "[if(not(empty(parameters('name'))), parameters('name'), format('{0}-{1}', parameters('sourceProtectionContainerName'), split(variables('calcTargetProtectionContainerResourceId'), '/')[10]))]" }, - "resources": [ - { + "resources": { + "recoveryServicesVault::replicationFabric::replicationContainer": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}/{2}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'))]" + }, + "recoveryServicesVault::replicationFabric": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults/replicationFabrics", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('recoveryVaultName'), parameters('replicationFabricName'))]" + }, + "recoveryServicesVault": { + "existing": true, + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2024-10-01", + "name": "[parameters('recoveryVaultName')]" + }, + "replicationContainer": { "type": "Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings", "apiVersion": "2022-10-01", "name": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]", "properties": { - "targetProtectionContainerId": "[variables('targetProtectionContainerResourceId')]", - "policyId": "[variables('policyResourceId')]", + "targetProtectionContainerId": "[variables('calcTargetProtectionContainerResourceId')]", + "policyId": "[variables('calcPolicyResourceId')]", "providerSpecificInput": { "instanceType": "A2A" } } } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the replication container." }, - "value": "[format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" + "value": "[variables('mappingName')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the replication container." }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[0], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[1], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[2], split(format('{0}/{1}/{2}/{3}', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName')), '/')[3])]" + "value": "[resourceId('Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectionContainerMappings', parameters('recoveryVaultName'), parameters('replicationFabricName'), parameters('sourceProtectionContainerName'), variables('mappingName'))]" }, "resourceGroupName": { "type": "string", diff --git a/avm/res/recovery-services/vault/replication-policy/main.json b/avm/res/recovery-services/vault/replication-policy/main.json index 5545634660..8686c9013f 100644 --- a/avm/res/recovery-services/vault/replication-policy/main.json +++ b/avm/res/recovery-services/vault/replication-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3181787105854140022" + "version": "0.33.13.18514", + "templateHash": "10948839526456404680" }, "name": "Recovery Services Vault Replication Policies", "description": "This module deploys a Recovery Services Vault Replication Policy for Disaster Recovery scenario.\n\n> **Note**: this version of the module only supports the `instanceType: 'A2A'` scenario." diff --git a/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep index 1e88c6427f..d9df105e54 100644 --- a/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/dr/main.test.bicep @@ -49,17 +49,17 @@ module testDeployment '../../../main.bicep' = [ replicationContainers: [ { name: 'ne-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerName: 'pluto' - targetProtectionContainerId: '${resourceGroup.id}/providers/Microsoft.RecoveryServices/vaults/${rsvName}/replicationFabrics/NorthEurope/replicationProtectionContainers/ne-container2' + targetProtectionContainerResourceId: '${resourceGroup.id}/providers/Microsoft.RecoveryServices/vaults/${rsvName}/replicationFabrics/NorthEurope/replicationProtectionContainers/ne-container2' } ] } { name: 'ne-container2' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'WE-2' @@ -75,7 +75,7 @@ module testDeployment '../../../main.bicep' = [ replicationContainers: [ { name: 'we-container1' - replicationContainerMappings: [ + mappings: [ { policyName: 'Default_values' targetContainerFabricName: 'NorthEurope' diff --git a/avm/res/recovery-services/vault/tests/e2e/encr/dependencies.bicep b/avm/res/recovery-services/vault/tests/e2e/encr/dependencies.bicep new file mode 100644 index 0000000000..859e78741b --- /dev/null +++ b/avm/res/recovery-services/vault/tests/e2e/encr/dependencies.bicep @@ -0,0 +1,61 @@ +@description('Optional. The location to deploy resources 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 Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required for encryption to work + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Reader-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '12338af0-0e69-4776-bea7-57ae8d297424' + ) // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the Key Vault Encryption Key.') +output keyVaultEncryptionKeyName string = keyVault::key.name + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id diff --git a/avm/res/recovery-services/vault/tests/e2e/encr/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/encr/main.test.bicep new file mode 100644 index 0000000000..127122d8ec --- /dev/null +++ b/avm/res/recovery-services/vault/tests/e2e/encr/main.test.bicep @@ -0,0 +1,73 @@ +targetScope = 'subscription' + +metadata name = 'Using encryption with Customer-Managed-Key' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-automation.account-${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 = 'rsvencr' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + // 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}' + 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' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + autoRotationEnabled: false + } + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + location: resourceLocation + } + } +] diff --git a/avm/res/recovery-services/vault/tests/e2e/max/dependencies.bicep b/avm/res/recovery-services/vault/tests/e2e/max/dependencies.bicep index 12b8653f54..a561567f44 100644 --- a/avm/res/recovery-services/vault/tests/e2e/max/dependencies.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/max/dependencies.bicep @@ -7,6 +7,15 @@ param virtualNetworkName 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 SSH Key generation.') +param sshDeploymentScriptName string + +@description('Required. The name of the SSH Key to create.') +param sshKeyName string + +@description('Required. The name of the virtual machine to create.') +param virtualMachineName string + var addressPrefix = '10.0.0.0/16' resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { @@ -29,6 +38,99 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'b24988ac-6180-42a0-ab88-20f7382dd24c' + ) // Contributor + principalType: 'ServicePrincipal' + } +} + +resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: sshDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' + scriptContent: loadTextContent('../../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' = { + name: sshKeyName + location: location + properties: { + publicKey: sshDeploymentScript.properties.outputs.publicKey + } +} + +module vm 'br/public:avm/res/compute/virtual-machine:0.10.1' = { + name: '${uniqueString(deployment().name, location)}-virtualMachine' + params: { + location: location + name: virtualMachineName + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' + } + zone: 0 + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: virtualNetwork.properties.subnets[0].id + pipConfiguration: { + name: 'pip-01' + } + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: 128 + caching: 'ReadWrite' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_D2s_v3' + disablePasswordAuthentication: true + publicKeys: [ + { + keyData: sshKey.properties.publicKey + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + } +} + resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { name: 'privatelink.siterecovery.windowsazure.com' location: 'global' @@ -45,11 +147,6 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { } } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - @description('The resource ID of the created Virtual Network Subnet.') output subnetResourceId string = virtualNetwork.properties.subnets[0].id @@ -61,3 +158,6 @@ output managedIdentityResourceId string = managedIdentity.id @description('The resource ID of the created Private DNS Zone.') output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Virtual Machine.') +output virtualMachineResourceId string = vm.outputs.resourceId diff --git a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep index 27c43a282f..177bc345cb 100644 --- a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep @@ -38,6 +38,9 @@ module nestedDependencies 'dependencies.bicep' = { location: resourceLocation virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' + virtualMachineName: 'dep-${namePrefix}-vm-${serviceShort}' } } @@ -71,6 +74,15 @@ module testDeployment '../../../main.bicep' = [ enhancedSecurityState: 'Disabled' softDeleteFeatureState: 'Disabled' } + protectedItems: [ + { + name: 'vm;iaasvmcontainerv2;${resourceGroup.name};${last(split(nestedDependencies.outputs.virtualMachineResourceId, '/'))}' + protectionContainerName: 'IaasVMContainer;iaasvmcontainerv2;${resourceGroup.name};${last(split(nestedDependencies.outputs.virtualMachineResourceId, '/'))}' + policyName: 'VMpolicy' + protectedItemType: 'Microsoft.Compute/virtualMachines' + sourceResourceId: nestedDependencies.outputs.virtualMachineResourceId + } + ] backupPolicies: [ { name: 'VMpolicy' @@ -301,10 +313,6 @@ module testDeployment '../../../main.bicep' = [ } } ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } replicationAlertSettings: { customEmailAddresses: [ 'test.user@testcompany.com' @@ -420,9 +428,12 @@ module testDeployment '../../../main.bicep' = [ monitoringSettings: { azureMonitorAlertSettings: { alertsForAllJobFailures: 'Enabled' + alertsForAllFailoverIssues: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } securitySettings: { diff --git a/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep index 6311e84bed..54126852cf 100644 --- a/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep @@ -301,10 +301,6 @@ module testDeployment '../../../main.bicep' = [ } } ] - backupStorageConfig: { - crossRegionRestoreFlag: true - storageModelType: 'GeoRedundant' - } replicationAlertSettings: { customEmailAddresses: [ 'test.user@testcompany.com' @@ -398,9 +394,12 @@ module testDeployment '../../../main.bicep' = [ monitoringSettings: { azureMonitorAlertSettings: { alertsForAllJobFailures: 'Enabled' + alertsForAllFailoverIssues: 'Enabled' + alertsForAllReplicationIssues: 'Enabled' } classicAlertSettings: { alertsForCriticalOperations: 'Enabled' + emailNotificationsForSiteRecovery: 'Enabled' } } securitySettings: { diff --git a/avm/res/recovery-services/vault/version.json b/avm/res/recovery-services/vault/version.json index 21226dd43f..09c3664cec 100644 --- a/avm/res/recovery-services/vault/version.json +++ b/avm/res/recovery-services/vault/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.6", + "version": "0.7", "pathFilters": [ "./main.json" ] From 571063987ea4dc190e4cb8da4e783a09e7fe12c5 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 11 Feb 2025 09:32:31 +0100 Subject: [PATCH 23/31] fix: Fixed PE deployment when defining a different RG/Subscription than the default (#4421) ## Description Validated scenarios - Use default (i.e., subnet): works - Specify dedicated RG resource Id: works ## Pipeline Reference | Pipeline | | -------- | [![avm.res.cache.redis](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cache.redis.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cache.redis.yml) [![avm.res.container-registry.registry](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml) [![avm.res.databricks.workspace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.databricks.workspace.yml) (unrelated) [![avm.res.db-for-postgre-sql.flexible-server](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.db-for-postgre-sql.flexible-server.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.db-for-postgre-sql.flexible-server.yml) [![avm.res.key-vault.vault](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.key-vault.vault.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.key-vault.vault.yml) [![avm.res.purview.account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.purview.account.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.purview.account.yml) [![avm.res.recovery-services.vault](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml) [![avm.res.relay.namespace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.relay.namespace.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.relay.namespace.yml) [![avm.res.service-bus.namespace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.service-bus.namespace.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.service-bus.namespace.yml) [![avm.res.sql.server](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml) [![avm.res.storage.storage-account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) [![avm.res.synapse.workspace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.synapse.workspace.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.synapse.workspace.yml) [![avm.res.web.site](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.web.site.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.web.site.yml) [![avm.res.web.static-site](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.web.static-site.yml/badge.svg?branch=users%2Falsehr%2FkvltPERGTest&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.web.static-site.yml) ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [x] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/cache/redis/main.bicep | 13 +-- avm/res/cache/redis/main.json | 4 +- .../container-registry/registry/main.bicep | 13 +-- avm/res/container-registry/registry/main.json | 26 ++--- avm/res/databricks/workspace/main.bicep | 26 ++--- avm/res/databricks/workspace/main.json | 8 +- .../flexible-server/main.bicep | 13 +-- .../flexible-server/main.json | 4 +- avm/res/key-vault/vault/README.md | 5 +- .../key-vault/vault/access-policy/main.json | 4 +- avm/res/key-vault/vault/key/main.json | 4 +- avm/res/key-vault/vault/main.bicep | 20 ++-- avm/res/key-vault/vault/main.json | 102 +++++------------- avm/res/key-vault/vault/secret/main.json | 4 +- .../vault/tests/e2e/max/main.test.bicep | 1 + avm/res/purview/account/main.bicep | 65 ++++------- avm/res/purview/account/main.json | 12 ++- avm/res/recovery-services/vault/main.bicep | 29 +++-- avm/res/recovery-services/vault/main.json | 12 ++- avm/res/relay/namespace/main.bicep | 13 +-- avm/res/relay/namespace/main.json | 4 +- avm/res/service-bus/namespace/main.bicep | 13 +-- avm/res/service-bus/namespace/main.json | 46 ++++---- avm/res/sql/server/main.bicep | 13 +-- avm/res/sql/server/main.json | 4 +- avm/res/storage/storage-account/main.bicep | 13 +-- avm/res/storage/storage-account/main.json | 54 +++++----- avm/res/synapse/workspace/main.bicep | 13 +-- avm/res/synapse/workspace/main.json | 26 ++--- avm/res/web/site/main.bicep | 13 +-- avm/res/web/site/main.json | 60 ++++++----- avm/res/web/site/slot/main.bicep | 13 +-- avm/res/web/site/slot/main.json | 26 ++--- avm/res/web/static-site/main.bicep | 13 +-- avm/res/web/static-site/main.json | 22 ++-- 35 files changed, 303 insertions(+), 408 deletions(-) diff --git a/avm/res/cache/redis/main.bicep b/avm/res/cache/redis/main.bicep index c8b5c6167d..461bab33b7 100644 --- a/avm/res/cache/redis/main.bicep +++ b/avm/res/cache/redis/main.bicep @@ -304,15 +304,10 @@ resource redis_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04- module redis_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-redis-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(redis.id, '/'))}-${privateEndpoint.?service ?? 'redisCache'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/cache/redis/main.json b/avm/res/cache/redis/main.json index 7697018b60..10bffbc878 100644 --- a/avm/res/cache/redis/main.json +++ b/avm/res/cache/redis/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "17774807916018865720" + "templateHash": "1242857667100916577" }, "name": "Redis Cache", "description": "This module deploys a Redis Cache." @@ -1167,6 +1167,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-redis-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/container-registry/registry/main.bicep b/avm/res/container-registry/registry/main.bicep index 7b7670fd32..f6a01e5d55 100644 --- a/avm/res/container-registry/registry/main.bicep +++ b/avm/res/container-registry/registry/main.bicep @@ -447,15 +447,10 @@ resource registry_roleAssignments 'Microsoft.Authorization/roleAssignments@2022- module registry_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-registry-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(registry.id, '/'))}-${privateEndpoint.?service ?? 'registry'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/container-registry/registry/main.json b/avm/res/container-registry/registry/main.json index a125c7727e..c28fcccf4d 100644 --- a/avm/res/container-registry/registry/main.json +++ b/avm/res/container-registry/registry/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "7811628046063994725" + "version": "0.33.13.18514", + "templateHash": "1879570214296822193" }, "name": "Azure Container Registries (ACR)", "description": "This module deploys an Azure Container Registry (ACR)." @@ -1415,8 +1415,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "11112300500664950599" + "version": "0.33.13.18514", + "templateHash": "8957375042269792339" }, "name": "Container Registries scopeMaps", "description": "This module deploys an Azure Container Registry (ACR) scopeMap." @@ -1538,8 +1538,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "6036875058945996178" + "version": "0.33.13.18514", + "templateHash": "2771208879484692364" }, "name": "Azure Container Registry (ACR) Replications", "description": "This module deploys an Azure Container Registry (ACR) Replication." @@ -1682,8 +1682,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "15848218260506856293" + "version": "0.33.13.18514", + "templateHash": "16839288679507454258" }, "name": "Container Registries Credential Sets", "description": "This module deploys an ACR Credential Set." @@ -1866,8 +1866,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "3783697279882479947" + "version": "0.33.13.18514", + "templateHash": "13450234979206794925" }, "name": "Container Registries Cache", "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache))." @@ -2004,8 +2004,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "10084997815751263562" + "version": "0.33.13.18514", + "templateHash": "14557981877826360902" }, "name": "Azure Container Registry (ACR) Webhooks", "description": "This module deploys an Azure Container Registry (ACR) Webhook." @@ -2175,6 +2175,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-registry-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/databricks/workspace/main.bicep b/avm/res/databricks/workspace/main.bicep index b75702d2f7..fb1eadf689 100644 --- a/avm/res/databricks/workspace/main.bicep +++ b/avm/res/databricks/workspace/main.bicep @@ -438,15 +438,10 @@ resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022 module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -507,15 +502,10 @@ var _storageAccountId = resourceId( module storageAccount_storageAccountPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (storageAccountPrivateEndpoints ?? []): if (privateStorageAccount == 'Enabled') { name: '${uniqueString(deployment().name, location)}-workspacestorage-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${_storageAccountName}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/databricks/workspace/main.json b/avm/res/databricks/workspace/main.json index fc365caa58..01d52c2168 100644 --- a/avm/res/databricks/workspace/main.json +++ b/avm/res/databricks/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "5589679396689290907" + "templateHash": "5273652821148246861" }, "name": "Azure Databricks Workspaces", "description": "This module deploys an Azure Databricks Workspace." @@ -1011,8 +1011,8 @@ }, "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'), ''))), tryGet(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'), ''))), tryGet(parameters('customerManagedKeyManagedDisk'), 'keyVersion'), last(split(reference('cMKManagedDiskKeyVault::cMKKey').keyUriWithVersion, '/')))), 'rotationToLatestKeyVersionEnabled', coalesce(coalesce(tryGet(parameters('customerManagedKeyManagedDisk'), 'autoRotationEnabled'), equals(true(), true())), false())), 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": [ - "cMKManagedDiskKeyVault::cMKKey", "cMKKeyVault::cMKKey", + "cMKManagedDiskKeyVault::cMKKey", "cMKKeyVault", "cMKManagedDiskKeyVault" ] @@ -1095,6 +1095,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1853,6 +1855,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-workspacestorage-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageAccountPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" 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 08a780886b..dc508d19a4 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/main.bicep @@ -453,15 +453,10 @@ resource flexibleServer_diagnosticSettings 'Microsoft.Insights/diagnosticSetting module server_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): if (empty(delegatedSubnetResourceId)) { name: '${uniqueString(deployment().name, location)}-PostgreSQL-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(flexibleServer.id, '/'))}-${privateEndpoint.?service ?? 'postgresqlServer'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true 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 111ad605cf..6f63a1e86e 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "8102121291373013517" + "templateHash": "17738367672833372176" }, "name": "DBforPostgreSQL Flexible Servers", "description": "This module deploys a DBforPostgreSQL Flexible Server." @@ -1731,6 +1731,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PostgreSQL-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/key-vault/vault/README.md b/avm/res/key-vault/vault/README.md index 2b076102a2..4fe0b74122 100644 --- a/avm/res/key-vault/vault/README.md +++ b/avm/res/key-vault/vault/README.md @@ -463,6 +463,7 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } ] } + resourceGroupResourceId: '' subnetResourceId: '' } ] @@ -731,6 +732,7 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } ] }, + "resourceGroupResourceId": "", "subnetResourceId": "" } ] @@ -989,6 +991,7 @@ param privateEndpoints = [ } ] } + resourceGroupResourceId: '' subnetResourceId: '' } ] @@ -3168,7 +3171,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.9.0` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.10.1` | Remote reference | | `br/public:avm/utl/types/avm-common-types:0.5.1` | Remote reference | ## Data Collection diff --git a/avm/res/key-vault/vault/access-policy/main.json b/avm/res/key-vault/vault/access-policy/main.json index 74ccbb8e5b..1b7d43a370 100644 --- a/avm/res/key-vault/vault/access-policy/main.json +++ b/avm/res/key-vault/vault/access-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6744070574147884656" + "version": "0.33.13.18514", + "templateHash": "15662374115599475123" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy." diff --git a/avm/res/key-vault/vault/key/main.json b/avm/res/key-vault/vault/key/main.json index 562c4cda7c..ecd8d6c830 100644 --- a/avm/res/key-vault/vault/key/main.json +++ b/avm/res/key-vault/vault/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15884853996194439605" + "version": "0.33.13.18514", + "templateHash": "8627699258587559559" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key." diff --git a/avm/res/key-vault/vault/main.bicep b/avm/res/key-vault/vault/main.bicep index 654bcab7d0..3c0200eca1 100644 --- a/avm/res/key-vault/vault/main.bicep +++ b/avm/res/key-vault/vault/main.bicep @@ -304,18 +304,13 @@ module keyVault_keys 'key/main.bicep' = [ } ] -module keyVault_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.9.0' = [ +module keyVault_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-keyVault-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(keyVault.id, '/'))}-${privateEndpoint.?service ?? 'vault'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -403,8 +398,8 @@ output privateEndpoints privateEndpointOutputType[] = [ for (item, index) in (privateEndpoints ?? []): { name: keyVault_privateEndpoints[index].outputs.name resourceId: keyVault_privateEndpoints[index].outputs.resourceId - groupId: keyVault_privateEndpoints[index].outputs.groupId - customDnsConfigs: keyVault_privateEndpoints[index].outputs.customDnsConfig + groupId: keyVault_privateEndpoints[index].outputs.?groupId! + customDnsConfigs: keyVault_privateEndpoints[index].outputs.customDnsConfigs networkInterfaceResourceIds: keyVault_privateEndpoints[index].outputs.networkInterfaceResourceIds } ] @@ -432,7 +427,6 @@ output keys credentialOutputType[] = [ // Definitions // // ================ // @export() -@description('The type for a private endpoint output.') type privateEndpointOutputType = { @description('The name of the private endpoint.') name: string diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index 9bce3471d7..451db99b7b 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5900566328584197217" + "version": "0.33.13.18514", + "templateHash": "10562288197267069295" }, "name": "Key Vaults", "description": "This module deploys a Key Vault." @@ -72,8 +72,7 @@ } }, "metadata": { - "__bicep_export!": true, - "description": "The type for a private endpoint output." + "__bicep_export!": true } }, "credentialOutputType": { @@ -1385,8 +1384,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6744070574147884656" + "version": "0.33.13.18514", + "templateHash": "15662374115599475123" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy." @@ -1651,8 +1650,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6967022677055315423" + "version": "0.33.13.18514", + "templateHash": "7030946530357291103" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret." @@ -1965,8 +1964,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15884853996194439605" + "version": "0.33.13.18514", + "templateHash": "8627699258587559559" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key." @@ -2273,6 +2272,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-keyVault-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -2325,12 +2326,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6724714132049298262" + "version": "0.33.13.18514", + "templateHash": "15954548978129725136" }, "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint." }, "definitions": { "privateDnsZoneGroupType": { @@ -2397,50 +2397,6 @@ "__bicep_export!": true } }, - "manualPrivateLinkServiceConnectionType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } - } - }, - "metadata": { - "__bicep_export!": true - } - }, "privateLinkServiceConnectionType": { "type": "object", "properties": { @@ -2535,7 +2491,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.1" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } }, @@ -2633,7 +2589,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.1" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } } @@ -2729,11 +2685,11 @@ "manualPrivateLinkServiceConnections": { "type": "array", "items": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionType" + "$ref": "#/definitions/privateLinkServiceConnectionType" }, "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty." } }, "privateLinkServiceConnections": { @@ -2743,7 +2699,7 @@ }, "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty." } }, "enableTelemetry": { @@ -2780,7 +2736,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2886,12 +2842,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12329174801198479603" + "version": "0.33.13.18514", + "templateHash": "5440815542537978381" }, "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint Private DNS Zone Group." }, "definitions": { "privateDnsZoneGroupConfigType": { @@ -2969,10 +2924,7 @@ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] + } } }, "outputs": { @@ -3034,7 +2986,7 @@ }, "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" }, - "customDnsConfig": { + "customDnsConfigs": { "type": "array", "items": { "$ref": "#/definitions/customDnsConfigType" @@ -3119,8 +3071,8 @@ "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]", - "customDnsConfigs": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "groupId": "[tryGet(tryGet(reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]", + "customDnsConfigs": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]", "networkInterfaceResourceIds": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" } } diff --git a/avm/res/key-vault/vault/secret/main.json b/avm/res/key-vault/vault/secret/main.json index 6cdad0ef47..75557e043c 100644 --- a/avm/res/key-vault/vault/secret/main.json +++ b/avm/res/key-vault/vault/secret/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6967022677055315423" + "version": "0.33.13.18514", + "templateHash": "7030946530357291103" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret." diff --git a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep index daeb6d673f..896844e9de 100644 --- a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep @@ -249,6 +249,7 @@ module testDeployment '../../../main.bicep' = [ } ] } + resourceGroupResourceId: resourceGroup.id subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] diff --git a/avm/res/purview/account/main.bicep b/avm/res/purview/account/main.bicep index 6821e5bcda..678cd98182 100644 --- a/avm/res/purview/account/main.bicep +++ b/avm/res/purview/account/main.bicep @@ -190,15 +190,10 @@ resource account_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021- module account_accountPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (accountPrivateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-account-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -250,15 +245,10 @@ module account_accountPrivateEndpoints 'br/public:avm/res/network/private-endpoi module account_portalPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (portalPrivateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-portal-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -310,15 +300,10 @@ module account_portalPrivateEndpoints 'br/public:avm/res/network/private-endpoin module account_storageBlobPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (storageBlobPrivateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-blob-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -370,15 +355,10 @@ module account_storageBlobPrivateEndpoints 'br/public:avm/res/network/private-en module account_storageQueuePrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (storageQueuePrivateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-queue-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -430,15 +410,10 @@ module account_storageQueuePrivateEndpoints 'br/public:avm/res/network/private-e module account_eventHubPrivateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (eventHubPrivateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-eventHub-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/purview/account/main.json b/avm/res/purview/account/main.json index b06c5e1fc1..886766ba2f 100644 --- a/avm/res/purview/account/main.json +++ b/avm/res/purview/account/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "12517935064774862493" + "templateHash": "17913522692754850617" }, "name": "Purview Accounts", "description": "This module deploys a Purview Account." @@ -875,6 +875,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-account-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1630,6 +1632,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-portal-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -2385,6 +2389,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-blob-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -3140,6 +3146,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-queue-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -3895,6 +3903,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-eventHub-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/recovery-services/vault/main.bicep b/avm/res/recovery-services/vault/main.bicep index 96e98b1f01..888cf7054c 100644 --- a/avm/res/recovery-services/vault/main.bicep +++ b/avm/res/recovery-services/vault/main.bicep @@ -194,15 +194,15 @@ resource rsv 'Microsoft.RecoveryServices/vaults@2024-04-01' = { ? { azureMonitorAlertSettings: !empty(monitoringSettings.?azureMonitorAlertSettings) ? { - alertsForAllFailoverIssues: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllFailoverIssues ?? 'Enabled' - alertsForAllJobFailures: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllJobFailures ?? 'Enabled' - alertsForAllReplicationIssues: monitoringSettings!.azureMonitorAlertSettings.?alertsForAllReplicationIssues ?? 'Enabled' + alertsForAllFailoverIssues: monitoringSettings!.?azureMonitorAlertSettings.?alertsForAllFailoverIssues ?? 'Enabled' + alertsForAllJobFailures: monitoringSettings!.?azureMonitorAlertSettings.?alertsForAllJobFailures ?? 'Enabled' + alertsForAllReplicationIssues: monitoringSettings!.?azureMonitorAlertSettings.?alertsForAllReplicationIssues ?? 'Enabled' } : null classicAlertSettings: !empty(monitoringSettings.?classicAlertSettings) ? { - alertsForCriticalOperations: monitoringSettings!.classicAlertSettings.?alertsForCriticalOperations ?? 'Enabled' - emailNotificationsForSiteRecovery: monitoringSettings!.classicAlertSettings.?emailNotificationsForSiteRecovery ?? 'Enabled' + alertsForCriticalOperations: monitoringSettings!.?classicAlertSettings.?alertsForCriticalOperations ?? 'Enabled' + emailNotificationsForSiteRecovery: monitoringSettings!.?classicAlertSettings.?emailNotificationsForSiteRecovery ?? 'Enabled' } : null } @@ -223,7 +223,7 @@ resource rsv 'Microsoft.RecoveryServices/vaults@2024-04-01' = { } keyVaultProperties: { keyUri: !empty(customerManagedKey.?keyVersion) - ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.keyVersion}' + ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.?keyVersion}' : (customerManagedKey.?autoRotationEnabled ?? true) ? cMKKeyVault::cMKKey.properties.keyUri : cMKKeyVault::cMKKey.properties.keyUriWithVersion @@ -266,8 +266,8 @@ module rsv_backupStorageConfiguration 'backup-storage-config/main.bicep' = if (! name: '${uniqueString(deployment().name, location)}-RSV-BackupStorageConfig' params: { recoveryVaultName: rsv.name - storageModelType: backupStorageConfig!.storageModelType - crossRegionRestoreFlag: backupStorageConfig!.crossRegionRestoreFlag + storageModelType: backupStorageConfig!.?storageModelType + crossRegionRestoreFlag: backupStorageConfig!.?crossRegionRestoreFlag } } @@ -369,15 +369,10 @@ resource rsv_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-0 module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-rsv-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(rsv.id, '/'))}-${privateEndpoint.?service ?? 'AzureSiteRecovery'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/recovery-services/vault/main.json b/avm/res/recovery-services/vault/main.json index c162dc8dab..189515ddce 100644 --- a/avm/res/recovery-services/vault/main.json +++ b/avm/res/recovery-services/vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "1404292748211985740" + "templateHash": "16908039055526294885" }, "name": "Recovery Services Vaults", "description": "This module deploys a Recovery Services Vault." @@ -1496,12 +1496,12 @@ "tier": "Standard" }, "properties": { - "monitoringSettings": "[if(not(empty(parameters('monitoringSettings'))), createObject('azureMonitorAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'))), createObject('alertsForAllFailoverIssues', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllFailoverIssues'), 'Enabled'), 'alertsForAllJobFailures', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllJobFailures'), 'Enabled'), 'alertsForAllReplicationIssues', coalesce(tryGet(parameters('monitoringSettings').azureMonitorAlertSettings, 'alertsForAllReplicationIssues'), 'Enabled')), null()), 'classicAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'classicAlertSettings'))), createObject('alertsForCriticalOperations', coalesce(tryGet(parameters('monitoringSettings').classicAlertSettings, 'alertsForCriticalOperations'), 'Enabled'), 'emailNotificationsForSiteRecovery', coalesce(tryGet(parameters('monitoringSettings').classicAlertSettings, 'emailNotificationsForSiteRecovery'), 'Enabled')), null())), null())]", + "monitoringSettings": "[if(not(empty(parameters('monitoringSettings'))), createObject('azureMonitorAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'))), createObject('alertsForAllFailoverIssues', coalesce(tryGet(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'), 'alertsForAllFailoverIssues'), 'Enabled'), 'alertsForAllJobFailures', coalesce(tryGet(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'), 'alertsForAllJobFailures'), 'Enabled'), 'alertsForAllReplicationIssues', coalesce(tryGet(tryGet(parameters('monitoringSettings'), 'azureMonitorAlertSettings'), 'alertsForAllReplicationIssues'), 'Enabled')), null()), 'classicAlertSettings', if(not(empty(tryGet(parameters('monitoringSettings'), 'classicAlertSettings'))), createObject('alertsForCriticalOperations', coalesce(tryGet(tryGet(parameters('monitoringSettings'), 'classicAlertSettings'), 'alertsForCriticalOperations'), 'Enabled'), 'emailNotificationsForSiteRecovery', coalesce(tryGet(tryGet(parameters('monitoringSettings'), 'classicAlertSettings'), 'emailNotificationsForSiteRecovery'), 'Enabled')), null())), null())]", "securitySettings": "[parameters('securitySettings')]", "publicNetworkAccess": "[parameters('publicNetworkAccess')]", "redundancySettings": "[parameters('redundancySettings')]", "restoreSettings": "[parameters('restoreSettings')]", - "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('infrastructureEncryption', 'Enabled', 'kekIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), createObject('useSystemAssignedIdentity', empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))), 'keyVaultProperties', createObject('keyUri', if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), if(coalesce(tryGet(parameters('customerManagedKey'), 'autoRotationEnabled'), true()), reference('cMKKeyVault::cMKKey').keyUri, reference('cMKKeyVault::cMKKey').keyUriWithVersion)))), null())]" + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('infrastructureEncryption', 'Enabled', 'kekIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), createObject('useSystemAssignedIdentity', empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))), 'keyVaultProperties', createObject('keyUri', if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, tryGet(parameters('customerManagedKey'), 'keyVersion')), if(coalesce(tryGet(parameters('customerManagedKey'), 'autoRotationEnabled'), true()), reference('cMKKeyVault::cMKKey').keyUri, reference('cMKKeyVault::cMKKey').keyUriWithVersion)))), null())]" }, "dependsOn": [ "cMKKeyVault::cMKKey" @@ -2297,10 +2297,10 @@ "value": "[parameters('name')]" }, "storageModelType": { - "value": "[parameters('backupStorageConfig').storageModelType]" + "value": "[tryGet(parameters('backupStorageConfig'), 'storageModelType')]" }, "crossRegionRestoreFlag": { - "value": "[parameters('backupStorageConfig').crossRegionRestoreFlag]" + "value": "[tryGet(parameters('backupStorageConfig'), 'crossRegionRestoreFlag')]" } }, "template": { @@ -2953,6 +2953,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-rsv-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/relay/namespace/main.bicep b/avm/res/relay/namespace/main.bicep index b20ac876a2..5de0130cc8 100644 --- a/avm/res/relay/namespace/main.bicep +++ b/avm/res/relay/namespace/main.bicep @@ -218,15 +218,10 @@ resource namespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@202 module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-namespace-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/relay/namespace/main.json b/avm/res/relay/namespace/main.json index 9974d7667d..cbfc6ea08c 100644 --- a/avm/res/relay/namespace/main.json +++ b/avm/res/relay/namespace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10302508139309191094" + "templateHash": "7449491400928242470" }, "name": "Relay Namespaces", "description": "This module deploys a Relay Namespace" @@ -1931,6 +1931,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-namespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/service-bus/namespace/main.bicep b/avm/res/service-bus/namespace/main.bicep index 0861cba24b..ef6fcf6ca5 100644 --- a/avm/res/service-bus/namespace/main.bicep +++ b/avm/res/service-bus/namespace/main.bicep @@ -378,15 +378,10 @@ resource serviceBusNamespace_diagnosticSettings 'Microsoft.Insights/diagnosticSe module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-serviceBusNamespace-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(serviceBusNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/service-bus/namespace/main.json b/avm/res/service-bus/namespace/main.json index f8e1241c21..3f9fba0140 100644 --- a/avm/res/service-bus/namespace/main.json +++ b/avm/res/service-bus/namespace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5605645467272297098" + "version": "0.33.13.18514", + "templateHash": "7837803421760030856" }, "name": "Service Bus Namespaces", "description": "This module deploys a Service Bus Namespace." @@ -1865,8 +1865,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11843582332513126053" + "version": "0.33.13.18514", + "templateHash": "14374854229940696860" }, "name": "Service Bus Namespace Authorization Rules", "description": "This module deploys a Service Bus Namespace Authorization Rule." @@ -1968,8 +1968,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "953280430524155799" + "version": "0.33.13.18514", + "templateHash": "17399088623294854705" }, "name": "Service Bus Namespace Disaster Recovery Configs", "description": "This module deploys a Service Bus Namespace Disaster Recovery Config" @@ -2072,8 +2072,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1185508580247696644" + "version": "0.33.13.18514", + "templateHash": "16312291233623934616" }, "name": "Service Bus Namespace Migration Configuration", "description": "This module deploys a Service Bus Namespace Migration Configuration." @@ -2176,8 +2176,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "286643555978658471" + "version": "0.33.13.18514", + "templateHash": "17182735425325794067" }, "name": "Service Bus Namespace Network Rule Sets", "description": "This module deploys a ServiceBus Namespace Network Rule Set." @@ -2375,8 +2375,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2963369845110660460" + "version": "0.33.13.18514", + "templateHash": "4119251299070252186" }, "name": "Service Bus Namespace Queue", "description": "This module deploys a Service Bus Namespace Queue." @@ -2774,8 +2774,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4106322932640263973" + "version": "0.33.13.18514", + "templateHash": "7526885294323298219" }, "name": "Service Bus Namespace Queue Authorization Rules", "description": "This module deploys a Service Bus Namespace Queue Authorization Rule." @@ -2954,8 +2954,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4751434073420963969" + "version": "0.33.13.18514", + "templateHash": "15157624750923042287" }, "name": "Service Bus Namespace Topic", "description": "This module deploys a Service Bus Namespace Topic." @@ -3636,8 +3636,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9054915416075794466" + "version": "0.33.13.18514", + "templateHash": "8184508565282070207" }, "name": "Service Bus Namespace Topic Authorization Rules", "description": "This module deploys a Service Bus Namespace Topic Authorization Rule." @@ -3789,8 +3789,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3178099276922515439" + "version": "0.33.13.18514", + "templateHash": "13380479271935330273" }, "name": "Service Bus Namespace Topic Subscription", "description": "This module deploys a Service Bus Namespace Topic Subscription." @@ -4183,8 +4183,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2622393872040722258" + "version": "0.33.13.18514", + "templateHash": "4831934980907711659" }, "name": "Service Bus Namespace Topic Subscription Rule", "description": "This module deploys a Service Bus Namespace Topic Subscription Rule." @@ -4375,6 +4375,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-serviceBusNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/sql/server/main.bicep b/avm/res/sql/server/main.bicep index 363dd816ee..0e9d3a62cb 100644 --- a/avm/res/sql/server/main.bicep +++ b/avm/res/sql/server/main.bicep @@ -343,15 +343,10 @@ module server_elasticPools 'elastic-pool/main.bicep' = [ module server_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-server-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(server.id, '/'))}-${privateEndpoint.?service ?? 'sqlServer'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/sql/server/main.json b/avm/res/sql/server/main.json index cc2f195da1..070453a235 100644 --- a/avm/res/sql/server/main.json +++ b/avm/res/sql/server/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "2433863119343202155" + "templateHash": "11930227683565093918" }, "name": "Azure SQL Servers", "description": "This module deploys an Azure SQL Server." @@ -3685,6 +3685,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-server-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep index 91ee043a7e..66b9fc6703 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -502,15 +502,10 @@ resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-storageAccount-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index b3193cf49f..0d22a420a4 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "17960260729884623690" + "version": "0.33.13.18514", + "templateHash": "3424685276444889234" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account." @@ -1451,6 +1451,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-storageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -2222,8 +2224,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "10504956743360699891" + "version": "0.33.13.18514", + "templateHash": "4967204006599351003" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy." @@ -2331,8 +2333,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "5655292159520921149" + "version": "0.33.13.18514", + "templateHash": "2528560857012083896" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication." @@ -2569,8 +2571,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2058460323623594433" + "version": "0.33.13.18514", + "templateHash": "14339432978450199921" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -3036,8 +3038,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2991444340097371621" + "version": "0.33.13.18514", + "templateHash": "10816586207828434096" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -3325,8 +3327,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "8061556339565534458" + "version": "0.33.13.18514", + "templateHash": "2769922037435749045" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy." @@ -3505,8 +3507,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "3168394810831105529" + "version": "0.33.13.18514", + "templateHash": "987643333058038389" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service." @@ -3859,8 +3861,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12044655551245282190" + "version": "0.33.13.18514", + "templateHash": "15193761941438215308" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share." @@ -4294,8 +4296,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1736438454543575457" + "version": "0.33.13.18514", + "templateHash": "8158577333548255612" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -4613,8 +4615,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "6383154227554431205" + "version": "0.33.13.18514", + "templateHash": "9877120144610775153" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." @@ -4883,8 +4885,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "12583903411447171294" + "version": "0.33.13.18514", + "templateHash": "541986423744885003" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service." @@ -5199,8 +5201,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "1369356397929898951" + "version": "0.33.13.18514", + "templateHash": "11234204519679347949" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table." @@ -5453,8 +5455,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.93.31351", - "templateHash": "2275047425860597278" + "version": "0.33.13.18514", + "templateHash": "14510275109257916717" } }, "definitions": { diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index fb3e2fefa9..2bc090c5f4 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -352,15 +352,10 @@ module workspace_firewallRules 'firewall-rules/main.bicep' = [ module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.9.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.service}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 6982279774..c58cd50e2f 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17815795427207375469" + "version": "0.33.13.18514", + "templateHash": "4395970160208281653" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace." @@ -1067,8 +1067,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1357925296617686979" + "version": "0.33.13.18514", + "templateHash": "18124614252428623156" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime." @@ -1166,8 +1166,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5168623611246542439" + "version": "0.33.13.18514", + "templateHash": "4658877837973777703" } }, "parameters": { @@ -1254,8 +1254,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "9285184380796627148" + "version": "0.33.13.18514", + "templateHash": "18134135357281825028" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key." @@ -1360,8 +1360,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7870636790140091356" + "version": "0.33.13.18514", + "templateHash": "6961828897310133803" }, "name": "Synapse Workspaces Administrators", "description": "This module deploys Synapse Workspaces Administrators." @@ -1474,8 +1474,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3403338957196025610" + "version": "0.33.13.18514", + "templateHash": "4218971273589711859" }, "name": "Synapse Workspaces Firewall Rules", "description": "This module deploys Synapse Workspaces Firewall Rules." @@ -1554,6 +1554,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/web/site/main.bicep b/avm/res/web/site/main.bicep index 39729295db..8d62479680 100644 --- a/avm/res/web/site/main.bicep +++ b/avm/res/web/site/main.bicep @@ -484,15 +484,10 @@ resource app_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01 module app_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-app-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/web/site/main.json b/avm/res/web/site/main.json index 24e3af3ecf..dec2e20b5f 100644 --- a/avm/res/web/site/main.json +++ b/avm/res/web/site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11078104901059265686" + "version": "0.33.13.18514", + "templateHash": "1510038828157796019" }, "name": "Web/Function Apps", "description": "This module deploys a Web or Function App." @@ -1084,8 +1084,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6410547302386858558" + "version": "0.33.13.18514", + "templateHash": "3773744005628323179" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting." @@ -1246,8 +1246,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11113399312695963924" + "version": "0.33.13.18514", + "templateHash": "12604769145311962317" }, "name": "Site Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration." @@ -1349,8 +1349,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7848470524705559903" + "version": "0.33.13.18514", + "templateHash": "10353279242186955906" }, "name": "Site logs Config", "description": "This module deploys a Site logs Configuration." @@ -1440,8 +1440,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17229460238192107968" + "version": "0.33.13.18514", + "templateHash": "15063123874711680503" }, "name": "Site Web Config", "description": "This module deploys web settings configuration available under sites/config name: web." @@ -1530,8 +1530,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "18138875055545072289" + "version": "0.33.13.18514", + "templateHash": "10653723640225381902" }, "name": "Site Deployment Extension ", "description": "This module deploys a Site extension for MSDeploy." @@ -1748,8 +1748,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12729018089714646839" + "version": "0.33.13.18514", + "templateHash": "15803822027091526791" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot." @@ -2784,8 +2784,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "10124842813698211071" + "version": "0.33.13.18514", + "templateHash": "6379851449588708934" }, "name": "Site Slot App Settings", "description": "This module deploys a Site Slot App Setting." @@ -2961,8 +2961,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7246612330843636406" + "version": "0.33.13.18514", + "templateHash": "4192061847386712633" }, "name": "Site Slot Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration." @@ -3081,8 +3081,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13728299747043713048" + "version": "0.33.13.18514", + "templateHash": "13483227944246460692" }, "name": "Web Site Slot Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy." @@ -3205,8 +3205,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1399655044962772411" + "version": "0.33.13.18514", + "templateHash": "17428168852439619558" }, "name": "Web/Function Apps Slot Hybrid Connection Relay", "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay." @@ -3309,8 +3309,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "18138875055545072289" + "version": "0.33.13.18514", + "templateHash": "10653723640225381902" }, "name": "Site Deployment Extension ", "description": "This module deploys a Site extension for MSDeploy." @@ -3379,6 +3379,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-slot-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -4230,8 +4232,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7686713695944836722" + "version": "0.33.13.18514", + "templateHash": "1499299399255876013" }, "name": "Web Site Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Basic Publishing Credentials Policy." @@ -4345,8 +4347,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "6378705059063789109" + "version": "0.33.13.18514", + "templateHash": "3864138738153964150" }, "name": "Web/Function Apps Hybrid Connection Relay", "description": "This module deploys a Site Hybrid Connection Namespace Relay." @@ -4426,6 +4428,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-app-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/web/site/slot/main.bicep b/avm/res/web/site/slot/main.bicep index 56758d1f5c..f41579ba90 100644 --- a/avm/res/web/site/slot/main.bicep +++ b/avm/res/web/site/slot/main.bicep @@ -377,15 +377,10 @@ resource slot_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-0 module slot_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-slot-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(app.id, '/'))}-${privateEndpoint.?service ?? 'sites-${slot.name}'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/web/site/slot/main.json b/avm/res/web/site/slot/main.json index 06e32b96c3..f7a5a18c95 100644 --- a/avm/res/web/site/slot/main.json +++ b/avm/res/web/site/slot/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12729018089714646839" + "version": "0.33.13.18514", + "templateHash": "15803822027091526791" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot." @@ -1041,8 +1041,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "10124842813698211071" + "version": "0.33.13.18514", + "templateHash": "6379851449588708934" }, "name": "Site Slot App Settings", "description": "This module deploys a Site Slot App Setting." @@ -1218,8 +1218,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7246612330843636406" + "version": "0.33.13.18514", + "templateHash": "4192061847386712633" }, "name": "Site Slot Auth Settings V2 Config", "description": "This module deploys a Site Auth Settings V2 Configuration." @@ -1338,8 +1338,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13728299747043713048" + "version": "0.33.13.18514", + "templateHash": "13483227944246460692" }, "name": "Web Site Slot Basic Publishing Credentials Policies", "description": "This module deploys a Web Site Slot Basic Publishing Credentials Policy." @@ -1462,8 +1462,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1399655044962772411" + "version": "0.33.13.18514", + "templateHash": "17428168852439619558" }, "name": "Web/Function Apps Slot Hybrid Connection Relay", "description": "This module deploys a Site Slot Hybrid Connection Namespace Relay." @@ -1566,8 +1566,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "18138875055545072289" + "version": "0.33.13.18514", + "templateHash": "10653723640225381902" }, "name": "Site Deployment Extension ", "description": "This module deploys a Site extension for MSDeploy." @@ -1636,6 +1636,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-slot-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" diff --git a/avm/res/web/static-site/main.bicep b/avm/res/web/static-site/main.bicep index 2eab05ab58..f3387107ab 100644 --- a/avm/res/web/static-site/main.bicep +++ b/avm/res/web/static-site/main.bicep @@ -247,15 +247,10 @@ resource staticSite_roleAssignments 'Microsoft.Authorization/roleAssignments@202 module staticSite_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-staticSite-PrivateEndpoint-${index}' - scope: !empty(privateEndpoint.?resourceGroupResourceId) - ? resourceGroup( - split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], - split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] - ) - : resourceGroup( - split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], - split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] - ) + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(staticSite.id, '/'))}-${privateEndpoint.?service ?? 'staticSites'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true diff --git a/avm/res/web/static-site/main.json b/avm/res/web/static-site/main.json index 33de8d5d87..4ce780a6b8 100644 --- a/avm/res/web/static-site/main.json +++ b/avm/res/web/static-site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "7497371071073742378" + "version": "0.33.13.18514", + "templateHash": "5409964564427816888" }, "name": "Static Web Apps", "description": "This module deploys a Static Web App." @@ -701,8 +701,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8275628450081231495" + "version": "0.33.13.18514", + "templateHash": "6117646567314030149" }, "name": "Static Web App Site Linked Backends", "description": "This module deploys a Custom Function App into a Static Web App Site using the Linked Backends property." @@ -802,8 +802,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12709536246529127181" + "version": "0.33.13.18514", + "templateHash": "7998567469554918663" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config." @@ -896,8 +896,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12709536246529127181" + "version": "0.33.13.18514", + "templateHash": "7998567469554918663" }, "name": "Static Web App Site Config", "description": "This module deploys a Static Web App Site Config." @@ -991,8 +991,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2208155866464160058" + "version": "0.33.13.18514", + "templateHash": "3686358111815300788" }, "name": "Static Web App Site Custom Domains", "description": "This module deploys a Static Web App Site Custom Domain." @@ -1065,6 +1065,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-staticSite-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" From 4f9563e1c8f006d7bf7b55a3ca37a96ba087bd3b Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:56:06 +0100 Subject: [PATCH 24/31] feat: Update `avm/res/insights/metric-alert` to latest UDT (#4425) ## Description Update to latest UDT ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.metric-alert](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.insights.metric-alert.yml/badge.svg?branch=users%2Fkrbar%2FmetricAlrtUDT)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.insights.metric-alert.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/metric-alert/README.md | 9 ++ avm/res/insights/metric-alert/main.bicep | 30 +---- avm/res/insights/metric-alert/main.json | 158 ++++++++++++----------- 3 files changed, 94 insertions(+), 103 deletions(-) diff --git a/avm/res/insights/metric-alert/README.md b/avm/res/insights/metric-alert/README.md index 6f390fc6c6..7c91321ffc 100644 --- a/avm/res/insights/metric-alert/README.md +++ b/avm/res/insights/metric-alert/README.md @@ -8,6 +8,7 @@ This module deploys a Metric Alert. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -792,6 +793,14 @@ the period of time (in ISO 8601 duration format) that is used to monitor alert a | `resourceGroupName` | string | The resource group the metric alert was deployed into. | | `resourceId` | string | The resource ID of the metric alert. | +## 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.5.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/insights/metric-alert/main.bicep b/avm/res/insights/metric-alert/main.bicep index 5fd362a279..700a26304d 100644 --- a/avm/res/insights/metric-alert/main.bicep +++ b/avm/res/insights/metric-alert/main.bicep @@ -66,8 +66,9 @@ param actions array = [] @description('Required. Maps to the \'odata.type\' field. Specifies the type of the alert criteria.') param criteria alertType +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -180,36 +181,11 @@ output resourceId string = metricAlert.id @description('The location the resource was deployed into.') output location string = metricAlert.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? -}[]? - @discriminator('odata.type') type alertType = alertWebtestType | alertResourceType | alertMultiResourceType type alertResourceType = { diff --git a/avm/res/insights/metric-alert/main.json b/avm/res/insights/metric-alert/main.json index 0a13398ff1..22a05a4477 100644 --- a/avm/res/insights/metric-alert/main.json +++ b/avm/res/insights/metric-alert/main.json @@ -5,86 +5,13 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8398195355091608578" + "version": "0.33.93.31351", + "templateHash": "5542299104437497073" }, "name": "Metric Alerts", "description": "This module deploys a Metric Alert." }, "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 - }, "alertType": { "type": "object", "discriminator": { @@ -149,6 +76,81 @@ "type": "string" } } + }, + "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.5.1" + } + } } }, "parameters": { @@ -268,7 +270,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } From 72b15e4fa6c9d541519beef98d8d2f7112903e8a Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:56:35 +0100 Subject: [PATCH 25/31] feat: Update `avm/res/insights/webtest` to latest UDT (#4424) ## Description - update to latest UDT ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.webtest](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.webtest.yml/badge.svg?branch=users%2Fkrbar%2FwebtestUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.insights.webtest.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/webtest/README.md | 9 ++ avm/res/insights/webtest/main.bicep | 44 +------- avm/res/insights/webtest/main.json | 156 +++++++++++++++------------- 3 files changed, 97 insertions(+), 112 deletions(-) diff --git a/avm/res/insights/webtest/README.md b/avm/res/insights/webtest/README.md index f9f5197cd4..13f0ff3ee8 100644 --- a/avm/res/insights/webtest/README.md +++ b/avm/res/insights/webtest/README.md @@ -8,6 +8,7 @@ This module deploys a Web Test. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -775,6 +776,14 @@ The collection of validation rule properties. | `resourceGroupName` | string | The resource group the resource was deployed into. | | `resourceId` | string | The resource ID of the webtest. | +## 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.5.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/insights/webtest/main.bicep b/avm/res/insights/webtest/main.bicep index b8c0ad8b2a..e6563da00f 100644 --- a/avm/res/insights/webtest/main.bicep +++ b/avm/res/insights/webtest/main.bicep @@ -70,11 +70,13 @@ param validationRules object = {} @sys.description('Optional. An XML configuration specification for a WebTest.') param configuration object? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @sys.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.5.1' @sys.description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @sys.description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -185,41 +187,3 @@ output resourceGroupName string = resourceGroup().name @sys.description('The location the resource was deployed into.') output location string = webtest.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/insights/webtest/main.json b/avm/res/insights/webtest/main.json index f1d2d696dd..b144dea6d3 100644 --- a/avm/res/insights/webtest/main.json +++ b/avm/res/insights/webtest/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13500385176780435448" + "version": "0.33.93.31351", + "templateHash": "13066561667388649172" }, "name": "Web Tests", "description": "This module deploys a Web Test." @@ -35,80 +35,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.5.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.5.1" + } + } } }, "parameters": { @@ -243,12 +250,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." } From f77e8d7e1fa8a8a217aa56478d56b2c39fb3edb5 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:56:56 +0100 Subject: [PATCH 26/31] feat: Update `avm/res/event-grid/namespace` to latest UDT + output fix (#4423) ## Description - Update to latest UDTs - Fix of the private endpoint output / Update to the `privateEndpointOutputType` UDT ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.event-grid.namespace](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.event-grid.namespace.yml/badge.svg?branch=user%2Fkrbar%2FeventGridUDT)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.event-grid.namespace.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [x] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [X] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/event-grid/namespace/README.md | 59 +- .../namespace/ca-certificate/main.json | 4 +- .../namespace/client-group/main.json | 4 +- avm/res/event-grid/namespace/client/main.json | 4 +- avm/res/event-grid/namespace/main.bicep | 217 +- avm/res/event-grid/namespace/main.json | 1877 +++++++++-------- .../namespace/permission-binding/main.json | 4 +- .../namespace/topic-space/README.md | 9 + .../namespace/topic-space/main.bicep | 33 +- .../namespace/topic-space/main.json | 148 +- avm/res/event-grid/namespace/topic/README.md | 9 + .../topic/event-subscription/README.md | 9 + .../topic/event-subscription/main.bicep | 33 +- .../topic/event-subscription/main.json | 148 +- avm/res/event-grid/namespace/topic/main.bicep | 44 +- avm/res/event-grid/namespace/topic/main.json | 304 +-- avm/res/event-grid/namespace/version.json | 2 +- 17 files changed, 1436 insertions(+), 1472 deletions(-) diff --git a/avm/res/event-grid/namespace/README.md b/avm/res/event-grid/namespace/README.md index 0917cedaa2..26566a7f4d 100644 --- a/avm/res/event-grid/namespace/README.md +++ b/avm/res/event-grid/namespace/README.md @@ -2051,7 +2051,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. | @@ -2161,7 +2161,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 @@ -2258,7 +2258,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` @@ -2269,7 +2269,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 @@ -2322,22 +2322,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. | +| [`resourceGroupResourceId`](#parameter-privateendpointsresourcegroupresourceid) | string | The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. | | [`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` @@ -2350,7 +2350,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 @@ -2398,7 +2398,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 @@ -2416,7 +2416,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 @@ -2494,7 +2494,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 @@ -2554,7 +2554,7 @@ 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 @@ -2563,7 +2563,7 @@ The name of the private endpoint. ### 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 @@ -2574,7 +2574,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** @@ -2584,7 +2584,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 @@ -2601,7 +2601,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` @@ -2614,7 +2614,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 @@ -2639,9 +2639,9 @@ The name of the private link connection to create. - MinValue: 1 - MaxValue: 8 -### Parameter: `privateEndpoints.resourceGroupName` +### Parameter: `privateEndpoints.resourceGroupResourceId` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. - Required: No - Type: string @@ -2666,7 +2666,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** @@ -2776,7 +2776,7 @@ 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 @@ -2785,7 +2785,7 @@ The subresource to deploy the private endpoint for. For example "vault", "mysqlS ### 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 @@ -3018,7 +3018,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.10.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.5.1` | Remote reference | ## Data Collection diff --git a/avm/res/event-grid/namespace/ca-certificate/main.json b/avm/res/event-grid/namespace/ca-certificate/main.json index 30528042a1..2e6b66447f 100644 --- a/avm/res/event-grid/namespace/ca-certificate/main.json +++ b/avm/res/event-grid/namespace/ca-certificate/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13580243066591608578" + "version": "0.33.93.31351", + "templateHash": "5500161725034179010" }, "name": "Eventgrid Namespace CA Certificates", "description": "This module deploys an Eventgrid Namespace CA Certificate." diff --git a/avm/res/event-grid/namespace/client-group/main.json b/avm/res/event-grid/namespace/client-group/main.json index e42be83951..e15bfc0d69 100644 --- a/avm/res/event-grid/namespace/client-group/main.json +++ b/avm/res/event-grid/namespace/client-group/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "12442980068595434063" + "version": "0.33.93.31351", + "templateHash": "15034210943727152335" }, "name": "Eventgrid Namespace Client Groups", "description": "This module deploys an Eventgrid Namespace Client Group." diff --git a/avm/res/event-grid/namespace/client/main.json b/avm/res/event-grid/namespace/client/main.json index 09c397004f..7bc353b1c0 100644 --- a/avm/res/event-grid/namespace/client/main.json +++ b/avm/res/event-grid/namespace/client/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "13739700279576908785" + "version": "0.33.93.31351", + "templateHash": "310861179374860968" }, "name": "Eventgrid Namespace Clients", "description": "This module deploys an Eventgrid Namespace Client." diff --git a/avm/res/event-grid/namespace/main.bicep b/avm/res/event-grid/namespace/main.bicep index c4c74cbb8f..65518fdc16 100644 --- a/avm/res/event-grid/namespace/main.bicep +++ b/avm/res/event-grid/namespace/main.bicep @@ -15,8 +15,9 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The managed identity definition for this resource.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? @description('Optional. Allows the user to specify if the namespace resource supports zone-redundancy capability or not. If this property is not specified explicitly by the user, its default value depends on the following conditions: a. For Availability Zones enabled regions - The default property value would be true. b. For non-Availability Zones enabled regions - The default property value would be false. Once specified, this property cannot be updated.') param isZoneRedundant bool? @@ -32,17 +33,21 @@ param publicNetworkAccess string? @description('Optional. This can be used to restrict traffic from specific IPs instead of all IPs. Note: These are considered only if PublicNetworkAccess is enabled.') param inboundIpRules array? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @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.5.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.5.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[]? @allowed([ 'Enabled' @@ -267,10 +272,13 @@ resource namespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@202 } ] -module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ +module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-namespace-PrivateEndpoint-${index}' - scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') + scope: resourceGroup( + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[2], + split(privateEndpoint.?resourceGroupResourceId ?? privateEndpoint.?subnetResourceId, '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(namespace.id, '/'))}-${privateEndpoint.?service ?? 'topic'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -444,191 +452,42 @@ output systemAssignedMIPrincipalId string? = namespace.?identity.?principalId output topicResourceIds array = [ for index in range(0, length(topics ?? [])): namespace_topics[index].outputs.resourceId ] - @description('The private endpoints of the EventGrid Namespace.') -output privateEndpoints array = [ +output privateEndpoints privateEndpointOutputType[] = [ for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { name: namespace_privateEndpoints[i].outputs.name resourceId: namespace_privateEndpoints[i].outputs.resourceId - groupId: namespace_privateEndpoints[i].outputs.groupId - customDnsConfig: namespace_privateEndpoints[i].outputs.customDnsConfig - networkInterfaceIds: namespace_privateEndpoints[i].outputs.networkInterfaceIds + groupId: namespace_privateEndpoints[i].outputs.?groupId! + customDnsConfigs: namespace_privateEndpoints[i].outputs.customDnsConfigs + networkInterfaceResourceIds: namespace_privateEndpoints[i].outputs.networkInterfaceResourceIds } ] -// ================ // -// 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'? +// =============== // +// Definitions // +// =============== // - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? +@export() +@description('The type for a private endpoint output.') +type privateEndpointOutputType = { + @description('The name of the private endpoint.') + name: string -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? + @description('The resource ID of the private endpoint.') + resourceId: string - @description('Optional. The location to deploy the private endpoint to.') - location: string? + @description('The group Id for the private endpoint Group.') + groupId: 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.') + @description('The custom DNS configurations of the private endpoint.') customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') + @description('FQDN that resolves to private endpoint IP address.') fqdn: string? - @description('Required. A list of private IP addresses of the private endpoint.') + @description('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? -}[]? + @description('The IDs of the network interfaces associated with the private endpoint.') + networkInterfaceResourceIds: string[] +} diff --git a/avm/res/event-grid/namespace/main.json b/avm/res/event-grid/namespace/main.json index 26478a4e59..710d97699d 100644 --- a/avm/res/event-grid/namespace/main.json +++ b/avm/res/event-grid/namespace/main.json @@ -5,473 +5,582 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "13579387788541405387" + "version": "0.33.93.31351", + "templateHash": "4896325805194987111" }, "name": "Event Grid Namespaces", "description": "This module deploys an Event Grid Namespace." }, "definitions": { - "managedIdentitiesType": { + "privateEndpointOutputType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + } + }, + "groupId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "The group Id for the private endpoint Group." } }, - "userAssignedResourceIds": { + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "A list of private IP addresses of the private endpoint." + } + } + } + }, + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + } + }, + "networkInterfaceResourceIds": { "type": "array", "items": { "type": "string" }, - "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "The IDs of the network interfaces associated with the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true, + "description": "The type for a private endpoint output." + } }, - "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.5.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.5.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.5.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." - } + "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.5.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.5.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" }, - "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.5.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." + } + }, + "resourceGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used." + } + }, + "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." + } + } + }, + "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.5.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.5.1" + } + } } }, "parameters": { @@ -505,7 +614,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource." } @@ -538,24 +648,37 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "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." } }, "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." } @@ -813,7 +936,8 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-namespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -866,12 +990,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1277254088602407590" + "version": "0.33.13.18514", + "templateHash": "15954548978129725136" }, "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint." }, "definitions": { "privateDnsZoneGroupType": { @@ -893,80 +1016,118 @@ "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_export!": true } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "ipConfigurationType": { + "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." + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } } }, - "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\"." + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "privateLinkServiceConnectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "customDnsConfigType": { + "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_export!": true + } }, "lockType": { "type": "object", @@ -991,182 +1152,108 @@ } } }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } + "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.5.1" } - }, - "nullable": true + } }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." } - } - }, - "nullable": true - }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." } } }, - "nullable": true - }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" } - }, - "nullable": true + } }, - "privateDnsZoneGroupConfigType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group config." + "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\"." } }, - "privateDnsZoneResourceId": { + "conditionVersion": { "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, "metadata": { - "description": "Required. The resource id of the private DNS zone." + "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": "private-dns-zone-group/main.bicep" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } } @@ -1186,6 +1273,9 @@ }, "applicationSecurityGroupResourceIds": { "type": "array", + "items": { + "type": "string" + }, "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." @@ -1199,7 +1289,11 @@ } }, "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", + "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "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." } @@ -1220,12 +1314,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." } @@ -1238,21 +1337,33 @@ } }, "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty." } }, "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty." } }, "enableTelemetry": { @@ -1281,7 +1392,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": { @@ -1289,7 +1400,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.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1395,12 +1506,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5805178546717255803" + "version": "0.33.13.18514", + "templateHash": "5440815542537978381" }, "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint Private DNS Zone Group." }, "definitions": { "privateDnsZoneGroupConfigType": { @@ -1478,10 +1588,7 @@ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] + } } }, "outputs": { @@ -1543,26 +1650,33 @@ }, "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" }, - "customDnsConfig": { - "$ref": "#/definitions/customDnsConfigType", + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, "metadata": { "description": "The custom DNS configurations of the private endpoint." }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, - "networkInterfaceIds": { + "networkInterfaceResourceIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "The IDs of the network interfaces associated with the private endpoint." + "description": "The resource IDs of the network interfaces associated with the private endpoint." }, - "value": "[reference('privateEndpoint').networkInterfaces]" + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" }, "groupId": { "type": "string", + "nullable": true, "metadata": { "description": "The group Id for the private endpoint Group." }, - "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" } } } @@ -1614,8 +1728,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "15793214931835923034" + "version": "0.33.93.31351", + "templateHash": "3750609028879158720" }, "name": "Eventgrid Namespace Topics", "description": "This module deploys an Eventgrid Namespace Topic." @@ -1644,80 +1758,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.5.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.5.1" + } + } } }, "parameters": { @@ -1734,13 +1855,18 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } @@ -1896,85 +2022,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "17184382679184813652" + "version": "0.33.93.31351", + "templateHash": "2786410706674700781" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription." }, "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.5.1" + } + } } }, "parameters": { @@ -2018,7 +2146,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -2188,8 +2320,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16684000080098402376" + "version": "0.33.93.31351", + "templateHash": "5500161725034179010" }, "name": "Eventgrid Namespace CA Certificates", "description": "This module deploys an Eventgrid Namespace CA Certificate." @@ -2314,8 +2446,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "11246395673519136496" + "version": "0.33.93.31351", + "templateHash": "310861179374860968" }, "name": "Eventgrid Namespace Clients", "description": "This module deploys an Eventgrid Namespace Client." @@ -2476,8 +2608,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "15188233906898213813" + "version": "0.33.93.31351", + "templateHash": "15034210943727152335" }, "name": "Eventgrid Namespace Client Groups", "description": "This module deploys an Eventgrid Namespace Client Group." @@ -2593,85 +2725,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16328606795351825014" + "version": "0.33.93.31351", + "templateHash": "8680886384150003323" }, "name": "Eventgrid Namespace Topic Spaces", "description": "This module deploys an Eventgrid Namespace Topic Space." }, "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.5.1" + } + } } }, "parameters": { @@ -2702,7 +2836,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -2841,8 +2979,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2140320336515533966" + "version": "0.33.93.31351", + "templateHash": "17347618187908890991" }, "name": "Eventgrid Namespace Permissions Bindings", "description": "This module deploys an Eventgrid Namespace Permission Binding." @@ -2990,6 +3128,9 @@ }, "privateEndpoints": { "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointOutputType" + }, "metadata": { "description": "The private endpoints of the EventGrid Namespace." }, @@ -2998,9 +3139,9 @@ "input": { "name": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", "resourceId": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", - "groupId": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", - "customDnsConfig": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", - "networkInterfaceIds": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + "groupId": "[tryGet(tryGet(reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]", + "customDnsConfigs": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]", + "networkInterfaceResourceIds": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" } } } diff --git a/avm/res/event-grid/namespace/permission-binding/main.json b/avm/res/event-grid/namespace/permission-binding/main.json index c47335a6b8..5e0d007989 100644 --- a/avm/res/event-grid/namespace/permission-binding/main.json +++ b/avm/res/event-grid/namespace/permission-binding/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14853334081305348305" + "version": "0.33.93.31351", + "templateHash": "17347618187908890991" }, "name": "Eventgrid Namespace Permissions Bindings", "description": "This module deploys an Eventgrid Namespace Permission Binding." diff --git a/avm/res/event-grid/namespace/topic-space/README.md b/avm/res/event-grid/namespace/topic-space/README.md index 442efe3335..900dae5143 100644 --- a/avm/res/event-grid/namespace/topic-space/README.md +++ b/avm/res/event-grid/namespace/topic-space/README.md @@ -7,6 +7,7 @@ This module deploys an Eventgrid Namespace Topic Space. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -183,3 +184,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the Topic Space. | | `resourceGroupName` | string | The name of the resource group the Topic Space was created in. | | `resourceId` | string | The resource ID of the Topic Space. | + +## 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.5.1` | Remote reference | diff --git a/avm/res/event-grid/namespace/topic-space/main.bicep b/avm/res/event-grid/namespace/topic-space/main.bicep index 2020d61d90..6a58bf6bd3 100644 --- a/avm/res/event-grid/namespace/topic-space/main.bicep +++ b/avm/res/event-grid/namespace/topic-space/main.bicep @@ -14,8 +14,9 @@ param description string? @sys.description('Required. The topic filters in the Topic Space.') param topicTemplates array +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @sys.description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? var builtInRoleNames = { 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( @@ -119,33 +120,3 @@ output name string = topicSpace.name @sys.description('The name of the resource group the Topic Space was created in.') output resourceGroupName string = resourceGroup().name - -// ================ // -// Definitions // -// ================ // - -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/event-grid/namespace/topic-space/main.json b/avm/res/event-grid/namespace/topic-space/main.json index 3bfb89e09c..6ae1ca7d77 100644 --- a/avm/res/event-grid/namespace/topic-space/main.json +++ b/avm/res/event-grid/namespace/topic-space/main.json @@ -5,85 +5,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "936984304688301643" + "version": "0.33.93.31351", + "templateHash": "8680886384150003323" }, "name": "Eventgrid Namespace Topic Spaces", "description": "This module deploys an Eventgrid Namespace Topic Space." }, "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.5.1" + } + } } }, "parameters": { @@ -114,7 +116,11 @@ } }, "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/event-grid/namespace/topic/README.md b/avm/res/event-grid/namespace/topic/README.md index 8c64d5e05f..a8d8f52ac5 100644 --- a/avm/res/event-grid/namespace/topic/README.md +++ b/avm/res/event-grid/namespace/topic/README.md @@ -7,6 +7,7 @@ This module deploys an Eventgrid Namespace Topic. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -273,3 +274,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the Namespace Topic. | | `resourceGroupName` | string | The name of the resource group the Namespace Topic was created in. | | `resourceId` | string | The resource ID of the Namespace 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.5.1` | Remote reference | diff --git a/avm/res/event-grid/namespace/topic/event-subscription/README.md b/avm/res/event-grid/namespace/topic/event-subscription/README.md index 3efe652422..7270a86c44 100644 --- a/avm/res/event-grid/namespace/topic/event-subscription/README.md +++ b/avm/res/event-grid/namespace/topic/event-subscription/README.md @@ -7,6 +7,7 @@ This module deploys an Event Subscription. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -200,3 +201,11 @@ The principal type of the assigned principal ID. | `name` | string | The name of the Event Subscription. | | `resourceGroupName` | string | The name of the resource group the Event Subscription was created in. | | `resourceId` | string | The resource ID of the Event Subscription. | + +## 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.5.1` | Remote reference | diff --git a/avm/res/event-grid/namespace/topic/event-subscription/main.bicep b/avm/res/event-grid/namespace/topic/event-subscription/main.bicep index e75dc08187..dabe48cf5d 100644 --- a/avm/res/event-grid/namespace/topic/event-subscription/main.bicep +++ b/avm/res/event-grid/namespace/topic/event-subscription/main.bicep @@ -19,8 +19,9 @@ param eventDeliverySchema string = 'CloudEventSchemaV1_0' @description('Optional. Information about the filter for the Event Subscription.') param filtersConfiguration object? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? var builtInRoleNames = { 'Azure Resource Notifications System Topics Subscriber': subscriptionResourceId( @@ -135,33 +136,3 @@ output name string = eventSubscription.name @description('The name of the resource group the Event Subscription was created in.') output resourceGroupName string = resourceGroup().name - -// ================ // -// Definitions // -// ================ // - -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/event-grid/namespace/topic/event-subscription/main.json b/avm/res/event-grid/namespace/topic/event-subscription/main.json index e202dcea00..28b879c0d4 100644 --- a/avm/res/event-grid/namespace/topic/event-subscription/main.json +++ b/avm/res/event-grid/namespace/topic/event-subscription/main.json @@ -5,85 +5,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3328924279528017223" + "version": "0.33.93.31351", + "templateHash": "2786410706674700781" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription." }, "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.5.1" + } + } } }, "parameters": { @@ -127,7 +129,11 @@ } }, "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/event-grid/namespace/topic/main.bicep b/avm/res/event-grid/namespace/topic/main.bicep index 0962dfd472..9ecb200249 100644 --- a/avm/res/event-grid/namespace/topic/main.bicep +++ b/avm/res/event-grid/namespace/topic/main.bicep @@ -7,11 +7,13 @@ param namespaceName string @description('Required. Name of the topic.') param name string +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? @minValue(1) @maxValue(7) @@ -156,41 +158,3 @@ output name string = topic.name @description('The name of the resource group the Namespace Topic was created in.') output resourceGroupName string = resourceGroup().name - -// ================ // -// 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/event-grid/namespace/topic/main.json b/avm/res/event-grid/namespace/topic/main.json index be9052e144..ffffae5995 100644 --- a/avm/res/event-grid/namespace/topic/main.json +++ b/avm/res/event-grid/namespace/topic/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15715688844696636869" + "version": "0.33.93.31351", + "templateHash": "3750609028879158720" }, "name": "Eventgrid Namespace Topics", "description": "This module deploys an Eventgrid Namespace Topic." @@ -35,80 +35,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.5.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.5.1" + } + } } }, "parameters": { @@ -125,13 +132,18 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } @@ -287,85 +299,87 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3328924279528017223" + "version": "0.33.93.31351", + "templateHash": "2786410706674700781" }, "name": "Event Subscriptions", "description": "This module deploys an Event Subscription." }, "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.5.1" + } + } } }, "parameters": { @@ -409,7 +423,11 @@ } }, "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/event-grid/namespace/version.json b/avm/res/event-grid/namespace/version.json index ea4f3b6e67..21226dd43f 100644 --- a/avm/res/event-grid/namespace/version.json +++ b/avm/res/event-grid/namespace/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] From ec5d025928d23b5e27bc36ab903323769ba814ed Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:57:22 +0100 Subject: [PATCH 27/31] feat: Log Analytics Workspace updates - API versions and new properties (#4418) ## Description - update of the API versions - new parameter `features` of the type `workspaceFeaturesType` added - user defined type: `workspaceFeaturesType` - converted the former parameter `useResourcePermissions` into a property of the `features` parameter: `enableLogAccessUsingOnlyResourcePermissions` to align with the template reference - new properties of the `features` object implemented: - `disableLocalAuth` - `enableDataExport` - `immediatePurgeDataOn30Days` - update of the test cases to reflect new parameters ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.operational-insights.workspace](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.operational-insights.workspace.yml/badge.svg?branch=users%2Fkrbar%2FlawUpdate)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.operational-insights.workspace.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [x] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../operational-insights/workspace/README.md | 139 +++++++++++++----- .../workspace/data-export/README.md | 2 +- .../workspace/data-export/main.bicep | 4 +- .../workspace/data-export/main.json | 8 +- .../workspace/data-source/README.md | 2 +- .../workspace/data-source/main.bicep | 4 +- .../workspace/data-source/main.json | 8 +- .../workspace/linked-service/README.md | 2 +- .../workspace/linked-service/main.bicep | 4 +- .../workspace/linked-service/main.json | 8 +- .../linked-storage-account/README.md | 2 +- .../linked-storage-account/main.bicep | 4 +- .../linked-storage-account/main.json | 8 +- .../operational-insights/workspace/main.bicep | 27 +++- .../operational-insights/workspace/main.json | 116 ++++++++++----- .../workspace/saved-search/README.md | 2 +- .../workspace/saved-search/main.bicep | 4 +- .../workspace/saved-search/main.json | 8 +- .../storage-insight-config/README.md | 2 +- .../storage-insight-config/main.bicep | 4 +- .../storage-insight-config/main.json | 8 +- .../workspace/table/README.md | 2 +- .../workspace/table/main.bicep | 4 +- .../workspace/table/main.json | 8 +- .../workspace/tests/e2e/adv/main.test.bicep | 4 +- .../workspace/tests/e2e/max/main.test.bicep | 11 +- .../tests/e2e/waf-aligned/main.test.bicep | 8 +- .../workspace/version.json | 2 +- 28 files changed, 268 insertions(+), 137 deletions(-) diff --git a/avm/res/operational-insights/workspace/README.md b/avm/res/operational-insights/workspace/README.md index 8ea1cf3c5c..1d86fc74b0 100644 --- a/avm/res/operational-insights/workspace/README.md +++ b/avm/res/operational-insights/workspace/README.md @@ -18,14 +18,14 @@ This module deploys a Log Analytics Workspace. | `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.OperationalInsights/workspaces` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces) | -| `Microsoft.OperationalInsights/workspaces/dataExports` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataExports) | -| `Microsoft.OperationalInsights/workspaces/dataSources` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataSources) | -| `Microsoft.OperationalInsights/workspaces/linkedServices` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedServices) | -| `Microsoft.OperationalInsights/workspaces/linkedStorageAccounts` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedStorageAccounts) | -| `Microsoft.OperationalInsights/workspaces/savedSearches` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/savedSearches) | -| `Microsoft.OperationalInsights/workspaces/storageInsightConfigs` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/storageInsightConfigs) | -| `Microsoft.OperationalInsights/workspaces/tables` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces/tables) | +| `Microsoft.OperationalInsights/workspaces` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces) | +| `Microsoft.OperationalInsights/workspaces/dataExports` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/dataExports) | +| `Microsoft.OperationalInsights/workspaces/dataSources` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/dataSources) | +| `Microsoft.OperationalInsights/workspaces/linkedServices` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/linkedServices) | +| `Microsoft.OperationalInsights/workspaces/linkedStorageAccounts` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/linkedStorageAccounts) | +| `Microsoft.OperationalInsights/workspaces/savedSearches` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/savedSearches) | +| `Microsoft.OperationalInsights/workspaces/storageInsightConfigs` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/storageInsightConfigs) | +| `Microsoft.OperationalInsights/workspaces/tables` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-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/2024-03-01/onboardingStates) | @@ -198,6 +198,9 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = useThisWorkspace: true } ] + features: { + enableLogAccessUsingOnlyResourcePermissions: true + } gallerySolutions: [ { name: 'AzureAutomation(oiwadv001)' @@ -338,7 +341,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } - useResourcePermissions: true } } ``` @@ -508,6 +510,11 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = } ] }, + "features": { + "value": { + "enableLogAccessUsingOnlyResourcePermissions": true + } + }, "gallerySolutions": { "value": [ { @@ -669,9 +676,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "hidden-title": "This is visible in the resource name", "Role": "DeploymentValidation" } - }, - "useResourcePermissions": { - "value": true } } } @@ -830,6 +834,9 @@ param diagnosticSettings = [ useThisWorkspace: true } ] +param features = { + enableLogAccessUsingOnlyResourcePermissions: true +} param gallerySolutions = [ { name: 'AzureAutomation(oiwadv001)' @@ -970,7 +977,6 @@ param tags = { 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } -param useResourcePermissions = true ``` @@ -1161,6 +1167,12 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = workspaceResourceId: '' } ] + features: { + disableLocalAuth: true + enableDataExport: true + enableLogAccessUsingOnlyResourcePermissions: true + immediatePurgeDataOn30Days: true + } gallerySolutions: [ { name: 'AzureAutomation(oiwmax001)' @@ -1348,7 +1360,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } - useResourcePermissions: true } } ``` @@ -1481,6 +1492,14 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = } ] }, + "features": { + "value": { + "disableLocalAuth": true, + "enableDataExport": true, + "enableLogAccessUsingOnlyResourcePermissions": true, + "immediatePurgeDataOn30Days": true + } + }, "gallerySolutions": { "value": [ { @@ -1695,9 +1714,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "hidden-title": "This is visible in the resource name", "Role": "DeploymentValidation" } - }, - "useResourcePermissions": { - "value": true } } } @@ -1821,6 +1837,12 @@ param diagnosticSettings = [ workspaceResourceId: '' } ] +param features = { + disableLocalAuth: true + enableDataExport: true + enableLogAccessUsingOnlyResourcePermissions: true + immediatePurgeDataOn30Days: true +} param gallerySolutions = [ { name: 'AzureAutomation(oiwmax001)' @@ -2008,7 +2030,6 @@ param tags = { 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } -param useResourcePermissions = true ``` @@ -2129,6 +2150,9 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = workspaceResourceId: '' } ] + features: { + enableLogAccessUsingOnlyResourcePermissions: true + } gallerySolutions: [ { name: 'AzureAutomation(oiwwaf001)' @@ -2173,7 +2197,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } - useResourcePermissions: true } } ``` @@ -2300,6 +2323,11 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = } ] }, + "features": { + "value": { + "enableLogAccessUsingOnlyResourcePermissions": true + } + }, "gallerySolutions": { "value": [ { @@ -2361,9 +2389,6 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "hidden-title": "This is visible in the resource name", "Role": "DeploymentValidation" } - }, - "useResourcePermissions": { - "value": true } } } @@ -2481,6 +2506,9 @@ param diagnosticSettings = [ workspaceResourceId: '' } ] +param features = { + enableLogAccessUsingOnlyResourcePermissions: true +} param gallerySolutions = [ { name: 'AzureAutomation(oiwwaf001)' @@ -2525,7 +2553,6 @@ param tags = { 'hidden-title': 'This is visible in the resource name' Role: 'DeploymentValidation' } -param useResourcePermissions = true ``` @@ -2555,6 +2582,7 @@ param useResourcePermissions = true | [`dataSources`](#parameter-datasources) | array | LAW data sources to configure. | | [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`features`](#parameter-features) | object | The workspace features. | | [`forceCmkForQuery`](#parameter-forcecmkforquery) | bool | Indicates whether customer managed storage is mandatory for query management. | | [`gallerySolutions`](#parameter-gallerysolutions) | array | List of gallerySolutions to be created in the log analytics workspace. | | [`linkedServices`](#parameter-linkedservices) | array | List of services to be linked. | @@ -2571,7 +2599,6 @@ param useResourcePermissions = true | [`storageInsightsConfigs`](#parameter-storageinsightsconfigs) | array | List of storage accounts to be read by the workspace. | | [`tables`](#parameter-tables) | array | LAW custom tables to be deployed. | | [`tags`](#parameter-tags) | object | Tags of the resource. | -| [`useResourcePermissions`](#parameter-useresourcepermissions) | bool | Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions. | ### Parameter: `name` @@ -3078,6 +3105,60 @@ Enable/Disable usage telemetry for module. - MinValue: 0 - MaxValue: 730 +### Parameter: `features` + +The workspace features. + +- Required: No +- Type: object +- MinValue: 0 +- MaxValue: 730 + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`disableLocalAuth`](#parameter-featuresdisablelocalauth) | bool | Disable Non-EntraID based Auth. Default is true. | +| [`enableDataExport`](#parameter-featuresenabledataexport) | bool | Flag that indicate if data should be exported. | +| [`enableLogAccessUsingOnlyResourcePermissions`](#parameter-featuresenablelogaccessusingonlyresourcepermissions) | bool | Enable log access using only resource permissions. Default is false. | +| [`immediatePurgeDataOn30Days`](#parameter-featuresimmediatepurgedataon30days) | bool | Flag that describes if we want to remove the data after 30 days. | + +### Parameter: `features.disableLocalAuth` + +Disable Non-EntraID based Auth. Default is true. + +- Required: No +- Type: bool +- MinValue: 0 +- MaxValue: 730 + +### Parameter: `features.enableDataExport` + +Flag that indicate if data should be exported. + +- Required: No +- Type: bool +- MinValue: 0 +- MaxValue: 730 + +### Parameter: `features.enableLogAccessUsingOnlyResourcePermissions` + +Enable log access using only resource permissions. Default is false. + +- Required: No +- Type: bool +- MinValue: 0 +- MaxValue: 730 + +### Parameter: `features.immediatePurgeDataOn30Days` + +Flag that describes if we want to remove the data after 30 days. + +- Required: No +- Type: bool +- MinValue: 0 +- MaxValue: 730 + ### Parameter: `forceCmkForQuery` Indicates whether customer managed storage is mandatory for query management. @@ -4110,16 +4191,6 @@ Tags of the resource. - MinValue: 100 - MaxValue: 5000 -### Parameter: `useResourcePermissions` - -Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions. - -- Required: No -- Type: bool -- Default: `False` -- MinValue: 100 -- MaxValue: 5000 - ## Outputs | Output | Type | Description | diff --git a/avm/res/operational-insights/workspace/data-export/README.md b/avm/res/operational-insights/workspace/data-export/README.md index c4bbb39e28..f6438994a9 100644 --- a/avm/res/operational-insights/workspace/data-export/README.md +++ b/avm/res/operational-insights/workspace/data-export/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Data Export. | Resource Type | API Version | | :-- | :-- | -| `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/dataExports` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/dataExports) | ## Parameters diff --git a/avm/res/operational-insights/workspace/data-export/main.bicep b/avm/res/operational-insights/workspace/data-export/main.bicep index a1e4649b51..9c0bfa7426 100644 --- a/avm/res/operational-insights/workspace/data-export/main.bicep +++ b/avm/res/operational-insights/workspace/data-export/main.bicep @@ -27,11 +27,11 @@ param tableNames string[] // Deployments // // =============== // -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: workspaceName } -resource dataExport 'Microsoft.OperationalInsights/workspaces/dataExports@2020-08-01' = { +resource dataExport 'Microsoft.OperationalInsights/workspaces/dataExports@2023-09-01' = { parent: workspace name: name properties: { diff --git a/avm/res/operational-insights/workspace/data-export/main.json b/avm/res/operational-insights/workspace/data-export/main.json index 6b96dce5d9..4b77c88859 100644 --- a/avm/res/operational-insights/workspace/data-export/main.json +++ b/avm/res/operational-insights/workspace/data-export/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "14977926524140126314" + "version": "0.33.93.31351", + "templateHash": "15082251740316718256" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export." @@ -88,12 +88,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('workspaceName')]" }, "dataExport": { "type": "Microsoft.OperationalInsights/workspaces/dataExports", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", "properties": { "destination": "[parameters('destination')]", diff --git a/avm/res/operational-insights/workspace/data-source/README.md b/avm/res/operational-insights/workspace/data-source/README.md index 752f4583a9..5236dc5c9b 100644 --- a/avm/res/operational-insights/workspace/data-source/README.md +++ b/avm/res/operational-insights/workspace/data-source/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Data Source. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.OperationalInsights/workspaces/dataSources` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataSources) | +| `Microsoft.OperationalInsights/workspaces/dataSources` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/dataSources) | ## Parameters diff --git a/avm/res/operational-insights/workspace/data-source/main.bicep b/avm/res/operational-insights/workspace/data-source/main.bicep index 138d596782..aa62d35059 100644 --- a/avm/res/operational-insights/workspace/data-source/main.bicep +++ b/avm/res/operational-insights/workspace/data-source/main.bicep @@ -56,11 +56,11 @@ param syslogName string? @description('Optional. Severities to configure when kind is LinuxSyslog.') param syslogSeverities array = [] -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: logAnalyticsWorkspaceName } -resource dataSource 'Microsoft.OperationalInsights/workspaces/dataSources@2020-08-01' = { +resource dataSource 'Microsoft.OperationalInsights/workspaces/dataSources@2023-09-01' = { name: name parent: workspace kind: kind diff --git a/avm/res/operational-insights/workspace/data-source/main.json b/avm/res/operational-insights/workspace/data-source/main.json index 4f5dd5b680..1a6b16e915 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.32.4.45862", - "templateHash": "12082641043455308513" + "version": "0.33.93.31351", + "templateHash": "3186325409788999053" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source." @@ -130,12 +130,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "dataSource": { "type": "Microsoft.OperationalInsights/workspaces/dataSources", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "kind": "[parameters('kind')]", "tags": "[parameters('tags')]", diff --git a/avm/res/operational-insights/workspace/linked-service/README.md b/avm/res/operational-insights/workspace/linked-service/README.md index bca53b7a24..75c3ecb002 100644 --- a/avm/res/operational-insights/workspace/linked-service/README.md +++ b/avm/res/operational-insights/workspace/linked-service/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Linked Service. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.OperationalInsights/workspaces/linkedServices` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedServices) | +| `Microsoft.OperationalInsights/workspaces/linkedServices` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/linkedServices) | ## Parameters diff --git a/avm/res/operational-insights/workspace/linked-service/main.bicep b/avm/res/operational-insights/workspace/linked-service/main.bicep index 299750ed0a..4d2a2a86b7 100644 --- a/avm/res/operational-insights/workspace/linked-service/main.bicep +++ b/avm/res/operational-insights/workspace/linked-service/main.bicep @@ -16,11 +16,11 @@ param writeAccessResourceId string? @description('Optional. Tags to configure in the resource.') param tags object? -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: logAnalyticsWorkspaceName } -resource linkedService 'Microsoft.OperationalInsights/workspaces/linkedServices@2020-08-01' = { +resource linkedService 'Microsoft.OperationalInsights/workspaces/linkedServices@2023-09-01' = { name: name parent: workspace tags: tags diff --git a/avm/res/operational-insights/workspace/linked-service/main.json b/avm/res/operational-insights/workspace/linked-service/main.json index a7ece0d812..370cdfc4e9 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.32.4.45862", - "templateHash": "17762270878383445421" + "version": "0.33.93.31351", + "templateHash": "15202444687633091947" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service." @@ -50,12 +50,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "linkedService": { "type": "Microsoft.OperationalInsights/workspaces/linkedServices", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "tags": "[parameters('tags')]", "properties": { diff --git a/avm/res/operational-insights/workspace/linked-storage-account/README.md b/avm/res/operational-insights/workspace/linked-storage-account/README.md index a4604fdeea..85e4ef7b54 100644 --- a/avm/res/operational-insights/workspace/linked-storage-account/README.md +++ b/avm/res/operational-insights/workspace/linked-storage-account/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Linked Storage Account. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.OperationalInsights/workspaces/linkedStorageAccounts` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedStorageAccounts) | +| `Microsoft.OperationalInsights/workspaces/linkedStorageAccounts` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/linkedStorageAccounts) | ## Parameters diff --git a/avm/res/operational-insights/workspace/linked-storage-account/main.bicep b/avm/res/operational-insights/workspace/linked-storage-account/main.bicep index e77ca26f23..5fc0c473ed 100644 --- a/avm/res/operational-insights/workspace/linked-storage-account/main.bicep +++ b/avm/res/operational-insights/workspace/linked-storage-account/main.bicep @@ -17,11 +17,11 @@ param name string @description('Required. Linked storage accounts resources Ids.') param storageAccountIds string[] -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: logAnalyticsWorkspaceName } -resource linkedStorageAccount 'Microsoft.OperationalInsights/workspaces/linkedStorageAccounts@2020-08-01' = { +resource linkedStorageAccount 'Microsoft.OperationalInsights/workspaces/linkedStorageAccounts@2023-09-01' = { name: name parent: workspace properties: { 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 9ee99f5c48..603f7b3d2a 100644 --- a/avm/res/operational-insights/workspace/linked-storage-account/main.json +++ b/avm/res/operational-insights/workspace/linked-storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11986582912298301528" + "version": "0.33.93.31351", + "templateHash": "1489251440210164837" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account." @@ -45,12 +45,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "linkedStorageAccount": { "type": "Microsoft.OperationalInsights/workspaces/linkedStorageAccounts", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "properties": { "storageAccountIds": "[parameters('storageAccountIds')]" diff --git a/avm/res/operational-insights/workspace/main.bicep b/avm/res/operational-insights/workspace/main.bicep index edc8a326d2..d5b2e65c13 100644 --- a/avm/res/operational-insights/workspace/main.bicep +++ b/avm/res/operational-insights/workspace/main.bicep @@ -79,8 +79,8 @@ import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types @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 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 workspace features.') +param features workspaceFeaturesType? @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingType[]? @@ -185,14 +185,17 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT } } -resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = { location: location name: name tags: tags properties: { features: { searchVersion: 1 - enableLogAccessUsingOnlyResourcePermissions: useResourcePermissions + enableLogAccessUsingOnlyResourcePermissions: features.?enableLogAccessUsingOnlyResourcePermissions ?? false + disableLocalAuth: features.?disableLocalAuth ?? true + enableDataExport: features.?enableDataExport + immediatePurgeDataOn30Days: features.?immediatePurgeDataOn30Days } sku: { name: skuName @@ -648,3 +651,19 @@ type tableType = { @description('Optional. The role assignments for the table.') roleAssignments: roleAssignmentType[]? } + +@export() +@description('Features of the workspace.') +type workspaceFeaturesType = { + @description('Optional. Disable Non-EntraID based Auth. Default is true.') + disableLocalAuth: bool? + + @description('Optional. Flag that indicate if data should be exported.') + enableDataExport: bool? + + @description('Optional. Enable log access using only resource permissions. Default is false.') + enableLogAccessUsingOnlyResourcePermissions: bool? + + @description('Optional. Flag that describes if we want to remove the data after 30 days.') + immediatePurgeDataOn30Days: bool? +} diff --git a/avm/res/operational-insights/workspace/main.json b/avm/res/operational-insights/workspace/main.json index 1c6da556b6..4debca7e83 100644 --- a/avm/res/operational-insights/workspace/main.json +++ b/avm/res/operational-insights/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "4169914284504175169" + "version": "0.33.93.31351", + "templateHash": "2355986442928910370" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace." @@ -523,6 +523,43 @@ "description": "Properties of the custom table." } }, + "workspaceFeaturesType": { + "type": "object", + "properties": { + "disableLocalAuth": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Disable Non-EntraID based Auth. Default is true." + } + }, + "enableDataExport": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Flag that indicate if data should be exported." + } + }, + "enableLogAccessUsingOnlyResourcePermissions": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable log access using only resource permissions. Default is false." + } + }, + "immediatePurgeDataOn30Days": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Flag that describes if we want to remove the data after 30 days." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "Features of the workspace." + } + }, "_1.columnType": { "type": "object", "properties": { @@ -1070,11 +1107,11 @@ "description": "Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both." } }, - "useResourcePermissions": { - "type": "bool", - "defaultValue": false, + "features": { + "$ref": "#/definitions/workspaceFeaturesType", + "nullable": true, "metadata": { - "description": "Optional. Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions." + "description": "Optional. The workspace features." } }, "diagnosticSettings": { @@ -1173,14 +1210,17 @@ }, "logAnalyticsWorkspace": { "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { "features": { "searchVersion": 1, - "enableLogAccessUsingOnlyResourcePermissions": "[parameters('useResourcePermissions')]" + "enableLogAccessUsingOnlyResourcePermissions": "[coalesce(tryGet(parameters('features'), 'enableLogAccessUsingOnlyResourcePermissions'), false())]", + "disableLocalAuth": "[coalesce(tryGet(parameters('features'), 'disableLocalAuth'), true())]", + "enableDataExport": "[tryGet(parameters('features'), 'enableDataExport')]", + "immediatePurgeDataOn30Days": "[tryGet(parameters('features'), 'immediatePurgeDataOn30Days')]" }, "sku": { "name": "[parameters('skuName')]", @@ -1318,8 +1358,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "12715459455039038966" + "version": "0.33.93.31351", + "templateHash": "14024094214852981332" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config." @@ -1382,12 +1422,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "storageinsightconfig": { "type": "Microsoft.OperationalInsights/workspaces/storageInsightConfigs", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "tags": "[parameters('tags')]", "properties": { @@ -1463,8 +1503,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "17369295448584741847" + "version": "0.33.93.31351", + "templateHash": "15202444687633091947" }, "name": "Log Analytics Workspace Linked Services", "description": "This module deploys a Log Analytics Workspace Linked Service." @@ -1508,12 +1548,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "linkedService": { "type": "Microsoft.OperationalInsights/workspaces/linkedServices", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "tags": "[parameters('tags')]", "properties": { @@ -1582,8 +1622,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "4336014228195179628" + "version": "0.33.93.31351", + "templateHash": "1489251440210164837" }, "name": "Log Analytics Workspace Linked Storage Accounts", "description": "This module deploys a Log Analytics Workspace Linked Storage Account." @@ -1622,12 +1662,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "linkedStorageAccount": { "type": "Microsoft.OperationalInsights/workspaces/linkedStorageAccounts", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "properties": { "storageAccountIds": "[parameters('storageAccountIds')]" @@ -1715,8 +1755,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "10687105232425640835" + "version": "0.33.93.31351", + "templateHash": "14407663387414945082" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search." @@ -1792,12 +1832,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "savedSearch": { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "properties": { "etag": "[parameters('etag')]", @@ -1878,8 +1918,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "9265911316713795008" + "version": "0.33.93.31351", + "templateHash": "15082251740316718256" }, "name": "Log Analytics Workspace Data Exports", "description": "This module deploys a Log Analytics Workspace Data Export." @@ -1961,12 +2001,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('workspaceName')]" }, "dataExport": { "type": "Microsoft.OperationalInsights/workspaces/dataExports", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", "properties": { "destination": "[parameters('destination')]", @@ -2071,8 +2111,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16545899498885737893" + "version": "0.33.93.31351", + "templateHash": "3186325409788999053" }, "name": "Log Analytics Workspace Datasources", "description": "This module deploys a Log Analytics Workspace Data Source." @@ -2196,12 +2236,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "dataSource": { "type": "Microsoft.OperationalInsights/workspaces/dataSources", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "kind": "[parameters('kind')]", "tags": "[parameters('tags')]", @@ -2298,8 +2338,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "9728326644814973167" + "version": "0.33.93.31351", + "templateHash": "4329017759962267155" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table." @@ -2648,12 +2688,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('workspaceName')]" }, "table": { "type": "Microsoft.OperationalInsights/workspaces/tables", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", "properties": { "plan": "[parameters('plan')]", @@ -2942,7 +2982,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('logAnalyticsWorkspace', '2022-10-01', 'full').location]" + "value": "[reference('logAnalyticsWorkspace', '2023-09-01', 'full').location]" }, "systemAssignedMIPrincipalId": { "type": "string", @@ -2950,7 +2990,7 @@ "metadata": { "description": "The principal ID of the system assigned identity." }, - "value": "[tryGet(tryGet(reference('logAnalyticsWorkspace', '2022-10-01', 'full'), 'identity'), 'principalId')]" + "value": "[tryGet(tryGet(reference('logAnalyticsWorkspace', '2023-09-01', 'full'), 'identity'), 'principalId')]" } } } \ No newline at end of file diff --git a/avm/res/operational-insights/workspace/saved-search/README.md b/avm/res/operational-insights/workspace/saved-search/README.md index dfd853b645..697d8e95b1 100644 --- a/avm/res/operational-insights/workspace/saved-search/README.md +++ b/avm/res/operational-insights/workspace/saved-search/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Saved Search. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.OperationalInsights/workspaces/savedSearches` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/savedSearches) | +| `Microsoft.OperationalInsights/workspaces/savedSearches` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/savedSearches) | ## Parameters diff --git a/avm/res/operational-insights/workspace/saved-search/main.bicep b/avm/res/operational-insights/workspace/saved-search/main.bicep index e0b9512ed2..00a2de1f29 100644 --- a/avm/res/operational-insights/workspace/saved-search/main.bicep +++ b/avm/res/operational-insights/workspace/saved-search/main.bicep @@ -31,11 +31,11 @@ param version int? @description('Optional. The ETag of the saved search. To override an existing saved search, use "*" or specify the current Etag.') param etag string = '*' -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: logAnalyticsWorkspaceName } -resource savedSearch 'Microsoft.OperationalInsights/workspaces/savedSearches@2020-08-01' = { +resource savedSearch 'Microsoft.OperationalInsights/workspaces/savedSearches@2023-09-01' = { name: name parent: workspace //etag: etag // According to API, the variable should be here, but it doesn't work here. diff --git a/avm/res/operational-insights/workspace/saved-search/main.json b/avm/res/operational-insights/workspace/saved-search/main.json index 34553f9fe9..8d1d1cae6c 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.32.4.45862", - "templateHash": "9640551980154944642" + "version": "0.33.93.31351", + "templateHash": "14407663387414945082" }, "name": "Log Analytics Workspace Saved Searches", "description": "This module deploys a Log Analytics Workspace Saved Search." @@ -82,12 +82,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "savedSearch": { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "properties": { "etag": "[parameters('etag')]", diff --git a/avm/res/operational-insights/workspace/storage-insight-config/README.md b/avm/res/operational-insights/workspace/storage-insight-config/README.md index 8bd800b2d2..34afc44426 100644 --- a/avm/res/operational-insights/workspace/storage-insight-config/README.md +++ b/avm/res/operational-insights/workspace/storage-insight-config/README.md @@ -12,7 +12,7 @@ This module deploys a Log Analytics Workspace Storage Insight Config. | Resource Type | API Version | | :-- | :-- | -| `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/storageInsightConfigs` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/storageInsightConfigs) | ## Parameters diff --git a/avm/res/operational-insights/workspace/storage-insight-config/main.bicep b/avm/res/operational-insights/workspace/storage-insight-config/main.bicep index 4ec9de9a68..8cb9aabb2d 100644 --- a/avm/res/operational-insights/workspace/storage-insight-config/main.bicep +++ b/avm/res/operational-insights/workspace/storage-insight-config/main.bicep @@ -23,11 +23,11 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing name: last(split(storageAccountResourceId, '/'))! } -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: logAnalyticsWorkspaceName } -resource storageinsightconfig 'Microsoft.OperationalInsights/workspaces/storageInsightConfigs@2020-08-01' = { +resource storageinsightconfig 'Microsoft.OperationalInsights/workspaces/storageInsightConfigs@2023-09-01' = { name: name parent: workspace tags: tags 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 15f3aed89c..e80b09bf6b 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.32.4.45862", - "templateHash": "12148501849006788324" + "version": "0.33.93.31351", + "templateHash": "14024094214852981332" }, "name": "Log Analytics Workspace Storage Insight Configs", "description": "This module deploys a Log Analytics Workspace Storage Insight Config." @@ -69,12 +69,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('logAnalyticsWorkspaceName')]" }, "storageinsightconfig": { "type": "Microsoft.OperationalInsights/workspaces/storageInsightConfigs", - "apiVersion": "2020-08-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('logAnalyticsWorkspaceName'), parameters('name'))]", "tags": "[parameters('tags')]", "properties": { diff --git a/avm/res/operational-insights/workspace/table/README.md b/avm/res/operational-insights/workspace/table/README.md index c3cbc41a4c..32a0f782c8 100644 --- a/avm/res/operational-insights/workspace/table/README.md +++ b/avm/res/operational-insights/workspace/table/README.md @@ -14,7 +14,7 @@ This module deploys a Log Analytics Workspace Table. | 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.OperationalInsights/workspaces/tables` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces/tables) | +| `Microsoft.OperationalInsights/workspaces/tables` | [2023-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2023-09-01/workspaces/tables) | ## Parameters diff --git a/avm/res/operational-insights/workspace/table/main.bicep b/avm/res/operational-insights/workspace/table/main.bicep index ed15f51109..a886ffc8f3 100644 --- a/avm/res/operational-insights/workspace/table/main.bicep +++ b/avm/res/operational-insights/workspace/table/main.bicep @@ -86,11 +86,11 @@ var formattedRoleAssignments = [ // Deployments // // =============== // -resource workspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = { +resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { name: workspaceName } -resource table 'Microsoft.OperationalInsights/workspaces/tables@2022-10-01' = { +resource table 'Microsoft.OperationalInsights/workspaces/tables@2023-09-01' = { parent: workspace name: name properties: { diff --git a/avm/res/operational-insights/workspace/table/main.json b/avm/res/operational-insights/workspace/table/main.json index fa7999f6b9..fdf48788fd 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.32.4.45862", - "templateHash": "8047367069034259642" + "version": "0.33.93.31351", + "templateHash": "4329017759962267155" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table." @@ -355,12 +355,12 @@ "workspace": { "existing": true, "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[parameters('workspaceName')]" }, "table": { "type": "Microsoft.OperationalInsights/workspaces/tables", - "apiVersion": "2022-10-01", + "apiVersion": "2023-09-01", "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", "properties": { "plan": "[parameters('plan')]", 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 3a052d4bae..b16ae0b3b5 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 @@ -227,7 +227,9 @@ module testDeployment '../../../main.bicep' = [ ] } ] - useResourcePermissions: true + features: { + enableLogAccessUsingOnlyResourcePermissions: true + } tables: [ { name: 'CustomTableBasic_CL' 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 9b069e5ef2..e8f0c15a3e 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 @@ -173,6 +173,12 @@ module testDeployment '../../../main.bicep' = [ workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] + features: { + enableLogAccessUsingOnlyResourcePermissions: true + disableLocalAuth: true + enableDataExport: true + immediatePurgeDataOn30Days: true + } gallerySolutions: [ { name: 'AzureAutomation(${namePrefix}${serviceShort}001)' @@ -338,7 +344,6 @@ module testDeployment '../../../main.bicep' = [ ] } ] - useResourcePermissions: true tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -370,9 +375,5 @@ module testDeployment '../../../main.bicep' = [ } ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] 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 cf61ff31a9..5fa264c253 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 @@ -201,7 +201,9 @@ module testDeployment '../../../main.bicep' = [ ] } ] - useResourcePermissions: true + features: { + enableLogAccessUsingOnlyResourcePermissions: true + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -211,9 +213,5 @@ module testDeployment '../../../main.bicep' = [ systemAssigned: true } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] } ] diff --git a/avm/res/operational-insights/workspace/version.json b/avm/res/operational-insights/workspace/version.json index a830c3d961..91ffa760bf 100644 --- a/avm/res/operational-insights/workspace/version.json +++ b/avm/res/operational-insights/workspace/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.10", + "version": "0.11", "pathFilters": [ "./main.json" ] From 7161c9bc446f0551b42dc46d7c3054e45b9e8fa4 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 11 Feb 2025 11:09:38 +0100 Subject: [PATCH 28/31] feat: VPN-Site - Updated to latest UDTs (#4336) ## Description Updated to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.network.vpn-site](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.vpn-site.yml/badge.svg?branch=users%2Falsehr%2FvpnSite&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.vpn-site.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/network/vpn-site/README.md | 28 +--- avm/res/network/vpn-site/main.bicep | 44 +---- avm/res/network/vpn-site/main.json | 156 ++++++++++-------- .../tests/e2e/defaults/main.test.bicep | 4 - .../vpn-site/tests/e2e/max/main.test.bicep | 3 - .../tests/e2e/waf-aligned/main.test.bicep | 7 - 6 files changed, 97 insertions(+), 145 deletions(-) diff --git a/avm/res/network/vpn-site/README.md b/avm/res/network/vpn-site/README.md index 92f162d8a7..6d3a7c3542 100644 --- a/avm/res/network/vpn-site/README.md +++ b/avm/res/network/vpn-site/README.md @@ -8,6 +8,7 @@ This module deploys a VPN Site. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -52,7 +53,6 @@ module vpnSite 'br/public:avm/res/network/vpn-site:' = { '10.0.0.0/16' ] ipAddress: '1.2.3.4' - location: '' } } ``` @@ -84,9 +84,6 @@ module vpnSite 'br/public:avm/res/network/vpn-site:' = { }, "ipAddress": { "value": "1.2.3.4" - }, - "location": { - "value": "" } } } @@ -110,7 +107,6 @@ param addressPrefixes = [ '10.0.0.0/16' ] param ipAddress = '1.2.3.4' -param location = '' ``` @@ -422,10 +418,6 @@ module vpnSite 'br/public:avm/res/network/vpn-site:' = { linkSpeedInMbps: 0 } location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } o365Policy: { breakOutCategories: { allow: true @@ -500,12 +492,6 @@ module vpnSite 'br/public:avm/res/network/vpn-site:' = { "location": { "value": "" }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, "o365Policy": { "value": { "breakOutCategories": { @@ -576,10 +562,6 @@ param deviceProperties = { linkSpeedInMbps: 0 } param location = '' -param lock = { - kind: 'CanNotDelete' - name: 'myCustomLockName' -} o365Policy: { breakOutCategories: { allow: true @@ -900,6 +882,14 @@ List of all VPN site links. | `resourceGroupName` | string | The resource group the VPN site was deployed into. | | `resourceId` | string | The resource ID of the VPN site. | +## 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.5.1` | Remote reference | + ## Notes ### Parameter Usage `deviceProperties` diff --git a/avm/res/network/vpn-site/main.bicep b/avm/res/network/vpn-site/main.bicep index a203cf4305..3e2cfa9d5b 100644 --- a/avm/res/network/vpn-site/main.bicep +++ b/avm/res/network/vpn-site/main.bicep @@ -37,11 +37,13 @@ param enableTelemetry bool = true @description('Optional. List of all VPN site links.') param vpnSiteLinks array = [] +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.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.5.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') @@ -154,41 +156,3 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = vpnSite.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/network/vpn-site/main.json b/avm/res/network/vpn-site/main.json index af1125d3f1..bff519c79d 100644 --- a/avm/res/network/vpn-site/main.json +++ b/avm/res/network/vpn-site/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11509955796069504943" + "version": "0.33.13.18514", + "templateHash": "18110577874087174381" }, "name": "VPN Sites", "description": "This module deploys a VPN Site." @@ -35,80 +35,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.5.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.5.1" + } + } } }, "parameters": { @@ -196,12 +203,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/network/vpn-site/tests/e2e/defaults/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep index 4818c6fb53..7a2b075e26 100644 --- a/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/defaults/main.test.bicep @@ -50,7 +50,6 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - location: resourceLocation name: '${namePrefix}-${serviceShort}' virtualWanId: nestedDependencies.outputs.virtualWWANResourceId addressPrefixes: [ @@ -58,8 +57,5 @@ module testDeployment '../../../main.bicep' = [ ] ipAddress: '1.2.3.4' } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep index c3969e70e5..00e33360e0 100644 --- a/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/max/main.test.bicep @@ -126,8 +126,5 @@ module testDeployment '../../../main.bicep' = [ } ] } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep index 5f582100f2..36d8fa73cd 100644 --- a/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/vpn-site/tests/e2e/waf-aligned/main.test.bicep @@ -54,10 +54,6 @@ module testDeployment '../../../main.bicep' = [ location: resourceLocation name: '${namePrefix}-${serviceShort}' virtualWanId: nestedDependencies.outputs.virtualWWANResourceId - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } tags: { 'hidden-title': 'This is visible in the resource name' tagA: 'valueA' @@ -104,8 +100,5 @@ module testDeployment '../../../main.bicep' = [ } } } - dependsOn: [ - nestedDependencies - ] } ] From 3bd48fc892d9d63a97a177baabfd7e918b48447b Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 11 Feb 2025 11:12:38 +0100 Subject: [PATCH 29/31] feat: VPN-GW - Update to latest UDTs (#4338) ## Description Update to latest UDTs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.network.vpn-gateway](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.vpn-gateway.yml/badge.svg?branch=users%2Falsehr%2FvpnGWUDT&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.vpn-gateway.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/network/vpn-gateway/README.md | 31 ++++++------------ avm/res/network/vpn-gateway/main.bicep | 21 +++--------- avm/res/network/vpn-gateway/main.json | 32 +++++++++++++------ .../network/vpn-gateway/nat-rule/main.json | 4 +-- .../tests/e2e/defaults/main.test.bicep | 4 --- .../vpn-gateway/tests/e2e/max/main.test.bicep | 3 -- .../tests/e2e/waf-aligned/main.test.bicep | 7 ---- .../vpn-gateway/vpn-connection/main.json | 4 +-- 8 files changed, 40 insertions(+), 66 deletions(-) diff --git a/avm/res/network/vpn-gateway/README.md b/avm/res/network/vpn-gateway/README.md index 26eec74c1c..5bc27b3de4 100644 --- a/avm/res/network/vpn-gateway/README.md +++ b/avm/res/network/vpn-gateway/README.md @@ -8,6 +8,7 @@ This module deploys a VPN Gateway. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Notes](#Notes) - [Data Collection](#Data-Collection) @@ -48,8 +49,6 @@ module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { // Required parameters name: 'vpngmin001' virtualHubResourceId: '' - // Non-required parameters - location: '' } } ``` @@ -72,10 +71,6 @@ module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { }, "virtualHubResourceId": { "value": "" - }, - // Non-required parameters - "location": { - "value": "" } } } @@ -94,8 +89,6 @@ using 'br/public:avm/res/network/vpn-gateway:' // Required parameters param name = 'vpngmin001' param virtualHubResourceId = '' -// Non-required parameters -param location = '' ``` @@ -334,10 +327,6 @@ module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { peerWeight: 0 } location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } natRules: [ { externalMappings: [ @@ -407,12 +396,6 @@ module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { "location": { "value": "" }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, "natRules": { "value": [ { @@ -478,10 +461,6 @@ param bgpSettings = { peerWeight: 0 } param location = '' -param lock = { - kind: 'CanNotDelete' - name: 'myCustomLockName' -} param natRules = [ { externalMappings: [ @@ -677,6 +656,14 @@ The scale unit for this VPN gateway. | `resourceGroupName` | string | The name of the resource group the VPN gateway was deployed into. | | `resourceId` | string | The resource ID of the VPN gateway. | +## 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.5.1` | Remote reference | + ## Notes ### Parameter Usage: `bgpSettings` diff --git a/avm/res/network/vpn-gateway/main.bicep b/avm/res/network/vpn-gateway/main.bicep index 35b521cb72..763c83c387 100644 --- a/avm/res/network/vpn-gateway/main.bicep +++ b/avm/res/network/vpn-gateway/main.bicep @@ -31,8 +31,9 @@ param vpnGatewayScaleUnit int = 2 @description('Optional. Tags of the resource.') param tags object? +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.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 @@ -116,9 +117,9 @@ module vpnGateway_natRules 'nat-rule/main.bicep' = [ params: { name: natRule.name vpnGatewayName: vpnGateway.name - externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] - internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] - ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' + externalMappings: natRule.?externalMappings + internalMappings: natRule.?internalMappings + ipConfigurationId: natRule.?ipConfigurationId mode: natRule.?mode type: natRule.?type } @@ -160,15 +161,3 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = vpnGateway.location - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? diff --git a/avm/res/network/vpn-gateway/main.json b/avm/res/network/vpn-gateway/main.json index 11f4bc8d97..1a963a7743 100644 --- a/avm/res/network/vpn-gateway/main.json +++ b/avm/res/network/vpn-gateway/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8342635055821923062" + "version": "0.33.13.18514", + "templateHash": "13461484235913765557" }, "name": "VPN Gateways", "description": "This module deploys a VPN Gateway." @@ -35,7 +35,12 @@ } } }, - "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.5.1" + } + } } }, "parameters": { @@ -109,6 +114,7 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } @@ -217,9 +223,15 @@ "vpnGatewayName": { "value": "[parameters('name')]" }, - "externalMappings": "[if(contains(parameters('natRules')[copyIndex()], 'externalMappings'), createObject('value', parameters('natRules')[copyIndex()].externalMappings), createObject('value', createArray()))]", - "internalMappings": "[if(contains(parameters('natRules')[copyIndex()], 'internalMappings'), createObject('value', parameters('natRules')[copyIndex()].internalMappings), createObject('value', createArray()))]", - "ipConfigurationId": "[if(contains(parameters('natRules')[copyIndex()], 'ipConfigurationId'), createObject('value', parameters('natRules')[copyIndex()].ipConfigurationId), createObject('value', ''))]", + "externalMappings": { + "value": "[tryGet(parameters('natRules')[copyIndex()], 'externalMappings')]" + }, + "internalMappings": { + "value": "[tryGet(parameters('natRules')[copyIndex()], 'internalMappings')]" + }, + "ipConfigurationId": { + "value": "[tryGet(parameters('natRules')[copyIndex()], 'ipConfigurationId')]" + }, "mode": { "value": "[tryGet(parameters('natRules')[copyIndex()], 'mode')]" }, @@ -234,8 +246,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1228645763554247410" + "version": "0.33.13.18514", + "templateHash": "11380942489395706225" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule." @@ -415,8 +427,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5835591601144574416" + "version": "0.33.13.18514", + "templateHash": "6343342170986309278" }, "name": "VPN Gateway VPN Connections", "description": "This module deploys a VPN Gateway VPN Connection." diff --git a/avm/res/network/vpn-gateway/nat-rule/main.json b/avm/res/network/vpn-gateway/nat-rule/main.json index 4cc344b05e..dd5e884bea 100644 --- a/avm/res/network/vpn-gateway/nat-rule/main.json +++ b/avm/res/network/vpn-gateway/nat-rule/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "1228645763554247410" + "version": "0.33.13.18514", + "templateHash": "11380942489395706225" }, "name": "VPN Gateway NAT Rules", "description": "This module deploys a VPN Gateway NAT Rule." diff --git a/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep index 8debc2b069..1106c5eabd 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep @@ -51,12 +51,8 @@ module testDeployment '../../../main.bicep' = [ scope: resourceGroup name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { - location: resourceLocation name: '${namePrefix}${serviceShort}001' virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep index b51c76ee82..5f0696cb07 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep @@ -99,8 +99,5 @@ module testDeployment '../../../main.bicep' = [ Role: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep index 5213b39d56..db69482e5f 100644 --- a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -72,10 +72,6 @@ module testDeployment '../../../main.bicep' = [ routingWeight: 0 } ] - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } natRules: [ { externalMappings: [ @@ -99,8 +95,5 @@ module testDeployment '../../../main.bicep' = [ Role: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.json b/avm/res/network/vpn-gateway/vpn-connection/main.json index d0a68d2f0c..f345f8e837 100644 --- a/avm/res/network/vpn-gateway/vpn-connection/main.json +++ b/avm/res/network/vpn-gateway/vpn-connection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "5835591601144574416" + "version": "0.33.13.18514", + "templateHash": "6343342170986309278" }, "name": "VPN Gateway VPN Connections", "description": "This module deploys a VPN Gateway VPN Connection." From c891d2384c26888af3753ddb5439a82e42123d74 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Tue, 11 Feb 2025 11:23:31 +0100 Subject: [PATCH 30/31] feat: PowerBI - Update to latest UDT (#4307) ## Description Update to latest UDT ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.power-bi-dedicated.capacity](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.power-bi-dedicated.capacity.yml/badge.svg?branch=users%2Falsehr%2Fpowerbi&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.power-bi-dedicated.capacity.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/power-bi-dedicated/capacity/README.md | 46 ++-- .../power-bi-dedicated/capacity/main.bicep | 60 ++--- avm/res/power-bi-dedicated/capacity/main.json | 216 ++++++++++-------- .../tests/e2e/defaults/main.test.bicep | 1 - .../tests/e2e/waf-aligned/main.test.bicep | 5 - .../power-bi-dedicated/capacity/version.json | 4 +- 6 files changed, 160 insertions(+), 172 deletions(-) diff --git a/avm/res/power-bi-dedicated/capacity/README.md b/avm/res/power-bi-dedicated/capacity/README.md index c2f1039aab..3ea5083542 100644 --- a/avm/res/power-bi-dedicated/capacity/README.md +++ b/avm/res/power-bi-dedicated/capacity/README.md @@ -8,6 +8,7 @@ This module deploys a Power BI Dedicated Capacity. - [Usage examples](#Usage-examples) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) - [Data Collection](#Data-Collection) ## Resource Types @@ -51,8 +52,6 @@ module capacity 'br/public:avm/res/power-bi-dedicated/capacity:' = { sku: { capacity: 1 } - // Non-required parameters - location: '' } } ``` @@ -82,10 +81,6 @@ module capacity 'br/public:avm/res/power-bi-dedicated/capacity:' = { "value": { "capacity": 1 } - }, - // Non-required parameters - "location": { - "value": "" } } } @@ -109,8 +104,6 @@ param name = 'pbdcapmin001' param sku = { capacity: 1 } -// Non-required parameters -param location = '' ``` @@ -319,11 +312,6 @@ module capacity 'br/public:avm/res/power-bi-dedicated/capacity:' = { capacity: 1 } // Non-required parameters - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -360,15 +348,6 @@ module capacity 'br/public:avm/res/power-bi-dedicated/capacity:' = { } }, // Non-required parameters - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, "tags": { "value": { "Environment": "Non-Prod", @@ -399,11 +378,6 @@ param sku = { capacity: 1 } // Non-required parameters -param location = '' -param lock = { - kind: 'CanNotDelete' - name: 'myCustomLockName' -} param tags = { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -588,7 +562,7 @@ Array of role assignments to create. - `'Log Analytics Reader'` - `'Owner'` - `'Reader'` - - `'Role Based Access Control Administrator (Preview)'` + - `'Role Based Access Control Administrator'` - `'User Access Administrator'` **Required parameters** @@ -606,6 +580,7 @@ Array of role assignments to create. | [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`name`](#parameter-roleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | | [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | ### Parameter: `roleAssignments.principalId` @@ -656,6 +631,13 @@ The description of the role assignment. - Required: No - Type: string +### Parameter: `roleAssignments.name` + +The name (as GUID) of the role assignment. If not provided, a GUID will be generated. + +- Required: No +- Type: string + ### Parameter: `roleAssignments.principalType` The principal type of the assigned principal ID. @@ -689,6 +671,14 @@ Tags of the resource. | `resourceGroupName` | string | The name of the resource group the PowerBi Embedded was created in. | | `resourceId` | string | The resource ID of the PowerBi Embedded instance. | +## 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.5.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/power-bi-dedicated/capacity/main.bicep b/avm/res/power-bi-dedicated/capacity/main.bicep index 8b120ea109..dc803bc979 100644 --- a/avm/res/power-bi-dedicated/capacity/main.bicep +++ b/avm/res/power-bi-dedicated/capacity/main.bicep @@ -26,11 +26,13 @@ param members array @description('Optional. Mode of the resource.') param mode string = 'Gen2' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.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.5.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') @@ -44,7 +46,7 @@ var builtInRoleNames = { ) 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( + 'Role Based Access Control Administrator': subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' ) @@ -54,6 +56,17 @@ var builtInRoleNames = { ) } +var formattedRoleAssignments = [ + for (roleAssignment, index) in (roleAssignments ?? []): union(roleAssignment, { + roleDefinitionId: builtInRoleNames[?roleAssignment.roleDefinitionIdOrName] ?? (contains( + roleAssignment.roleDefinitionIdOrName, + '/providers/Microsoft.Authorization/roleDefinitions/' + ) + ? roleAssignment.roleDefinitionIdOrName + : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName)) + }) +] + #disable-next-line no-deployments-resources resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { name: '46d3xbcp.res.powerbidedicated-capacity.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' @@ -102,14 +115,10 @@ resource capacity_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(l } resource capacity_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ - for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(capacity.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + for (roleAssignment, index) in (formattedRoleAssignments ?? []): { + name: roleAssignment.?name ?? guid(capacity.id, roleAssignment.principalId, roleAssignment.roleDefinitionId) properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) - ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] - : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') - ? roleAssignment.roleDefinitionIdOrName - : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + roleDefinitionId: roleAssignment.roleDefinitionId principalId: roleAssignment.principalId description: roleAssignment.?description principalType: roleAssignment.?principalType @@ -137,37 +146,6 @@ output location string = capacity.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('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 skuTpe = { @description('Optional. The name of the SKU.') name: ('A1' | 'A2' | 'A3' | 'A4' | 'A5' | 'A6')? diff --git a/avm/res/power-bi-dedicated/capacity/main.json b/avm/res/power-bi-dedicated/capacity/main.json index 25a23c68e6..5fd245d210 100644 --- a/avm/res/power-bi-dedicated/capacity/main.json +++ b/avm/res/power-bi-dedicated/capacity/main.json @@ -5,13 +5,51 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "11211810764868342264" + "version": "0.33.13.18514", + "templateHash": "16622551566318541504" }, "name": "Power BI Dedicated Capacities", "description": "This module deploys a Power BI Dedicated Capacity." }, "definitions": { + "skuTpe": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "A6" + ], + "nullable": true, + "metadata": { + "description": "Optional. The name of the SKU." + } + }, + "capacity": { + "type": "int", + "metadata": { + "description": "Required. The capacity of the SKU." + } + }, + "tier": { + "type": "string", + "allowedValues": [ + "AutoPremiumHost", + "PBIE_Azure", + "Premium" + ], + "nullable": true, + "metadata": { + "description": "Optional. The tier of the SKU." + } + } + } + }, "lockType": { "type": "object", "properties": { @@ -35,110 +73,86 @@ } } }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } + "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.5.1" } - }, - "nullable": true + } }, - "skuTpe": { + "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": [ - "A1", - "A2", - "A3", - "A4", - "A5", - "A6" + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" ], "nullable": true, "metadata": { - "description": "Optional. The name of the SKU." + "description": "Optional. The principal type of the assigned principal ID." } }, - "capacity": { - "type": "int", + "description": { + "type": "string", + "nullable": true, "metadata": { - "description": "Required. The capacity of the SKU." + "description": "Optional. The description of the role assignment." } }, - "tier": { + "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": [ - "AutoPremiumHost", - "PBIE_Azure", - "Premium" + "2.0" ], "nullable": true, "metadata": { - "description": "Optional. The tier of the SKU." + "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.5.1" + } } } }, @@ -195,25 +209,37 @@ }, "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." } } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", "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')]" } }, @@ -273,20 +299,20 @@ "capacity_roleAssignments": { "copy": { "name": "capacity_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", "scope": "[format('Microsoft.PowerBIDedicated/capacities/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.PowerBIDedicated/capacities', 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.PowerBIDedicated/capacities', 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": [ "capacity" diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep index 515de7d0b9..6507af13cf 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/defaults/main.test.bicep @@ -57,7 +57,6 @@ module testDeployment '../../../main.bicep' = [ members: [ nestedDependencies.outputs.managedIdentityPrincipalId ] - location: resourceLocation } } ] diff --git a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep index 06d353ab48..89fe36f4c7 100644 --- a/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/power-bi-dedicated/capacity/tests/e2e/waf-aligned/main.test.bicep @@ -51,14 +51,9 @@ module testDeployment '../../../main.bicep' = [ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: resourceLocation sku: { capacity: 1 } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } members: [ nestedDependencies.outputs.managedIdentityPrincipalId ] diff --git a/avm/res/power-bi-dedicated/capacity/version.json b/avm/res/power-bi-dedicated/capacity/version.json index 8def869ede..729ac87673 100644 --- a/avm/res/power-bi-dedicated/capacity/version.json +++ b/avm/res/power-bi-dedicated/capacity/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 From 20a2949b3c6925707f70bba43ca5d527daa3be54 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Wed, 12 Feb 2025 00:19:24 +0100 Subject: [PATCH 31/31] feat: Container-App - Removed workaround for secrets (#4426) ## Description Replaced workaround of `secureList` with UDT ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.app.container-app](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.app.container-app.yml/badge.svg?branch=users%2Falsehr%2FdeprecateSecureListContainerApp&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.app.container-app.yml) | ## Type of Change - [x] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation --- avm/res/app/container-app/README.md | 156 +++++++++--------- avm/res/app/container-app/main.bicep | 50 ++++-- avm/res/app/container-app/main.json | 49 +++++- .../tests/e2e/defaults/main.test.bicep | 4 - .../tests/e2e/disable-ingress/main.test.bicep | 1 - .../tests/e2e/max/main.test.bicep | 26 ++- .../tests/e2e/vnet/main.test.bicep | 1 - .../tests/e2e/waf-aligned/main.test.bicep | 8 - avm/res/app/container-app/version.json | 2 +- 9 files changed, 168 insertions(+), 129 deletions(-) diff --git a/avm/res/app/container-app/README.md b/avm/res/app/container-app/README.md index 8fb2b89697..e07c1f8f48 100644 --- a/avm/res/app/container-app/README.md +++ b/avm/res/app/container-app/README.md @@ -59,8 +59,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { ] environmentResourceId: '' name: 'acamin001' - // Non-required parameters - location: '' } } ``` @@ -95,10 +93,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { }, "name": { "value": "acamin001" - }, - // Non-required parameters - "location": { - "value": "" } } } @@ -127,8 +121,6 @@ param containers = [ ] param environmentResourceId = '' param name = 'acamin001' -// Non-required parameters -param location = '' ``` @@ -162,7 +154,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { name: 'acapriv001' // Non-required parameters disableIngress: true - location: '' } } ``` @@ -201,9 +192,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { // Non-required parameters "disableIngress": { "value": true - }, - "location": { - "value": "" } } } @@ -234,7 +222,6 @@ param environmentResourceId = '' param name = 'acapriv001' // Non-required parameters param disableIngress = true -param location = '' ``` @@ -335,19 +322,17 @@ module containerApp 'br/public:avm/res/app/container-app:' = { ] } } - secrets: { - secureList: [ - { - name: 'containerappstoredsecret' - value: '' - } - { - identity: '' - keyVaultUrl: '' - name: 'keyvaultstoredsecret' - } - ] - } + secrets: [ + { + name: 'containerappstoredsecret' + value: '' + } + { + identity: '' + keyVaultUrl: '' + name: 'keyvaultstoredsecret' + } + ] tags: { Env: 'test' 'hidden-title': 'This is visible in the resource name' @@ -467,19 +452,17 @@ module containerApp 'br/public:avm/res/app/container-app:' = { } }, "secrets": { - "value": { - "secureList": [ - { - "name": "containerappstoredsecret", - "value": "" - }, - { - "identity": "", - "keyVaultUrl": "", - "name": "keyvaultstoredsecret" - } - ] - } + "value": [ + { + "name": "containerappstoredsecret", + "value": "" + }, + { + "identity": "", + "keyVaultUrl": "", + "name": "keyvaultstoredsecret" + } + ] }, "tags": { "value": { @@ -583,19 +566,17 @@ param runtime = { ] } } -param secrets = { - secureList: [ - { - name: 'containerappstoredsecret' - value: '' - } - { - identity: '' - keyVaultUrl: '' - name: 'keyvaultstoredsecret' - } - ] -} +param secrets = [ + { + name: 'containerappstoredsecret' + value: '' + } + { + identity: '' + keyVaultUrl: '' + name: 'keyvaultstoredsecret' + } +] param tags = { Env: 'test' 'hidden-title': 'This is visible in the resource name' @@ -643,7 +624,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { ingressExternal: false ingressTargetPort: 80 ingressTransport: 'tcp' - location: '' } } ``` @@ -700,9 +680,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { }, "ingressTransport": { "value": "tcp" - }, - "location": { - "value": "" } } } @@ -743,7 +720,6 @@ param ingressAllowInsecure = false param ingressExternal = false param ingressTargetPort = 80 param ingressTransport = 'tcp' -param location = '' ``` @@ -795,11 +771,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { // Non-required parameters ingressAllowInsecure: false ingressExternal: false - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } managedIdentities: { userAssignedResourceIds: [ '' @@ -868,15 +839,6 @@ module containerApp 'br/public:avm/res/app/container-app:' = { "ingressExternal": { "value": false }, - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, "managedIdentities": { "value": { "userAssignedResourceIds": [ @@ -937,11 +899,6 @@ param name = 'acawaf001' // Non-required parameters param ingressAllowInsecure = false param ingressExternal = false -param location = '' -param lock = { - kind: 'CanNotDelete' - name: 'myCustomLockName' -} param managedIdentities = { userAssignedResourceIds: [ '' @@ -997,7 +954,7 @@ param tags = { | [`scaleMaxReplicas`](#parameter-scalemaxreplicas) | int | Maximum number of container replicas. Defaults to 10 if not set. | | [`scaleMinReplicas`](#parameter-scaleminreplicas) | int | Minimum number of container replicas. Defaults to 3 if not set. | | [`scaleRules`](#parameter-scalerules) | array | Scaling rules. | -| [`secrets`](#parameter-secrets) | secureObject | The secrets of the Container App. | +| [`secrets`](#parameter-secrets) | array | The secrets of the Container App. | | [`service`](#parameter-service) | object | Dev ContainerApp service type. | | [`serviceBinds`](#parameter-servicebinds) | array | List of container app services bound to the app. | | [`stickySessionsAffinity`](#parameter-stickysessionsaffinity) | string | Bool indicating if the Container App should enable session affinity. | @@ -1970,8 +1927,49 @@ Scaling rules. The secrets of the Container App. - Required: No -- Type: secureObject -- Default: `{}` +- Type: array + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyVaultUrl`](#parameter-secretskeyvaulturl) | string | Azure Key Vault URL pointing to the secret referenced by the Container App Job. Required if `value` is null. | +| [`value`](#parameter-secretsvalue) | securestring | The secret value, if not fetched from Key Vault. Required if `keyVaultUrl` is not null. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`identity`](#parameter-secretsidentity) | string | Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity. | +| [`name`](#parameter-secretsname) | string | The name of the secret. | + +### Parameter: `secrets.keyVaultUrl` + +Azure Key Vault URL pointing to the secret referenced by the Container App Job. Required if `value` is null. + +- Required: No +- Type: string + +### Parameter: `secrets.value` + +The secret value, if not fetched from Key Vault. Required if `keyVaultUrl` is not null. + +- Required: No +- Type: securestring + +### Parameter: `secrets.identity` + +Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity. + +- Required: No +- Type: string + +### Parameter: `secrets.name` + +The name of the secret. + +- Required: No +- Type: string ### Parameter: `service` diff --git a/avm/res/app/container-app/main.bicep b/avm/res/app/container-app/main.bicep index 201ba8da5b..3f6e2fcd83 100644 --- a/avm/res/app/container-app/main.bicep +++ b/avm/res/app/container-app/main.bicep @@ -135,8 +135,7 @@ param containers containerType[] param initContainersTemplate array = [] @description('Optional. The secrets of the Container App.') -@secure() -param secrets object = {} +param secrets secretType[]? @description('Optional. User friendly suffix that is appended to the revision name.') param revisionSuffix string = '' @@ -147,8 +146,6 @@ param volumes array = [] @description('Optional. Workload profile name to pin for container app execution.') param workloadProfileName string = '' -var secretList = !empty(secrets) ? secrets.secureList : [] - var formattedUserAssignedIdentities = reduce( map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, @@ -261,20 +258,24 @@ resource containerApp 'Microsoft.App/containerApps@2024-10-02-preview' = { service: (includeAddOns && !empty(service)) ? service : null maxInactiveRevisions: maxInactiveRevisions registries: !empty(registries) ? registries : null - secrets: secretList + secrets: secrets runtime: { - dotnet: !empty(runtime.?dotnet) ? { - autoConfigureDataProtection: runtime.?dotnet.autoConfigureDataProtection - } : null - java: !empty(runtime.?java) ? { - enableMetrics: runtime.?java.enableMetrics - javaAgent: { - enabled: runtime.?java.enableJavaAgent - logging: { - loggerSettings: runtime.?java.?loggerSettings + dotnet: !empty(runtime.?dotnet) + ? { + autoConfigureDataProtection: runtime.?dotnet.autoConfigureDataProtection } - } - } : null + : null + java: !empty(runtime.?java) + ? { + enableMetrics: runtime.?java.enableMetrics + javaAgent: { + enabled: runtime.?java.enableJavaAgent + logging: { + loggerSettings: runtime.?java.?loggerSettings + } + } + } + : null } } template: { @@ -544,3 +545,20 @@ type runtimeType = { }[]? }? }? + +@export() +@description('The type for a secret.') +type secretType = { + @description('Optional. Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity.') + identity: string? + + @description('Conditional. Azure Key Vault URL pointing to the secret referenced by the Container App Job. Required if `value` is null.') + keyVaultUrl: string? + + @description('Optional. The name of the secret.') + name: string? + + @description('Conditional. The secret value, if not fetched from Key Vault. Required if `keyVaultUrl` is not null.') + @secure() + value: string? +} diff --git a/avm/res/app/container-app/main.json b/avm/res/app/container-app/main.json index 2cf631732b..88cf79e58a 100644 --- a/avm/res/app/container-app/main.json +++ b/avm/res/app/container-app/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.13.18514", - "templateHash": "10576304396294722473" + "templateHash": "7075159430454310469" }, "name": "Container Apps", "description": "This module deploys a Container App." @@ -512,6 +512,43 @@ "description": "Optional. App runtime configuration for the Container App." } }, + "secretType": { + "type": "object", + "properties": { + "identity": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of a managed identity to authenticate with Azure Key Vault, or System to use a system-assigned identity." + } + }, + "keyVaultUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. Azure Key Vault URL pointing to the secret referenced by the Container App Job. Required if `value` is null." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the secret." + } + }, + "value": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Conditional. The secret value, if not fetched from Key Vault. Required if `keyVaultUrl` is not null." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a secret." + } + }, "lockType": { "type": "object", "properties": { @@ -934,8 +971,11 @@ } }, "secrets": { - "type": "secureObject", - "defaultValue": {}, + "type": "array", + "items": { + "$ref": "#/definitions/secretType" + }, + "nullable": true, "metadata": { "description": "Optional. The secrets of the Container App." } @@ -970,7 +1010,6 @@ "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)))))]" } ], - "secretList": "[if(not(empty(parameters('secrets'))), parameters('secrets').secureList, createArray())]", "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", "builtInRoleNames": { @@ -1019,7 +1058,7 @@ "service": "[if(and(parameters('includeAddOns'), not(empty(parameters('service')))), parameters('service'), null())]", "maxInactiveRevisions": "[parameters('maxInactiveRevisions')]", "registries": "[if(not(empty(parameters('registries'))), parameters('registries'), null())]", - "secrets": "[variables('secretList')]", + "secrets": "[parameters('secrets')]", "runtime": { "dotnet": "[if(not(empty(tryGet(parameters('runtime'), 'dotnet'))), createObject('autoConfigureDataProtection', tryGet(parameters('runtime'), 'dotnet', 'autoConfigureDataProtection')), null())]", "java": "[if(not(empty(tryGet(parameters('runtime'), 'java'))), createObject('enableMetrics', tryGet(parameters('runtime'), 'java', 'enableMetrics'), 'javaAgent', createObject('enabled', tryGet(parameters('runtime'), 'java', 'enableJavaAgent'), 'logging', createObject('loggerSettings', tryGet(tryGet(parameters('runtime'), 'java'), 'loggerSettings')))), null())]" diff --git a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep index c534e47cb3..bfc7880b4a 100644 --- a/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/defaults/main.test.bicep @@ -52,7 +52,6 @@ module testDeployment '../../../main.bicep' = [ params: { name: '${namePrefix}${serviceShort}001' environmentResourceId: nestedDependencies.outputs.managedEnvironmentResourceId - location: resourceLocation containers: [ { name: 'simple-hello-world-container' @@ -65,8 +64,5 @@ module testDeployment '../../../main.bicep' = [ } ] } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/app/container-app/tests/e2e/disable-ingress/main.test.bicep b/avm/res/app/container-app/tests/e2e/disable-ingress/main.test.bicep index ffe04696b9..694d877bab 100644 --- a/avm/res/app/container-app/tests/e2e/disable-ingress/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/disable-ingress/main.test.bicep @@ -52,7 +52,6 @@ module testDeployment '../../../main.bicep' = [ params: { name: '${namePrefix}${serviceShort}001' environmentResourceId: nestedDependencies.outputs.managedEnvironmentResourceId - location: resourceLocation disableIngress: true containers: [ { diff --git a/avm/res/app/container-app/tests/e2e/max/main.test.bicep b/avm/res/app/container-app/tests/e2e/max/main.test.bicep index b2b2d87fd4..67a05f663f 100644 --- a/avm/res/app/container-app/tests/e2e/max/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/max/main.test.bicep @@ -95,19 +95,17 @@ module testDeployment '../../../main.bicep' = [ nestedDependencies.outputs.managedIdentityResourceId ] } - secrets: { - secureList: [ - { - name: 'containerappstoredsecret' - value: myCustomContainerAppSecret - } - { - name: 'keyvaultstoredsecret' - keyVaultUrl: nestedDependencies.outputs.keyVaultSecretURI - identity: nestedDependencies.outputs.managedIdentityResourceId - } - ] - } + secrets: [ + { + name: 'containerappstoredsecret' + value: myCustomContainerAppSecret + } + { + name: 'keyvaultstoredsecret' + keyVaultUrl: nestedDependencies.outputs.keyVaultSecretURI + identity: nestedDependencies.outputs.managedIdentityResourceId + } + ] containers: [ { name: 'simple-hello-world-container' @@ -150,7 +148,7 @@ module testDeployment '../../../main.bicep' = [ java: { enableJavaAgent: true enableMetrics: false - loggerSettings:[ + loggerSettings: [ { level: 'info' logger: 'test' diff --git a/avm/res/app/container-app/tests/e2e/vnet/main.test.bicep b/avm/res/app/container-app/tests/e2e/vnet/main.test.bicep index 3c34893f8c..dd909e518e 100644 --- a/avm/res/app/container-app/tests/e2e/vnet/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/vnet/main.test.bicep @@ -52,7 +52,6 @@ module testDeployment '../../../main.bicep' = [ params: { name: '${namePrefix}${serviceShort}001' environmentResourceId: nestedDependencies.outputs.managedEnvironmentResourceId - location: resourceLocation ingressExternal: false ingressTransport: 'tcp' ingressAllowInsecure: false diff --git a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep index a25b1ec60d..0bbe6788df 100644 --- a/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/app/container-app/tests/e2e/waf-aligned/main.test.bicep @@ -59,11 +59,6 @@ module testDeployment '../../../main.bicep' = [ Env: 'test' } environmentResourceId: nestedDependencies.outputs.managedEnvironmentResourceId - location: resourceLocation - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } managedIdentities: { userAssignedResourceIds: [ nestedDependencies.outputs.managedIdentityResourceId @@ -98,8 +93,5 @@ module testDeployment '../../../main.bicep' = [ } ] } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/app/container-app/version.json b/avm/res/app/container-app/version.json index 15548e8d1a..7466cbe674 100644 --- a/avm/res/app/container-app/version.json +++ b/avm/res/app/container-app/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.12", + "version": "0.13", "pathFilters": [ "./main.json" ]