Repository: Azure/bicep-registry-modules
Pull request #5117: fix: SQL-Server - Fixed minor bug of key rotation
Author: login: AlexanderSehr
Labels: name: Type: AVM :a: :v: :m:
description: This is an AVM related issue
name: Needs: Module Owner :mega:
description: This module needs an owner to develop or maintain it
name: Type: Bug :bug:
description: Something isn't working
name: Class: Resource Module :package:
description: This is a resource module
Created: 2025-04-27T07:45:38Z | Merged: 2025-04-27T11:44:23Z

## Description

The way the SQL server resource handels CMK is a bit different from most other services. 
- The Key itself **must** be provided with a key version (i.e., it is **not** optional)
- However, auto-rotation is still possible, but it uses a dedicated resource for it called 'encryption-protector'. That, in turn, allows you to configure CMK rotation

Other
- Cleaned up CMK test (unused key).
- Added descriptions to types
- Aligned zonal implementation with AVM spec
- Aligned several properties with AVM specs
- Aligned some of the type names

Test: 
1. Deploy default deployment
   ![image](https://github.com/user-attachments/assets/90141d6b-fe5a-4c61-ab1a-b697155e7845)
2. Generated a new version of the `keyServerEncryptionKey` and waited for a short time
3. Result
   ![image](https://github.com/user-attachments/assets/54b20a6c-6a59-4453-a5a6-84be70122dc1)
 

## Pipeline Reference

<!-- Insert your Pipeline Status Badge below -->

| Pipeline |
| -------- |
|    [![avm.res.sql.server](https://github.com/AlexanderSehr/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml/badge.svg?branch=users%2Falsehr%2FsqlServerKeyFix&event=workflow_dispatch)](https://github.com/AlexanderSehr/bicep-registry-modules/actions/workflows/avm.res.sql.server.yml)      |

## Type of Change

<!-- Use the checkboxes [x] on the options that are relevant. -->

- [ ] 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



Diff:
diff --git a/avm/res/sql/server/README.md b/avm/res/sql/server/README.md
index 776a55f4864..b404df70ced 100644
--- a/avm/res/sql/server/README.md
+++ b/avm/res/sql/server/README.md
@@ -277,7 +277,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         '<managedIdentityResourceId>'
       ]
     }
-    primaryUserAssignedIdentityId: '<primaryUserAssignedIdentityId>'
+    primaryUserAssignedIdentityResourceId: '<primaryUserAssignedIdentityResourceId>'
   }
 }
 ```
@@ -324,8 +324,8 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         ]
       }
     },
-    "primaryUserAssignedIdentityId": {
-      "value": "<primaryUserAssignedIdentityId>"
+    "primaryUserAssignedIdentityResourceId": {
+      "value": "<primaryUserAssignedIdentityResourceId>"
     }
   }
 }
@@ -363,7 +363,7 @@ param managedIdentities = {
     '<managedIdentityResourceId>'
   ]
 }
-param primaryUserAssignedIdentityId = '<primaryUserAssignedIdentityId>'
+param primaryUserAssignedIdentityResourceId = '<primaryUserAssignedIdentityResourceId>'
 ```
 
 </details>
@@ -463,10 +463,12 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     administratorLoginPassword: '<administratorLoginPassword>'
     elasticPools: [
       {
+        availabilityZone: -1
         name: 'ssep-ep-001'
         zoneRedundant: false
       }
       {
+        availabilityZone: -1
         name: 'ssep-ep-002'
         perDatabaseSettings: {
           maxCapacity: '4'
@@ -511,10 +513,12 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "elasticPools": {
       "value": [
         {
+          "availabilityZone": -1,
           "name": "ssep-ep-001",
           "zoneRedundant": false
         },
         {
+          "availabilityZone": -1,
           "name": "ssep-ep-002",
           "perDatabaseSettings": {
             "maxCapacity": "4",
@@ -553,10 +557,12 @@ param administratorLogin = 'adminUserName'
 param administratorLoginPassword = '<administratorLoginPassword>'
 param elasticPools = [
   {
+    availabilityZone: -1
     name: 'ssep-ep-001'
     zoneRedundant: false
   }
   {
+    availabilityZone: -1
     name: 'ssep-ep-002'
     perDatabaseSettings: {
       maxCapacity: '4'
@@ -596,6 +602,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     administratorLoginPassword: '<administratorLoginPassword>'
     databases: [
       {
+        availabilityZone: -1
         maxSizeBytes: 2147483648
         name: 'ssfog-db1'
         sku: {
@@ -605,6 +612,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         zoneRedundant: false
       }
       {
+        availabilityZone: -1
         maxSizeBytes: 2147483648
         name: 'ssfog-db2'
         sku: {
@@ -615,6 +623,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         zoneRedundant: false
       }
       {
+        availabilityZone: -1
         maxSizeBytes: 2147483648
         name: 'ssfog-db3'
         sku: {
@@ -701,6 +710,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "databases": {
       "value": [
         {
+          "availabilityZone": -1,
           "maxSizeBytes": 2147483648,
           "name": "ssfog-db1",
           "sku": {
@@ -710,6 +720,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
           "zoneRedundant": false
         },
         {
+          "availabilityZone": -1,
           "maxSizeBytes": 2147483648,
           "name": "ssfog-db2",
           "sku": {
@@ -720,6 +731,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
           "zoneRedundant": false
         },
         {
+          "availabilityZone": -1,
           "maxSizeBytes": 2147483648,
           "name": "ssfog-db3",
           "sku": {
@@ -802,6 +814,7 @@ param administratorLogin = 'adminUserName'
 param administratorLoginPassword = '<administratorLoginPassword>'
 param databases = [
   {
+    availabilityZone: -1
     maxSizeBytes: 2147483648
     name: 'ssfog-db1'
     sku: {
@@ -811,6 +824,7 @@ param databases = [
     zoneRedundant: false
   }
   {
+    availabilityZone: -1
     maxSizeBytes: 2147483648
     name: 'ssfog-db2'
     sku: {
@@ -821,6 +835,7 @@ param databases = [
     zoneRedundant: false
   }
   {
+    availabilityZone: -1
     maxSizeBytes: 2147483648
     name: 'ssfog-db3'
     sku: {
@@ -902,6 +917,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     administratorLoginPassword: '<administratorLoginPassword>'
     databases: [
       {
+        availabilityZone: -1
         name: 'myDatabase'
         zoneRedundant: false
       }
@@ -942,6 +958,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "databases": {
       "value": [
         {
+          "availabilityZone": -1,
           "name": "myDatabase",
           "zoneRedundant": false
         }
@@ -978,6 +995,7 @@ param administratorLogin = 'adminUserName'
 param administratorLoginPassword = '<administratorLoginPassword>'
 param databases = [
   {
+    availabilityZone: -1
     name: 'myDatabase'
     zoneRedundant: false
   }
@@ -1019,6 +1037,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     }
     databases: [
       {
+        availabilityZone: -1
         backupLongTermRetentionPolicy: {
           monthlyRetention: 'P6M'
         }
@@ -1053,6 +1072,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     ]
     elasticPools: [
       {
+        availabilityZone: -1
         name: 'sqlsmax-ep-001'
         sku: {
           capacity: 10
@@ -1079,7 +1099,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         '<serverIdentityResourceId>'
       ]
     }
-    primaryUserAssignedIdentityId: '<primaryUserAssignedIdentityId>'
+    primaryUserAssignedIdentityResourceId: '<primaryUserAssignedIdentityResourceId>'
     privateEndpoints: [
       {
         privateDnsZoneGroup: {
@@ -1143,7 +1163,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
       {
         ignoreMissingVnetServiceEndpoint: true
         name: 'newVnetRule1'
-        virtualNetworkSubnetId: '<virtualNetworkSubnetId>'
+        virtualNetworkSubnetResourceId: '<virtualNetworkSubnetResourceId>'
       }
     ]
     vulnerabilityAssessmentsObj: {
@@ -1196,6 +1216,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "databases": {
       "value": [
         {
+          "availabilityZone": -1,
           "backupLongTermRetentionPolicy": {
             "monthlyRetention": "P6M"
           },
@@ -1232,6 +1253,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "elasticPools": {
       "value": [
         {
+          "availabilityZone": -1,
           "name": "sqlsmax-ep-001",
           "sku": {
             "capacity": 10,
@@ -1267,8 +1289,8 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         ]
       }
     },
-    "primaryUserAssignedIdentityId": {
-      "value": "<primaryUserAssignedIdentityId>"
+    "primaryUserAssignedIdentityResourceId": {
+      "value": "<primaryUserAssignedIdentityResourceId>"
     },
     "privateEndpoints": {
       "value": [
@@ -1344,7 +1366,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         {
           "ignoreMissingVnetServiceEndpoint": true,
           "name": "newVnetRule1",
-          "virtualNetworkSubnetId": "<virtualNetworkSubnetId>"
+          "virtualNetworkSubnetResourceId": "<virtualNetworkSubnetResourceId>"
         }
       ]
     },
@@ -1389,6 +1411,7 @@ param customerManagedKey = {
 }
 param databases = [
   {
+    availabilityZone: -1
     backupLongTermRetentionPolicy: {
       monthlyRetention: 'P6M'
     }
@@ -1423,6 +1446,7 @@ param databases = [
 ]
 param elasticPools = [
   {
+    availabilityZone: -1
     name: 'sqlsmax-ep-001'
     sku: {
       capacity: 10
@@ -1449,7 +1473,7 @@ param managedIdentities = {
     '<serverIdentityResourceId>'
   ]
 }
-param primaryUserAssignedIdentityId = '<primaryUserAssignedIdentityId>'
+param primaryUserAssignedIdentityResourceId = '<primaryUserAssignedIdentityResourceId>'
 param privateEndpoints = [
   {
     privateDnsZoneGroup: {
@@ -1513,7 +1537,7 @@ param virtualNetworkRules = [
   {
     ignoreMissingVnetServiceEndpoint: true
     name: 'newVnetRule1'
-    virtualNetworkSubnetId: '<virtualNetworkSubnetId>'
+    virtualNetworkSubnetResourceId: '<virtualNetworkSubnetResourceId>'
   }
 ]
 param vulnerabilityAssessmentsObj = {
@@ -1553,6 +1577,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     administratorLoginPassword: '<administratorLoginPassword>'
     databases: [
       {
+        availabilityZone: -1
         createMode: 'Secondary'
         maxSizeBytes: 2147483648
         name: '<name>'
@@ -1600,6 +1625,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "databases": {
       "value": [
         {
+          "availabilityZone": -1,
           "createMode": "Secondary",
           "maxSizeBytes": 2147483648,
           "name": "<name>",
@@ -1643,6 +1669,7 @@ param administratorLogin = 'adminUserName'
 param administratorLoginPassword = '<administratorLoginPassword>'
 param databases = [
   {
+    availabilityZone: -1
     createMode: 'Secondary'
     maxSizeBytes: 2147483648
     name: '<name>'
@@ -1690,7 +1717,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         '<managedIdentityResourceId>'
       ]
     }
-    primaryUserAssignedIdentityId: '<primaryUserAssignedIdentityId>'
+    primaryUserAssignedIdentityResourceId: '<primaryUserAssignedIdentityResourceId>'
     securityAlertPolicies: [
       {
         emailAccountAdmins: true
@@ -1755,8 +1782,8 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         ]
       }
     },
-    "primaryUserAssignedIdentityId": {
-      "value": "<primaryUserAssignedIdentityId>"
+    "primaryUserAssignedIdentityResourceId": {
+      "value": "<primaryUserAssignedIdentityResourceId>"
     },
     "securityAlertPolicies": {
       "value": [
@@ -1816,7 +1843,7 @@ param managedIdentities = {
     '<managedIdentityResourceId>'
   ]
 }
-param primaryUserAssignedIdentityId = '<primaryUserAssignedIdentityId>'
+param primaryUserAssignedIdentityResourceId = '<primaryUserAssignedIdentityResourceId>'
 param securityAlertPolicies = [
   {
     emailAccountAdmins: true
@@ -1879,6 +1906,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     }
     databases: [
       {
+        availabilityZone: 1
         backupLongTermRetentionPolicy: {
           monthlyRetention: 'P6M'
         }
@@ -1908,6 +1936,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     ]
     elasticPools: [
       {
+        availabilityZone: -1
         maintenanceConfigurationId: '<maintenanceConfigurationId>'
         name: 'sqlswaf-ep-001'
         sku: {
@@ -1924,7 +1953,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         '<managedIdentityResourceId>'
       ]
     }
-    primaryUserAssignedIdentityId: '<primaryUserAssignedIdentityId>'
+    primaryUserAssignedIdentityResourceId: '<primaryUserAssignedIdentityResourceId>'
     privateEndpoints: [
       {
         privateDnsZoneGroup: {
@@ -1960,7 +1989,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
       {
         ignoreMissingVnetServiceEndpoint: true
         name: 'newVnetRule1'
-        virtualNetworkSubnetId: '<virtualNetworkSubnetId>'
+        virtualNetworkSubnetResourceId: '<virtualNetworkSubnetResourceId>'
       }
     ]
     vulnerabilityAssessmentsObj: {
@@ -2016,6 +2045,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "databases": {
       "value": [
         {
+          "availabilityZone": 1,
           "backupLongTermRetentionPolicy": {
             "monthlyRetention": "P6M"
           },
@@ -2047,6 +2077,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
     "elasticPools": {
       "value": [
         {
+          "availabilityZone": -1,
           "maintenanceConfigurationId": "<maintenanceConfigurationId>",
           "name": "sqlswaf-ep-001",
           "sku": {
@@ -2068,8 +2099,8 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         ]
       }
     },
-    "primaryUserAssignedIdentityId": {
-      "value": "<primaryUserAssignedIdentityId>"
+    "primaryUserAssignedIdentityResourceId": {
+      "value": "<primaryUserAssignedIdentityResourceId>"
     },
     "privateEndpoints": {
       "value": [
@@ -2115,7 +2146,7 @@ module server 'br/public:avm/res/sql/server:<version>' = {
         {
           "ignoreMissingVnetServiceEndpoint": true,
           "name": "newVnetRule1",
-          "virtualNetworkSubnetId": "<virtualNetworkSubnetId>"
+          "virtualNetworkSubnetResourceId": "<virtualNetworkSubnetResourceId>"
         }
       ]
     },
@@ -2165,6 +2196,7 @@ param customerManagedKey = {
 }
 param databases = [
   {
+    availabilityZone: 1
     backupLongTermRetentionPolicy: {
       monthlyRetention: 'P6M'
     }
@@ -2194,6 +2226,7 @@ param databases = [
 ]
 param elasticPools = [
   {
+    availabilityZone: -1
     maintenanceConfigurationId: '<maintenanceConfigurationId>'
     name: 'sqlswaf-ep-001'
     sku: {
@@ -2210,7 +2243,7 @@ param managedIdentities = {
     '<managedIdentityResourceId>'
   ]
 }
-param primaryUserAssignedIdentityId = '<primaryUserAssignedIdentityId>'
+param primaryUserAssignedIdentityResourceId = '<primaryUserAssignedIdentityResourceId>'
 param privateEndpoints = [
   {
     privateDnsZoneGroup: {
@@ -2246,7 +2279,7 @@ param virtualNetworkRules = [
   {
     ignoreMissingVnetServiceEndpoint: true
     name: 'newVnetRule1'
-    virtualNetworkSubnetId: '<virtualNetworkSubnetId>'
+    virtualNetworkSubnetResourceId: '<virtualNetworkSubnetResourceId>'
   }
 ]
 param vulnerabilityAssessmentsObj = {
@@ -2281,7 +2314,7 @@ param vulnerabilityAssessmentsObj = {
 | [`administratorLogin`](#parameter-administratorlogin) | string | The administrator username for the server. Required if no `administrators` object for AAD authentication is provided. |
 | [`administratorLoginPassword`](#parameter-administratorloginpassword) | securestring | The administrator login password. Required if no `administrators` object for AAD authentication is provided. |
 | [`administrators`](#parameter-administrators) | object | The Azure Active Directory (AAD) administrator authentication. Required if no `administratorLogin` & `administratorLoginPassword` is provided. |
-| [`primaryUserAssignedIdentityId`](#parameter-primaryuserassignedidentityid) | string | The resource ID of a user assigned identity to be used by default. Required if "userAssignedIdentities" is not empty. |
+| [`primaryUserAssignedIdentityResourceId`](#parameter-primaryuserassignedidentityresourceid) | string | The resource ID of a user assigned identity to be used by default. Required if "userAssignedIdentities" is not empty. |
 
 **Optional parameters**
 
@@ -2324,7 +2357,6 @@ The administrator username for the server. Required if no `administrators` objec
 
 - Required: No
 - Type: string
-- Default: `''`
 
 ### Parameter: `administratorLoginPassword`
 
@@ -2332,7 +2364,6 @@ The administrator login password. Required if no `administrators` object for AAD
 
 - Required: No
 - Type: securestring
-- Default: `''`
 
 ### Parameter: `administrators`
 
@@ -2413,13 +2444,12 @@ Tenant ID of the administrator.
 - Required: No
 - Type: string
 
-### Parameter: `primaryUserAssignedIdentityId`
+### Parameter: `primaryUserAssignedIdentityResourceId`
 
 The resource ID of a user assigned identity to be used by default. Required if "userAssignedIdentities" is not empty.
 
 - Required: No
 - Type: string
-- Default: `''`
 
 ### Parameter: `auditSettings`
 
@@ -2589,12 +2619,12 @@ The databases to create in the server.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
+| [`availabilityZone`](#parameter-databasesavailabilityzone) | int | If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones). |
 | [`name`](#parameter-databasesname) | string | The name of the Elastic Pool. |
 
 **Optional parameters**
@@ -2602,7 +2632,6 @@ The databases to create in the server.
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`autoPauseDelay`](#parameter-databasesautopausedelay) | int | Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled. |
-| [`availabilityZone`](#parameter-databasesavailabilityzone) | string | Specifies the availability zone the database is pinned to. |
 | [`backupLongTermRetentionPolicy`](#parameter-databasesbackuplongtermretentionpolicy) | object | The long term backup retention policy for the database. |
 | [`backupShortTermRetentionPolicy`](#parameter-databasesbackupshorttermretentionpolicy) | object | The short term backup retention policy for the database. |
 | [`catalogCollation`](#parameter-databasescatalogcollation) | string | Collation of the metadata catalog. |
@@ -2641,6 +2670,22 @@ The databases to create in the server.
 | [`useFreeLimit`](#parameter-databasesusefreelimit) | bool | Whether or not the database uses free monthly limits. Allowed on one database in a subscription. |
 | [`zoneRedundant`](#parameter-databaseszoneredundant) | bool | Whether or not this database is zone redundant, which means the replicas of this database will be spread across multiple availability zones. |
 
+### Parameter: `databases.availabilityZone`
+
+If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).
+
+- Required: Yes
+- Type: int
+- Allowed:
+  ```Bicep
+  [
+    -1
+    1
+    2
+    3
+  ]
+  ```
+
 ### Parameter: `databases.name`
 
 The name of the Elastic Pool.
@@ -2655,22 +2700,6 @@ Time in minutes after which database is automatically paused. A value of -1 mean
 - Required: No
 - Type: int
 
-### Parameter: `databases.availabilityZone`
-
-Specifies the availability zone the database is pinned to.
-
-- Required: No
-- Type: string
-- Allowed:
-  ```Bicep
-  [
-    '1'
-    '2'
-    '3'
-    'NoPreference'
-  ]
-  ```
-
 ### Parameter: `databases.backupLongTermRetentionPolicy`
 
 The long term backup retention policy for the database.
@@ -3279,12 +3308,12 @@ The Elastic Pools to create in the server.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
+| [`availabilityZone`](#parameter-elasticpoolsavailabilityzone) | int | If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones). |
 | [`name`](#parameter-elasticpoolsname) | string | The name of the Elastic Pool. |
 
 **Optional parameters**
@@ -3292,7 +3321,6 @@ The Elastic Pools to create in the server.
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`autoPauseDelay`](#parameter-elasticpoolsautopausedelay) | int | Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. |
-| [`availabilityZone`](#parameter-elasticpoolsavailabilityzone) | string | Specifies the availability zone the pool's primary replica is pinned to. |
 | [`highAvailabilityReplicaCount`](#parameter-elasticpoolshighavailabilityreplicacount) | int | The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools. |
 | [`licenseType`](#parameter-elasticpoolslicensetype) | string | The license type to apply for this elastic pool. |
 | [`maintenanceConfigurationId`](#parameter-elasticpoolsmaintenanceconfigurationid) | string | Maintenance configuration id assigned to the elastic pool. This configuration defines the period when the maintenance updates will will occur. |
@@ -3304,6 +3332,22 @@ The Elastic Pools to create in the server.
 | [`tags`](#parameter-elasticpoolstags) | object | Tags of the resource. |
 | [`zoneRedundant`](#parameter-elasticpoolszoneredundant) | bool | Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones. |
 
+### Parameter: `elasticPools.availabilityZone`
+
+If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).
+
+- Required: Yes
+- Type: int
+- Allowed:
+  ```Bicep
+  [
+    -1
+    1
+    2
+    3
+  ]
+  ```
+
 ### Parameter: `elasticPools.name`
 
 The name of the Elastic Pool.
@@ -3318,22 +3362,6 @@ Time in minutes after which elastic pool is automatically paused. A value of -1
 - Required: No
 - Type: int
 
-### Parameter: `elasticPools.availabilityZone`
-
-Specifies the availability zone the pool's primary replica is pinned to.
-
-- Required: No
-- Type: string
-- Allowed:
-  ```Bicep
-  [
-    '1'
-    '2'
-    '3'
-    'NoPreference'
-  ]
-  ```
-
 ### Parameter: `elasticPools.highAvailabilityReplicaCount`
 
 The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.
@@ -3533,7 +3561,6 @@ The failover groups configuration.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
@@ -3682,7 +3709,6 @@ The firewall rules to create in the server.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
@@ -3739,7 +3765,6 @@ The keys to configure.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Optional parameters**
 
@@ -4300,11 +4325,9 @@ Whether or not to restrict outbound network access for this server.
 
 - Required: No
 - Type: string
-- Default: `''`
 - Allowed:
   ```Bicep
   [
-    ''
     'Disabled'
     'Enabled'
   ]
@@ -4467,7 +4490,6 @@ The security alert policies to create in the server.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
@@ -4574,14 +4596,13 @@ The virtual network rules to create in the server.
 
 - Required: No
 - Type: array
-- Default: `[]`
 
 **Required parameters**
 
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`name`](#parameter-virtualnetworkrulesname) | string | The name of the Server Virtual Network Rule. |
-| [`virtualNetworkSubnetId`](#parameter-virtualnetworkrulesvirtualnetworksubnetid) | string | The resource ID of the virtual network subnet. |
+| [`virtualNetworkSubnetResourceId`](#parameter-virtualnetworkrulesvirtualnetworksubnetresourceid) | string | The resource ID of the virtual network subnet. |
 
 **Optional parameters**
 
@@ -4596,7 +4617,7 @@ The name of the Server Virtual Network Rule.
 - Required: Yes
 - Type: string
 
-### Parameter: `virtualNetworkRules.virtualNetworkSubnetId`
+### Parameter: `virtualNetworkRules.virtualNetworkSubnetResourceId`
 
 The resource ID of the virtual network subnet.
 
diff --git a/avm/res/sql/server/database/README.md b/avm/res/sql/server/database/README.md
index ca66ef08d0d..fdfb63c97dc 100644
--- a/avm/res/sql/server/database/README.md
+++ b/avm/res/sql/server/database/README.md
@@ -24,6 +24,7 @@ This module deploys an Azure SQL Server Database.
 
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
+| [`availabilityZone`](#parameter-availabilityzone) | int | If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones). |
 | [`name`](#parameter-name) | string | The name of the database. |
 
 **Conditional parameters**
@@ -37,7 +38,6 @@ This module deploys an Azure SQL Server Database.
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`autoPauseDelay`](#parameter-autopausedelay) | int | Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled. |
-| [`availabilityZone`](#parameter-availabilityzone) | string | Specifies the availability zone the database is pinned to. |
 | [`backupLongTermRetentionPolicy`](#parameter-backuplongtermretentionpolicy) | object | The long term backup retention policy to create for the database. |
 | [`backupShortTermRetentionPolicy`](#parameter-backupshorttermretentionpolicy) | object | The short term backup retention policy to create for the database. |
 | [`catalogCollation`](#parameter-catalogcollation) | string | Collation of the metadata catalog. |
@@ -77,6 +77,22 @@ This module deploys an Azure SQL Server Database.
 | [`useFreeLimit`](#parameter-usefreelimit) | bool | Whether or not the database uses free monthly limits. Allowed on one database in a subscription. |
 | [`zoneRedundant`](#parameter-zoneredundant) | bool | Whether or not this database is zone redundant. |
 
+### Parameter: `availabilityZone`
+
+If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).
+
+- Required: Yes
+- Type: int
+- Allowed:
+  ```Bicep
+  [
+    -1
+    1
+    2
+    3
+  ]
+  ```
+
 ### Parameter: `name`
 
 The name of the database.
@@ -99,23 +115,6 @@ Time in minutes after which database is automatically paused. A value of -1 mean
 - Type: int
 - Default: `-1`
 
-### Parameter: `availabilityZone`
-
-Specifies the availability zone the database is pinned to.
-
-- Required: No
-- Type: string
-- Default: `'NoPreference'`
-- Allowed:
-  ```Bicep
-  [
-    '1'
-    '2'
-    '3'
-    'NoPreference'
-  ]
-  ```
-
 ### Parameter: `backupLongTermRetentionPolicy`
 
 The long term backup retention policy to create for the database.
diff --git a/avm/res/sql/server/database/main.bicep b/avm/res/sql/server/database/main.bicep
index 47ae07deeb3..ab7cb571c52 100644
--- a/avm/res/sql/server/database/main.bicep
+++ b/avm/res/sql/server/database/main.bicep
@@ -18,8 +18,14 @@ param sku databaseSkuType = {
 @description('Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled.')
 param autoPauseDelay int = -1
 
-@description('Optional. Specifies the availability zone the database is pinned to.')
-param availabilityZone '1' | '2' | '3' | 'NoPreference' = 'NoPreference'
+@description('Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).')
+@allowed([
+  -1
+  1
+  2
+  3
+])
+param availabilityZone int
 
 @description('Optional. Collation of the metadata catalog.')
 param catalogCollation string = 'DATABASE_DEFAULT'
@@ -174,7 +180,7 @@ resource database 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
   identity: identity
   properties: {
     autoPauseDelay: autoPauseDelay
-    availabilityZone: availabilityZone
+    availabilityZone: availabilityZone != -1 ? string(availabilityZone) : 'NoPreference'
     catalogCollation: catalogCollation
     collation: collation
     createMode: createMode
diff --git a/avm/res/sql/server/database/main.json b/avm/res/sql/server/database/main.json
index cef703698e2..acbfa163ceb 100644
--- a/avm/res/sql/server/database/main.json
+++ b/avm/res/sql/server/database/main.json
@@ -6,7 +6,7 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "6857638731147235031"
+      "templateHash": "3444518233599497149"
     },
     "name": "SQL Server Database",
     "description": "This module deploys an Azure SQL Server Database."
@@ -308,16 +308,15 @@
       }
     },
     "availabilityZone": {
-      "type": "string",
+      "type": "int",
       "allowedValues": [
-        "1",
-        "2",
-        "3",
-        "NoPreference"
+        -1,
+        1,
+        2,
+        3
       ],
-      "defaultValue": "NoPreference",
       "metadata": {
-        "description": "Optional. Specifies the availability zone the database is pinned to."
+        "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
       }
     },
     "catalogCollation": {
@@ -645,7 +644,7 @@
       "identity": "[variables('identity')]",
       "properties": {
         "autoPauseDelay": "[parameters('autoPauseDelay')]",
-        "availabilityZone": "[parameters('availabilityZone')]",
+        "availabilityZone": "[if(not(equals(parameters('availabilityZone'), -1)), string(parameters('availabilityZone')), 'NoPreference')]",
         "catalogCollation": "[parameters('catalogCollation')]",
         "collation": "[parameters('collation')]",
         "createMode": "[parameters('createMode')]",
diff --git a/avm/res/sql/server/elastic-pool/README.md b/avm/res/sql/server/elastic-pool/README.md
index 8491a1de90c..eac1b2bbac8 100644
--- a/avm/res/sql/server/elastic-pool/README.md
+++ b/avm/res/sql/server/elastic-pool/README.md
@@ -20,6 +20,7 @@ This module deploys an Azure SQL Server Elastic Pool.
 
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
+| [`availabilityZone`](#parameter-availabilityzone) | int | If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones). |
 | [`name`](#parameter-name) | string | The name of the Elastic Pool. |
 
 **Conditional parameters**
@@ -33,7 +34,6 @@ This module deploys an Azure SQL Server Elastic Pool.
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`autoPauseDelay`](#parameter-autopausedelay) | int | Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled. |
-| [`availabilityZone`](#parameter-availabilityzone) | string | Specifies the availability zone the pool's primary replica is pinned to. |
 | [`highAvailabilityReplicaCount`](#parameter-highavailabilityreplicacount) | int | The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools. |
 | [`licenseType`](#parameter-licensetype) | string | The license type to apply for this elastic pool. |
 | [`location`](#parameter-location) | string | Location for all resources. |
@@ -46,6 +46,22 @@ This module deploys an Azure SQL Server Elastic Pool.
 | [`tags`](#parameter-tags) | object | Tags of the resource. |
 | [`zoneRedundant`](#parameter-zoneredundant) | bool | Whether or not this elastic pool is zone redundant, which means the replicas of this elastic pool will be spread across multiple availability zones. |
 
+### Parameter: `availabilityZone`
+
+If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).
+
+- Required: Yes
+- Type: int
+- Allowed:
+  ```Bicep
+  [
+    -1
+    1
+    2
+    3
+  ]
+  ```
+
 ### Parameter: `name`
 
 The name of the Elastic Pool.
@@ -68,23 +84,6 @@ Time in minutes after which elastic pool is automatically paused. A value of -1
 - Type: int
 - Default: `-1`
 
-### Parameter: `availabilityZone`
-
-Specifies the availability zone the pool's primary replica is pinned to.
-
-- Required: No
-- Type: string
-- Default: `'NoPreference'`
-- Allowed:
-  ```Bicep
-  [
-    '1'
-    '2'
-    '3'
-    'NoPreference'
-  ]
-  ```
-
 ### Parameter: `highAvailabilityReplicaCount`
 
 The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.
diff --git a/avm/res/sql/server/elastic-pool/main.bicep b/avm/res/sql/server/elastic-pool/main.bicep
index 6a6f5b3e4a7..5575cd3f9e0 100644
--- a/avm/res/sql/server/elastic-pool/main.bicep
+++ b/avm/res/sql/server/elastic-pool/main.bicep
@@ -14,7 +14,7 @@ param tags object?
 param location string = resourceGroup().location
 
 @description('Optional. The elastic pool SKU.')
-param sku elasticPoolSkuType = {
+param sku skuType = {
   capacity: 2
   name: 'GP_Gen5'
   tier: 'GeneralPurpose'
@@ -23,8 +23,14 @@ param sku elasticPoolSkuType = {
 @description('Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled.')
 param autoPauseDelay int = -1
 
-@description('Optional. Specifies the availability zone the pool\'s primary replica is pinned to.')
-param availabilityZone '1' | '2' | '3' | 'NoPreference' = 'NoPreference'
+@description('Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).')
+@allowed([
+  -1
+  1
+  2
+  3
+])
+param availabilityZone int
 
 @description('Optional. The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.')
 param highAvailabilityReplicaCount int?
@@ -46,7 +52,7 @@ param maxSizeBytes int = 34359738368
 param minCapacity int?
 
 @description('Optional. The per database settings for the elastic pool.')
-param perDatabaseSettings elasticPoolPerDatabaseSettingsType = {
+param perDatabaseSettings perDatabaseSettingsType = {
   autoPauseDelay: -1
   maxCapacity: '2'
   minCapacity: '0'
@@ -70,7 +76,7 @@ resource elasticPool 'Microsoft.Sql/servers/elasticPools@2023-08-01-preview' = {
   sku: sku
   properties: {
     autoPauseDelay: autoPauseDelay
-    availabilityZone: availabilityZone
+    availabilityZone: availabilityZone != -1 ? string(availabilityZone) : 'NoPreference'
     highAvailabilityReplicaCount: highAvailabilityReplicaCount
     licenseType: licenseType
     maintenanceConfigurationId: maintenanceConfigurationId
@@ -107,7 +113,7 @@ output location string = elasticPool.location
 
 @export()
 @description('The per database settings for the elastic pool.')
-type elasticPoolPerDatabaseSettingsType = {
+type perDatabaseSettingsType = {
   @description('Optional. Auto Pause Delay for per database within pool.')
   autoPauseDelay: int?
 
@@ -121,7 +127,7 @@ type elasticPoolPerDatabaseSettingsType = {
 
 @export()
 @description('The elastic pool SKU.')
-type elasticPoolSkuType = {
+type skuType = {
   @description('Optional. The capacity of the particular SKU.')
   capacity: int?
 
diff --git a/avm/res/sql/server/elastic-pool/main.json b/avm/res/sql/server/elastic-pool/main.json
index 8956b7e1d58..f815d5e89c3 100644
--- a/avm/res/sql/server/elastic-pool/main.json
+++ b/avm/res/sql/server/elastic-pool/main.json
@@ -6,13 +6,13 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "15648031842218670048"
+      "templateHash": "6480963111257796466"
     },
     "name": "SQL Server Elastic Pool",
     "description": "This module deploys an Azure SQL Server Elastic Pool."
   },
   "definitions": {
-    "elasticPoolPerDatabaseSettingsType": {
+    "perDatabaseSettingsType": {
       "type": "object",
       "properties": {
         "autoPauseDelay": {
@@ -40,7 +40,7 @@
         "description": "The per database settings for the elastic pool."
       }
     },
-    "elasticPoolSkuType": {
+    "skuType": {
       "type": "object",
       "properties": {
         "capacity": {
@@ -126,7 +126,7 @@
       }
     },
     "sku": {
-      "$ref": "#/definitions/elasticPoolSkuType",
+      "$ref": "#/definitions/skuType",
       "defaultValue": {
         "capacity": 2,
         "name": "GP_Gen5",
@@ -144,16 +144,15 @@
       }
     },
     "availabilityZone": {
-      "type": "string",
+      "type": "int",
       "allowedValues": [
-        "1",
-        "2",
-        "3",
-        "NoPreference"
+        -1,
+        1,
+        2,
+        3
       ],
-      "defaultValue": "NoPreference",
       "metadata": {
-        "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to."
+        "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
       }
     },
     "highAvailabilityReplicaCount": {
@@ -196,7 +195,7 @@
       }
     },
     "perDatabaseSettings": {
-      "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType",
+      "$ref": "#/definitions/perDatabaseSettingsType",
       "defaultValue": {
         "autoPauseDelay": -1,
         "maxCapacity": "2",
@@ -241,7 +240,7 @@
       "sku": "[parameters('sku')]",
       "properties": {
         "autoPauseDelay": "[parameters('autoPauseDelay')]",
-        "availabilityZone": "[parameters('availabilityZone')]",
+        "availabilityZone": "[if(not(equals(parameters('availabilityZone'), -1)), string(parameters('availabilityZone')), 'NoPreference')]",
         "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]",
         "licenseType": "[parameters('licenseType')]",
         "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]",
diff --git a/avm/res/sql/server/failover-group/main.bicep b/avm/res/sql/server/failover-group/main.bicep
index 0726df7b562..a01cfe2a434 100644
--- a/avm/res/sql/server/failover-group/main.bicep
+++ b/avm/res/sql/server/failover-group/main.bicep
@@ -14,10 +14,10 @@ param databases string[]
 param partnerServers string[]
 
 @description('Optional. Read-only endpoint of the failover group instance.')
-param readOnlyEndpoint failoverGroupReadOnlyEndpointType?
+param readOnlyEndpoint readOnlyEndpointType?
 
 @description('Required. Read-write endpoint of the failover group instance.')
-param readWriteEndpoint failoverGroupReadWriteEndpointType
+param readWriteEndpoint readWriteEndpointType
 
 @description('Required. Databases secondary type on partner server.')
 param secondaryType 'Geo' | 'Standby'
@@ -68,7 +68,8 @@ output resourceId string = failoverGroup.id
 output resourceGroupName string = resourceGroup().name
 
 @export()
-type failoverGroupReadOnlyEndpointType = {
+@description('The type for a read-only endpoint.')
+type readOnlyEndpointType = {
   @description('Required. Failover policy of the read-only endpoint for the failover group.')
   failoverPolicy: 'Disabled' | 'Enabled'
 
@@ -77,7 +78,8 @@ type failoverGroupReadOnlyEndpointType = {
 }
 
 @export()
-type failoverGroupReadWriteEndpointType = {
+@description('The type for a read-write endpoint.')
+type readWriteEndpointType = {
   @description('Required. Failover policy of the read-write endpoint for the failover group. If failoverPolicy is Automatic then failoverWithDataLossGracePeriodMinutes is required.')
   failoverPolicy: 'Automatic' | 'Manual'
 
diff --git a/avm/res/sql/server/failover-group/main.json b/avm/res/sql/server/failover-group/main.json
index 103142efaf6..c4a7c89dc4f 100644
--- a/avm/res/sql/server/failover-group/main.json
+++ b/avm/res/sql/server/failover-group/main.json
@@ -6,13 +6,13 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "5841212065211909434"
+      "templateHash": "16705539934522968897"
     },
     "name": "Azure SQL Server failover group",
     "description": "This module deploys Azure SQL Server failover group."
   },
   "definitions": {
-    "failoverGroupReadOnlyEndpointType": {
+    "readOnlyEndpointType": {
       "type": "object",
       "properties": {
         "failoverPolicy": {
@@ -33,10 +33,11 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a read-only endpoint."
       }
     },
-    "failoverGroupReadWriteEndpointType": {
+    "readWriteEndpointType": {
       "type": "object",
       "properties": {
         "failoverPolicy": {
@@ -58,7 +59,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a read-write endpoint."
       }
     }
   },
@@ -94,14 +96,14 @@
       }
     },
     "readOnlyEndpoint": {
-      "$ref": "#/definitions/failoverGroupReadOnlyEndpointType",
+      "$ref": "#/definitions/readOnlyEndpointType",
       "nullable": true,
       "metadata": {
         "description": "Optional. Read-only endpoint of the failover group instance."
       }
     },
     "readWriteEndpoint": {
-      "$ref": "#/definitions/failoverGroupReadWriteEndpointType",
+      "$ref": "#/definitions/readWriteEndpointType",
       "metadata": {
         "description": "Required. Read-write endpoint of the failover group instance."
       }
diff --git a/avm/res/sql/server/main.bicep b/avm/res/sql/server/main.bicep
index d32421b6de6..51a7a37c9ce 100644
--- a/avm/res/sql/server/main.bicep
+++ b/avm/res/sql/server/main.bicep
@@ -2,11 +2,11 @@ metadata name = 'Azure SQL Servers'
 metadata description = 'This module deploys an Azure SQL Server.'
 
 @description('Conditional. The administrator username for the server. Required if no `administrators` object for AAD authentication is provided.')
-param administratorLogin string = ''
+param administratorLogin string?
 
 @description('Conditional. The administrator login password. Required if no `administrators` object for AAD authentication is provided.')
 @secure()
-param administratorLoginPassword string = ''
+param administratorLoginPassword string?
 
 @description('Optional. Location for all resources.')
 param location string = resourceGroup().location
@@ -19,7 +19,7 @@ import { managedIdentityAllType, managedIdentityOnlyUserAssignedType } from 'br/
 param managedIdentities managedIdentityAllType?
 
 @description('Conditional. The resource ID of a user assigned identity to be used by default. Required if "userAssignedIdentities" is not empty.')
-param primaryUserAssignedIdentityId string = ''
+param primaryUserAssignedIdentityResourceId string?
 
 import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
 @description('Optional. The lock settings of the service.')
@@ -36,22 +36,22 @@ param tags object?
 param enableTelemetry bool = true
 
 @description('Optional. The databases to create in the server.')
-param databases databasePropertyType[] = []
+param databases databaseType[]?
 
 @description('Optional. The Elastic Pools to create in the server.')
-param elasticPools elasticPoolPropertyType[] = []
+param elasticPools elasticPoolType[]?
 
 @description('Optional. The firewall rules to create in the server.')
-param firewallRules firewallRuleType[] = []
+param firewallRules firewallRuleType[]?
 
 @description('Optional. The virtual network rules to create in the server.')
-param virtualNetworkRules virtualNetworkRuleType[] = []
+param virtualNetworkRules virtualNetworkRuleType[]?
 
 @description('Optional. The security alert policies to create in the server.')
-param securityAlertPolicies securityAlerPolicyType[] = []
+param securityAlertPolicies securityAlerPolicyType[]?
 
 @description('Optional. The keys to configure.')
-param keys keyType[] = []
+param keys keyType[]?
 
 import { customerManagedKeyWithAutoRotateType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
 @description('Optional. The customer managed key definition for server TDE.')
@@ -96,11 +96,10 @@ param publicNetworkAccess string = ''
 
 @description('Optional. Whether or not to restrict outbound network access for this server.')
 @allowed([
-  ''
   'Enabled'
   'Disabled'
 ])
-param restrictOutboundNetworkAccess string = ''
+param restrictOutboundNetworkAccess string?
 
 var formattedUserAssignedIdentities = reduce(
   map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }),
@@ -129,7 +128,7 @@ param auditSettings auditSettingsType = {
 param secretsExportConfiguration secretsExportConfigurationType?
 
 @description('Optional. The failover groups configuration.')
-param failoverGroups failoverGroupType[] = []
+param failoverGroups failoverGroupType[]?
 
 var enableReferencedModulesTelemetry = false
 
@@ -223,25 +222,23 @@ resource server 'Microsoft.Sql/servers@2023-08-01-preview' = {
   tags: tags
   identity: identity
   properties: {
-    administratorLogin: !empty(administratorLogin) ? administratorLogin : null
-    administratorLoginPassword: !empty(administratorLoginPassword) ? administratorLoginPassword : null
+    administratorLogin: administratorLogin
+    administratorLoginPassword: administratorLoginPassword
     administrators: union({ administratorType: 'ActiveDirectory' }, administrators ?? {})
     federatedClientId: federatedClientId
     isIPv6Enabled: isIPv6Enabled
     keyId: customerManagedKey != null
       ? !empty(customerManagedKey.?keyVersion)
           ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.?keyVersion}'
-          : (customerManagedKey.?autoRotationEnabled ?? true)
-              ? cMKKeyVault::cMKKey.properties.keyUri
-              : cMKKeyVault::cMKKey.properties.keyUriWithVersion
+          : cMKKeyVault::cMKKey.properties.keyUriWithVersion
       : null
     version: '12.0'
     minimalTlsVersion: minimalTlsVersion
-    primaryUserAssignedIdentityId: !empty(primaryUserAssignedIdentityId) ? primaryUserAssignedIdentityId : null
+    primaryUserAssignedIdentityId: primaryUserAssignedIdentityResourceId
     publicNetworkAccess: !empty(publicNetworkAccess)
       ? publicNetworkAccess
       : (!empty(privateEndpoints) && empty(firewallRules) && empty(virtualNetworkRules) ? 'Disabled' : null)
-    restrictOutboundNetworkAccess: !empty(restrictOutboundNetworkAccess) ? restrictOutboundNetworkAccess : null
+    restrictOutboundNetworkAccess: restrictOutboundNetworkAccess
   }
 }
 
@@ -273,7 +270,7 @@ resource server_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04
 ]
 
 module server_databases 'database/main.bicep' = [
-  for (database, index) in databases: {
+  for (database, index) in (databases ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-DB-${index}'
     params: {
       // properties derived from parent server resource, no override allowed
@@ -332,7 +329,7 @@ module server_databases 'database/main.bicep' = [
 ]
 
 module server_elasticPools 'elastic-pool/main.bicep' = [
-  for (elasticPool, index) in elasticPools: {
+  for (elasticPool, index) in (elasticPools ?? []): {
     name: '${uniqueString(deployment().name, location)}-SQLServer-ElasticPool-${index}'
     params: {
       // properties derived from parent server resource, no override allowed
@@ -415,7 +412,7 @@ module server_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.
 ]
 
 module server_firewallRules 'firewall-rule/main.bicep' = [
-  for (firewallRule, index) in firewallRules: {
+  for (firewallRule, index) in (firewallRules ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-FirewallRules-${index}'
     params: {
       name: firewallRule.name
@@ -427,19 +424,19 @@ module server_firewallRules 'firewall-rule/main.bicep' = [
 ]
 
 module server_virtualNetworkRules 'virtual-network-rule/main.bicep' = [
-  for (virtualNetworkRule, index) in virtualNetworkRules: {
+  for (virtualNetworkRule, index) in (virtualNetworkRules ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-VirtualNetworkRules-${index}'
     params: {
       serverName: server.name
       name: virtualNetworkRule.name
       ignoreMissingVnetServiceEndpoint: virtualNetworkRule.?ignoreMissingVnetServiceEndpoint
-      virtualNetworkSubnetId: virtualNetworkRule.virtualNetworkSubnetId
+      virtualNetworkSubnetResourceId: virtualNetworkRule.virtualNetworkSubnetResourceId
     }
   }
 ]
 
 module server_securityAlertPolicies 'security-alert-policy/main.bicep' = [
-  for (securityAlertPolicy, index) in securityAlertPolicies: {
+  for (securityAlertPolicy, index) in (securityAlertPolicies ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-SecAlertPolicy-${index}'
     params: {
       name: securityAlertPolicy.name
@@ -471,7 +468,7 @@ module server_vulnerabilityAssessment 'vulnerability-assessment/main.bicep' = if
 }
 
 module server_keys 'key/main.bicep' = [
-  for (key, index) in keys: {
+  for (key, index) in (keys ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-Key-${index}'
     params: {
       serverName: server.name
@@ -486,13 +483,11 @@ module cmk_key 'key/main.bicep' = if (customerManagedKey != null) {
   name: '${uniqueString(deployment().name, location)}-Sql-Key'
   params: {
     serverName: server.name
-    name: '${cMKKeyVault.name}_${customerManagedKey.?keyName}_${customerManagedKey.?keyVersion}'
+    name: '${cMKKeyVault.name}_${customerManagedKey.?keyName}_${!empty(customerManagedKey.?keyVersion) ? customerManagedKey.?keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/'))}'
     serverKeyType: 'AzureKeyVault'
     uri: !empty(customerManagedKey.?keyVersion)
       ? '${cMKKeyVault::cMKKey.properties.keyUri}/${customerManagedKey!.?keyVersion}'
-      : (customerManagedKey.?autoRotationEnabled ?? true)
-          ? cMKKeyVault::cMKKey.properties.keyUri
-          : cMKKeyVault::cMKKey.properties.keyUriWithVersion
+      : cMKKeyVault::cMKKey.properties.keyUriWithVersion
   }
 }
 
@@ -545,7 +540,7 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura
         ? [
             {
               name: secretsExportConfiguration!.?sqlAzureConnectionStringSercretName
-              value: 'Server=${server.properties.fullyQualifiedDomainName}; Database=${!empty(databases) ? databases[0].name : ''}; User=${administratorLogin}; Password=${administratorLoginPassword}'
+              value: 'Server=${server.properties.fullyQualifiedDomainName}; Database=${!empty(databases) ? databases[?0].name : ''}; User=${administratorLogin}; Password=${administratorLoginPassword}'
             }
           ]
         : []
@@ -554,7 +549,7 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura
 }
 
 module failover_groups 'failover-group/main.bicep' = [
-  for (failoverGroup, index) in failoverGroups: {
+  for (failoverGroup, index) in (failoverGroups ?? []): {
     name: '${uniqueString(deployment().name, location)}-Sql-FailoverGroup-${index}'
     params: {
       name: failoverGroup.name
@@ -612,10 +607,10 @@ output privateEndpoints privateEndpointOutputType[] = [
 // =============== //
 
 import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
-import { elasticPoolPerDatabaseSettingsType, elasticPoolSkuType } from 'elastic-pool/main.bicep'
+import { perDatabaseSettingsType, skuType } from 'elastic-pool/main.bicep'
 import { databaseSkuType, shortTermBackupRetentionPolicyType, longTermBackupRetentionPolicyType } from 'database/main.bicep'
 import { recurringScansType } from 'vulnerability-assessment/main.bicep'
-import { failoverGroupReadOnlyEndpointType, failoverGroupReadWriteEndpointType } from 'failover-group/main.bicep'
+import { readOnlyEndpointType, readWriteEndpointType } from 'failover-group/main.bicep'
 
 @export()
 @description('The type for a private endpoint output.')
@@ -643,6 +638,7 @@ type privateEndpointOutputType = {
 }
 
 @export()
+@description('The type for audit settings.')
 type auditSettingsType = {
   @description('Optional. Specifies the name of the audit settings.')
   name: string?
@@ -676,6 +672,7 @@ type auditSettingsType = {
 }
 
 @export()
+@description('The type for a secrets export configuration.')
 type secretsExportConfigurationType = {
   @description('Required. The resource ID of the key vault where to store the secrets of this module.')
   keyVaultResourceId: string
@@ -688,6 +685,7 @@ type secretsExportConfigurationType = {
 }
 
 @export()
+@description('The type for a sever-external administrator.')
 type serverExternalAdministratorType = {
   @description('Optional. Type of the sever administrator.')
   administratorType: 'ActiveDirectory'?
@@ -709,7 +707,8 @@ type serverExternalAdministratorType = {
 }
 
 @export()
-type databasePropertyType = {
+@description('The type for a database.')
+type databaseType = {
   @description('Required. The name of the Elastic Pool.')
   name: string
 
@@ -725,8 +724,8 @@ type databasePropertyType = {
   @description('Optional. Time in minutes after which database is automatically paused. A value of -1 means that automatic pause is disabled.')
   autoPauseDelay: int?
 
-  @description('Optional. Specifies the availability zone the database is pinned to.')
-  availabilityZone: '1' | '2' | '3' | 'NoPreference'?
+  @description('Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).')
+  availabilityZone: (-1 | 1 | 2 | 3)
 
   @description('Optional. Collation of the metadata catalog.')
   catalogCollation: string?
@@ -846,7 +845,8 @@ type databasePropertyType = {
 }
 
 @export()
-type elasticPoolPropertyType = {
+@description('The type for an elastic pool property.')
+type elasticPoolType = {
   @description('Required. The name of the Elastic Pool.')
   name: string
 
@@ -854,13 +854,13 @@ type elasticPoolPropertyType = {
   tags: object?
 
   @description('Optional. The elastic pool SKU.')
-  sku: elasticPoolSkuType?
+  sku: skuType?
 
   @description('Optional. Time in minutes after which elastic pool is automatically paused. A value of -1 means that automatic pause is disabled.')
   autoPauseDelay: int?
 
-  @description('Optional. Specifies the availability zone the pool\'s primary replica is pinned to.')
-  availabilityZone: '1' | '2' | '3' | 'NoPreference'?
+  @description('Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones).')
+  availabilityZone: (-1 | 1 | 2 | 3)
 
   @description('Optional. The number of secondary replicas associated with the elastic pool that are used to provide high availability. Applicable only to Hyperscale elastic pools.')
   highAvailabilityReplicaCount: int?
@@ -878,7 +878,7 @@ type elasticPoolPropertyType = {
   minCapacity: int?
 
   @description('Optional. The per database settings for the elastic pool.')
-  perDatabaseSettings: elasticPoolPerDatabaseSettingsType?
+  perDatabaseSettings: perDatabaseSettingsType?
 
   @description('Optional. Type of enclave requested on the elastic pool.')
   preferredEnclaveType: 'Default' | 'VBS'?
@@ -888,18 +888,7 @@ type elasticPoolPropertyType = {
 }
 
 @export()
-type encryptionProtectorType = {
-  @description('Required. The name of the server key.')
-  serverKeyName: string
-
-  @description('Optional. The encryption protector type.')
-  serverKeyType: 'ServiceManaged' | 'AzureKeyVault'?
-
-  @description('Optional. Key auto rotation opt-in flag.')
-  autoRotationEnabled: bool?
-}
-
-@export()
+@description('The type for a vulnerability assessment.')
 type vulnerabilityAssessmentType = {
   @description('Required. The name of the vulnerability assessment.')
   name: string
@@ -918,6 +907,7 @@ type vulnerabilityAssessmentType = {
 }
 
 @export()
+@description('The type for a firewall rule.')
 type firewallRuleType = {
   @description('Required. The name of the firewall rule.')
   name: string
@@ -930,6 +920,7 @@ type firewallRuleType = {
 }
 
 @export()
+@description('The type for a key.')
 type keyType = {
   @description('Optional. The name of the key. Must follow the [<keyVaultName>_<keyName>_<keyVersion>] pattern.')
   name: string?
@@ -942,18 +933,20 @@ type keyType = {
 }
 
 @export()
+@description('The type for a virtual network rule.')
 type virtualNetworkRuleType = {
   @description('Required. The name of the Server Virtual Network Rule.')
   name: string
 
   @description('Required. The resource ID of the virtual network subnet.')
-  virtualNetworkSubnetId: string
+  virtualNetworkSubnetResourceId: string
 
   @description('Optional. Allow creating a firewall rule before the virtual network has vnet service endpoint enabled.')
   ignoreMissingVnetServiceEndpoint: bool?
 }
 
 @export()
+@description('The type for a security alert policy.')
 type securityAlerPolicyType = {
   @description('Required. The name of the Security Alert Policy.')
   name: string
@@ -987,6 +980,7 @@ type securityAlerPolicyType = {
 }
 
 @export()
+@description('The type for a failover group.')
 type failoverGroupType = {
   @description('Required. The name of the failover group.')
   name: string
@@ -1001,10 +995,10 @@ type failoverGroupType = {
   partnerServers: string[]
 
   @description('Optional. Read-only endpoint of the failover group instance.')
-  readOnlyEndpoint: failoverGroupReadOnlyEndpointType?
+  readOnlyEndpoint: readOnlyEndpointType?
 
   @description('Required. Read-write endpoint of the failover group instance.')
-  readWriteEndpoint: failoverGroupReadWriteEndpointType
+  readWriteEndpoint: readWriteEndpointType
 
   @description('Required. Databases secondary type on partner server.')
   secondaryType: 'Geo' | 'Standby'
diff --git a/avm/res/sql/server/main.json b/avm/res/sql/server/main.json
index 5c35a4cab58..cda9d6bee6d 100644
--- a/avm/res/sql/server/main.json
+++ b/avm/res/sql/server/main.json
@@ -6,7 +6,7 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "17310040518768029446"
+      "templateHash": "8377942864127974447"
     },
     "name": "Azure SQL Servers",
     "description": "This module deploys an Azure SQL Server."
@@ -158,7 +158,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for audit settings."
       }
     },
     "secretsExportConfigurationType": {
@@ -186,7 +187,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a secrets export configuration."
       }
     },
     "serverExternalAdministratorType": {
@@ -240,10 +242,11 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a sever-external administrator."
       }
     },
-    "databasePropertyType": {
+    "databaseType": {
       "type": "object",
       "properties": {
         "name": {
@@ -281,16 +284,15 @@
           }
         },
         "availabilityZone": {
-          "type": "string",
+          "type": "int",
           "allowedValues": [
-            "1",
-            "2",
-            "3",
-            "NoPreference"
+            -1,
+            1,
+            2,
+            3
           ],
-          "nullable": true,
           "metadata": {
-            "description": "Optional. Specifies the availability zone the database is pinned to."
+            "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
           }
         },
         "catalogCollation": {
@@ -577,10 +579,11 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a database."
       }
     },
-    "elasticPoolPropertyType": {
+    "elasticPoolType": {
       "type": "object",
       "properties": {
         "name": {
@@ -597,7 +600,7 @@
           }
         },
         "sku": {
-          "$ref": "#/definitions/elasticPoolSkuType",
+          "$ref": "#/definitions/skuType",
           "nullable": true,
           "metadata": {
             "description": "Optional. The elastic pool SKU."
@@ -611,16 +614,15 @@
           }
         },
         "availabilityZone": {
-          "type": "string",
+          "type": "int",
           "allowedValues": [
-            "1",
-            "2",
-            "3",
-            "NoPreference"
+            -1,
+            1,
+            2,
+            3
           ],
-          "nullable": true,
           "metadata": {
-            "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to."
+            "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
           }
         },
         "highAvailabilityReplicaCount": {
@@ -663,7 +665,7 @@
           }
         },
         "perDatabaseSettings": {
-          "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType",
+          "$ref": "#/definitions/perDatabaseSettingsType",
           "nullable": true,
           "metadata": {
             "description": "Optional. The per database settings for the elastic pool."
@@ -689,39 +691,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
-      }
-    },
-    "encryptionProtectorType": {
-      "type": "object",
-      "properties": {
-        "serverKeyName": {
-          "type": "string",
-          "metadata": {
-            "description": "Required. The name of the server key."
-          }
-        },
-        "serverKeyType": {
-          "type": "string",
-          "allowedValues": [
-            "AzureKeyVault",
-            "ServiceManaged"
-          ],
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. The encryption protector type."
-          }
-        },
-        "autoRotationEnabled": {
-          "type": "bool",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. Key auto rotation opt-in flag."
-          }
-        }
-      },
-      "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for an elastic pool property."
       }
     },
     "vulnerabilityAssessmentType": {
@@ -762,7 +733,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a vulnerability assessment."
       }
     },
     "firewallRuleType": {
@@ -790,7 +762,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a firewall rule."
       }
     },
     "keyType": {
@@ -823,7 +796,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a key."
       }
     },
     "virtualNetworkRuleType": {
@@ -835,7 +809,7 @@
             "description": "Required. The name of the Server Virtual Network Rule."
           }
         },
-        "virtualNetworkSubnetId": {
+        "virtualNetworkSubnetResourceId": {
           "type": "string",
           "metadata": {
             "description": "Required. The resource ID of the virtual network subnet."
@@ -850,7 +824,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a virtual network rule."
       }
     },
     "securityAlerPolicyType": {
@@ -928,7 +903,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a security alert policy."
       }
     },
     "failoverGroupType": {
@@ -966,14 +942,14 @@
           }
         },
         "readOnlyEndpoint": {
-          "$ref": "#/definitions/failoverGroupReadOnlyEndpointType",
+          "$ref": "#/definitions/readOnlyEndpointType",
           "nullable": true,
           "metadata": {
             "description": "Optional. Read-only endpoint of the failover group instance."
           }
         },
         "readWriteEndpoint": {
-          "$ref": "#/definitions/failoverGroupReadWriteEndpointType",
+          "$ref": "#/definitions/readWriteEndpointType",
           "metadata": {
             "description": "Required. Read-write endpoint of the failover group instance."
           }
@@ -990,7 +966,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for a failover group."
       }
     },
     "_1.privateEndpointCustomDnsConfigType": {
@@ -1342,148 +1319,6 @@
         }
       }
     },
-    "elasticPoolPerDatabaseSettingsType": {
-      "type": "object",
-      "properties": {
-        "autoPauseDelay": {
-          "type": "int",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. Auto Pause Delay for per database within pool."
-          }
-        },
-        "maxCapacity": {
-          "type": "string",
-          "metadata": {
-            "description": "Required. The maximum capacity any one database can consume. Examples: '0.5', '2'."
-          }
-        },
-        "minCapacity": {
-          "type": "string",
-          "metadata": {
-            "description": "Required. The minimum capacity all databases are guaranteed. Examples: '0.5', '1'."
-          }
-        }
-      },
-      "metadata": {
-        "description": "The per database settings for the elastic pool.",
-        "__bicep_imported_from!": {
-          "sourceTemplate": "elastic-pool/main.bicep"
-        }
-      }
-    },
-    "elasticPoolSkuType": {
-      "type": "object",
-      "properties": {
-        "capacity": {
-          "type": "int",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. The capacity of the particular SKU."
-          }
-        },
-        "family": {
-          "type": "string",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here."
-          }
-        },
-        "name": {
-          "type": "string",
-          "allowedValues": [
-            "BC_DC",
-            "BC_Gen5",
-            "BasicPool",
-            "GP_DC",
-            "GP_FSv2",
-            "GP_Gen5",
-            "HS_Gen5",
-            "HS_MOPRMS",
-            "HS_PRMS",
-            "PremiumPool",
-            "ServerlessPool",
-            "StandardPool"
-          ],
-          "metadata": {
-            "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3."
-          }
-        },
-        "size": {
-          "type": "string",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. Size of the particular SKU."
-          }
-        },
-        "tier": {
-          "type": "string",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium."
-          }
-        }
-      },
-      "metadata": {
-        "description": "The elastic pool SKU.",
-        "__bicep_imported_from!": {
-          "sourceTemplate": "elastic-pool/main.bicep"
-        }
-      }
-    },
-    "failoverGroupReadOnlyEndpointType": {
-      "type": "object",
-      "properties": {
-        "failoverPolicy": {
-          "type": "string",
-          "allowedValues": [
-            "Disabled",
-            "Enabled"
-          ],
-          "metadata": {
-            "description": "Required. Failover policy of the read-only endpoint for the failover group."
-          }
-        },
-        "targetServer": {
-          "type": "string",
-          "metadata": {
-            "description": "Required. The target partner server where the read-only endpoint points to."
-          }
-        }
-      },
-      "metadata": {
-        "__bicep_imported_from!": {
-          "sourceTemplate": "failover-group/main.bicep"
-        }
-      }
-    },
-    "failoverGroupReadWriteEndpointType": {
-      "type": "object",
-      "properties": {
-        "failoverPolicy": {
-          "type": "string",
-          "allowedValues": [
-            "Automatic",
-            "Manual"
-          ],
-          "metadata": {
-            "description": "Required. Failover policy of the read-write endpoint for the failover group. If failoverPolicy is Automatic then failoverWithDataLossGracePeriodMinutes is required."
-          }
-        },
-        "failoverWithDataLossGracePeriodMinutes": {
-          "type": "int",
-          "nullable": true,
-          "metadata": {
-            "description": "Optional. Grace period before failover with data loss is attempted for the read-write endpoint."
-          }
-        }
-      },
-      "metadata": {
-        "__bicep_imported_from!": {
-          "sourceTemplate": "failover-group/main.bicep"
-        }
-      }
-    },
     "lockType": {
       "type": "object",
       "properties": {
@@ -1620,6 +1455,36 @@
         }
       }
     },
+    "perDatabaseSettingsType": {
+      "type": "object",
+      "properties": {
+        "autoPauseDelay": {
+          "type": "int",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. Auto Pause Delay for per database within pool."
+          }
+        },
+        "maxCapacity": {
+          "type": "string",
+          "metadata": {
+            "description": "Required. The maximum capacity any one database can consume. Examples: '0.5', '2'."
+          }
+        },
+        "minCapacity": {
+          "type": "string",
+          "metadata": {
+            "description": "Required. The minimum capacity all databases are guaranteed. Examples: '0.5', '1'."
+          }
+        }
+      },
+      "metadata": {
+        "description": "The per database settings for the elastic pool.",
+        "__bicep_imported_from!": {
+          "sourceTemplate": "elastic-pool/main.bicep"
+        }
+      }
+    },
     "privateEndpointSingleServiceType": {
       "type": "object",
       "properties": {
@@ -1762,6 +1627,61 @@
         }
       }
     },
+    "readOnlyEndpointType": {
+      "type": "object",
+      "properties": {
+        "failoverPolicy": {
+          "type": "string",
+          "allowedValues": [
+            "Disabled",
+            "Enabled"
+          ],
+          "metadata": {
+            "description": "Required. Failover policy of the read-only endpoint for the failover group."
+          }
+        },
+        "targetServer": {
+          "type": "string",
+          "metadata": {
+            "description": "Required. The target partner server where the read-only endpoint points to."
+          }
+        }
+      },
+      "metadata": {
+        "description": "The type for a read-only endpoint.",
+        "__bicep_imported_from!": {
+          "sourceTemplate": "failover-group/main.bicep"
+        }
+      }
+    },
+    "readWriteEndpointType": {
+      "type": "object",
+      "properties": {
+        "failoverPolicy": {
+          "type": "string",
+          "allowedValues": [
+            "Automatic",
+            "Manual"
+          ],
+          "metadata": {
+            "description": "Required. Failover policy of the read-write endpoint for the failover group. If failoverPolicy is Automatic then failoverWithDataLossGracePeriodMinutes is required."
+          }
+        },
+        "failoverWithDataLossGracePeriodMinutes": {
+          "type": "int",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. Grace period before failover with data loss is attempted for the read-write endpoint."
+          }
+        }
+      },
+      "metadata": {
+        "description": "The type for a read-write endpoint.",
+        "__bicep_imported_from!": {
+          "sourceTemplate": "failover-group/main.bicep"
+        }
+      }
+    },
     "recurringScansType": {
       "type": "object",
       "properties": {
@@ -1790,6 +1710,7 @@
         }
       },
       "metadata": {
+        "description": "The type for recurring scans.",
         "__bicep_imported_from!": {
           "sourceTemplate": "vulnerability-assessment/main.bicep"
         }
@@ -1910,19 +1831,78 @@
           "sourceTemplate": "database/main.bicep"
         }
       }
+    },
+    "skuType": {
+      "type": "object",
+      "properties": {
+        "capacity": {
+          "type": "int",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. The capacity of the particular SKU."
+          }
+        },
+        "family": {
+          "type": "string",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. If the service has different generations of hardware, for the same SKU, then that can be captured here."
+          }
+        },
+        "name": {
+          "type": "string",
+          "allowedValues": [
+            "BC_DC",
+            "BC_Gen5",
+            "BasicPool",
+            "GP_DC",
+            "GP_FSv2",
+            "GP_Gen5",
+            "HS_Gen5",
+            "HS_MOPRMS",
+            "HS_PRMS",
+            "PremiumPool",
+            "ServerlessPool",
+            "StandardPool"
+          ],
+          "metadata": {
+            "description": "Required. The name of the SKU, typically, a letter + Number code, e.g. P3."
+          }
+        },
+        "size": {
+          "type": "string",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. Size of the particular SKU."
+          }
+        },
+        "tier": {
+          "type": "string",
+          "nullable": true,
+          "metadata": {
+            "description": "Optional. The tier or edition of the particular SKU, e.g. Basic, Premium."
+          }
+        }
+      },
+      "metadata": {
+        "description": "The elastic pool SKU.",
+        "__bicep_imported_from!": {
+          "sourceTemplate": "elastic-pool/main.bicep"
+        }
+      }
     }
   },
   "parameters": {
     "administratorLogin": {
       "type": "string",
-      "defaultValue": "",
+      "nullable": true,
       "metadata": {
         "description": "Conditional. The administrator username for the server. Required if no `administrators` object for AAD authentication is provided."
       }
     },
     "administratorLoginPassword": {
       "type": "securestring",
-      "defaultValue": "",
+      "nullable": true,
       "metadata": {
         "description": "Conditional. The administrator login password. Required if no `administrators` object for AAD authentication is provided."
       }
@@ -1947,9 +1927,9 @@
         "description": "Optional. The managed identity definition for this resource."
       }
     },
-    "primaryUserAssignedIdentityId": {
+    "primaryUserAssignedIdentityResourceId": {
       "type": "string",
-      "defaultValue": "",
+      "nullable": true,
       "metadata": {
         "description": "Conditional. The resource ID of a user assigned identity to be used by default. Required if \"userAssignedIdentities\" is not empty."
       }
@@ -1988,9 +1968,9 @@
     "databases": {
       "type": "array",
       "items": {
-        "$ref": "#/definitions/databasePropertyType"
+        "$ref": "#/definitions/databaseType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The databases to create in the server."
       }
@@ -1998,9 +1978,9 @@
     "elasticPools": {
       "type": "array",
       "items": {
-        "$ref": "#/definitions/elasticPoolPropertyType"
+        "$ref": "#/definitions/elasticPoolType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The Elastic Pools to create in the server."
       }
@@ -2010,7 +1990,7 @@
       "items": {
         "$ref": "#/definitions/firewallRuleType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The firewall rules to create in the server."
       }
@@ -2020,7 +2000,7 @@
       "items": {
         "$ref": "#/definitions/virtualNetworkRuleType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The virtual network rules to create in the server."
       }
@@ -2030,7 +2010,7 @@
       "items": {
         "$ref": "#/definitions/securityAlerPolicyType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The security alert policies to create in the server."
       }
@@ -2040,7 +2020,7 @@
       "items": {
         "$ref": "#/definitions/keyType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The keys to configure."
       }
@@ -2117,9 +2097,8 @@
     },
     "restrictOutboundNetworkAccess": {
       "type": "string",
-      "defaultValue": "",
+      "nullable": true,
       "allowedValues": [
-        "",
         "Enabled",
         "Disabled"
       ],
@@ -2155,7 +2134,7 @@
       "items": {
         "$ref": "#/definitions/failoverGroupType"
       },
-      "defaultValue": [],
+      "nullable": true,
       "metadata": {
         "description": "Optional. The failover groups configuration."
       }
@@ -2234,17 +2213,17 @@
       "tags": "[parameters('tags')]",
       "identity": "[variables('identity')]",
       "properties": {
-        "administratorLogin": "[if(not(empty(parameters('administratorLogin'))), parameters('administratorLogin'), null())]",
-        "administratorLoginPassword": "[if(not(empty(parameters('administratorLoginPassword'))), parameters('administratorLoginPassword'), null())]",
+        "administratorLogin": "[parameters('administratorLogin')]",
+        "administratorLoginPassword": "[parameters('administratorLoginPassword')]",
         "administrators": "[union(createObject('administratorType', 'ActiveDirectory'), coalesce(parameters('administrators'), createObject()))]",
         "federatedClientId": "[parameters('federatedClientId')]",
         "isIPv6Enabled": "[parameters('isIPv6Enabled')]",
-        "keyId": "[if(not(equals(parameters('customerManagedKey'), null())), 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())]",
+        "keyId": "[if(not(equals(parameters('customerManagedKey'), null())), if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, tryGet(parameters('customerManagedKey'), 'keyVersion')), reference('cMKKeyVault::cMKKey').keyUriWithVersion), null())]",
         "version": "12.0",
         "minimalTlsVersion": "[parameters('minimalTlsVersion')]",
-        "primaryUserAssignedIdentityId": "[if(not(empty(parameters('primaryUserAssignedIdentityId'))), parameters('primaryUserAssignedIdentityId'), null())]",
+        "primaryUserAssignedIdentityId": "[parameters('primaryUserAssignedIdentityResourceId')]",
         "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(and(not(empty(parameters('privateEndpoints'))), empty(parameters('firewallRules'))), empty(parameters('virtualNetworkRules'))), 'Disabled', null()))]",
-        "restrictOutboundNetworkAccess": "[if(not(empty(parameters('restrictOutboundNetworkAccess'))), parameters('restrictOutboundNetworkAccess'), null())]"
+        "restrictOutboundNetworkAccess": "[parameters('restrictOutboundNetworkAccess')]"
       },
       "dependsOn": [
         "cMKKeyVault::cMKKey"
@@ -2289,7 +2268,7 @@
     "server_databases": {
       "copy": {
         "name": "server_databases",
-        "count": "[length(parameters('databases'))]"
+        "count": "[length(coalesce(parameters('databases'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -2307,124 +2286,124 @@
             "value": "[parameters('location')]"
           },
           "tags": {
-            "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'tags'), parameters('tags'))]"
+            "value": "[coalesce(tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
           },
           "name": {
-            "value": "[parameters('databases')[copyIndex()].name]"
+            "value": "[coalesce(parameters('databases'), createArray())[copyIndex()].name]"
           },
           "managedIdentities": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'managedIdentities')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'managedIdentities')]"
           },
           "sku": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'sku')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'sku')]"
           },
           "autoPauseDelay": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'autoPauseDelay')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'autoPauseDelay')]"
           },
           "availabilityZone": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'availabilityZone')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'availabilityZone')]"
           },
           "catalogCollation": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'catalogCollation')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'catalogCollation')]"
           },
           "collation": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'collation')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'collation')]"
           },
           "createMode": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'createMode')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'createMode')]"
           },
           "elasticPoolResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'elasticPoolResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'elasticPoolResourceId')]"
           },
           "encryptionProtector": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'encryptionProtector')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'encryptionProtector')]"
           },
           "encryptionProtectorAutoRotation": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'encryptionProtectorAutoRotation')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'encryptionProtectorAutoRotation')]"
           },
           "federatedClientId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'federatedClientId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'federatedClientId')]"
           },
           "freeLimitExhaustionBehavior": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'freeLimitExhaustionBehavior')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'freeLimitExhaustionBehavior')]"
           },
           "highAvailabilityReplicaCount": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'highAvailabilityReplicaCount')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'highAvailabilityReplicaCount')]"
           },
           "isLedgerOn": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'isLedgerOn')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'isLedgerOn')]"
           },
           "licenseType": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'licenseType')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'licenseType')]"
           },
           "longTermRetentionBackupResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'longTermRetentionBackupResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'longTermRetentionBackupResourceId')]"
           },
           "maintenanceConfigurationId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'maintenanceConfigurationId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'maintenanceConfigurationId')]"
           },
           "manualCutover": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'manualCutover')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'manualCutover')]"
           },
           "maxSizeBytes": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'maxSizeBytes')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'maxSizeBytes')]"
           },
           "minCapacity": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'minCapacity')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'minCapacity')]"
           },
           "performCutover": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'performCutover')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'performCutover')]"
           },
           "preferredEnclaveType": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'preferredEnclaveType')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'preferredEnclaveType')]"
           },
           "readScale": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'readScale')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'readScale')]"
           },
           "recoverableDatabaseResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'recoverableDatabaseResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'recoverableDatabaseResourceId')]"
           },
           "recoveryServicesRecoveryPointResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'recoveryServicesRecoveryPointResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'recoveryServicesRecoveryPointResourceId')]"
           },
           "requestedBackupStorageRedundancy": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'requestedBackupStorageRedundancy')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'requestedBackupStorageRedundancy')]"
           },
           "restorableDroppedDatabaseResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'restorableDroppedDatabaseResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'restorableDroppedDatabaseResourceId')]"
           },
           "restorePointInTime": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'restorePointInTime')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'restorePointInTime')]"
           },
           "sampleName": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'sampleName')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'sampleName')]"
           },
           "secondaryType": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'secondaryType')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'secondaryType')]"
           },
           "sourceDatabaseDeletionDate": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseDeletionDate')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'sourceDatabaseDeletionDate')]"
           },
           "sourceDatabaseResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceDatabaseResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'sourceDatabaseResourceId')]"
           },
           "sourceResourceId": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'sourceResourceId')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'sourceResourceId')]"
           },
           "useFreeLimit": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'useFreeLimit')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'useFreeLimit')]"
           },
           "zoneRedundant": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'zoneRedundant')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'zoneRedundant')]"
           },
           "diagnosticSettings": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'diagnosticSettings')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'diagnosticSettings')]"
           },
           "backupShortTermRetentionPolicy": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'backupShortTermRetentionPolicy')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'backupShortTermRetentionPolicy')]"
           },
           "backupLongTermRetentionPolicy": {
-            "value": "[tryGet(parameters('databases')[copyIndex()], 'backupLongTermRetentionPolicy')]"
+            "value": "[tryGet(coalesce(parameters('databases'), createArray())[copyIndex()], 'backupLongTermRetentionPolicy')]"
           }
         },
         "template": {
@@ -2435,7 +2414,7 @@
             "_generator": {
               "name": "bicep",
               "version": "0.34.44.8038",
-              "templateHash": "6857638731147235031"
+              "templateHash": "3444518233599497149"
             },
             "name": "SQL Server Database",
             "description": "This module deploys an Azure SQL Server Database."
@@ -2737,16 +2716,15 @@
               }
             },
             "availabilityZone": {
-              "type": "string",
+              "type": "int",
               "allowedValues": [
-                "1",
-                "2",
-                "3",
-                "NoPreference"
+                -1,
+                1,
+                2,
+                3
               ],
-              "defaultValue": "NoPreference",
               "metadata": {
-                "description": "Optional. Specifies the availability zone the database is pinned to."
+                "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
               }
             },
             "catalogCollation": {
@@ -3074,7 +3052,7 @@
               "identity": "[variables('identity')]",
               "properties": {
                 "autoPauseDelay": "[parameters('autoPauseDelay')]",
-                "availabilityZone": "[parameters('availabilityZone')]",
+                "availabilityZone": "[if(not(equals(parameters('availabilityZone'), -1)), string(parameters('availabilityZone')), 'NoPreference')]",
                 "catalogCollation": "[parameters('catalogCollation')]",
                 "collation": "[parameters('collation')]",
                 "createMode": "[parameters('createMode')]",
@@ -3459,7 +3437,7 @@
     "server_elasticPools": {
       "copy": {
         "name": "server_elasticPools",
-        "count": "[length(parameters('elasticPools'))]"
+        "count": "[length(coalesce(parameters('elasticPools'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -3477,43 +3455,43 @@
             "value": "[parameters('location')]"
           },
           "tags": {
-            "value": "[coalesce(tryGet(parameters('elasticPools')[copyIndex()], 'tags'), parameters('tags'))]"
+            "value": "[coalesce(tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
           },
           "name": {
-            "value": "[parameters('elasticPools')[copyIndex()].name]"
+            "value": "[coalesce(parameters('elasticPools'), createArray())[copyIndex()].name]"
           },
           "sku": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'sku')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'sku')]"
           },
           "autoPauseDelay": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'autoPauseDelay')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'autoPauseDelay')]"
           },
           "availabilityZone": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'availabilityZone')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'availabilityZone')]"
           },
           "highAvailabilityReplicaCount": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'highAvailabilityReplicaCount')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'highAvailabilityReplicaCount')]"
           },
           "licenseType": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'licenseType')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'licenseType')]"
           },
           "maintenanceConfigurationId": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'maintenanceConfigurationId')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'maintenanceConfigurationId')]"
           },
           "maxSizeBytes": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'maxSizeBytes')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'maxSizeBytes')]"
           },
           "minCapacity": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'minCapacity')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'minCapacity')]"
           },
           "perDatabaseSettings": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'perDatabaseSettings')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'perDatabaseSettings')]"
           },
           "preferredEnclaveType": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'preferredEnclaveType')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'preferredEnclaveType')]"
           },
           "zoneRedundant": {
-            "value": "[tryGet(parameters('elasticPools')[copyIndex()], 'zoneRedundant')]"
+            "value": "[tryGet(coalesce(parameters('elasticPools'), createArray())[copyIndex()], 'zoneRedundant')]"
           }
         },
         "template": {
@@ -3524,13 +3502,13 @@
             "_generator": {
               "name": "bicep",
               "version": "0.34.44.8038",
-              "templateHash": "15648031842218670048"
+              "templateHash": "6480963111257796466"
             },
             "name": "SQL Server Elastic Pool",
             "description": "This module deploys an Azure SQL Server Elastic Pool."
           },
           "definitions": {
-            "elasticPoolPerDatabaseSettingsType": {
+            "perDatabaseSettingsType": {
               "type": "object",
               "properties": {
                 "autoPauseDelay": {
@@ -3558,7 +3536,7 @@
                 "description": "The per database settings for the elastic pool."
               }
             },
-            "elasticPoolSkuType": {
+            "skuType": {
               "type": "object",
               "properties": {
                 "capacity": {
@@ -3644,7 +3622,7 @@
               }
             },
             "sku": {
-              "$ref": "#/definitions/elasticPoolSkuType",
+              "$ref": "#/definitions/skuType",
               "defaultValue": {
                 "capacity": 2,
                 "name": "GP_Gen5",
@@ -3662,16 +3640,15 @@
               }
             },
             "availabilityZone": {
-              "type": "string",
+              "type": "int",
               "allowedValues": [
-                "1",
-                "2",
-                "3",
-                "NoPreference"
+                -1,
+                1,
+                2,
+                3
               ],
-              "defaultValue": "NoPreference",
               "metadata": {
-                "description": "Optional. Specifies the availability zone the pool's primary replica is pinned to."
+                "description": "Required. If set to 1, 2 or 3, the availability zone is hardcoded to that value. If set to -1, no zone is defined. Note that the availability zone numbers here are the logical availability zone in your Azure subscription. Different subscriptions might have a different mapping of the physical zone and logical zone. To understand more, please refer to [Physical and logical availability zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview?tabs=azure-cli#physical-and-logical-availability-zones)."
               }
             },
             "highAvailabilityReplicaCount": {
@@ -3714,7 +3691,7 @@
               }
             },
             "perDatabaseSettings": {
-              "$ref": "#/definitions/elasticPoolPerDatabaseSettingsType",
+              "$ref": "#/definitions/perDatabaseSettingsType",
               "defaultValue": {
                 "autoPauseDelay": -1,
                 "maxCapacity": "2",
@@ -3759,7 +3736,7 @@
               "sku": "[parameters('sku')]",
               "properties": {
                 "autoPauseDelay": "[parameters('autoPauseDelay')]",
-                "availabilityZone": "[parameters('availabilityZone')]",
+                "availabilityZone": "[if(not(equals(parameters('availabilityZone'), -1)), string(parameters('availabilityZone')), 'NoPreference')]",
                 "highAvailabilityReplicaCount": "[parameters('highAvailabilityReplicaCount')]",
                 "licenseType": "[parameters('licenseType')]",
                 "maintenanceConfigurationId": "[parameters('maintenanceConfigurationId')]",
@@ -4567,7 +4544,7 @@
     "server_firewallRules": {
       "copy": {
         "name": "server_firewallRules",
-        "count": "[length(parameters('firewallRules'))]"
+        "count": "[length(coalesce(parameters('firewallRules'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -4579,16 +4556,16 @@
         "mode": "Incremental",
         "parameters": {
           "name": {
-            "value": "[parameters('firewallRules')[copyIndex()].name]"
+            "value": "[coalesce(parameters('firewallRules'), createArray())[copyIndex()].name]"
           },
           "serverName": {
             "value": "[parameters('name')]"
           },
           "endIpAddress": {
-            "value": "[tryGet(parameters('firewallRules')[copyIndex()], 'endIpAddress')]"
+            "value": "[tryGet(coalesce(parameters('firewallRules'), createArray())[copyIndex()], 'endIpAddress')]"
           },
           "startIpAddress": {
-            "value": "[tryGet(parameters('firewallRules')[copyIndex()], 'startIpAddress')]"
+            "value": "[tryGet(coalesce(parameters('firewallRules'), createArray())[copyIndex()], 'startIpAddress')]"
           }
         },
         "template": {
@@ -4674,7 +4651,7 @@
     "server_virtualNetworkRules": {
       "copy": {
         "name": "server_virtualNetworkRules",
-        "count": "[length(parameters('virtualNetworkRules'))]"
+        "count": "[length(coalesce(parameters('virtualNetworkRules'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -4689,13 +4666,13 @@
             "value": "[parameters('name')]"
           },
           "name": {
-            "value": "[parameters('virtualNetworkRules')[copyIndex()].name]"
+            "value": "[coalesce(parameters('virtualNetworkRules'), createArray())[copyIndex()].name]"
           },
           "ignoreMissingVnetServiceEndpoint": {
-            "value": "[tryGet(parameters('virtualNetworkRules')[copyIndex()], 'ignoreMissingVnetServiceEndpoint')]"
+            "value": "[tryGet(coalesce(parameters('virtualNetworkRules'), createArray())[copyIndex()], 'ignoreMissingVnetServiceEndpoint')]"
           },
-          "virtualNetworkSubnetId": {
-            "value": "[parameters('virtualNetworkRules')[copyIndex()].virtualNetworkSubnetId]"
+          "virtualNetworkSubnetResourceId": {
+            "value": "[coalesce(parameters('virtualNetworkRules'), createArray())[copyIndex()].virtualNetworkSubnetResourceId]"
           }
         },
         "template": {
@@ -4705,7 +4682,7 @@
             "_generator": {
               "name": "bicep",
               "version": "0.34.44.8038",
-              "templateHash": "529105308382514230"
+              "templateHash": "5983453570514916999"
             },
             "name": "Azure SQL Server Virtual Network Rules",
             "description": "This module deploys an Azure SQL Server Virtual Network Rule."
@@ -4724,7 +4701,7 @@
                 "description": "Optional. Allow creating a firewall rule before the virtual network has vnet service endpoint enabled."
               }
             },
-            "virtualNetworkSubnetId": {
+            "virtualNetworkSubnetResourceId": {
               "type": "string",
               "metadata": {
                 "description": "Required. The resource ID of the virtual network subnet."
@@ -4744,7 +4721,7 @@
               "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]",
               "properties": {
                 "ignoreMissingVnetServiceEndpoint": "[parameters('ignoreMissingVnetServiceEndpoint')]",
-                "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetId')]"
+                "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetResourceId')]"
               }
             }
           ],
@@ -4780,7 +4757,7 @@
     "server_securityAlertPolicies": {
       "copy": {
         "name": "server_securityAlertPolicies",
-        "count": "[length(parameters('securityAlertPolicies'))]"
+        "count": "[length(coalesce(parameters('securityAlertPolicies'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -4792,31 +4769,31 @@
         "mode": "Incremental",
         "parameters": {
           "name": {
-            "value": "[parameters('securityAlertPolicies')[copyIndex()].name]"
+            "value": "[coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()].name]"
           },
           "serverName": {
             "value": "[parameters('name')]"
           },
           "disabledAlerts": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'disabledAlerts')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'disabledAlerts')]"
           },
           "emailAccountAdmins": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'emailAccountAdmins')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'emailAccountAdmins')]"
           },
           "emailAddresses": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'emailAddresses')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'emailAddresses')]"
           },
           "retentionDays": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'retentionDays')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'retentionDays')]"
           },
           "state": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'state')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'state')]"
           },
           "storageAccountAccessKey": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'storageAccountAccessKey')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'storageAccountAccessKey')]"
           },
           "storageEndpoint": {
-            "value": "[tryGet(parameters('securityAlertPolicies')[copyIndex()], 'storageEndpoint')]"
+            "value": "[tryGet(coalesce(parameters('securityAlertPolicies'), createArray())[copyIndex()], 'storageEndpoint')]"
           }
         },
         "template": {
@@ -5002,7 +4979,7 @@
             "_generator": {
               "name": "bicep",
               "version": "0.34.44.8038",
-              "templateHash": "16010734059576789187"
+              "templateHash": "15940284955382664780"
             },
             "name": "Azure SQL Server Vulnerability Assessments",
             "description": "This module deploys an Azure SQL Server Vulnerability Assessment."
@@ -5036,7 +5013,8 @@
                 }
               },
               "metadata": {
-                "__bicep_export!": true
+                "__bicep_export!": true,
+                "description": "The type for recurring scans."
               }
             }
           },
@@ -5193,7 +5171,7 @@
     "server_keys": {
       "copy": {
         "name": "server_keys",
-        "count": "[length(parameters('keys'))]"
+        "count": "[length(coalesce(parameters('keys'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -5208,13 +5186,13 @@
             "value": "[parameters('name')]"
           },
           "name": {
-            "value": "[tryGet(parameters('keys')[copyIndex()], 'name')]"
+            "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'name')]"
           },
           "serverKeyType": {
-            "value": "[tryGet(parameters('keys')[copyIndex()], 'serverKeyType')]"
+            "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'serverKeyType')]"
           },
           "uri": {
-            "value": "[tryGet(parameters('keys')[copyIndex()], 'uri')]"
+            "value": "[tryGet(coalesce(parameters('keys'), createArray())[copyIndex()], 'uri')]"
           }
         },
         "template": {
@@ -5328,12 +5306,12 @@
             "value": "[parameters('name')]"
           },
           "name": {
-            "value": "[format('{0}_{1}_{2}', last(split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')), tryGet(parameters('customerManagedKey'), 'keyName'), tryGet(parameters('customerManagedKey'), 'keyVersion'))]"
+            "value": "[format('{0}_{1}_{2}', last(split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')), tryGet(parameters('customerManagedKey'), 'keyName'), if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), tryGet(parameters('customerManagedKey'), 'keyVersion'), last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))]"
           },
           "serverKeyType": {
             "value": "AzureKeyVault"
           },
-          "uri": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), createObject('value', format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, tryGet(parameters('customerManagedKey'), 'keyVersion'))), if(coalesce(tryGet(parameters('customerManagedKey'), 'autoRotationEnabled'), true()), createObject('value', reference('cMKKeyVault::cMKKey').keyUri), createObject('value', reference('cMKKeyVault::cMKKey').keyUriWithVersion)))]"
+          "uri": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), createObject('value', format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, tryGet(parameters('customerManagedKey'), 'keyVersion'))), createObject('value', reference('cMKKeyVault::cMKKey').keyUriWithVersion))]"
         },
         "template": {
           "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -5813,7 +5791,7 @@
             "value": "[last(split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/'))]"
           },
           "secretsToSet": {
-            "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'sqlAdminPasswordSecretName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'sqlAdminPasswordSecretName'), 'value', parameters('administratorLoginPassword'))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'sqlAzureConnectionStringSercretName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'sqlAzureConnectionStringSercretName'), 'value', format('Server={0}; Database={1}; User={2}; Password={3}', reference('server').fullyQualifiedDomainName, if(not(empty(parameters('databases'))), parameters('databases')[0].name, ''), parameters('administratorLogin'), parameters('administratorLoginPassword')))), createArray()))]"
+            "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'sqlAdminPasswordSecretName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'sqlAdminPasswordSecretName'), 'value', parameters('administratorLoginPassword'))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'sqlAzureConnectionStringSercretName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'sqlAzureConnectionStringSercretName'), 'value', format('Server={0}; Database={1}; User={2}; Password={3}', reference('server').fullyQualifiedDomainName, if(not(empty(parameters('databases'))), tryGet(parameters('databases'), 0, 'name'), ''), parameters('administratorLogin'), parameters('administratorLoginPassword')))), createArray()))]"
           }
         },
         "template": {
@@ -5946,7 +5924,7 @@
     "failover_groups": {
       "copy": {
         "name": "failover_groups",
-        "count": "[length(parameters('failoverGroups'))]"
+        "count": "[length(coalesce(parameters('failoverGroups'), createArray()))]"
       },
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2022-09-01",
@@ -5958,28 +5936,28 @@
         "mode": "Incremental",
         "parameters": {
           "name": {
-            "value": "[parameters('failoverGroups')[copyIndex()].name]"
+            "value": "[coalesce(parameters('failoverGroups'), createArray())[copyIndex()].name]"
           },
           "tags": {
-            "value": "[coalesce(tryGet(parameters('failoverGroups')[copyIndex()], 'tags'), parameters('tags'))]"
+            "value": "[coalesce(tryGet(coalesce(parameters('failoverGroups'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
           },
           "serverName": {
             "value": "[parameters('name')]"
           },
           "databases": {
-            "value": "[parameters('failoverGroups')[copyIndex()].databases]"
+            "value": "[coalesce(parameters('failoverGroups'), createArray())[copyIndex()].databases]"
           },
           "partnerServers": {
-            "value": "[parameters('failoverGroups')[copyIndex()].partnerServers]"
+            "value": "[coalesce(parameters('failoverGroups'), createArray())[copyIndex()].partnerServers]"
           },
           "readOnlyEndpoint": {
-            "value": "[tryGet(parameters('failoverGroups')[copyIndex()], 'readOnlyEndpoint')]"
+            "value": "[tryGet(coalesce(parameters('failoverGroups'), createArray())[copyIndex()], 'readOnlyEndpoint')]"
           },
           "readWriteEndpoint": {
-            "value": "[parameters('failoverGroups')[copyIndex()].readWriteEndpoint]"
+            "value": "[coalesce(parameters('failoverGroups'), createArray())[copyIndex()].readWriteEndpoint]"
           },
           "secondaryType": {
-            "value": "[parameters('failoverGroups')[copyIndex()].secondaryType]"
+            "value": "[coalesce(parameters('failoverGroups'), createArray())[copyIndex()].secondaryType]"
           }
         },
         "template": {
@@ -5990,13 +5968,13 @@
             "_generator": {
               "name": "bicep",
               "version": "0.34.44.8038",
-              "templateHash": "5841212065211909434"
+              "templateHash": "16705539934522968897"
             },
             "name": "Azure SQL Server failover group",
             "description": "This module deploys Azure SQL Server failover group."
           },
           "definitions": {
-            "failoverGroupReadOnlyEndpointType": {
+            "readOnlyEndpointType": {
               "type": "object",
               "properties": {
                 "failoverPolicy": {
@@ -6017,10 +5995,11 @@
                 }
               },
               "metadata": {
-                "__bicep_export!": true
+                "__bicep_export!": true,
+                "description": "The type for a read-only endpoint."
               }
             },
-            "failoverGroupReadWriteEndpointType": {
+            "readWriteEndpointType": {
               "type": "object",
               "properties": {
                 "failoverPolicy": {
@@ -6042,7 +6021,8 @@
                 }
               },
               "metadata": {
-                "__bicep_export!": true
+                "__bicep_export!": true,
+                "description": "The type for a read-write endpoint."
               }
             }
           },
@@ -6078,14 +6058,14 @@
               }
             },
             "readOnlyEndpoint": {
-              "$ref": "#/definitions/failoverGroupReadOnlyEndpointType",
+              "$ref": "#/definitions/readOnlyEndpointType",
               "nullable": true,
               "metadata": {
                 "description": "Optional. Read-only endpoint of the failover group instance."
               }
             },
             "readWriteEndpoint": {
-              "$ref": "#/definitions/failoverGroupReadWriteEndpointType",
+              "$ref": "#/definitions/readWriteEndpointType",
               "metadata": {
                 "description": "Required. Read-write endpoint of the failover group instance."
               }
diff --git a/avm/res/sql/server/tests/e2e/cmk/dependencies.bicep b/avm/res/sql/server/tests/e2e/cmk/dependencies.bicep
index c3add13a0d4..ffa67fddf37 100644
--- a/avm/res/sql/server/tests/e2e/cmk/dependencies.bicep
+++ b/avm/res/sql/server/tests/e2e/cmk/dependencies.bicep
@@ -35,13 +35,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
       kty: 'RSA'
     }
   }
-
-  resource dbKey 'keys@2022-07-01' = {
-    name: 'keyDatabaseEncryptionKey'
-    properties: {
-      kty: 'RSA'
-    }
-  }
 }
 
 resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
@@ -57,19 +50,6 @@ resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   }
 }
 
-resource dbKeyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
-  name: guid('msi-${keyVault::dbKey.id}-${location}-${managedIdentity.id}-Key-Vault-Crypto-Service-Encryption-User-RoleAssignment')
-  scope: keyVault::dbKey
-  properties: {
-    principalId: managedIdentity.properties.principalId
-    roleDefinitionId: subscriptionResourceId(
-      'Microsoft.Authorization/roleDefinitions',
-      'e147488a-f6f5-4113-8e2d-b22465e65bf6'
-    ) // Key Vault Crypto Service Encryption User
-    principalType: 'ServicePrincipal'
-  }
-}
-
 @description('The principal ID of the created managed identity.')
 output managedIdentityPrincipalId string = managedIdentity.properties.principalId
 
@@ -82,12 +62,6 @@ output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVers
 @description('The name of the created Key Vault Encryption Key.')
 output keyVaultKeyName string = keyVault::key.name
 
-@description('The URL of the created Key Vault Database Encryption Key.')
-output keyVaultDatabaseEncryptionKeyUrl string = keyVault::dbKey.properties.keyUriWithVersion
-
-@description('The name of the created Key Vault Database Encryption Key.')
-output keyVaultDatabaseKeyName string = keyVault::dbKey.name
-
 @description('The name of the created Key Vault.')
 output keyVaultName string = keyVault.name
 
diff --git a/avm/res/sql/server/tests/e2e/cmk/main.test.bicep b/avm/res/sql/server/tests/e2e/cmk/main.test.bicep
index 2fa569a3cb2..0bdb573d87f 100644
--- a/avm/res/sql/server/tests/e2e/cmk/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/cmk/main.test.bicep
@@ -12,7 +12,8 @@ metadata description = 'This instance deploys the module with Customer-Managed-K
 param resourceGroupName string = 'dep-${namePrefix}-sql.servers-${serviceShort}-rg'
 
 @description('Optional. The location to deploy resources to.')
-param resourceLocation string = deployment().location
+// param resourceLocation string = deployment().location
+var resourceLocation = 'eastasia'
 
 @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 = 'sscmk'
@@ -55,7 +56,7 @@ module testDeployment '../../../main.bicep' = [
     name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
     params: {
       name: '${namePrefix}${serviceShort}001'
-      primaryUserAssignedIdentityId: nestedDependencies.outputs.managedIdentityResourceId
+      primaryUserAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId
       administrators: {
         azureADOnlyAuthentication: true
         login: 'myspn'
@@ -63,14 +64,12 @@ module testDeployment '../../../main.bicep' = [
         principalType: 'Application'
         tenantId: tenant().tenantId
       }
-
       managedIdentities: {
         systemAssigned: false
         userAssignedResourceIds: [
           nestedDependencies.outputs.managedIdentityResourceId
         ]
       }
-
       customerManagedKey: {
         keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId
         keyName: nestedDependencies.outputs.keyVaultKeyName
diff --git a/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep b/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep
index 99153efae46..00f0768f9d2 100644
--- a/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/elasticPool/main.test.bicep
@@ -54,6 +54,7 @@ module testDeployment '../../../main.bicep' = [
         {
           name: '${namePrefix}-${serviceShort}-ep-001'
           zoneRedundant: false
+          availabilityZone: -1
         }
         // more complex elastic pool with non-default SKU and per database settings
         {
@@ -68,6 +69,7 @@ module testDeployment '../../../main.bicep' = [
             maxCapacity: '4'
           }
           zoneRedundant: false
+          availabilityZone: -1
         }
       ]
     }
diff --git a/avm/res/sql/server/tests/e2e/failover-group/main.test.bicep b/avm/res/sql/server/tests/e2e/failover-group/main.test.bicep
index d8ff3b2a5fd..6abb05d72f9 100644
--- a/avm/res/sql/server/tests/e2e/failover-group/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/failover-group/main.test.bicep
@@ -70,6 +70,7 @@ module testDeployment '../../../main.bicep' = [
           }
           maxSizeBytes: 2147483648
           zoneRedundant: false
+          availabilityZone: -1
         }
         {
           name: '${namePrefix}-${serviceShort}-db2'
@@ -79,8 +80,8 @@ module testDeployment '../../../main.bicep' = [
             capacity: 2
           }
           maxSizeBytes: 2147483648
-          // licenseType: 'LicenseIncluded'
           zoneRedundant: false
+          availabilityZone: -1
         }
         {
           name: '${namePrefix}-${serviceShort}-db3'
@@ -90,6 +91,7 @@ module testDeployment '../../../main.bicep' = [
           }
           maxSizeBytes: 2147483648
           zoneRedundant: false
+          availabilityZone: -1
         }
       ]
       failoverGroups: [
diff --git a/avm/res/sql/server/tests/e2e/kvSecrets/main.test.bicep b/avm/res/sql/server/tests/e2e/kvSecrets/main.test.bicep
index 06f60cb7438..6500c92f836 100644
--- a/avm/res/sql/server/tests/e2e/kvSecrets/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/kvSecrets/main.test.bicep
@@ -67,6 +67,7 @@ module testDeployment '../../../main.bicep' = [
         {
           name: 'myDatabase'
           zoneRedundant: false
+          availabilityZone: -1
         }
       ]
     }
diff --git a/avm/res/sql/server/tests/e2e/max/main.test.bicep b/avm/res/sql/server/tests/e2e/max/main.test.bicep
index aa05ce92a6c..9f5d792fd37 100644
--- a/avm/res/sql/server/tests/e2e/max/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/max/main.test.bicep
@@ -80,7 +80,7 @@ module testDeployment '../../../main.bicep' = [
         kind: 'CanNotDelete'
         name: 'myCustomLockName'
       }
-      primaryUserAssignedIdentityId: nestedDependencies.outputs.serverIdentityResourceId
+      primaryUserAssignedIdentityResourceId: nestedDependencies.outputs.serverIdentityResourceId
       administratorLogin: 'adminUserName'
       administratorLoginPassword: password
       location: enforcedLocation
@@ -126,6 +126,7 @@ module testDeployment '../../../main.bicep' = [
             tier: 'GeneralPurpose'
             capacity: 10
           }
+          availabilityZone: -1
         }
       ]
       databases: [
@@ -160,6 +161,7 @@ module testDeployment '../../../main.bicep' = [
           backupLongTermRetentionPolicy: {
             monthlyRetention: 'P6M'
           }
+          availabilityZone: -1
         }
       ]
       customerManagedKey: {
@@ -219,7 +221,7 @@ module testDeployment '../../../main.bicep' = [
         {
           ignoreMissingVnetServiceEndpoint: true
           name: 'newVnetRule1'
-          virtualNetworkSubnetId: nestedDependencies.outputs.serviceEndpointSubnetResourceId
+          virtualNetworkSubnetResourceId: nestedDependencies.outputs.serviceEndpointSubnetResourceId
         }
       ]
       restrictOutboundNetworkAccess: 'Disabled'
diff --git a/avm/res/sql/server/tests/e2e/secondary/main.test.bicep b/avm/res/sql/server/tests/e2e/secondary/main.test.bicep
index a0379cc734a..c7cb01294ca 100644
--- a/avm/res/sql/server/tests/e2e/secondary/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/secondary/main.test.bicep
@@ -68,6 +68,7 @@ module testDeployment '../../../main.bicep' = [
           createMode: 'Secondary'
           sourceDatabaseResourceId: nestedDependencies.outputs.databaseResourceId
           zoneRedundant: false
+          availabilityZone: -1
         }
       ]
       tags: {
diff --git a/avm/res/sql/server/tests/e2e/vulnAssm/main.test.bicep b/avm/res/sql/server/tests/e2e/vulnAssm/main.test.bicep
index 6a7658aa21d..2d59fd59b92 100644
--- a/avm/res/sql/server/tests/e2e/vulnAssm/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/vulnAssm/main.test.bicep
@@ -55,7 +55,7 @@ module testDeployment '../../../main.bicep' = [
     name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
     params: {
       name: '${namePrefix}-${serviceShort}'
-      primaryUserAssignedIdentityId: nestedDependencies.outputs.managedIdentityResourceId
+      primaryUserAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId
       administratorLogin: 'adminUserName'
       administratorLoginPassword: password
       location: resourceLocation
diff --git a/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep b/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep
index 13f764f25ad..72c11ab79ef 100644
--- a/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep
+++ b/avm/res/sql/server/tests/e2e/waf-aligned/main.test.bicep
@@ -71,7 +71,7 @@ module testDeployment '../../../main.bicep' = [
     name: '${uniqueString(deployment().name, enforcedLocation)}-test-${serviceShort}-${iteration}'
     params: {
       name: '${namePrefix}-${serviceShort}'
-      primaryUserAssignedIdentityId: nestedDependencies.outputs.managedIdentityResourceId
+      primaryUserAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId
       administrators: {
         azureADOnlyAuthentication: true
         login: 'myspn'
@@ -100,6 +100,7 @@ module testDeployment '../../../main.bicep' = [
             tier: 'GeneralPurpose'
             capacity: 10
           }
+          availabilityZone: -1 // SQLDB_GP_Gen5_10 does not support availability zone 1
           maintenanceConfigurationId: '${subscription().id}/providers/Microsoft.Maintenance/publicMaintenanceConfigurations/SQL_${enforcedLocation}_DB_1'
         }
       ]
@@ -130,6 +131,7 @@ module testDeployment '../../../main.bicep' = [
           backupLongTermRetentionPolicy: {
             monthlyRetention: 'P6M'
           }
+          availabilityZone: 1
         }
       ]
       customerManagedKey: {
@@ -173,7 +175,7 @@ module testDeployment '../../../main.bicep' = [
         {
           ignoreMissingVnetServiceEndpoint: true
           name: 'newVnetRule1'
-          virtualNetworkSubnetId: nestedDependencies.outputs.serviceEndpointSubnetResourceId
+          virtualNetworkSubnetResourceId: nestedDependencies.outputs.serviceEndpointSubnetResourceId
         }
       ]
       restrictOutboundNetworkAccess: 'Disabled'
diff --git a/avm/res/sql/server/version.json b/avm/res/sql/server/version.json
index 7d87cc7c016..3c63f3c3df7 100644
--- a/avm/res/sql/server/version.json
+++ b/avm/res/sql/server/version.json
@@ -1,6 +1,6 @@
 {
   "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#",
-  "version": "0.15",
+  "version": "0.16",
   "pathFilters": [
     "./main.json"
   ]
diff --git a/avm/res/sql/server/virtual-network-rule/README.md b/avm/res/sql/server/virtual-network-rule/README.md
index f044d5d22eb..342d15bda5f 100644
--- a/avm/res/sql/server/virtual-network-rule/README.md
+++ b/avm/res/sql/server/virtual-network-rule/README.md
@@ -21,7 +21,7 @@ This module deploys an Azure SQL Server Virtual Network Rule.
 | Parameter | Type | Description |
 | :-- | :-- | :-- |
 | [`name`](#parameter-name) | string | The name of the Server Virtual Network Rule. |
-| [`virtualNetworkSubnetId`](#parameter-virtualnetworksubnetid) | string | The resource ID of the virtual network subnet. |
+| [`virtualNetworkSubnetResourceId`](#parameter-virtualnetworksubnetresourceid) | string | The resource ID of the virtual network subnet. |
 
 **Conditional parameters**
 
@@ -42,7 +42,7 @@ The name of the Server Virtual Network Rule.
 - Required: Yes
 - Type: string
 
-### Parameter: `virtualNetworkSubnetId`
+### Parameter: `virtualNetworkSubnetResourceId`
 
 The resource ID of the virtual network subnet.
 
diff --git a/avm/res/sql/server/virtual-network-rule/main.bicep b/avm/res/sql/server/virtual-network-rule/main.bicep
index af4f7a05b73..c16c32cb495 100644
--- a/avm/res/sql/server/virtual-network-rule/main.bicep
+++ b/avm/res/sql/server/virtual-network-rule/main.bicep
@@ -8,7 +8,7 @@ param name string
 param ignoreMissingVnetServiceEndpoint bool = false
 
 @description('Required. The resource ID of the virtual network subnet.')
-param virtualNetworkSubnetId string
+param virtualNetworkSubnetResourceId string
 
 @description('Conditional. The name of the parent SQL Server. Required if the template is used in a standalone deployment.')
 param serverName string
@@ -22,7 +22,7 @@ resource virtualNetworkRule 'Microsoft.Sql/servers/virtualNetworkRules@2023-08-0
   parent: server
   properties: {
     ignoreMissingVnetServiceEndpoint: ignoreMissingVnetServiceEndpoint
-    virtualNetworkSubnetId: virtualNetworkSubnetId
+    virtualNetworkSubnetId: virtualNetworkSubnetResourceId
   }
 }
 
diff --git a/avm/res/sql/server/virtual-network-rule/main.json b/avm/res/sql/server/virtual-network-rule/main.json
index fc25828dbba..13dc137ec3c 100644
--- a/avm/res/sql/server/virtual-network-rule/main.json
+++ b/avm/res/sql/server/virtual-network-rule/main.json
@@ -5,7 +5,7 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "529105308382514230"
+      "templateHash": "5983453570514916999"
     },
     "name": "Azure SQL Server Virtual Network Rules",
     "description": "This module deploys an Azure SQL Server Virtual Network Rule."
@@ -24,7 +24,7 @@
         "description": "Optional. Allow creating a firewall rule before the virtual network has vnet service endpoint enabled."
       }
     },
-    "virtualNetworkSubnetId": {
+    "virtualNetworkSubnetResourceId": {
       "type": "string",
       "metadata": {
         "description": "Required. The resource ID of the virtual network subnet."
@@ -44,7 +44,7 @@
       "name": "[format('{0}/{1}', parameters('serverName'), parameters('name'))]",
       "properties": {
         "ignoreMissingVnetServiceEndpoint": "[parameters('ignoreMissingVnetServiceEndpoint')]",
-        "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetId')]"
+        "virtualNetworkSubnetId": "[parameters('virtualNetworkSubnetResourceId')]"
       }
     }
   ],
diff --git a/avm/res/sql/server/vulnerability-assessment/main.bicep b/avm/res/sql/server/vulnerability-assessment/main.bicep
index 5ee25a654b7..704adc1b1fa 100644
--- a/avm/res/sql/server/vulnerability-assessment/main.bicep
+++ b/avm/res/sql/server/vulnerability-assessment/main.bicep
@@ -50,6 +50,7 @@ resource vulnerabilityAssessment 'Microsoft.Sql/servers/vulnerabilityAssessments
 }
 
 @export()
+@description('The type for recurring scans.')
 type recurringScansType = {
   @description('Required. Specifies an array of e-mail addresses to which the scan notification is sent.')
   emails: string[]
diff --git a/avm/res/sql/server/vulnerability-assessment/main.json b/avm/res/sql/server/vulnerability-assessment/main.json
index 9746096a98c..fac9434948e 100644
--- a/avm/res/sql/server/vulnerability-assessment/main.json
+++ b/avm/res/sql/server/vulnerability-assessment/main.json
@@ -6,7 +6,7 @@
     "_generator": {
       "name": "bicep",
       "version": "0.34.44.8038",
-      "templateHash": "16010734059576789187"
+      "templateHash": "15940284955382664780"
     },
     "name": "Azure SQL Server Vulnerability Assessments",
     "description": "This module deploys an Azure SQL Server Vulnerability Assessment."
@@ -40,7 +40,8 @@
         }
       },
       "metadata": {
-        "__bicep_export!": true
+        "__bicep_export!": true,
+        "description": "The type for recurring scans."
       }
     }
   },


Reviews:
user: login: peterbud
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-27T11:02:51Z
user: login: AlexanderSehr
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-27T11:41:44Z
user: login: peterbud
body: Thanks once again!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-27T11:44:06Z

Review comments:
path: avm/res/sql/server/tests/e2e/cmk/dependencies.bicep
user: login: peterbud
body: It's OK to remove the dbKey, we can put it back once we get to the implementation of database level CMK
created_at: 2025-04-27T11:02:51Z
author_association: CONTRIBUTOR
path: avm/res/sql/server/tests/e2e/cmk/dependencies.bicep
user: login: AlexanderSehr
body: Correct. It's currently not used and at least was a bit confusing for me, when troubleshooting 😄 Let's add it when we need it. 
created_at: 2025-04-27T11:41:44Z
author_association: COLLABORATOR

PR comments:
user: login: peterbud
created_at: 2025-04-27T11:14:17Z
body: That's a lot of changes - thank you!

Question:
Theoretically the user still can configure the CMK without the `keyVersion`, right? I could not figure out what happens in the following cases:
  * `keyVersion` provided, `autoRotation` set to true: that's where we have a test set up, so that works
  * `keyVersion` NOT provided, `autoRotation` set to true
  * `keyVersion` provided, `autoRotation` set to false
  * `keyVersion` NOT provided, `autoRotation` set to false
author_association: CONTRIBUTOR
user: login: AlexanderSehr
created_at: 2025-04-27T11:40:58Z
body: > That's a lot of changes - thank you!
> 
> Question: Theoretically the user still can configure the CMK without the `keyVersion`, right? I could not figure out what happens in the following cases:
> 
> * `keyVersion` provided, `autoRotation` set to true: that's where we have a test set up, so that works
> * `keyVersion` NOT provided, `autoRotation` set to true
> * `keyVersion` provided, `autoRotation` set to false
> * `keyVersion` NOT provided, `autoRotation` set to false

Hey @peterbud,
it is indeed an interesting case as the resource has this kinda odd `encryption-protector` resource. For your cases, my understanding the following:
 - `keyVersion` provided, `autoRotation` set to true: that's where we have a test set up, so that works
   -  In this case, the key version is used for the initial version. If it were to change in the key vault via a new version (see screenshots), the auto-rotation will pick up on it a few minutes later
 - `keyVersion` NOT provided, `autoRotation` set to true
   - In this case, the same applies as in the previous case, just that the template will catch the latest version at the deployment time for the user. Again, if that key is updated in the key vault, the auto-ration will pick up on it. The key version remains mandatory for the RP - but - providing it is optional for the user because the template automatically gets the latest for him/her.  
 - `keyVersion` provided, `autoRotation` set to false
   - In this case, the key version specified will be used. An update to the same in the key vault will **not** be picked up by the RP and it will continue to use the version specified at deployment time. 
 - `keyVersion` NOT provided, `autoRotation` set to false
   - Finally, in this case, the template again fetches the latest version at deployment time on behalf of the user. The RP will **not** pick up on any updates to that key in the keyvault and continue to use the original version.

I hope that makes sense :)
author_association: COLLABORATOR