-### Example 11: _SQL Database_
+### Example 11: _Deploying with a sql role definision and assignment_
+
+This instance deploys the module with sql role definision and assignment
+
+
+
+
+via Bicep module
+
+```bicep
+module databaseAccount 'br/public:avm/res/document-db/database-account:' = {
+ name: 'databaseAccountDeployment'
+ params: {
+ // Required parameters
+ name: 'role-ref'
+ // Non-required parameters
+ location: ''
+ sqlRoleAssignmentsPrincipalIds: [
+ ''
+ ]
+ sqlRoleDefinitions: [
+ {
+ name: 'cosmos-sql-role-test'
+ }
+ ]
+ }
+}
+```
+
+
+
+
+
+
+via JSON Parameter file
+
+```json
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ // Required parameters
+ "name": {
+ "value": "role-ref"
+ },
+ // Non-required parameters
+ "location": {
+ "value": ""
+ },
+ "sqlRoleAssignmentsPrincipalIds": {
+ "value": [
+ ""
+ ]
+ },
+ "sqlRoleDefinitions": {
+ "value": [
+ {
+ "name": "cosmos-sql-role-test"
+ }
+ ]
+ }
+ }
+}
+```
+
+
+
+
+### Example 12: _SQL Database_
This instance deploys the module with a SQL Database.
@@ -2056,7 +2127,7 @@ module databaseAccount 'br/public:avm/res/document-db/database-account:
-### Example 12: _WAF-aligned_
+### Example 13: _WAF-aligned_
This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.
@@ -2251,6 +2322,8 @@ module databaseAccount 'br/public:avm/res/document-db/database-account:
| [`secretsKeyVault`](#parameter-secretskeyvault) | object | Key vault reference and secret settings to add the connection strings and keys generated by the cosmosdb account. |
| [`serverVersion`](#parameter-serverversion) | string | Default to 4.2. Specifies the MongoDB server version to use. |
| [`sqlDatabases`](#parameter-sqldatabases) | array | SQL Databases configurations. |
+| [`sqlRoleAssignmentsPrincipalIds`](#parameter-sqlroleassignmentsprincipalids) | array | SQL Role Definitions configurations. |
+| [`sqlRoleDefinitions`](#parameter-sqlroledefinitions) | array | SQL Role Definitions configurations. |
| [`tags`](#parameter-tags) | object | Tags of the Database Account resource. |
### Parameter: `name`
@@ -3554,6 +3627,70 @@ Default to 400. Request units per second. Will be ignored if autoscaleSettingsMa
- Required: No
- Type: int
+### Parameter: `sqlRoleAssignmentsPrincipalIds`
+
+SQL Role Definitions configurations.
+
+- Required: No
+- Type: array
+- Default: `[]`
+
+### Parameter: `sqlRoleDefinitions`
+
+SQL Role Definitions configurations.
+
+- Required: No
+- Type: array
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`name`](#parameter-sqlroledefinitionsname) | string | Name of the SQL Role Definition. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`dataAction`](#parameter-sqlroledefinitionsdataaction) | array | An array of data actions that are allowed. |
+| [`roleName`](#parameter-sqlroledefinitionsrolename) | string | A user-friendly name for the Role Definition. Must be unique for the database account. |
+| [`roleType`](#parameter-sqlroledefinitionsroletype) | string | Indicates whether the Role Definition was built-in or user created. |
+
+### Parameter: `sqlRoleDefinitions.name`
+
+Name of the SQL Role Definition.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `sqlRoleDefinitions.dataAction`
+
+An array of data actions that are allowed.
+
+- Required: No
+- Type: array
+
+### Parameter: `sqlRoleDefinitions.roleName`
+
+A user-friendly name for the Role Definition. Must be unique for the database account.
+
+- Required: No
+- Type: string
+
+### Parameter: `sqlRoleDefinitions.roleType`
+
+Indicates whether the Role Definition was built-in or user created.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ 'BuiltInRole'
+ 'CustomRole'
+ ]
+ ```
+
### Parameter: `tags`
Tags of the Database Account resource.
@@ -3566,6 +3703,7 @@ Tags of the Database Account resource.
| Output | Type | Description |
| :-- | :-- | :-- |
+| `endpoint` | string | The endpoint of the database account. |
| `location` | string | The location the resource was deployed into. |
| `name` | string | The name of the database account. |
| `resourceGroupName` | string | The name of the resource group the database account was created in. |
diff --git a/avm/res/document-db/database-account/main.bicep b/avm/res/document-db/database-account/main.bicep
index 3e8626e9c9..c8c33f24c2 100644
--- a/avm/res/document-db/database-account/main.bicep
+++ b/avm/res/document-db/database-account/main.bicep
@@ -73,6 +73,12 @@ param serverVersion string = '4.2'
@description('Optional. SQL Databases configurations.')
param sqlDatabases sqlDatabaseType[] = []
+@description('Optional. SQL Role Definitions configurations.')
+param sqlRoleAssignmentsPrincipalIds array = []
+
+@description('Optional. SQL Role Definitions configurations.')
+param sqlRoleDefinitions sqlRoleDefinitionsType
+
@description('Optional. MongoDB Databases configurations.')
param mongodbDatabases array = []
@@ -408,6 +414,20 @@ module databaseAccount_sqlDatabases 'sql-database/main.bicep' = [
}
]
+module databaseAccount_sqlRoleDefinitions 'sql-role/main.bicep' = [
+ for sqlRoleDefinition in (sqlRoleDefinitions ?? []): {
+ name: '${uniqueString(deployment().name, location)}-sqlrd-${sqlRoleDefinition.name}'
+ params: {
+ name: sqlRoleDefinition.name
+ databaseAccountName: databaseAccount.name
+ dataActions: sqlRoleDefinition.?dataActions
+ roleName: sqlRoleDefinition.?roleName
+ roleType: sqlRoleDefinition.?roleType
+ principalIds: sqlRoleAssignmentsPrincipalIds
+ }
+ }
+]
+
module databaseAccount_mongodbDatabases 'mongodb-database/main.bicep' = [
for mongodbDatabase in mongodbDatabases: {
name: '${uniqueString(deployment().name, location)}-mongodb-${mongodbDatabase.name}'
@@ -546,6 +566,9 @@ output systemAssignedMIPrincipalId string = databaseAccount.?identity.?principal
@description('The location the resource was deployed into.')
output location string = databaseAccount.location
+@description('The endpoint of the database account.')
+output endpoint string = databaseAccount.properties.documentEndpoint
+
// =============== //
// Definitions //
// =============== //
@@ -722,6 +745,20 @@ type failoverLocationsType = {
locationName: string
}
+type sqlRoleDefinitionsType = {
+ @description('Required. Name of the SQL Role Definition.')
+ name: string
+
+ @description('Optional. An array of data actions that are allowed.')
+ dataAction: array?
+
+ @description('Optional. A user-friendly name for the Role Definition. Must be unique for the database account.')
+ roleName: string?
+
+ @description('Optional. Indicates whether the Role Definition was built-in or user created.')
+ roleType: ('CustomRole' | 'BuiltInRole')?
+}[]?
+
type sqlDatabaseType = {
@description('Required. Name of the SQL database .')
name: string
diff --git a/avm/res/document-db/database-account/main.json b/avm/res/document-db/database-account/main.json
index ec16d7c7a8..bd68978465 100644
--- a/avm/res/document-db/database-account/main.json
+++ b/avm/res/document-db/database-account/main.json
@@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "5516885052191994610"
+ "version": "0.28.1.47646",
+ "templateHash": "17921062197239369089"
},
"name": "DocumentDB Database Accounts",
"description": "This module deploys a DocumentDB Database Account.",
@@ -467,6 +467,46 @@
}
}
},
+ "sqlRoleDefinitionsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role Definition."
+ }
+ },
+ "dataAction": {
+ "type": "array",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "allowedValues": [
+ "BuiltInRole",
+ "CustomRole"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
"sqlDatabaseType": {
"type": "object",
"properties": {
@@ -907,6 +947,19 @@
"description": "Optional. SQL Databases configurations."
}
},
+ "sqlRoleAssignmentsPrincipalIds": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. SQL Role Definitions configurations."
+ }
+ },
+ "sqlRoleDefinitions": {
+ "$ref": "#/definitions/sqlRoleDefinitionsType",
+ "metadata": {
+ "description": "Optional. SQL Role Definitions configurations."
+ }
+ },
"mongodbDatabases": {
"type": "array",
"defaultValue": [],
@@ -1260,8 +1313,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "8319829662998768775"
+ "version": "0.28.1.47646",
+ "templateHash": "5335306568168720143"
},
"name": "DocumentDB Database Account SQL Databases",
"description": "This module deploys a SQL Database in a CosmosDB Account.",
@@ -1393,8 +1446,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "3824205620211058652"
+ "version": "0.28.1.47646",
+ "templateHash": "18224989843504865412"
},
"name": "DocumentDB Database Account SQL Database Containers",
"description": "This module deploys a SQL Database Container in a CosmosDB Account.",
@@ -1611,6 +1664,330 @@
"databaseAccount"
]
},
+ "databaseAccount_sqlRoleDefinitions": {
+ "copy": {
+ "name": "databaseAccount_sqlRoleDefinitions",
+ "count": "[length(coalesce(parameters('sqlRoleDefinitions'), createArray()))]"
+ },
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-sqlrd-{1}', uniqueString(deployment().name, parameters('location')), coalesce(parameters('sqlRoleDefinitions'), createArray())[copyIndex()].name)]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[coalesce(parameters('sqlRoleDefinitions'), createArray())[copyIndex()].name]"
+ },
+ "databaseAccountName": {
+ "value": "[parameters('name')]"
+ },
+ "dataActions": {
+ "value": "[tryGet(coalesce(parameters('sqlRoleDefinitions'), createArray())[copyIndex()], 'dataActions')]"
+ },
+ "roleName": {
+ "value": "[tryGet(coalesce(parameters('sqlRoleDefinitions'), createArray())[copyIndex()], 'roleName')]"
+ },
+ "roleType": {
+ "value": "[tryGet(coalesce(parameters('sqlRoleDefinitions'), createArray())[copyIndex()], 'roleType')]"
+ },
+ "principalIds": {
+ "value": "[parameters('sqlRoleAssignmentsPrincipalIds')]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "6438933554145929110"
+ },
+ "name": "DocumentDB Database Account SQL Role.",
+ "description": "This module deploys SQL Role Definision and Assignment in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role."
+ }
+ },
+ "dataActions": {
+ "type": "array",
+ "defaultValue": [
+ "Microsoft.DocumentDB/databaseAccounts/readMetadata",
+ "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
+ "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
+ ],
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "principalIds": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. Ids needs to be granted."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "defaultValue": "Reader Writer",
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "defaultValue": "CustomRole",
+ "allowedValues": [
+ "CustomRole",
+ "BuiltInRole"
+ ],
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('sql-role-definition-{0}', uniqueString(parameters('name')))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "databaseAccountName": {
+ "value": "[parameters('databaseAccountName')]"
+ },
+ "dataActions": {
+ "value": "[parameters('dataActions')]"
+ },
+ "roleName": {
+ "value": "[parameters('roleName')]"
+ },
+ "roleType": {
+ "value": "[parameters('roleType')]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "5774063578247320117"
+ },
+ "name": "DocumentDB Database Account SQL Role Definitions.",
+ "description": "This module deploys a SQL Role Definision in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "dataActions": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "defaultValue": "Reader Writer",
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "defaultValue": "CustomRole",
+ "allowedValues": [
+ "CustomRole",
+ "BuiltInRole"
+ ],
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]",
+ "properties": {
+ "assignableScopes": [
+ "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ ],
+ "permissions": [
+ {
+ "dataActions": "[parameters('dataActions')]"
+ }
+ ],
+ "roleName": "[parameters('roleName')]",
+ "type": "[parameters('roleType')]"
+ }
+ }
+ ],
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the SQL database."
+ },
+ "value": "[guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the SQL database."
+ },
+ "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL database was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ }
+ },
+ {
+ "copy": {
+ "name": "sqlRoleAssignment",
+ "count": "[length(parameters('principalIds'))]",
+ "mode": "serial",
+ "batchSize": 1
+ },
+ "condition": "[not(empty(parameters('principalIds')[copyIndex()]))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('sql-role-assign-{0}', uniqueString(parameters('principalIds')[copyIndex()]))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[guid(reference(resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name')))), '2022-09-01').outputs.resourceId.value, parameters('principalIds')[copyIndex()], resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')))]"
+ },
+ "databaseAccountName": {
+ "value": "[parameters('databaseAccountName')]"
+ },
+ "roleDefinitionId": {
+ "value": "[reference(resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name')))), '2022-09-01').outputs.resourceId.value]"
+ },
+ "principalId": {
+ "value": "[parameters('principalIds')[copyIndex()]]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "4968352550056104037"
+ },
+ "name": "DocumentDB Database Account SQL Role Assignments.",
+ "description": "This module deploys a SQL Role Assignment in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role Assignment."
+ }
+ },
+ "principalId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Required. Id needs to be granted."
+ }
+ },
+ "roleDefinitionId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Id of the SQL Role Definition."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]",
+ "properties": {
+ "principalId": "[parameters('principalId')]",
+ "roleDefinitionId": "[parameters('roleDefinitionId')]",
+ "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ }
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL Role Assignment was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name'))))]"
+ ]
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL Role Definition and Assignment were created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "databaseAccount"
+ ]
+ },
"databaseAccount_mongodbDatabases": {
"copy": {
"name": "databaseAccount_mongodbDatabases",
@@ -1646,8 +2023,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "1527748615955553712"
+ "version": "0.28.1.47646",
+ "templateHash": "10789567092566068185"
},
"name": "DocumentDB Database Account MongoDB Databases",
"description": "This module deploys a MongoDB Database within a CosmosDB Account.",
@@ -1749,8 +2126,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "6235322895830297683"
+ "version": "0.28.1.47646",
+ "templateHash": "15131365585122011750"
},
"name": "DocumentDB Database Account MongoDB Database Collections",
"description": "This module deploys a MongoDB Database Collection.",
@@ -1905,8 +2282,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "6889435067791947905"
+ "version": "0.28.1.47646",
+ "templateHash": "6730968766448186151"
},
"name": "DocumentDB Database Account Gremlin Databases",
"description": "This module deploys a Gremlin Database within a CosmosDB Account.",
@@ -2009,8 +2386,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "3987394297554402770"
+ "version": "0.28.1.47646",
+ "templateHash": "16910156821054362754"
},
"name": "DocumentDB Database Accounts Gremlin Databases Graphs",
"description": "This module deploys a DocumentDB Database Accounts Gremlin Database Graph.",
@@ -2872,8 +3249,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.27.1.19265",
- "templateHash": "17423703517558214368"
+ "version": "0.28.1.47646",
+ "templateHash": "13154453205210713878"
}
},
"definitions": {
@@ -2965,6 +3342,13 @@
"description": "The location the resource was deployed into."
},
"value": "[reference('databaseAccount', '2023-04-15', 'full').location]"
+ },
+ "endpoint": {
+ "type": "string",
+ "metadata": {
+ "description": "The endpoint of the database account."
+ },
+ "value": "[reference('databaseAccount').documentEndpoint]"
}
}
}
\ No newline at end of file
diff --git a/avm/res/document-db/database-account/sql-role/README.md b/avm/res/document-db/database-account/sql-role/README.md
new file mode 100644
index 0000000000..71fc8b9386
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/README.md
@@ -0,0 +1,116 @@
+# DocumentDB Database Account SQL Role. `[Microsoft.DocumentDB/databaseAccounts]`
+
+This module deploys SQL Role Definision and Assignment in a CosmosDB Account.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments` | [2023-04-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DocumentDB/2023-04-15/databaseAccounts/sqlRoleAssignments) |
+| `Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions` | [2023-04-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DocumentDB/2023-04-15/databaseAccounts/sqlRoleDefinitions) |
+
+## Parameters
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`name`](#parameter-name) | string | Name of the SQL Role. |
+
+**Conditional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`databaseAccountName`](#parameter-databaseaccountname) | string | The name of the parent Database Account. Required if the template is used in a standalone deployment. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`dataActions`](#parameter-dataactions) | array | An array of data actions that are allowed. |
+| [`principalIds`](#parameter-principalids) | array | Ids needs to be granted. |
+| [`roleName`](#parameter-rolename) | string | A user-friendly name for the Role Definition. Must be unique for the database account. |
+| [`roleType`](#parameter-roletype) | string | Indicates whether the Role Definition was built-in or user created. |
+
+### Parameter: `name`
+
+Name of the SQL Role.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `databaseAccountName`
+
+The name of the parent Database Account. Required if the template is used in a standalone deployment.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `dataActions`
+
+An array of data actions that are allowed.
+
+- Required: No
+- Type: array
+- Default:
+ ```Bicep
+ [
+ 'Microsoft.DocumentDB/databaseAccounts/readMetadata'
+ 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*'
+ 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*'
+ ]
+ ```
+
+### Parameter: `principalIds`
+
+Ids needs to be granted.
+
+- Required: No
+- Type: array
+- Default: `[]`
+
+### Parameter: `roleName`
+
+A user-friendly name for the Role Definition. Must be unique for the database account.
+
+- Required: No
+- Type: string
+- Default: `'Reader Writer'`
+
+### Parameter: `roleType`
+
+Indicates whether the Role Definition was built-in or user created.
+
+- Required: No
+- Type: string
+- Default: `'CustomRole'`
+- Allowed:
+ ```Bicep
+ [
+ 'BuiltInRole'
+ 'CustomRole'
+ ]
+ ```
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `resourceGroupName` | string | The name of the resource group the SQL Role Definition and Assignment were created in. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/document-db/database-account/sql-role/main.bicep b/avm/res/document-db/database-account/sql-role/main.bicep
new file mode 100644
index 0000000000..3de96361c0
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/main.bicep
@@ -0,0 +1,66 @@
+metadata name = 'DocumentDB Database Account SQL Role.'
+metadata description = 'This module deploys SQL Role Definision and Assignment in a CosmosDB Account.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment.')
+param databaseAccountName string
+
+@description('Required. Name of the SQL Role.')
+param name string
+
+@description('Optional. An array of data actions that are allowed.')
+param dataActions array = [
+ 'Microsoft.DocumentDB/databaseAccounts/readMetadata'
+ 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*'
+ 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*'
+]
+
+@description('Optional. Ids needs to be granted.')
+param principalIds array = []
+
+@description('Optional. A user-friendly name for the Role Definition. Must be unique for the database account.')
+param roleName string = 'Reader Writer'
+
+@description('Optional. Indicates whether the Role Definition was built-in or user created.')
+@allowed([
+ 'CustomRole'
+ 'BuiltInRole'
+])
+param roleType string = 'CustomRole'
+
+resource databaseAccount 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = {
+ name: databaseAccountName
+}
+
+module sqlRoleDefinition 'sql-role-definitions/main.bicep' = {
+ name: 'sql-role-definition-${uniqueString(name)}'
+ params: {
+ databaseAccountName: databaseAccount.name
+ dataActions: dataActions
+ roleName: roleName
+ roleType: roleType
+ }
+ dependsOn: [
+ databaseAccount
+ ]
+}
+
+@batchSize(1)
+module sqlRoleAssignment 'sql-role-assignments/main.bicep' = [
+ for principalId in principalIds: if (!empty(principalId)) {
+ name: 'sql-role-assign-${uniqueString(principalId)}'
+ params: {
+ name: guid(sqlRoleDefinition.outputs.resourceId, principalId, databaseAccount.id)
+ databaseAccountName: databaseAccountName
+ roleDefinitionId: sqlRoleDefinition.outputs.resourceId
+ principalId: principalId
+ }
+ dependsOn: [
+ databaseAccount
+ sqlRoleDefinition
+ ]
+ }
+]
+
+@description('The name of the resource group the SQL Role Definition and Assignment were created in.')
+output resourceGroupName string = resourceGroup().name
diff --git a/avm/res/document-db/database-account/sql-role/main.json b/avm/res/document-db/database-account/sql-role/main.json
new file mode 100644
index 0000000000..0d05737081
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/main.json
@@ -0,0 +1,286 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "6438933554145929110"
+ },
+ "name": "DocumentDB Database Account SQL Role.",
+ "description": "This module deploys SQL Role Definision and Assignment in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role."
+ }
+ },
+ "dataActions": {
+ "type": "array",
+ "defaultValue": [
+ "Microsoft.DocumentDB/databaseAccounts/readMetadata",
+ "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
+ "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
+ ],
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "principalIds": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. Ids needs to be granted."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "defaultValue": "Reader Writer",
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "defaultValue": "CustomRole",
+ "allowedValues": [
+ "CustomRole",
+ "BuiltInRole"
+ ],
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('sql-role-definition-{0}', uniqueString(parameters('name')))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "databaseAccountName": {
+ "value": "[parameters('databaseAccountName')]"
+ },
+ "dataActions": {
+ "value": "[parameters('dataActions')]"
+ },
+ "roleName": {
+ "value": "[parameters('roleName')]"
+ },
+ "roleType": {
+ "value": "[parameters('roleType')]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "5774063578247320117"
+ },
+ "name": "DocumentDB Database Account SQL Role Definitions.",
+ "description": "This module deploys a SQL Role Definision in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "dataActions": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "defaultValue": "Reader Writer",
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "defaultValue": "CustomRole",
+ "allowedValues": [
+ "CustomRole",
+ "BuiltInRole"
+ ],
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]",
+ "properties": {
+ "assignableScopes": [
+ "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ ],
+ "permissions": [
+ {
+ "dataActions": "[parameters('dataActions')]"
+ }
+ ],
+ "roleName": "[parameters('roleName')]",
+ "type": "[parameters('roleType')]"
+ }
+ }
+ ],
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the SQL database."
+ },
+ "value": "[guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the SQL database."
+ },
+ "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL database was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ }
+ },
+ {
+ "copy": {
+ "name": "sqlRoleAssignment",
+ "count": "[length(parameters('principalIds'))]",
+ "mode": "serial",
+ "batchSize": 1
+ },
+ "condition": "[not(empty(parameters('principalIds')[copyIndex()]))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('sql-role-assign-{0}', uniqueString(parameters('principalIds')[copyIndex()]))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[guid(reference(resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name')))), '2022-09-01').outputs.resourceId.value, parameters('principalIds')[copyIndex()], resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')))]"
+ },
+ "databaseAccountName": {
+ "value": "[parameters('databaseAccountName')]"
+ },
+ "roleDefinitionId": {
+ "value": "[reference(resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name')))), '2022-09-01').outputs.resourceId.value]"
+ },
+ "principalId": {
+ "value": "[parameters('principalIds')[copyIndex()]]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "4968352550056104037"
+ },
+ "name": "DocumentDB Database Account SQL Role Assignments.",
+ "description": "This module deploys a SQL Role Assignment in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role Assignment."
+ }
+ },
+ "principalId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Required. Id needs to be granted."
+ }
+ },
+ "roleDefinitionId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Id of the SQL Role Definition."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]",
+ "properties": {
+ "principalId": "[parameters('principalId')]",
+ "roleDefinitionId": "[parameters('roleDefinitionId')]",
+ "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ }
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL Role Assignment was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Resources/deployments', format('sql-role-definition-{0}', uniqueString(parameters('name'))))]"
+ ]
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL Role Definition and Assignment were created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-assignments/README.md b/avm/res/document-db/database-account/sql-role/sql-role-assignments/README.md
new file mode 100644
index 0000000000..8dba3341cc
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-assignments/README.md
@@ -0,0 +1,77 @@
+# DocumentDB Database Account SQL Role Assignments. `[Microsoft.DocumentDB/databaseaccount/sqlrole/sqlroleassignments]`
+
+This module deploys a SQL Role Assignment in a CosmosDB Account.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments` | [2023-04-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DocumentDB/2023-04-15/databaseAccounts/sqlRoleAssignments) |
+
+## Parameters
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`name`](#parameter-name) | string | Name of the SQL Role Assignment. |
+| [`principalId`](#parameter-principalid) | string | Id needs to be granted. |
+| [`roleDefinitionId`](#parameter-roledefinitionid) | string | Id of the SQL Role Definition. |
+
+**Conditional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`databaseAccountName`](#parameter-databaseaccountname) | string | The name of the parent Database Account. Required if the template is used in a standalone deployment. |
+
+### Parameter: `name`
+
+Name of the SQL Role Assignment.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `principalId`
+
+Id needs to be granted.
+
+- Required: No
+- Type: string
+- Default: `''`
+
+### Parameter: `roleDefinitionId`
+
+Id of the SQL Role Definition.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `databaseAccountName`
+
+The name of the parent Database Account. Required if the template is used in a standalone deployment.
+
+- Required: Yes
+- Type: string
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `resourceGroupName` | string | The name of the resource group the SQL Role Assignment was created in. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.bicep b/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.bicep
new file mode 100644
index 0000000000..32c24742a9
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.bicep
@@ -0,0 +1,32 @@
+metadata name = 'DocumentDB Database Account SQL Role Assignments.'
+metadata description = 'This module deploys a SQL Role Assignment in a CosmosDB Account.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment.')
+param databaseAccountName string
+
+@description('Required. Name of the SQL Role Assignment.')
+param name string
+
+@description('Required. Id needs to be granted.')
+param principalId string = ''
+
+@description('Required. Id of the SQL Role Definition.')
+param roleDefinitionId string
+
+resource databaseAccount 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = {
+ name: databaseAccountName
+}
+
+resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2023-04-15' = {
+ parent: databaseAccount
+ name: name
+ properties: {
+ principalId: principalId
+ roleDefinitionId: roleDefinitionId
+ scope: databaseAccount.id
+ }
+}
+
+@description('The name of the resource group the SQL Role Assignment was created in.')
+output resourceGroupName string = resourceGroup().name
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.json b/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.json
new file mode 100644
index 0000000000..97c74bb0ed
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-assignments/main.json
@@ -0,0 +1,62 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.27.1.19265",
+ "templateHash": "12924779272926798782"
+ },
+ "name": "DocumentDB Database Account SQL Role Assignments.",
+ "description": "This module deploys a SQL Role Assignment in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the SQL Role Assignment."
+ }
+ },
+ "principalId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Required. Id needs to be granted."
+ }
+ },
+ "roleDefinitionId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Id of the SQL Role Definition."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]",
+ "properties": {
+ "principalId": "[parameters('principalId')]",
+ "roleDefinitionId": "[parameters('roleDefinitionId')]",
+ "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ }
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL Role Assignment was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-definitions/README.md b/avm/res/document-db/database-account/sql-role/sql-role-definitions/README.md
new file mode 100644
index 0000000000..3a1eb3680c
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-definitions/README.md
@@ -0,0 +1,88 @@
+# DocumentDB Database Account SQL Role Definitions. `[Microsoft.DocumentDB/databaseaccount/sqlrole/sqlroledefinitions]`
+
+This module deploys a SQL Role Definision in a CosmosDB Account.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions` | [2023-04-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.DocumentDB/2023-04-15/databaseAccounts/sqlRoleDefinitions) |
+
+## Parameters
+
+**Conditional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`databaseAccountName`](#parameter-databaseaccountname) | string | The name of the parent Database Account. Required if the template is used in a standalone deployment. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`dataActions`](#parameter-dataactions) | array | An array of data actions that are allowed. |
+| [`roleName`](#parameter-rolename) | string | A user-friendly name for the Role Definition. Must be unique for the database account. |
+| [`roleType`](#parameter-roletype) | string | Indicates whether the Role Definition was built-in or user created. |
+
+### Parameter: `databaseAccountName`
+
+The name of the parent Database Account. Required if the template is used in a standalone deployment.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `dataActions`
+
+An array of data actions that are allowed.
+
+- Required: No
+- Type: array
+- Default: `[]`
+
+### Parameter: `roleName`
+
+A user-friendly name for the Role Definition. Must be unique for the database account.
+
+- Required: No
+- Type: string
+- Default: `'Reader Writer'`
+
+### Parameter: `roleType`
+
+Indicates whether the Role Definition was built-in or user created.
+
+- Required: No
+- Type: string
+- Default: `'CustomRole'`
+- Allowed:
+ ```Bicep
+ [
+ 'BuiltInRole'
+ 'CustomRole'
+ ]
+ ```
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the SQL database. |
+| `resourceGroupName` | string | The name of the resource group the SQL database was created in. |
+| `resourceId` | string | The resource ID of the SQL database. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.bicep b/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.bicep
new file mode 100644
index 0000000000..98d8ab4879
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.bicep
@@ -0,0 +1,49 @@
+metadata name = 'DocumentDB Database Account SQL Role Definitions.'
+metadata description = 'This module deploys a SQL Role Definision in a CosmosDB Account.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment.')
+param databaseAccountName string
+
+@description('Optional. An array of data actions that are allowed.')
+param dataActions array = []
+
+@description('Optional. A user-friendly name for the Role Definition. Must be unique for the database account.')
+param roleName string = 'Reader Writer'
+
+@description('Optional. Indicates whether the Role Definition was built-in or user created.')
+@allowed([
+ 'CustomRole'
+ 'BuiltInRole'
+])
+param roleType string = 'CustomRole'
+
+resource databaseAccount 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = {
+ name: databaseAccountName
+}
+
+resource sqlRoleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2023-04-15' = {
+ parent: databaseAccount
+ name: guid(databaseAccount.id, databaseAccountName, 'sql-role')
+ properties: {
+ assignableScopes: [
+ databaseAccount.id
+ ]
+ permissions: [
+ {
+ dataActions: dataActions
+ }
+ ]
+ roleName: roleName
+ type: roleType
+ }
+}
+
+@description('The name of the SQL database.')
+output name string = sqlRoleDefinition.name
+
+@description('The resource ID of the SQL database.')
+output resourceId string = sqlRoleDefinition.id
+
+@description('The name of the resource group the SQL database was created in.')
+output resourceGroupName string = resourceGroup().name
diff --git a/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.json b/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.json
new file mode 100644
index 0000000000..b7029bd4a1
--- /dev/null
+++ b/avm/res/document-db/database-account/sql-role/sql-role-definitions/main.json
@@ -0,0 +1,89 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "5774063578247320117"
+ },
+ "name": "DocumentDB Database Account SQL Role Definitions.",
+ "description": "This module deploys a SQL Role Definision in a CosmosDB Account.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "databaseAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment."
+ }
+ },
+ "dataActions": {
+ "type": "array",
+ "defaultValue": [],
+ "metadata": {
+ "description": "Optional. An array of data actions that are allowed."
+ }
+ },
+ "roleName": {
+ "type": "string",
+ "defaultValue": "Reader Writer",
+ "metadata": {
+ "description": "Optional. A user-friendly name for the Role Definition. Must be unique for the database account."
+ }
+ },
+ "roleType": {
+ "type": "string",
+ "defaultValue": "CustomRole",
+ "allowedValues": [
+ "CustomRole",
+ "BuiltInRole"
+ ],
+ "metadata": {
+ "description": "Optional. Indicates whether the Role Definition was built-in or user created."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
+ "apiVersion": "2023-04-15",
+ "name": "[format('{0}/{1}', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]",
+ "properties": {
+ "assignableScopes": [
+ "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName'))]"
+ ],
+ "permissions": [
+ {
+ "dataActions": "[parameters('dataActions')]"
+ }
+ ],
+ "roleName": "[parameters('roleName')]",
+ "type": "[parameters('roleType')]"
+ }
+ }
+ ],
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the SQL database."
+ },
+ "value": "[guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the SQL database."
+ },
+ "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('databaseAccountName'), guid(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), parameters('databaseAccountName'), 'sql-role'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the SQL database was created in."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/document-db/database-account/tests/e2e/role/dependencies.bicep b/avm/res/document-db/database-account/tests/e2e/role/dependencies.bicep
new file mode 100644
index 0000000000..b5c4657c14
--- /dev/null
+++ b/avm/res/document-db/database-account/tests/e2e/role/dependencies.bicep
@@ -0,0 +1,36 @@
+@description('Optional. The location to deploy to.')
+param location string = resourceGroup().location
+
+@description('Required. The name of the App Service to create.')
+param appName string
+
+@description('Required. The name of the App Service Plan to create.')
+param appServicePlanName string
+
+resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
+ name: appServicePlanName
+ location: location
+ sku: {
+ name: 'B3'
+ }
+ properties: {
+ reserved: true
+ }
+}
+
+resource app 'Microsoft.Web/sites@2022-09-01' = {
+ name: appName
+ location: location
+ kind: 'app,linux'
+ properties: {
+ serverFarmId: appServicePlan.id
+ siteConfig: {
+ linuxFxVersion: 'dotnetcore|8.0'
+ alwaysOn: true
+ }
+ }
+ identity: { type: 'SystemAssigned' }
+}
+
+@description('The app identity Principal Id.')
+output identityPrincipalId string = app.identity.principalId
diff --git a/avm/res/document-db/database-account/tests/e2e/role/main.test.bicep b/avm/res/document-db/database-account/tests/e2e/role/main.test.bicep
new file mode 100644
index 0000000000..737b310b7c
--- /dev/null
+++ b/avm/res/document-db/database-account/tests/e2e/role/main.test.bicep
@@ -0,0 +1,59 @@
+targetScope = 'subscription'
+
+metadata name = 'Deploying with a sql role definision and assignment'
+metadata description = 'This instance deploys the module with sql role definision and assignment'
+
+// ========== //
+// Parameters //
+// ========== //
+
+@description('Optional. The name of the resource group to deploy for testing purposes.')
+@maxLength(90)
+param resourceGroupName string = 'dep-${namePrefix}-documentdb.databaseaccounts-${serviceShort}-rg'
+
+@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 = 'dddarole'
+
+@description('Optional. A token to inject into the name of each resource.')
+param namePrefix string = '#_namePrefix_#'
+
+// Pipeline is selecting random regions which dont support all cosmos features and have constraints when creating new cosmos
+#disable-next-line no-hardcoded-location
+var enforcedLocation = 'eastus2'
+
+// ============== //
+// General resources
+// ============== //
+resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = {
+ name: resourceGroupName
+ location: enforcedLocation
+}
+
+module nestedDependencies 'dependencies.bicep' = {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, enforcedLocation)}-nestedDependencies'
+ params: {
+ appName: 'dep-${namePrefix}-app-${serviceShort}'
+ appServicePlanName: 'dep-${namePrefix}-asp-${serviceShort}'
+ location: enforcedLocation
+ }
+}
+
+// ============== //
+// Test Execution //
+// ============== //
+
+module testDeployment '../../../main.bicep' = {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, enforcedLocation)}-test-role-${serviceShort}'
+ params: {
+ location: enforcedLocation
+ name: '${namePrefix}-role-ref'
+ sqlRoleAssignmentsPrincipalIds: [
+ nestedDependencies.outputs.identityPrincipalId
+ ]
+ sqlRoleDefinitions: [
+ { name: 'cosmos-sql-role-test' }
+ ]
+ }
+}
diff --git a/avm/res/event-hub/namespace/README.md b/avm/res/event-hub/namespace/README.md
index c8e4813f6b..511d9a0980 100644
--- a/avm/res/event-hub/namespace/README.md
+++ b/avm/res/event-hub/namespace/README.md
@@ -1355,6 +1355,8 @@ Configuration details for private endpoints. For security reasons, it is recomme
| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. |
| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. |
| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. |
+| [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. |
+| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. |
| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. |
| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". |
| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. |
@@ -1550,6 +1552,20 @@ The private DNS zone groups to associate the private endpoint with. A DNS zone g
- Required: No
- Type: array
+### Parameter: `privateEndpoints.privateLinkServiceConnectionName`
+
+The name of the private link connection to create.
+
+- Required: No
+- Type: string
+
+### Parameter: `privateEndpoints.resourceGroupName`
+
+Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.
+
+- Required: No
+- Type: string
+
### Parameter: `privateEndpoints.roleAssignments`
Array of role assignments to create.
@@ -1824,7 +1840,7 @@ This section gives you an overview of all local-referenced module files (i.e., o
| Reference | Type |
| :-- | :-- |
-| `br/public:avm/res/network/private-endpoint:0.4.0` | Remote reference |
+| `br/public:avm/res/network/private-endpoint:0.4.1` | Remote reference |
## Data Collection
diff --git a/avm/res/event-hub/namespace/main.bicep b/avm/res/event-hub/namespace/main.bicep
index 8e3df44a89..b9b601e39d 100644
--- a/avm/res/event-hub/namespace/main.bicep
+++ b/avm/res/event-hub/namespace/main.bicep
@@ -338,12 +338,13 @@ module eventHubNamespace_networkRuleSet 'network-rule-set/main.bicep' = if (!emp
}
}
-module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [
+module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [
for (privateEndpoint, index) in (privateEndpoints ?? []): {
- name: '${uniqueString(deployment().name, location)}-EventHubNamespace-PrivateEndpoint-${index}'
+ name: '${uniqueString(deployment().name, location)}-eventHubNamespace-PrivateEndpoint-${index}'
+ scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '')
params: {
name: privateEndpoint.?name ?? 'pep-${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}'
- privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true
+ privateLinkServiceConnections: privateEndpoint.?isManualConnection != true
? [
{
name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}'
@@ -356,7 +357,7 @@ module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-end
}
]
: null
- manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true
+ manualPrivateLinkServiceConnections: privateEndpoint.?isManualConnection == true
? [
{
name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}'
@@ -520,6 +521,9 @@ type privateEndpointType = {
@description('Optional. The location to deploy the private endpoint to.')
location: string?
+ @description('Optional. The name of the private link connection to create.')
+ privateLinkServiceConnectionName: string?
+
@description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".')
service: string?
@@ -583,6 +587,9 @@ type privateEndpointType = {
@description('Optional. Enable/Disable usage telemetry for module.')
enableTelemetry: bool?
+
+ @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.')
+ resourceGroupName: string?
}[]?
type diagnosticSettingType = {
diff --git a/avm/res/event-hub/namespace/main.json b/avm/res/event-hub/namespace/main.json
index bf75aa20c5..6e62b52bc2 100644
--- a/avm/res/event-hub/namespace/main.json
+++ b/avm/res/event-hub/namespace/main.json
@@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
- "templateHash": "15950832845960149615"
+ "templateHash": "10058273912362518894"
},
"name": "Event Hub Namespaces",
"description": "This module deploys an Event Hub Namespace.",
@@ -146,6 +146,13 @@
"description": "Optional. The location to deploy the private endpoint to."
}
},
+ "privateLinkServiceConnectionName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the private link connection to create."
+ }
+ },
"service": {
"type": "string",
"nullable": true,
@@ -305,6 +312,13 @@
"metadata": {
"description": "Optional. Enable/Disable usage telemetry for module."
}
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource."
+ }
}
}
},
@@ -1845,7 +1859,8 @@
},
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
- "name": "[format('{0}-EventHubNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "name": "[format('{0}-eventHubNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
@@ -1855,8 +1870,8 @@
"name": {
"value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex()))]"
},
- "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')))))), createObject('value', null()))]",
- "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
+ "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')))))), createObject('value', null()))]",
+ "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
"subnetResourceId": {
"value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
},
@@ -1901,8 +1916,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.24.24.22086",
- "templateHash": "2592884001616184297"
+ "version": "0.25.53.49325",
+ "templateHash": "4120048060064073955"
},
"name": "Private Endpoints",
"description": "This module deploys a Private Endpoint.",
@@ -2267,7 +2282,7 @@
"condition": "[parameters('enableTelemetry')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2023-07-01",
- "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
"properties": {
"mode": "Incremental",
"template": {
@@ -2372,8 +2387,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.24.24.22086",
- "templateHash": "9321937464667207030"
+ "version": "0.25.53.49325",
+ "templateHash": "11244630631275470040"
},
"name": "Private Endpoint Private DNS Zone Groups",
"description": "This module deploys a Private Endpoint Private DNS Zone Group.",
diff --git a/avm/res/hybrid-compute/machine/README.md b/avm/res/hybrid-compute/machine/README.md
new file mode 100644
index 0000000000..8d2d8eb387
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/README.md
@@ -0,0 +1,629 @@
+# Hybrid Compute Machines `[Microsoft.HybridCompute/machines]`
+
+This module deploys an Arc Machine for use with Arc Resource Bridge for Azure Stack HCI or VMware. In these scenarios, this resource module will be used in combination with another resource module to create the require Virtual Machine Instance extension resource on this Arc Machine resource. This module should not be used for other Arc-enabled server scenarios, where the Arc Machine resource is created automatically by the onboarding process.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Usage examples](#Usage-examples)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) |
+| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) |
+| `Microsoft.GuestConfiguration/guestConfigurationAssignments` | [2020-06-25](https://learn.microsoft.com/en-us/azure/templates/Microsoft.GuestConfiguration/2020-06-25/guestConfigurationAssignments) |
+| `Microsoft.HybridCompute/machines` | [2024-03-31-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.HybridCompute/machines) |
+
+## Usage examples
+
+The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository.
+
+>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order.
+
+>**Note**: To reference the module, please use the following syntax `br/public:avm/res/hybrid-compute/machine:`.
+
+- [Creates an Arc Machine using only the defaults](#example-1-creates-an-arc-machine-using-only-the-defaults)
+- [Creates an Arc Machine with maximum configurations](#example-2-creates-an-arc-machine-with-maximum-configurations)
+- [Creates an VMWare machine using only the defaults](#example-3-creates-an-vmware-machine-using-only-the-defaults)
+- [WAF-aligned](#example-4-waf-aligned)
+
+### Example 1: _Creates an Arc Machine using only the defaults_
+
+This instance deploys the module with the minimum set of required parameters.
+
+
+
+
+via Bicep module
+
+```bicep
+module machine 'br/public:avm/res/hybrid-compute/machine:' = {
+ name: 'machineDeployment'
+ params: {
+ // Required parameters
+ kind: 'HCI'
+ name: 'arcmachcimin'
+ // Non-required parameters
+ location: ''
+ }
+}
+```
+
+
+
+
+
+
+via JSON Parameter file
+
+```json
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ // Required parameters
+ "kind": {
+ "value": "HCI"
+ },
+ "name": {
+ "value": "arcmachcimin"
+ },
+ // Non-required parameters
+ "location": {
+ "value": ""
+ }
+ }
+}
+```
+
+
+
+
+### Example 2: _Creates an Arc Machine with maximum configurations_
+
+This instance deploys the module with most of its features enabled.
+
+
+
+
+via Bicep module
+
+```bicep
+module machine 'br/public:avm/res/hybrid-compute/machine:' = {
+ name: 'machineDeployment'
+ params: {
+ // Required parameters
+ kind: 'HCI'
+ name: 'arcmachcimx'
+ // Non-required parameters
+ guestConfiguration: {
+ assignmentType: 'ApplyAndMonitor'
+ configurationParameter: [
+ {
+ name: 'Minimum Password Length;ExpectedValue'
+ value: '16'
+ }
+ {
+ name: 'Minimum Password Length;RemediateValue'
+ value: '16'
+ }
+ {
+ name: 'Maximum Password Age;ExpectedValue'
+ value: '75'
+ }
+ {
+ name: 'Maximum Password Age;RemediateValue'
+ value: '75'
+ }
+ ]
+ name: 'AzureWindowsBaseline'
+ version: '1.*'
+ }
+ location: ''
+ osType: 'Windows'
+ patchAssessmentMode: 'AutomaticByPlatform'
+ patchMode: 'AutomaticByPlatform'
+ privateLinkScopeResourceId: ''
+ tags: {
+ Environment: 'Non-Prod'
+ 'hidden-title': 'This is visible in the resource name'
+ Role: 'DeploymentValidation'
+ }
+ }
+}
+```
+
+
+
+
+
+
+via JSON Parameter file
+
+```json
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ // Required parameters
+ "kind": {
+ "value": "HCI"
+ },
+ "name": {
+ "value": "arcmachcimx"
+ },
+ // Non-required parameters
+ "guestConfiguration": {
+ "value": {
+ "assignmentType": "ApplyAndMonitor",
+ "configurationParameter": [
+ {
+ "name": "Minimum Password Length;ExpectedValue",
+ "value": "16"
+ },
+ {
+ "name": "Minimum Password Length;RemediateValue",
+ "value": "16"
+ },
+ {
+ "name": "Maximum Password Age;ExpectedValue",
+ "value": "75"
+ },
+ {
+ "name": "Maximum Password Age;RemediateValue",
+ "value": "75"
+ }
+ ],
+ "name": "AzureWindowsBaseline",
+ "version": "1.*"
+ }
+ },
+ "location": {
+ "value": ""
+ },
+ "osType": {
+ "value": "Windows"
+ },
+ "patchAssessmentMode": {
+ "value": "AutomaticByPlatform"
+ },
+ "patchMode": {
+ "value": "AutomaticByPlatform"
+ },
+ "privateLinkScopeResourceId": {
+ "value": ""
+ },
+ "tags": {
+ "value": {
+ "Environment": "Non-Prod",
+ "hidden-title": "This is visible in the resource name",
+ "Role": "DeploymentValidation"
+ }
+ }
+ }
+}
+```
+
+
+
+
+### Example 3: _Creates an VMWare machine using only the defaults_
+
+This instance deploys the module with the minimum set of required parameters.
+
+
+
+
+via Bicep module
+
+```bicep
+module machine 'br/public:avm/res/hybrid-compute/machine:' = {
+ name: 'machineDeployment'
+ params: {
+ // Required parameters
+ kind: 'VMware'
+ name: 'arcmacvmwmin'
+ // Non-required parameters
+ location: ''
+ }
+}
+```
+
+
+
+
+
+
+via JSON Parameter file
+
+```json
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ // Required parameters
+ "kind": {
+ "value": "VMware"
+ },
+ "name": {
+ "value": "arcmacvmwmin"
+ },
+ // Non-required parameters
+ "location": {
+ "value": ""
+ }
+ }
+}
+```
+
+
+
+
+### Example 4: _WAF-aligned_
+
+This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.
+
+
+
+
+via Bicep module
+
+```bicep
+module machine 'br/public:avm/res/hybrid-compute/machine:' = {
+ name: 'machineDeployment'
+ params: {
+ // Required parameters
+ kind: 'HCI'
+ name: 'arcmacwaf'
+ // Non-required parameters
+ location: ''
+ tags: {
+ Environment: 'Non-Prod'
+ 'hidden-title': 'This is visible in the resource name'
+ Role: 'DeploymentValidation'
+ }
+ }
+}
+```
+
+
+
+
+
+
+via JSON Parameter file
+
+```json
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ // Required parameters
+ "kind": {
+ "value": "HCI"
+ },
+ "name": {
+ "value": "arcmacwaf"
+ },
+ // Non-required parameters
+ "location": {
+ "value": ""
+ },
+ "tags": {
+ "value": {
+ "Environment": "Non-Prod",
+ "hidden-title": "This is visible in the resource name",
+ "Role": "DeploymentValidation"
+ }
+ }
+ }
+}
+```
+
+
+
+
+
+## Parameters
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`kind`](#parameter-kind) | string | Kind of Arc machine to be created. Possible values are: HCI, SCVMM, VMware. |
+| [`name`](#parameter-name) | string | The name of the Arc machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. |
+
+**Conditional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`osType`](#parameter-ostype) | string | Required if you are providing OS-type specified configurations, such as patch settings. The chosen OS type, either Windows or Linux. |
+| [`privateLinkScopeResourceId`](#parameter-privatelinkscoperesourceid) | string | The resource ID of an Arc Private Link Scope which which to associate this machine. Required if you are using Private Link for Arc and your Arc Machine will resolve a Private Endpoint for connectivity to Azure. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`clientPublicKey`](#parameter-clientpublickey) | securestring | The Public Key that the client provides to be used during initial resource onboarding. |
+| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. |
+| [`guestConfiguration`](#parameter-guestconfiguration) | object | The guest configuration for the Arc machine. Needs the Guest Configuration extension to be enabled. |
+| [`location`](#parameter-location) | string | Location for all resources. |
+| [`lock`](#parameter-lock) | object | The lock settings of the service. |
+| [`parentClusterResourceId`](#parameter-parentclusterresourceid) | string | Parent cluster resource ID (Azure Stack HCI). |
+| [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. |
+| [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. |
+| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. |
+| [`tags`](#parameter-tags) | object | Tags of the resource. |
+| [`vmId`](#parameter-vmid) | string | The GUID of the on-premises virtual machine from your hypervisor. |
+
+### Parameter: `kind`
+
+Kind of Arc machine to be created. Possible values are: HCI, SCVMM, VMware.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `name`
+
+The name of the Arc machine to be created. You should use a unique prefix to reduce name collisions in Active Directory.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `osType`
+
+Required if you are providing OS-type specified configurations, such as patch settings. The chosen OS type, either Windows or Linux.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ 'Linux'
+ 'Windows'
+ ]
+ ```
+
+### Parameter: `privateLinkScopeResourceId`
+
+The resource ID of an Arc Private Link Scope which which to associate this machine. Required if you are using Private Link for Arc and your Arc Machine will resolve a Private Endpoint for connectivity to Azure.
+
+- Required: No
+- Type: string
+- Default: `''`
+
+### Parameter: `clientPublicKey`
+
+The Public Key that the client provides to be used during initial resource onboarding.
+
+- Required: No
+- Type: securestring
+- Default: `''`
+
+### Parameter: `enableTelemetry`
+
+Enable/Disable usage telemetry for module.
+
+- Required: No
+- Type: bool
+- Default: `True`
+
+### Parameter: `guestConfiguration`
+
+The guest configuration for the Arc machine. Needs the Guest Configuration extension to be enabled.
+
+- Required: No
+- Type: object
+- Default: `{}`
+
+### Parameter: `location`
+
+Location for all resources.
+
+- Required: No
+- Type: string
+- Default: `[resourceGroup().location]`
+
+### Parameter: `lock`
+
+The lock settings of the service.
+
+- Required: No
+- Type: object
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`kind`](#parameter-lockkind) | string | Specify the type of lock. |
+| [`name`](#parameter-lockname) | string | Specify the name of lock. |
+
+### Parameter: `lock.kind`
+
+Specify the type of lock.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ 'CanNotDelete'
+ 'None'
+ 'ReadOnly'
+ ]
+ ```
+
+### Parameter: `lock.name`
+
+Specify the name of lock.
+
+- Required: No
+- Type: string
+
+### Parameter: `parentClusterResourceId`
+
+Parent cluster resource ID (Azure Stack HCI).
+
+- Required: No
+- Type: string
+- Default: `''`
+
+### Parameter: `patchAssessmentMode`
+
+VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours.
+
+- Required: No
+- Type: string
+- Default: `'ImageDefault'`
+- Allowed:
+ ```Bicep
+ [
+ 'AutomaticByPlatform'
+ 'ImageDefault'
+ ]
+ ```
+
+### Parameter: `patchMode`
+
+VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ 'AutomaticByOS'
+ 'AutomaticByPlatform'
+ 'ImageDefault'
+ 'Manual'
+ ]
+ ```
+
+### Parameter: `roleAssignments`
+
+Array of role assignments to create.
+
+- Required: No
+- Type: array
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. |
+| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". |
+| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. |
+| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. |
+| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. |
+| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. |
+
+### Parameter: `roleAssignments.principalId`
+
+The principal ID of the principal (user/group/identity) to assign the role to.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `roleAssignments.roleDefinitionIdOrName`
+
+The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `roleAssignments.condition`
+
+The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".
+
+- Required: No
+- Type: string
+
+### Parameter: `roleAssignments.conditionVersion`
+
+Version of the condition.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ '2.0'
+ ]
+ ```
+
+### Parameter: `roleAssignments.delegatedManagedIdentityResourceId`
+
+The Resource Id of the delegated managed identity resource.
+
+- Required: No
+- Type: string
+
+### Parameter: `roleAssignments.description`
+
+The description of the role assignment.
+
+- Required: No
+- Type: string
+
+### Parameter: `roleAssignments.principalType`
+
+The principal type of the assigned principal ID.
+
+- Required: No
+- Type: string
+- Allowed:
+ ```Bicep
+ [
+ 'Device'
+ 'ForeignGroup'
+ 'Group'
+ 'ServicePrincipal'
+ 'User'
+ ]
+ ```
+
+### Parameter: `tags`
+
+Tags of the resource.
+
+- Required: No
+- Type: object
+
+### Parameter: `vmId`
+
+The GUID of the on-premises virtual machine from your hypervisor.
+
+- Required: No
+- Type: string
+- Default: `''`
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `location` | string | The location the resource was deployed into. |
+| `name` | string | The name of the machine. |
+| `resourceGroupName` | string | The name of the resource group the VM was created in. |
+| `resourceId` | string | The resource ID of the machine. |
+| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/hybrid-compute/machine/extension/README.md b/avm/res/hybrid-compute/machine/extension/README.md
new file mode 100644
index 0000000000..aef5344c17
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/extension/README.md
@@ -0,0 +1,147 @@
+# Arc Machine Extensions `[Microsoft.HybridCompute/machines/extensions]`
+
+This module deploys a Arc Machine Extension. This module should be used as a standalone deployment after the Arc agent has connected to the Arc Machine resource.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.HybridCompute/machines/extensions` | [2024-03-31-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.HybridCompute/machines/extensions) |
+
+## Parameters
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`arcMachineName`](#parameter-arcmachinename) | string | The name of the parent Arc Machine that extension is provisioned for. |
+| [`autoUpgradeMinorVersion`](#parameter-autoupgrademinorversion) | bool | Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. |
+| [`enableAutomaticUpgrade`](#parameter-enableautomaticupgrade) | bool | Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. |
+| [`name`](#parameter-name) | string | The name of the Arc Machine extension. |
+| [`publisher`](#parameter-publisher) | string | The name of the extension handler publisher. |
+| [`type`](#parameter-type) | string | Specifies the type of the extension; an example is "CustomScriptExtension". |
+| [`typeHandlerVersion`](#parameter-typehandlerversion) | string | Specifies the version of the script handler. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`forceUpdateTag`](#parameter-forceupdatetag) | string | How the extension handler should be forced to update even if the extension configuration has not changed. |
+| [`location`](#parameter-location) | string | The location the extension is deployed to. |
+| [`protectedSettings`](#parameter-protectedsettings) | secureObject | Any object that contains the extension specific protected settings. |
+| [`settings`](#parameter-settings) | object | Any object that contains the extension specific settings. |
+| [`tags`](#parameter-tags) | object | Tags of the resource. |
+
+### Parameter: `arcMachineName`
+
+The name of the parent Arc Machine that extension is provisioned for.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `autoUpgradeMinorVersion`
+
+Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true.
+
+- Required: Yes
+- Type: bool
+
+### Parameter: `enableAutomaticUpgrade`
+
+Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available.
+
+- Required: Yes
+- Type: bool
+
+### Parameter: `name`
+
+The name of the Arc Machine extension.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `publisher`
+
+The name of the extension handler publisher.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `type`
+
+Specifies the type of the extension; an example is "CustomScriptExtension".
+
+- Required: Yes
+- Type: string
+
+### Parameter: `typeHandlerVersion`
+
+Specifies the version of the script handler.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `forceUpdateTag`
+
+How the extension handler should be forced to update even if the extension configuration has not changed.
+
+- Required: No
+- Type: string
+- Default: `''`
+
+### Parameter: `location`
+
+The location the extension is deployed to.
+
+- Required: No
+- Type: string
+- Default: `[resourceGroup().location]`
+
+### Parameter: `protectedSettings`
+
+Any object that contains the extension specific protected settings.
+
+- Required: No
+- Type: secureObject
+- Default: `{}`
+
+### Parameter: `settings`
+
+Any object that contains the extension specific settings.
+
+- Required: No
+- Type: object
+- Default: `{}`
+
+### Parameter: `tags`
+
+Tags of the resource.
+
+- Required: No
+- Type: object
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `location` | string | The location the resource was deployed into. |
+| `name` | string | The name of the extension. |
+| `resourceGroupName` | string | The name of the Resource Group the extension was created in. |
+| `resourceId` | string | The resource ID of the extension. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/hybrid-compute/machine/extension/main.bicep b/avm/res/hybrid-compute/machine/extension/main.bicep
new file mode 100644
index 0000000000..2c68e47c59
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/extension/main.bicep
@@ -0,0 +1,73 @@
+metadata name = 'Arc Machine Extensions'
+metadata description = 'This module deploys a Arc Machine Extension. This module should be used as a standalone deployment after the Arc agent has connected to the Arc Machine resource.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Required. The name of the parent Arc Machine that extension is provisioned for.')
+param arcMachineName string
+
+@description('Required. The name of the Arc Machine extension.')
+param name string
+
+@description('Optional. The location the extension is deployed to.')
+param location string = resourceGroup().location
+
+@description('Required. The name of the extension handler publisher.')
+param publisher string
+
+@description('Required. Specifies the type of the extension; an example is "CustomScriptExtension".')
+param type string
+
+@description('Required. Specifies the version of the script handler.')
+param typeHandlerVersion string
+
+@description('Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true.')
+param autoUpgradeMinorVersion bool
+
+@description('Optional. How the extension handler should be forced to update even if the extension configuration has not changed.')
+param forceUpdateTag string = ''
+
+@description('Optional. Any object that contains the extension specific settings.')
+param settings object = {}
+
+@description('Optional. Any object that contains the extension specific protected settings.')
+@secure()
+param protectedSettings object = {}
+
+@description('Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available.')
+param enableAutomaticUpgrade bool
+
+@description('Optional. Tags of the resource.')
+param tags object?
+
+resource machine 'Microsoft.HybridCompute/machines@2024-03-31-preview' existing = {
+ name: arcMachineName
+}
+
+resource extension 'Microsoft.HybridCompute/machines/extensions@2024-03-31-preview' = {
+ name: name
+ parent: machine
+ location: location
+ tags: tags
+ properties: {
+ publisher: publisher
+ type: type
+ typeHandlerVersion: typeHandlerVersion
+ autoUpgradeMinorVersion: autoUpgradeMinorVersion
+ enableAutomaticUpgrade: enableAutomaticUpgrade
+ forceUpdateTag: !empty(forceUpdateTag) ? forceUpdateTag : null
+ settings: !empty(settings) ? settings : null
+ protectedSettings: !empty(protectedSettings) ? protectedSettings : null
+ }
+}
+
+@description('The name of the extension.')
+output name string = extension.name
+
+@description('The resource ID of the extension.')
+output resourceId string = extension.id
+
+@description('The name of the Resource Group the extension was created in.')
+output resourceGroupName string = resourceGroup().name
+
+@description('The location the resource was deployed into.')
+output location string = extension.location
diff --git a/avm/res/hybrid-compute/machine/extension/main.json b/avm/res/hybrid-compute/machine/extension/main.json
new file mode 100644
index 0000000000..4c7f7f20b5
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/extension/main.json
@@ -0,0 +1,152 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "16938870032761436213"
+ },
+ "name": "Arc Machine Extensions",
+ "description": "This module deploys a Arc Machine Extension. This module should be used as a standalone deployment after the Arc agent has connected to the Arc Machine resource.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "arcMachineName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the parent Arc Machine that extension is provisioned for."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the Arc Machine extension."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Optional. The location the extension is deployed to."
+ }
+ },
+ "publisher": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the extension handler publisher."
+ }
+ },
+ "type": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"."
+ }
+ },
+ "typeHandlerVersion": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Specifies the version of the script handler."
+ }
+ },
+ "autoUpgradeMinorVersion": {
+ "type": "bool",
+ "metadata": {
+ "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true."
+ }
+ },
+ "forceUpdateTag": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed."
+ }
+ },
+ "settings": {
+ "type": "object",
+ "defaultValue": {},
+ "metadata": {
+ "description": "Optional. Any object that contains the extension specific settings."
+ }
+ },
+ "protectedSettings": {
+ "type": "secureObject",
+ "defaultValue": {},
+ "metadata": {
+ "description": "Optional. Any object that contains the extension specific protected settings."
+ }
+ },
+ "enableAutomaticUpgrade": {
+ "type": "bool",
+ "metadata": {
+ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Tags of the resource."
+ }
+ }
+ },
+ "resources": {
+ "machine": {
+ "existing": true,
+ "type": "Microsoft.HybridCompute/machines",
+ "apiVersion": "2024-03-31-preview",
+ "name": "[parameters('arcMachineName')]"
+ },
+ "extension": {
+ "type": "Microsoft.HybridCompute/machines/extensions",
+ "apiVersion": "2024-03-31-preview",
+ "name": "[format('{0}/{1}', parameters('arcMachineName'), parameters('name'))]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "publisher": "[parameters('publisher')]",
+ "type": "[parameters('type')]",
+ "typeHandlerVersion": "[parameters('typeHandlerVersion')]",
+ "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]",
+ "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]",
+ "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]",
+ "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]",
+ "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]"
+ },
+ "dependsOn": [
+ "machine"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the extension."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the extension."
+ },
+ "value": "[resourceId('Microsoft.HybridCompute/machines/extensions', parameters('arcMachineName'), parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the Resource Group the extension was created in."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('extension', '2024-03-31-preview', 'full').location]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/hybrid-compute/machine/main.bicep b/avm/res/hybrid-compute/machine/main.bicep
new file mode 100644
index 0000000000..7ceb726e2b
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/main.bicep
@@ -0,0 +1,256 @@
+metadata name = 'Hybrid Compute Machines'
+metadata description = 'This module deploys an Arc Machine for use with Arc Resource Bridge for Azure Stack HCI or VMware. In these scenarios, this resource module will be used in combination with another resource module to create the require Virtual Machine Instance extension resource on this Arc Machine resource. This module should not be used for other Arc-enabled server scenarios, where the Arc Machine resource is created automatically by the onboarding process.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Required. The name of the Arc machine to be created. You should use a unique prefix to reduce name collisions in Active Directory.')
+param name string
+
+@description('Required. Kind of Arc machine to be created. Possible values are: HCI, SCVMM, VMware.')
+param kind string
+
+@description('Conditional. The resource ID of an Arc Private Link Scope which which to associate this machine. Required if you are using Private Link for Arc and your Arc Machine will resolve a Private Endpoint for connectivity to Azure.')
+param privateLinkScopeResourceId string = ''
+
+@description('Optional. Parent cluster resource ID (Azure Stack HCI).')
+param parentClusterResourceId string = ''
+
+@description('Optional. The GUID of the on-premises virtual machine from your hypervisor.')
+param vmId string = ''
+
+@description('Optional. The Public Key that the client provides to be used during initial resource onboarding.')
+@secure()
+param clientPublicKey string = ''
+
+@description('Optional. VM guest patching orchestration mode. \'AutomaticByOS\' & \'Manual\' are for Windows only, \'ImageDefault\' for Linux only.')
+@allowed([
+ 'AutomaticByPlatform'
+ 'AutomaticByOS'
+ 'Manual'
+ 'ImageDefault'
+])
+param patchMode string?
+
+@description('Optional. VM guest patching assessment mode. Set it to \'AutomaticByPlatform\' to enable automatically check for updates every 24 hours.')
+@allowed([
+ 'AutomaticByPlatform'
+ 'ImageDefault'
+])
+param patchAssessmentMode string = 'ImageDefault'
+
+// support added in 2024-05-20-preview
+//@description('Optional. Captures the hotpatch capability enrollment intent of the customers, which enables customers to patch their Windows machines without requiring a reboot.')
+//param enableHotpatching bool = false
+
+// Child resources
+@description('Optional. The guest configuration for the Arc machine. Needs the Guest Configuration extension to be enabled.')
+param guestConfiguration object = {}
+
+@description('Conditional. Required if you are providing OS-type specified configurations, such as patch settings. The chosen OS type, either Windows or Linux.')
+@allowed([
+ 'Windows'
+ 'Linux'
+])
+param osType string?
+
+// Shared parameters
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Optional. The lock settings of the service.')
+param lock lockType
+
+@description('Optional. Array of role assignments to create.')
+param roleAssignments roleAssignmentType
+
+@description('Optional. Tags of the resource.')
+param tags object?
+
+@description('Optional. Enable/Disable usage telemetry for module.')
+param enableTelemetry bool = true
+
+var linuxConfiguration = {
+ patchSettings: (patchMode == 'AutomaticByPlatform' || patchMode == 'ImageDefault')
+ ? {
+ patchMode: patchMode
+ assessmentMode: patchAssessmentMode
+ }
+ : null
+}
+
+var windowsConfiguration = {
+ patchSettings: (patchMode == 'AutomaticByPlatform' || patchMode == 'AutomaticByOS' || patchMode == 'Manual')
+ ? {
+ patchMode: patchMode
+ assessmentMode: patchAssessmentMode
+ // enableHotpatching: enableHotpatching // support added in 2024-05-20-preview
+ }
+ : null
+}
+
+var builtInRoleNames = {
+ Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Role Based Access Control Administrator (Preview)': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ 'f58310d9-a9f6-439a-9e8d-f62e7b41a168'
+ )
+ 'User Access Administrator': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
+ )
+ 'Arc machine Administrator Login': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ '1c0163c0-47e6-4577-8991-ea5c82e286e4'
+ )
+ 'Arc machine Contributor': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ '9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
+ )
+ 'Arc machine User Login': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ 'fb879df8-f326-4884-b1cf-06f3ad86be52'
+ )
+ 'Windows Admin Center Administrator Login': subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ 'a6333a3e-0164-44c3-b281-7a577aff287f'
+ )
+}
+
+#disable-next-line no-deployments-resources
+resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) {
+ name: '46d3xbcp.res.hybridcompute-machine.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}'
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
+ contentVersion: '0.0.0'
+ resources: []
+ outputs: {
+ telemetry: {
+ type: 'String'
+ value: 'For more information, see https://aka.ms/avm/TelemetryInfo'
+ }
+ }
+ }
+ }
+}
+
+resource machine 'Microsoft.HybridCompute/machines@2024-03-31-preview' = {
+ name: name
+ location: location
+ identity: {
+ type: 'SystemAssigned'
+ }
+ tags: tags
+ kind: kind
+ properties: {
+ osProfile: {
+ windowsConfiguration: osType == 'Windows' ? windowsConfiguration : null
+ linuxConfiguration: osType == 'Linux' ? linuxConfiguration : null
+ }
+ parentClusterResourceId: parentClusterResourceId
+ vmId: vmId
+ clientPublicKey: clientPublicKey
+ privateLinkScopeResourceId: !empty(privateLinkScopeResourceId) ? privateLinkScopeResourceId : null
+ }
+}
+
+resource AzureWindowsBaseline 'Microsoft.GuestConfiguration/guestConfigurationAssignments@2020-06-25' = if (!empty(guestConfiguration)) {
+ name: 'gca-${name}'
+ scope: machine
+ dependsOn: []
+ location: location
+ properties: {
+ guestConfiguration: guestConfiguration
+ }
+}
+
+resource machine_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') {
+ name: lock.?name ?? 'lock-${name}'
+ properties: {
+ level: lock.?kind ?? ''
+ notes: lock.?kind == 'CanNotDelete'
+ ? 'Cannot delete resource or child resources.'
+ : 'Cannot delete or modify the resource or child resources.'
+ }
+ scope: machine
+}
+
+resource machine_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [
+ for (roleAssignment, index) in (roleAssignments ?? []): {
+ name: guid(machine.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName)
+ ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName]
+ : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/')
+ ? roleAssignment.roleDefinitionIdOrName
+ : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName)
+ principalId: roleAssignment.principalId
+ description: roleAssignment.?description
+ principalType: roleAssignment.?principalType
+ condition: roleAssignment.?condition
+ conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set
+ delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId
+ }
+ scope: machine
+ }
+]
+
+@description('The name of the machine.')
+output name string = machine.name
+
+@description('The resource ID of the machine.')
+output resourceId string = machine.id
+
+@description('The name of the resource group the VM was created in.')
+output resourceGroupName string = resourceGroup().name
+
+@description('The principal ID of the system assigned identity.')
+output systemAssignedMIPrincipalId string = machine.?identity.?principalId ?? ''
+
+@description('The location the resource was deployed into.')
+output location string = machine.location
+
+// =============== //
+// Definitions //
+// =============== //
+
+type managedIdentitiesType = {
+ @description('Optional. Enables system assigned managed identity on the resource.')
+ systemAssigned: bool?
+
+ @description('Optional. The resource ID(s) to assign to the resource.')
+ userAssignedResourceIds: string[]?
+}?
+
+type lockType = {
+ @description('Optional. Specify the name of lock.')
+ name: string?
+
+ @description('Optional. Specify the type of lock.')
+ kind: ('CanNotDelete' | 'ReadOnly' | 'None')?
+}?
+
+type roleAssignmentType = {
+ @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.')
+ roleDefinitionIdOrName: string
+
+ @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.')
+ principalId: string
+
+ @description('Optional. The principal type of the assigned principal ID.')
+ principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')?
+
+ @description('Optional. The description of the role assignment.')
+ description: string?
+
+ @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".')
+ condition: string?
+
+ @description('Optional. Version of the condition.')
+ conditionVersion: '2.0'?
+
+ @description('Optional. The Resource Id of the delegated managed identity resource.')
+ delegatedManagedIdentityResourceId: string?
+}[]?
diff --git a/avm/res/hybrid-compute/machine/main.json b/avm/res/hybrid-compute/machine/main.json
new file mode 100644
index 0000000000..a2151e8063
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/main.json
@@ -0,0 +1,397 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "6825923126291924605"
+ },
+ "name": "Hybrid Compute Machines",
+ "description": "This module deploys an Arc Machine for use with Arc Resource Bridge for Azure Stack HCI or VMware. In these scenarios, this resource module will be used in combination with another resource module to create the require Virtual Machine Instance extension resource on this Arc Machine resource. This module should not be used for other Arc-enabled server scenarios, where the Arc Machine resource is created automatically by the onboarding process.",
+ "owner": "Azure/module-maintainers"
+ },
+ "definitions": {
+ "managedIdentitiesType": {
+ "type": "object",
+ "properties": {
+ "systemAssigned": {
+ "type": "bool",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Enables system assigned managed identity on the resource."
+ }
+ },
+ "userAssignedResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The resource ID(s) to assign to the resource."
+ }
+ }
+ },
+ "nullable": true
+ },
+ "lockType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the name of lock."
+ }
+ },
+ "kind": {
+ "type": "string",
+ "allowedValues": [
+ "CanNotDelete",
+ "None",
+ "ReadOnly"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the type of lock."
+ }
+ }
+ },
+ "nullable": true
+ },
+ "roleAssignmentType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "roleDefinitionIdOrName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
+ }
+ },
+ "principalId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
+ }
+ },
+ "principalType": {
+ "type": "string",
+ "allowedValues": [
+ "Device",
+ "ForeignGroup",
+ "Group",
+ "ServicePrincipal",
+ "User"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The principal type of the assigned principal ID."
+ }
+ },
+ "description": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The description of the role assignment."
+ }
+ },
+ "condition": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
+ }
+ },
+ "conditionVersion": {
+ "type": "string",
+ "allowedValues": [
+ "2.0"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Version of the condition."
+ }
+ },
+ "delegatedManagedIdentityResourceId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The Resource Id of the delegated managed identity resource."
+ }
+ }
+ }
+ },
+ "nullable": true
+ }
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the Arc machine to be created. You should use a unique prefix to reduce name collisions in Active Directory."
+ }
+ },
+ "kind": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Kind of Arc machine to be created. Possible values are: HCI, SCVMM, VMware."
+ }
+ },
+ "privateLinkScopeResourceId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Conditional. The resource ID of an Arc Private Link Scope which which to associate this machine. Required if you are using Private Link for Arc and your Arc Machine will resolve a Private Endpoint for connectivity to Azure."
+ }
+ },
+ "parentClusterResourceId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. Parent cluster resource ID (Azure Stack HCI)."
+ }
+ },
+ "vmId": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. The GUID of the on-premises virtual machine from your hypervisor."
+ }
+ },
+ "clientPublicKey": {
+ "type": "securestring",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. The Public Key that the client provides to be used during initial resource onboarding."
+ }
+ },
+ "patchMode": {
+ "type": "string",
+ "nullable": true,
+ "allowedValues": [
+ "AutomaticByPlatform",
+ "AutomaticByOS",
+ "Manual",
+ "ImageDefault"
+ ],
+ "metadata": {
+ "description": "Optional. VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only."
+ }
+ },
+ "patchAssessmentMode": {
+ "type": "string",
+ "defaultValue": "ImageDefault",
+ "allowedValues": [
+ "AutomaticByPlatform",
+ "ImageDefault"
+ ],
+ "metadata": {
+ "description": "Optional. VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours."
+ }
+ },
+ "guestConfiguration": {
+ "type": "object",
+ "defaultValue": {},
+ "metadata": {
+ "description": "Optional. The guest configuration for the Arc machine. Needs the Guest Configuration extension to be enabled."
+ }
+ },
+ "osType": {
+ "type": "string",
+ "nullable": true,
+ "allowedValues": [
+ "Windows",
+ "Linux"
+ ],
+ "metadata": {
+ "description": "Conditional. Required if you are providing OS-type specified configurations, such as patch settings. The chosen OS type, either Windows or Linux."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Optional. Location for all resources."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
+ }
+ },
+ "roleAssignments": {
+ "$ref": "#/definitions/roleAssignmentType",
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Tags of the resource."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ }
+ },
+ "variables": {
+ "linuxConfiguration": {
+ "patchSettings": "[if(or(equals(parameters('patchMode'), 'AutomaticByPlatform'), equals(parameters('patchMode'), 'ImageDefault')), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]"
+ },
+ "windowsConfiguration": {
+ "patchSettings": "[if(or(or(equals(parameters('patchMode'), 'AutomaticByPlatform'), equals(parameters('patchMode'), 'AutomaticByOS')), equals(parameters('patchMode'), 'Manual')), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]"
+ },
+ "builtInRoleNames": {
+ "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
+ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
+ "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
+ "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
+ "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]",
+ "Arc machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]",
+ "Arc machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]",
+ "Arc machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]",
+ "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2023-07-01",
+ "name": "[format('46d3xbcp.res.hybridcompute-machine.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "0.0.0",
+ "resources": [],
+ "outputs": {
+ "telemetry": {
+ "type": "String",
+ "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
+ }
+ }
+ }
+ }
+ },
+ "machine": {
+ "type": "Microsoft.HybridCompute/machines",
+ "apiVersion": "2024-03-31-preview",
+ "name": "[parameters('name')]",
+ "location": "[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "tags": "[parameters('tags')]",
+ "kind": "[parameters('kind')]",
+ "properties": {
+ "osProfile": {
+ "windowsConfiguration": "[if(equals(parameters('osType'), 'Windows'), variables('windowsConfiguration'), null())]",
+ "linuxConfiguration": "[if(equals(parameters('osType'), 'Linux'), variables('linuxConfiguration'), null())]"
+ },
+ "parentClusterResourceId": "[parameters('parentClusterResourceId')]",
+ "vmId": "[parameters('vmId')]",
+ "clientPublicKey": "[parameters('clientPublicKey')]",
+ "privateLinkScopeResourceId": "[if(not(empty(parameters('privateLinkScopeResourceId'))), parameters('privateLinkScopeResourceId'), null())]"
+ }
+ },
+ "AzureWindowsBaseline": {
+ "condition": "[not(empty(parameters('guestConfiguration')))]",
+ "type": "Microsoft.GuestConfiguration/guestConfigurationAssignments",
+ "apiVersion": "2020-06-25",
+ "scope": "[format('Microsoft.HybridCompute/machines/{0}', parameters('name'))]",
+ "name": "[format('gca-{0}', parameters('name'))]",
+ "location": "[parameters('location')]",
+ "properties": {
+ "guestConfiguration": "[parameters('guestConfiguration')]"
+ },
+ "dependsOn": [
+ "machine"
+ ]
+ },
+ "machine_lock": {
+ "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
+ "type": "Microsoft.Authorization/locks",
+ "apiVersion": "2020-05-01",
+ "scope": "[format('Microsoft.HybridCompute/machines/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
+ "properties": {
+ "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
+ "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
+ },
+ "dependsOn": [
+ "machine"
+ ]
+ },
+ "machine_roleAssignments": {
+ "copy": {
+ "name": "machine_roleAssignments",
+ "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('Microsoft.HybridCompute/machines/{0}', parameters('name'))]",
+ "name": "[guid(resourceId('Microsoft.HybridCompute/machines', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]",
+ "properties": {
+ "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]",
+ "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]",
+ "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]",
+ "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]",
+ "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]",
+ "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
+ "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
+ },
+ "dependsOn": [
+ "machine"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the machine."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the machine."
+ },
+ "value": "[resourceId('Microsoft.HybridCompute/machines', parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the VM was created in."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "systemAssignedMIPrincipalId": {
+ "type": "string",
+ "metadata": {
+ "description": "The principal ID of the system assigned identity."
+ },
+ "value": "[coalesce(tryGet(tryGet(reference('machine', '2024-03-31-preview', 'full'), 'identity'), 'principalId'), '')]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('machine', '2024-03-31-preview', 'full').location]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/hybrid-compute/machine/tests/e2e/hci.defaults/main.test.bicep b/avm/res/hybrid-compute/machine/tests/e2e/hci.defaults/main.test.bicep
new file mode 100644
index 0000000000..66b423867d
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/tests/e2e/hci.defaults/main.test.bicep
@@ -0,0 +1,48 @@
+targetScope = 'subscription'
+
+metadata name = 'Creates an Arc Machine using only the defaults'
+metadata description = 'This instance deploys the module with the minimum set of required parameters.'
+
+// ========== //
+// Parameters //
+// ========== //
+
+@description('Optional. The name of the resource group to deploy for testing purposes.')
+@maxLength(90)
+param resourceGroupName string = 'dep-${namePrefix}-hybridCompute.machine-${serviceShort}-rg'
+
+@description('Optional. The location to deploy resources to.')
+param resourceLocation string = deployment().location
+
+@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
+param serviceShort string = 'arcmachcimin'
+
+@description('Optional. A token to inject into the name of each resource.')
+param namePrefix string = '#_namePrefix_#'
+
+// ============ //
+// Dependencies //
+// ============ //
+
+// General resources
+// =================
+resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: resourceGroupName
+ location: resourceLocation
+}
+
+// ============== //
+// Test Execution //
+// ============== //
+@batchSize(1)
+module testDeployment '../../../main.bicep' = [
+ for iteration in ['init', 'idem']: {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
+ params: {
+ location: resourceLocation
+ name: '${namePrefix}${serviceShort}'
+ kind: 'HCI'
+ }
+ }
+]
diff --git a/avm/res/hybrid-compute/machine/tests/e2e/max.hci/dependencies.bicep b/avm/res/hybrid-compute/machine/tests/e2e/max.hci/dependencies.bicep
new file mode 100644
index 0000000000..f482c45c67
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/tests/e2e/max.hci/dependencies.bicep
@@ -0,0 +1,21 @@
+@description('Required. The name of the Private Link Scope to create.')
+param privateLinkScopeName string
+
+@description('Optional. The location to deploy to.')
+param location string = resourceGroup().location
+
+resource privateLinkScope 'Microsoft.HybridCompute/privateLinkScopes@2023-10-03-preview' = {
+ name: privateLinkScopeName
+ location: location
+ tags: {
+ 'hidden-title': 'This is visible in the resource name'
+ Environment: 'Non-Prod'
+ Role: 'DeploymentValidation'
+ }
+ properties: {
+ publicNetworkAccess: 'Enabled'
+ }
+}
+
+@description('The resource ID of the created Private Link Scope.')
+output privateLinkScopeResourceId string = privateLinkScope.id
diff --git a/avm/res/hybrid-compute/machine/tests/e2e/max.hci/main.test.bicep b/avm/res/hybrid-compute/machine/tests/e2e/max.hci/main.test.bicep
new file mode 100644
index 0000000000..7f9d565e22
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/tests/e2e/max.hci/main.test.bicep
@@ -0,0 +1,89 @@
+targetScope = 'subscription'
+
+metadata name = 'Creates an Arc Machine with maximum configurations'
+metadata description = 'This instance deploys the module with most of its features enabled.'
+
+// ========== //
+// Parameters //
+// ========== //
+
+@description('Optional. The name of the resource group to deploy for testing purposes.')
+@maxLength(90)
+param resourceGroupName string = 'dep-${namePrefix}-hybridCompute.machine-${serviceShort}-rg'
+
+@description('Optional. The location to deploy resources to.')
+param resourceLocation string = deployment().location
+
+@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
+param serviceShort string = 'arcmachcimx'
+
+@description('Optional. A token to inject into the name of each resource.')
+param namePrefix string = '#_namePrefix_#'
+
+// ============ //
+// Dependencies //
+// ============ //
+
+// General resources
+// =================
+resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: resourceGroupName
+ location: resourceLocation
+}
+
+module nestedDependencies 'dependencies.bicep' = {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies'
+ params: {
+ location: resourceLocation
+ privateLinkScopeName: 'dep-${namePrefix}-pls-${serviceShort}'
+ }
+}
+
+// ============== //
+// Test Execution //
+// ============== //
+@batchSize(1)
+module testDeployment '../../../main.bicep' = [
+ for iteration in ['init', 'idem']: {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
+ params: {
+ location: resourceLocation
+ name: '${namePrefix}${serviceShort}'
+ kind: 'HCI'
+ patchAssessmentMode: 'AutomaticByPlatform'
+ patchMode: 'AutomaticByPlatform'
+ privateLinkScopeResourceId: nestedDependencies.outputs.privateLinkScopeResourceId
+ guestConfiguration: {
+ name: 'AzureWindowsBaseline'
+ version: '1.*'
+ assignmentType: 'ApplyAndMonitor'
+ configurationParameter: [
+ {
+ name: 'Minimum Password Length;ExpectedValue'
+ value: '16'
+ }
+ {
+ name: 'Minimum Password Length;RemediateValue'
+ value: '16'
+ }
+ {
+ name: 'Maximum Password Age;ExpectedValue'
+ value: '75'
+ }
+ {
+ name: 'Maximum Password Age;RemediateValue'
+ value: '75'
+ }
+ ]
+ }
+ osType: 'Windows'
+ tags: {
+ 'hidden-title': 'This is visible in the resource name'
+ Environment: 'Non-Prod'
+ Role: 'DeploymentValidation'
+ }
+ }
+ }
+]
diff --git a/avm/res/hybrid-compute/machine/tests/e2e/vmware.defaults/main.test.bicep b/avm/res/hybrid-compute/machine/tests/e2e/vmware.defaults/main.test.bicep
new file mode 100644
index 0000000000..524d3881ec
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/tests/e2e/vmware.defaults/main.test.bicep
@@ -0,0 +1,49 @@
+targetScope = 'subscription'
+
+metadata name = 'Creates an VMWare machine using only the defaults'
+
+metadata description = 'This instance deploys the module with the minimum set of required parameters.'
+
+// ========== //
+// Parameters //
+// ========== //
+
+@description('Optional. The name of the resource group to deploy for testing purposes.')
+@maxLength(90)
+param resourceGroupName string = 'dep-${namePrefix}-hybridCompute.machine-${serviceShort}-rg'
+
+@description('Optional. The location to deploy resources to.')
+param resourceLocation string = deployment().location
+
+@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
+param serviceShort string = 'arcmacvmwmin'
+
+@description('Optional. A token to inject into the name of each resource.')
+param namePrefix string = '#_namePrefix_#'
+
+// ============ //
+// Dependencies //
+// ============ //
+
+// General resources
+// =================
+resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: resourceGroupName
+ location: resourceLocation
+}
+
+// ============== //
+// Test Execution //
+// ============== //
+@batchSize(1)
+module testDeployment '../../../main.bicep' = [
+ for iteration in ['init', 'idem']: {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
+ params: {
+ location: resourceLocation
+ name: '${namePrefix}${serviceShort}'
+ kind: 'VMware'
+ }
+ }
+]
diff --git a/avm/res/hybrid-compute/machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/hybrid-compute/machine/tests/e2e/waf-aligned/main.test.bicep
new file mode 100644
index 0000000000..f9932ecb3e
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/tests/e2e/waf-aligned/main.test.bicep
@@ -0,0 +1,53 @@
+targetScope = 'subscription'
+
+metadata name = 'WAF-aligned'
+metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.'
+
+// ========== //
+// Parameters //
+// ========== //
+
+@description('Optional. The name of the resource group to deploy for testing purposes.')
+@maxLength(90)
+param resourceGroupName string = 'dep-${namePrefix}-hybridCompute.machine-${serviceShort}-rg'
+
+@description('Optional. The location to deploy resources to.')
+param resourceLocation string = deployment().location
+
+@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
+param serviceShort string = 'arcmacwaf'
+
+@description('Optional. A token to inject into the name of each resource.')
+param namePrefix string = '#_namePrefix_#'
+
+// ============ //
+// Dependencies //
+// ============ //
+
+// General resources
+// =================
+resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: resourceGroupName
+ location: resourceLocation
+}
+
+// ============== //
+// Test Execution //
+// ============== //
+@batchSize(1)
+module testDeployment '../../../main.bicep' = [
+ for iteration in ['init', 'idem']: {
+ scope: resourceGroup
+ name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
+ params: {
+ location: resourceLocation
+ name: '${namePrefix}${serviceShort}'
+ kind: 'HCI'
+ tags: {
+ 'hidden-title': 'This is visible in the resource name'
+ Environment: 'Non-Prod'
+ Role: 'DeploymentValidation'
+ }
+ }
+ }
+]
diff --git a/avm/res/hybrid-compute/machine/version.json b/avm/res/hybrid-compute/machine/version.json
new file mode 100644
index 0000000000..0200aa0775
--- /dev/null
+++ b/avm/res/hybrid-compute/machine/version.json
@@ -0,0 +1,7 @@
+{
+ "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#",
+ "version": "0.1",
+ "pathFilters": [
+ "./main.json"
+ ]
+}
diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md
index 26de2f7d59..6931df0373 100644
--- a/avm/res/storage/storage-account/README.md
+++ b/avm/res/storage/storage-account/README.md
@@ -2694,7 +2694,7 @@ Configuration details for private endpoints. For security reasons, it is recomme
| Parameter | Type | Description |
| :-- | :-- | :-- |
-| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". |
+| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file". |
| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. |
**Optional parameters**
@@ -2706,19 +2706,21 @@ Configuration details for private endpoints. For security reasons, it is recomme
| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. |
| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. |
| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. |
-| [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | Manual PrivateLink Service Connections. |
+| [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. |
| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. |
| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. |
| [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. |
| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. |
| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. |
| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. |
+| [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. |
+| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. |
| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. |
| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. |
### Parameter: `privateEndpoints.service`
-The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".
+The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file".
- Required: Yes
- Type: string
@@ -2838,7 +2840,7 @@ A private ip address obtained from the private endpoint's subnet.
### Parameter: `privateEndpoints.isManualConnection`
-Manual PrivateLink Service Connections.
+If Manual Private Link Connection is required.
- Required: No
- Type: bool
@@ -2914,6 +2916,20 @@ The private DNS zone groups to associate the private endpoint with. A DNS zone g
- Required: No
- Type: array
+### Parameter: `privateEndpoints.privateLinkServiceConnectionName`
+
+The name of the private link connection to create.
+
+- Required: No
+- Type: string
+
+### Parameter: `privateEndpoints.resourceGroupName`
+
+Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.
+
+- Required: No
+- Type: string
+
### Parameter: `privateEndpoints.roleAssignments`
Array of role assignments to create.
diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep
index d2e7e2864d..67f2dcc12e 100644
--- a/avm/res/storage/storage-account/main.bicep
+++ b/avm/res/storage/storage-account/main.bicep
@@ -476,10 +476,11 @@ resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments
module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [
for (privateEndpoint, index) in (privateEndpoints ?? []): {
- name: '${uniqueString(deployment().name, location)}-StorageAccount-PrivateEndpoint-${index}'
+ name: '${uniqueString(deployment().name, location)}-storageAccount-PrivateEndpoint-${index}'
+ scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '')
params: {
name: privateEndpoint.?name ?? 'pep-${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}'
- privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true
+ privateLinkServiceConnections: privateEndpoint.?isManualConnection != true
? [
{
name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}'
@@ -492,7 +493,7 @@ module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoi
}
]
: null
- manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true
+ manualPrivateLinkServiceConnections: privateEndpoint.?isManualConnection == true
? [
{
name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(storageAccount.id, '/'))}-${privateEndpoint.service}-${index}'
@@ -713,7 +714,10 @@ type privateEndpointType = {
@description('Optional. The location to deploy the private endpoint to.')
location: string?
- @description('Required. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".')
+ @description('Optional. The name of the private link connection to create.')
+ privateLinkServiceConnectionName: string?
+
+ @description('Required. The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file".')
service: string
@description('Required. Resource ID of the subnet where the endpoint needs to be created.')
@@ -725,7 +729,7 @@ type privateEndpointType = {
@description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.')
privateDnsZoneResourceIds: string[]?
- @description('Optional. Manual PrivateLink Service Connections.')
+ @description('Optional. If Manual Private Link Connection is required.')
isManualConnection: bool?
@description('Optional. A message passed to the owner of the remote resource with the manual connection request.')
@@ -776,6 +780,9 @@ type privateEndpointType = {
@description('Optional. Enable/Disable usage telemetry for module.')
enableTelemetry: bool?
+
+ @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.')
+ resourceGroupName: string?
}[]?
type diagnosticSettingType = {
diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json
index 4624ad705b..fb8ad05467 100644
--- a/avm/res/storage/storage-account/main.json
+++ b/avm/res/storage/storage-account/main.json
@@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
- "templateHash": "11817355272215191914"
+ "templateHash": "9679329912314181282"
},
"name": "Storage Accounts",
"description": "This module deploys a Storage Account.",
@@ -217,10 +217,17 @@
"description": "Optional. The location to deploy the private endpoint to."
}
},
+ "privateLinkServiceConnectionName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the private link connection to create."
+ }
+ },
"service": {
"type": "string",
"metadata": {
- "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"."
+ "description": "Required. The subresource to deploy the private endpoint for. For example \"blob\", \"table\", \"queue\" or \"file\"."
}
},
"subnetResourceId": {
@@ -250,7 +257,7 @@
"type": "bool",
"nullable": true,
"metadata": {
- "description": "Optional. Manual PrivateLink Service Connections."
+ "description": "Optional. If Manual Private Link Connection is required."
}
},
"manualConnectionRequestMessage": {
@@ -375,6 +382,13 @@
"metadata": {
"description": "Optional. Enable/Disable usage telemetry for module."
}
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource."
+ }
}
}
},
@@ -1023,7 +1037,8 @@
},
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
- "name": "[format('{0}-StorageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "name": "[format('{0}-storageAccount-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
@@ -1033,8 +1048,8 @@
"name": {
"value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex()))]"
},
- "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]",
- "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
+ "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]",
+ "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Storage/storageAccounts', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Storage/storageAccounts', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
"subnetResourceId": {
"value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
},
diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md
index eb60880311..cbc4919670 100644
--- a/avm/res/synapse/workspace/README.md
+++ b/avm/res/synapse/workspace/README.md
@@ -27,6 +27,7 @@ This module deploys a Synapse Workspace.
| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) |
| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) |
| `Microsoft.Synapse/workspaces` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces) |
+| `Microsoft.Synapse/workspaces/administrators` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/administrators) |
| `Microsoft.Synapse/workspaces/integrationRuntimes` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/integrationRuntimes) |
| `Microsoft.Synapse/workspaces/keys` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/keys) |
@@ -346,6 +347,11 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {
name: 'swmax001'
sqlAdministratorLogin: 'synwsadmin'
// Non-required parameters
+ administrator: {
+ administratorType: 'ServicePrincipal'
+ login: 'dep-msi-swmax'
+ sid: ''
+ }
diagnosticSettings: [
{
eventHubAuthorizationRuleResourceId: ''
@@ -469,6 +475,13 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {
"value": "synwsadmin"
},
// Non-required parameters
+ "administrator": {
+ "value": {
+ "administratorType": "ServicePrincipal",
+ "login": "dep-msi-swmax",
+ "sid": ""
+ }
+ },
"diagnosticSettings": {
"value": [
{
@@ -758,6 +771,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {
| Parameter | Type | Description |
| :-- | :-- | :-- |
| [`accountUrl`](#parameter-accounturl) | string | The account URL of the data lake storage account. |
+| [`administrator`](#parameter-administrator) | object | The Entra ID administrator for the synapse workspace. |
| [`allowedAadTenantIdsForLinking`](#parameter-allowedaadtenantidsforlinking) | array | Allowed AAD Tenant IDs For Linking. |
| [`azureADOnlyAuthentication`](#parameter-azureadonlyauthentication) | bool | Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource. |
| [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. |
@@ -818,6 +832,55 @@ The account URL of the data lake storage account.
- Type: string
- Default: `[format('https://{0}.dfs.{1}', last(split(parameters('defaultDataLakeStorageAccountResourceId'), '/')), environment().suffixes.storage)]`
+### Parameter: `administrator`
+
+The Entra ID administrator for the synapse workspace.
+
+- Required: No
+- Type: object
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`administratorType`](#parameter-administratoradministratortype) | string | Workspace active directory administrator type. |
+| [`login`](#parameter-administratorlogin) | securestring | Login of the workspace active directory administrator. |
+| [`sid`](#parameter-administratorsid) | securestring | Object ID of the workspace active directory administrator. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`tenantId`](#parameter-administratortenantid) | securestring | Tenant ID of the workspace active directory administrator. |
+
+### Parameter: `administrator.administratorType`
+
+Workspace active directory administrator type.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `administrator.login`
+
+Login of the workspace active directory administrator.
+
+- Required: Yes
+- Type: securestring
+
+### Parameter: `administrator.sid`
+
+Object ID of the workspace active directory administrator.
+
+- Required: Yes
+- Type: securestring
+
+### Parameter: `administrator.tenantId`
+
+Tenant ID of the workspace active directory administrator.
+
+- Required: No
+- Type: securestring
+
### Parameter: `allowedAadTenantIdsForLinking`
Allowed AAD Tenant IDs For Linking.
diff --git a/avm/res/synapse/workspace/administrators/README.md b/avm/res/synapse/workspace/administrators/README.md
new file mode 100644
index 0000000000..07ebda7b00
--- /dev/null
+++ b/avm/res/synapse/workspace/administrators/README.md
@@ -0,0 +1,92 @@
+# Synapse Workspaces Administrators `[Microsoft.Synapse/workspaces/administrators]`
+
+This module deploys Synapse Workspaces Administrators.
+
+## Navigation
+
+- [Resource Types](#Resource-Types)
+- [Parameters](#Parameters)
+- [Outputs](#Outputs)
+- [Cross-referenced modules](#Cross-referenced-modules)
+- [Data Collection](#Data-Collection)
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Synapse/workspaces/administrators` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/administrators) |
+
+## Parameters
+
+**Required parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`administratorType`](#parameter-administratortype) | string | Workspace active directory administrator type. |
+| [`login`](#parameter-login) | securestring | Login of the workspace active directory administrator. |
+| [`sid`](#parameter-sid) | securestring | Object ID of the workspace active directory administrator. |
+
+**Conditional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. |
+
+**Optional parameters**
+
+| Parameter | Type | Description |
+| :-- | :-- | :-- |
+| [`tenantId`](#parameter-tenantid) | string | Tenant ID of the workspace active directory administrator. |
+
+### Parameter: `administratorType`
+
+Workspace active directory administrator type.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `login`
+
+Login of the workspace active directory administrator.
+
+- Required: Yes
+- Type: securestring
+
+### Parameter: `sid`
+
+Object ID of the workspace active directory administrator.
+
+- Required: Yes
+- Type: securestring
+
+### Parameter: `workspaceName`
+
+The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.
+
+- Required: Yes
+- Type: string
+
+### Parameter: `tenantId`
+
+Tenant ID of the workspace active directory administrator.
+
+- Required: No
+- Type: string
+- Default: `[tenant().tenantId]`
+
+
+## Outputs
+
+| Output | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed administrator. |
+| `resourceGroupName` | string | The resource group of the deployed administrator. |
+| `resourceId` | string | The resource ID of the deployed administrator. |
+
+## Cross-referenced modules
+
+_None_
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/avm/res/synapse/workspace/administrators/main.bicep b/avm/res/synapse/workspace/administrators/main.bicep
new file mode 100644
index 0000000000..c6410bb361
--- /dev/null
+++ b/avm/res/synapse/workspace/administrators/main.bicep
@@ -0,0 +1,44 @@
+metadata name = 'Synapse Workspaces Administrators'
+metadata description = 'This module deploys Synapse Workspaces Administrators.'
+metadata owner = 'Azure/module-maintainers'
+
+@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.')
+param workspaceName string
+
+@description('Required. Workspace active directory administrator type.')
+param administratorType string
+
+@description('Required. Login of the workspace active directory administrator.')
+@secure()
+param login string
+
+@description('Required. Object ID of the workspace active directory administrator.')
+@secure()
+param sid string
+
+@description('Optional. Tenant ID of the workspace active directory administrator.')
+param tenantId string = tenant().tenantId
+
+resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = {
+ name: workspaceName
+}
+
+resource synapse_workspace_administrator 'Microsoft.Synapse/workspaces/administrators@2021-06-01' = {
+ name: 'activeDirectory'
+ parent: workspace
+ properties: {
+ administratorType: administratorType
+ login: login
+ sid: sid
+ tenantId: tenantId
+ }
+}
+
+@description('The name of the deployed administrator.')
+output name string = synapse_workspace_administrator.name
+
+@description('The resource ID of the deployed administrator.')
+output resourceId string = synapse_workspace_administrator.id
+
+@description('The resource group of the deployed administrator.')
+output resourceGroupName string = resourceGroup().name
diff --git a/avm/res/synapse/workspace/administrators/main.json b/avm/res/synapse/workspace/administrators/main.json
new file mode 100644
index 0000000000..76087e4632
--- /dev/null
+++ b/avm/res/synapse/workspace/administrators/main.json
@@ -0,0 +1,83 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "351030244990389212"
+ },
+ "name": "Synapse Workspaces Administrators",
+ "description": "This module deploys Synapse Workspaces Administrators.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "workspaceName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment."
+ }
+ },
+ "administratorType": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Workspace active directory administrator type."
+ }
+ },
+ "login": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Login of the workspace active directory administrator."
+ }
+ },
+ "sid": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Object ID of the workspace active directory administrator."
+ }
+ },
+ "tenantId": {
+ "type": "string",
+ "defaultValue": "[tenant().tenantId]",
+ "metadata": {
+ "description": "Optional. Tenant ID of the workspace active directory administrator."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Synapse/workspaces/administrators",
+ "apiVersion": "2021-06-01",
+ "name": "[format('{0}/{1}', parameters('workspaceName'), 'activeDirectory')]",
+ "properties": {
+ "administratorType": "[parameters('administratorType')]",
+ "login": "[parameters('login')]",
+ "sid": "[parameters('sid')]",
+ "tenantId": "[parameters('tenantId')]"
+ }
+ }
+ ],
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the deployed administrator."
+ },
+ "value": "activeDirectory"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the deployed administrator."
+ },
+ "value": "[resourceId('Microsoft.Synapse/workspaces/administrators', parameters('workspaceName'), 'activeDirectory')]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group of the deployed administrator."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+}
\ No newline at end of file
diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep
index 086fd3eb92..538751229e 100644
--- a/avm/res/synapse/workspace/main.bicep
+++ b/avm/res/synapse/workspace/main.bicep
@@ -31,6 +31,9 @@ param defaultDataLakeStorageFilesystem string
@description('Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace\'s primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account.')
param defaultDataLakeStorageCreateManagedPrivateEndpoint bool = false
+@description('Optional. The Entra ID administrator for the synapse workspace.')
+param administrator adminType
+
@description('Optional. The customer managed key definition.')
param customerManagedKey customerManagedKeyType
@@ -274,6 +277,18 @@ module workspace_key 'key/main.bicep' = if (encryptionActivateWorkspace) {
]
}
+// - Workspace Entra ID Administrator
+module workspace_administrator 'administrators/main.bicep' = if (!empty(administrator)) {
+ name: '${workspace.name}-administrator'
+ params: {
+ workspaceName: workspace.name
+ administratorType: administrator!.administratorType
+ login: administrator!.login
+ sid: administrator!.sid
+ tenantId: administrator.?tenantId
+ }
+}
+
// Resource Lock
resource workspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') {
name: lock.?name ?? 'lock-${name}'
@@ -564,3 +579,20 @@ type customerManagedKeyType = {
@description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.')
userAssignedIdentityResourceId: string?
}?
+
+type adminType = {
+ @description('Required. Workspace active directory administrator type.')
+ administratorType: string
+
+ @description('Required. Login of the workspace active directory administrator.')
+ @secure()
+ login: string
+
+ @description('Required. Object ID of the workspace active directory administrator.')
+ @secure()
+ sid: string
+
+ @description('Optional. Tenant ID of the workspace active directory administrator.')
+ @secure()
+ tenantId: string?
+}?
diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json
index fef9827d54..4b0570811e 100644
--- a/avm/res/synapse/workspace/main.json
+++ b/avm/res/synapse/workspace/main.json
@@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
- "templateHash": "8395600145628095339"
+ "templateHash": "16827959448836859226"
},
"name": "Synapse Workspaces",
"description": "This module deploys a Synapse Workspace.",
@@ -434,6 +434,37 @@
}
},
"nullable": true
+ },
+ "adminType": {
+ "type": "object",
+ "properties": {
+ "administratorType": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Workspace active directory administrator type."
+ }
+ },
+ "login": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Login of the workspace active directory administrator."
+ }
+ },
+ "sid": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Object ID of the workspace active directory administrator."
+ }
+ },
+ "tenantId": {
+ "type": "securestring",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Tenant ID of the workspace active directory administrator."
+ }
+ }
+ },
+ "nullable": true
}
},
"parameters": {
@@ -498,6 +529,12 @@
"description": "Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account."
}
},
+ "administrator": {
+ "$ref": "#/definitions/adminType",
+ "metadata": {
+ "description": "Optional. The Entra ID administrator for the synapse workspace."
+ }
+ },
"customerManagedKey": {
"$ref": "#/definitions/customerManagedKeyType",
"metadata": {
@@ -1079,6 +1116,121 @@
"workspace_cmk_rbac"
]
},
+ "workspace_administrator": {
+ "condition": "[not(empty(parameters('administrator')))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-administrator', parameters('name'))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "workspaceName": {
+ "value": "[parameters('name')]"
+ },
+ "administratorType": {
+ "value": "[parameters('administrator').administratorType]"
+ },
+ "login": {
+ "value": "[parameters('administrator').login]"
+ },
+ "sid": {
+ "value": "[parameters('administrator').sid]"
+ },
+ "tenantId": {
+ "value": "[tryGet(parameters('administrator'), 'tenantId')]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.28.1.47646",
+ "templateHash": "351030244990389212"
+ },
+ "name": "Synapse Workspaces Administrators",
+ "description": "This module deploys Synapse Workspaces Administrators.",
+ "owner": "Azure/module-maintainers"
+ },
+ "parameters": {
+ "workspaceName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment."
+ }
+ },
+ "administratorType": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Workspace active directory administrator type."
+ }
+ },
+ "login": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Login of the workspace active directory administrator."
+ }
+ },
+ "sid": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. Object ID of the workspace active directory administrator."
+ }
+ },
+ "tenantId": {
+ "type": "string",
+ "defaultValue": "[tenant().tenantId]",
+ "metadata": {
+ "description": "Optional. Tenant ID of the workspace active directory administrator."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Synapse/workspaces/administrators",
+ "apiVersion": "2021-06-01",
+ "name": "[format('{0}/{1}', parameters('workspaceName'), 'activeDirectory')]",
+ "properties": {
+ "administratorType": "[parameters('administratorType')]",
+ "login": "[parameters('login')]",
+ "sid": "[parameters('sid')]",
+ "tenantId": "[parameters('tenantId')]"
+ }
+ }
+ ],
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the deployed administrator."
+ },
+ "value": "activeDirectory"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the deployed administrator."
+ },
+ "value": "[resourceId('Microsoft.Synapse/workspaces/administrators', parameters('workspaceName'), 'activeDirectory')]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group of the deployed administrator."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "workspace"
+ ]
+ },
"workspace_privateEndpoints": {
"copy": {
"name": "workspace_privateEndpoints",
diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep
index 682ca135f8..ff749a63ba 100644
--- a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep
+++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep
@@ -77,6 +77,12 @@ module testDeployment '../../../main.bicep' = [
nestedDependencies.outputs.managedIdentityResourceId
]
}
+ administrator: {
+ administratorType: 'ServicePrincipal'
+ login: 'dep-${namePrefix}-msi-${serviceShort}'
+ sid: nestedDependencies.outputs.managedIdentityPrincipalId
+ }
+
roleAssignments: [
{
roleDefinitionIdOrName: 'Owner'
diff --git a/avm/res/web/serverfarm/README.md b/avm/res/web/serverfarm/README.md
index 8cf41b7807..82e59d5e52 100644
--- a/avm/res/web/serverfarm/README.md
+++ b/avm/res/web/serverfarm/README.md
@@ -417,6 +417,13 @@ The name of the SKU will Determine the tier, size, family of the App Service Pla
- Required: Yes
- Type: string
+- Example:
+ ```Bicep
+ 'F1'
+ 'B1'
+ 'P1v3'
+ 'I1v2'
+ ```
### Parameter: `reserved`
diff --git a/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 b/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1
index 673e5929fe..49e70020b8 100644
--- a/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1
+++ b/avm/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1
@@ -330,6 +330,7 @@ function Set-DefinitionSection {
$isRequired = (Get-IsParameterRequired -TemplateFileContent $TemplateFileContent -Parameter $parameter) ? 'Yes' : 'No'
$description = $parameter.ContainsKey('metadata') ? $parameter['metadata']['description'].substring("$category. ".Length).Replace("`n- ", '').Replace("`r`n", '').Replace("`n", '
') : $null
+ $example = ($parameter.ContainsKey('metadata') -and $parameter['metadata'].ContainsKey('example')) ? $parameter['metadata']['example'] : $null
#####################
# Table content #
@@ -412,6 +413,29 @@ function Set-DefinitionSection {
$formattedAllowedValues = $null
}
+ # Format example
+ # ==============
+ if (-not [String]::IsNullOrEmpty($example)) {
+ # allign content to the left by removing trailing whitespaces
+ $leadingSpacesToTrim = ($example -match '^(\s+).+') ? $matches[1].Length : 0
+ $exampleLines = $example -split '\n'
+ # Removing excess leading spaces
+ $example = ($exampleLines | Where-Object { -not [String]::IsNullOrEmpty($_) } | ForEach-Object { " $_" -replace "^\s{$leadingSpacesToTrim}" } | Out-String).TrimEnd()
+
+ if ($exampleLines.count -eq 1) {
+ $formattedExample = '- Example: `{0}`' -f $example.TrimStart()
+ } else {
+ $formattedExample = @(
+ '- Example:',
+ ' ```Bicep',
+ $example,
+ ' ```'
+ )
+ }
+ } else {
+ $formattedExample = $null
+ }
+
# Build list item
# ===============
$listSectionContent += @(
@@ -422,7 +446,8 @@ function Set-DefinitionSection {
('- Required: {0}' -f $isRequired),
('- Type: {0}' -f $type),
((-not [String]::IsNullOrEmpty($formattedDefaultValue)) ? $formattedDefaultValue : $null),
- ((-not [String]::IsNullOrEmpty($formattedAllowedValues)) ? $formattedAllowedValues : $null)
+ ((-not [String]::IsNullOrEmpty($formattedAllowedValues)) ? $formattedAllowedValues : $null),
+ ((-not [String]::IsNullOrEmpty($formattedExample)) ? $formattedExample : $null)
''
) | Where-Object { $null -ne $_ }
diff --git a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml
index a6881b3844..5e9c67b778 100644
--- a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml
+++ b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml
@@ -31,6 +31,7 @@ spec:
- Azure.ContainerApp.PublicAccess
# Azure Virtual Machine
- Azure.VM.AMA
+ - Azure.VM.MaintenanceConfig # Excluded as it requires user input
- Azure.VM.Standalone
# Azure App Service
- Azure.AppService.WebProbe # Supressed as the probe path is specific to the app
diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml
index 9c163ed9dd..8db91d89ca 100644
--- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml
+++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml
@@ -81,4 +81,4 @@ rule:
- Azure.VM.UseHybridUseBenefit
- Azure.Storage.UseReplication
- Azure.AppConfig.PurgeProtect
- - Azure.APIM.MultiRegion
+ - Azure.APIM.MultiRegion # Team agreed this is too expensive for most use cases and is safe to ignore.