diff --git a/arm/Microsoft.KeyVault/vaults/.bicep/nested_privateEndpoint.bicep b/arm/Microsoft.KeyVault/vaults/.bicep/nested_privateEndpoint.bicep index 82ab478cd6..0e3f625a39 100644 --- a/arm/Microsoft.KeyVault/vaults/.bicep/nested_privateEndpoint.bicep +++ b/arm/Microsoft.KeyVault/vaults/.bicep/nested_privateEndpoint.bicep @@ -37,7 +37,7 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-05-01' = { } resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2021-02-01' = if (!empty(privateEndpoint_var.privateDnsZoneResourceIds)) { - name: '${privateEndpoint_var.name}/default' + name: '${privateEndpoint.name}/default' properties: { privateDnsZoneConfigs: [for j in range(0, length(privateEndpoint_var.privateDnsZoneResourceIds)): { name: last(split(privateEndpoint_var.privateDnsZoneResourceIds[j], '/')) @@ -46,7 +46,4 @@ resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZone } }] } - dependsOn: [ - privateEndpoint - ] } diff --git a/arm/Microsoft.KeyVault/vaults/.parameters/parameters.json b/arm/Microsoft.KeyVault/vaults/.parameters/parameters.json index 8e3c424c38..66f042ed63 100644 --- a/arm/Microsoft.KeyVault/vaults/.parameters/parameters.json +++ b/arm/Microsoft.KeyVault/vaults/.parameters/parameters.json @@ -27,7 +27,15 @@ "name": "secretName", "value": "secretValue", "contentType": "Something", - "attributesNbf": 10000 + "attributesNbf": 10000, + "roleAssignments": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "<>" + ] + } + ] } ] }, @@ -35,7 +43,46 @@ "value": [ { "name": "keyName", - "attributesNbf": 10000 + "attributesNbf": 10000, + "roleAssignments": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "<>" + ] + } + ] + } + ] + }, + "accessPolicies": { + "value": [ + { + "objectId": "<>", + "permissions": { + "keys": [ + "get", + "list", + "update" + ], + "secrets": [ + "all" + ] + }, + "tenantId": "<>" + }, + { + "objectId": "<>", + "permissions": { + "certificates": [ + "backup", + "create", + "delete" + ], + "secrets": [ + "all" + ] + } } ] }, diff --git a/arm/Microsoft.KeyVault/vaults/accessPolicies/.bicep/nested_cuaId.bicep b/arm/Microsoft.KeyVault/vaults/accessPolicies/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.KeyVault/vaults/accessPolicies/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.KeyVault/vaults/accessPolicies/deploy.bicep b/arm/Microsoft.KeyVault/vaults/accessPolicies/deploy.bicep new file mode 100644 index 0000000000..c650718230 --- /dev/null +++ b/arm/Microsoft.KeyVault/vaults/accessPolicies/deploy.bicep @@ -0,0 +1,44 @@ +@description('Required. The name of the key vault') +param keyVaultName string + +@description('Optional. The access policy deployment') +param name string = 'add' + +@description('Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault\'s tenant ID.') +param accessPolicies array = [] + +@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +var formattedAccessPolicies = [for accessPolicy in accessPolicies: { + applicationId: contains(accessPolicy, 'applicationId') ? accessPolicy.applicationId : '' + objectId: contains(accessPolicy, 'objectId') ? accessPolicy.objectId : '' + permissions: accessPolicy.permissions + tenantId: contains(accessPolicy, 'tenantId') ? accessPolicy.tenantId : tenant().tenantId +}] + +module pid_cuaId './.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = { + name: keyVaultName +} + +resource policies 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = { + name: name + parent: keyVault + properties: { + accessPolicies: formattedAccessPolicies + } +} + +@description('The name of the resource group the access policies assignment was created in.') +output accessPolicyResourceGroup string = resourceGroup().name + +@description('The name of the access policies assignment') +output accessPolicyName string = policies.name + +@description('The resource ID of the access policies assignment') +output accessPolicyResourceId string = policies.id diff --git a/arm/Microsoft.KeyVault/vaults/accessPolicies/readme.md b/arm/Microsoft.KeyVault/vaults/accessPolicies/readme.md new file mode 100644 index 0000000000..89d2ae20bc --- /dev/null +++ b/arm/Microsoft.KeyVault/vaults/accessPolicies/readme.md @@ -0,0 +1,56 @@ +# Key Vault Access Policies `[Microsoft.KeyVault/vaults/accessPolicies]` + +This module deploys key vault access policies. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.KeyVault/vaults/accessPolicies` | 2021-06-01-preview | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `accessPolicies` | array | `[]` | | Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault's tenant ID. | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `keyVaultName` | string | | | Required. The name of the key vault | +| `name` | string | `add` | | Optional. The access policy deployment | + + +### Parameter Usage: `accessPolicies` + +```json +"accessPolicies": { + "value": [ + { + "tenantId": null, // Optional + "applicationId": null, // Optional + "objectId": null, + "permissions": { + "certificates": [ + "All" + ], + "keys": [ + "All" + ], + "secrets": [ + "All" + ] + } + } + ] +} +``` + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `accessPolicyName` | string | The name of the access policies assignment | +| `accessPolicyResourceGroup` | string | The name of the resource group the access policies assignment was created in. | +| `accessPolicyResourceId` | string | The resource ID of the access policies assignment | + +## Template references + +- [Vaults/Accesspolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2021-06-01-preview/vaults/accessPolicies) diff --git a/arm/Microsoft.KeyVault/vaults/deploy.bicep b/arm/Microsoft.KeyVault/vaults/deploy.bicep index 5cca02fc9e..cfe932e206 100644 --- a/arm/Microsoft.KeyVault/vaults/deploy.bicep +++ b/arm/Microsoft.KeyVault/vaults/deploy.bicep @@ -152,6 +152,13 @@ var networkAcls_var = { ipRules: (empty(networkAcls) ? null : ((length(networkAcls.ipRules) == 0) ? [] : networkAcls.ipRules)) } +var formattedAccessPolicies = [for accessPolicy in accessPolicies: { + applicationId: contains(accessPolicy, 'applicationId') ? accessPolicy.applicationId : '' + objectId: contains(accessPolicy, 'objectId') ? accessPolicy.objectId : '' + permissions: accessPolicy.permissions + tenantId: contains(accessPolicy, 'tenantId') ? accessPolicy.tenantId : tenant().tenantId +}] + module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -171,7 +178,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { createMode: createMode enablePurgeProtection: ((!enablePurgeProtection) ? null : enablePurgeProtection) tenantId: subscription().tenantId - accessPolicies: accessPolicies + accessPolicies: formattedAccessPolicies sku: { name: vaultSku family: 'A' @@ -202,6 +209,14 @@ resource keyVault_diagnosticSettings 'Microsoft.Insights/diagnosticsettings@2017 scope: keyVault } +module keyVault_accessPolicies 'accessPolicies/deploy.bicep' = if (!empty(accessPolicies)) { + name: '${uniqueString(deployment().name, location)}-AccessPolicies' + params: { + keyVaultName: keyVault.name + accessPolicies: formattedAccessPolicies + } +} + module keyVault_secrets 'secrets/deploy.bicep' = [for (secret, index) in secrets: { name: '${uniqueString(deployment().name, location)}-Secret-${index}' params: { @@ -213,10 +228,8 @@ module keyVault_secrets 'secrets/deploy.bicep' = [for (secret, index) in secrets attributesNbf: contains(secret, 'attributesNbf') ? secret.attributesNbf : -1 contentType: contains(secret, 'contentType') ? secret.contentType : '' tags: contains(secret, 'tags') ? secret.tags : {} + roleAssignments: contains(secret, 'roleAssignments') ? secret.roleAssignments : [] } - dependsOn: [ - keyVault - ] }] module keyVault_keys 'keys/deploy.bicep' = [for (key, index) in keys: { @@ -232,10 +245,8 @@ module keyVault_keys 'keys/deploy.bicep' = [for (key, index) in keys: { keySize: contains(key, 'keySize') ? key.keySize : -1 kty: contains(key, 'kty') ? key.kty : 'EC' tags: contains(key, 'tags') ? key.tags : {} + roleAssignments: contains(key, 'roleAssignments') ? key.roleAssignments : [] } - dependsOn: [ - keyVault - ] }] module keyVault_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (privateEndpoint, index) in privateEndpoints: { diff --git a/arm/Microsoft.KeyVault/vaults/keys/.bicep/nested_rbac.bicep b/arm/Microsoft.KeyVault/vaults/keys/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..0b991d1c64 --- /dev/null +++ b/arm/Microsoft.KeyVault/vaults/keys/.bicep/nested_rbac.bicep @@ -0,0 +1,40 @@ +param principalIds array +param roleDefinitionIdOrName string +param resourceId string + +var builtInRoleNames = { + 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Key Vault Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483') + 'Key Vault Certificates Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985') + 'Key Vault Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395') + 'Key Vault Crypto Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603') + 'Key Vault Crypto Service Encryption User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') + 'Key Vault Crypto User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + 'Key Vault Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2') + 'Key Vault Secrets Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource key 'Microsoft.KeyVault/vaults/keys@2021-06-01-preview' existing = { + name: '${split(resourceId, '/')[8]}/${split(resourceId, '/')[10]}' +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for principalId in principalIds: { + name: guid(key.name, principalId, roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + } + scope: key +}] diff --git a/arm/Microsoft.KeyVault/vaults/keys/deploy.bicep b/arm/Microsoft.KeyVault/vaults/keys/deploy.bicep index 9524efa76c..8a34081c3c 100644 --- a/arm/Microsoft.KeyVault/vaults/keys/deploy.bicep +++ b/arm/Microsoft.KeyVault/vaults/keys/deploy.bicep @@ -49,6 +49,9 @@ param keySize int = -1 ]) param kty string = 'EC' +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') +param roleAssignments array = [] + @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' @@ -78,11 +81,20 @@ resource key 'Microsoft.KeyVault/vaults/keys@2019-09-01' = { } } +module key_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${deployment().name}-rbac-${index}' + params: { + principalIds: roleAssignment.principalIds + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + resourceId: key.id + } +}] + @description('The name of the key.') output keyName string = key.name -@description('The Resource ID of the key.') +@description('The resource ID of the key.') output keyResourceId string = key.id -@description('The name of the Resource Group the key was created in.') +@description('The name of the resource group the key was created in.') output keyResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.KeyVault/vaults/keys/readme.md b/arm/Microsoft.KeyVault/vaults/keys/readme.md index cbc1397d26..c12ac3ddfe 100644 --- a/arm/Microsoft.KeyVault/vaults/keys/readme.md +++ b/arm/Microsoft.KeyVault/vaults/keys/readme.md @@ -6,6 +6,7 @@ This module deploys a key vault key. | Resource Type | API Version | | :-- | :-- | +| `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.KeyVault/vaults/keys` | 2019-09-01 | ## Parameters @@ -22,6 +23,7 @@ This module deploys a key vault key. | `keyVaultName` | string | | | Required. The name of the key vault | | `kty` | string | `EC` | `[EC, EC-HSM, RSA, RSA-HSM]` | Optional. The type of the key. | | `name` | string | | | Required. The name of the key | +| `roleAssignments` | array | `[]` | | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | | `tags` | object | `{object}` | | Optional. Resource tags. | ### Parameter Usage: `tags` @@ -41,14 +43,37 @@ Tag names and tag values can be provided as needed. A tag can be left without a } ``` +### Parameter Usage: `roleAssignments` + +```json +"roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "12345678-1234-1234-1234-123456789012", // object 1 + "78945612-1234-1234-1234-123456789012" // object 2 + ] + }, + { + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11", + "principalIds": [ + "12345678-1234-1234-1234-123456789012" // object 1 + ] + } + ] +} +``` + ## Outputs | Output Name | Type | Description | | :-- | :-- | :-- | | `keyName` | string | The name of the key. | -| `keyResourceGroup` | string | The name of the Resource Group the key was created in. | -| `keyResourceId` | string | The Resource ID of the key. | +| `keyResourceGroup` | string | The name of the resource group the key was created in. | +| `keyResourceId` | string | The resource ID of the key. | ## Template references +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Vaults/Keys](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/keys) diff --git a/arm/Microsoft.KeyVault/vaults/readme.md b/arm/Microsoft.KeyVault/vaults/readme.md index b0f813474f..82dc0db1ec 100644 --- a/arm/Microsoft.KeyVault/vaults/readme.md +++ b/arm/Microsoft.KeyVault/vaults/readme.md @@ -10,6 +10,7 @@ This module deploys a key vault and it's child resources. | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.Insights/diagnosticSettings` | 2017-05-01-preview | | `Microsoft.KeyVault/vaults` | 2019-09-01 | +| `Microsoft.KeyVault/vaults/accessPolicies` | 2021-06-01-preview | | `Microsoft.KeyVault/vaults/keys` | 2019-09-01 | | `Microsoft.KeyVault/vaults/secrets` | 2019-09-01 | | `Microsoft.Network/privateEndpoints` | 2021-05-01 | @@ -19,7 +20,7 @@ This module deploys a key vault and it's child resources. | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | -| `accessPolicies` | array | `[]` | | Optional. Array of access policies object | +| `accessPolicies` | _[accessPolicies](accessPolicies/readme.md)_ array | `[]` | | Optional. Array of access policies object | | `baseTime` | string | `[utcNow('u')]` | | Generated. Do not provide a value! This date value is used to generate a SAS token to access the modules. | | `createMode` | string | `default` | | Optional. The vault's create mode to indicate whether the vault need to be recovered or not. - recover or default. | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | @@ -119,7 +120,8 @@ Tag names and tag values can be provided as needed. A tag can be left without a "accessPolicies": { "value": [ { - "tenantId": null, + "tenantId": null, // Optional + "applicationId": null, // Optional "objectId": null, "permissions": { "certificates": [ @@ -188,6 +190,7 @@ To use Private Endpoint the following dependencies must be deployed: - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2017-05-01-preview/diagnosticSettings) - [Vaults](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults) +- [Vaults/Accesspolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2021-06-01-preview/vaults/accessPolicies) - [Vaults/Keys](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/keys) - [Vaults/Secrets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/secrets) - [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) diff --git a/arm/Microsoft.KeyVault/vaults/secrets/.bicep/nested_rbac.bicep b/arm/Microsoft.KeyVault/vaults/secrets/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..ad6f84eca9 --- /dev/null +++ b/arm/Microsoft.KeyVault/vaults/secrets/.bicep/nested_rbac.bicep @@ -0,0 +1,39 @@ +param principalIds array +param roleDefinitionIdOrName string +param resourceId string + +var builtInRoleNames = { + 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Key Vault Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483') + 'Key Vault Certificates Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985') + 'Key Vault Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395') + 'Key Vault Crypto Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603') + 'Key Vault Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21090545-7ca7-4776-b22c-e363652d74d2') + 'Key Vault Secrets Officer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7') + 'Key Vault Secrets User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource secret 'Microsoft.KeyVault/vaults/secrets@2021-06-01-preview' existing = { + name: '${split(resourceId, '/')[8]}/${split(resourceId, '/')[10]}' +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for principalId in principalIds: { + name: guid(secret.name, principalId, roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + } + scope: secret +}] diff --git a/arm/Microsoft.KeyVault/vaults/secrets/deploy.bicep b/arm/Microsoft.KeyVault/vaults/secrets/deploy.bicep index faf4a54aca..92d414b57f 100644 --- a/arm/Microsoft.KeyVault/vaults/secrets/deploy.bicep +++ b/arm/Microsoft.KeyVault/vaults/secrets/deploy.bicep @@ -27,6 +27,9 @@ param value string @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') +param roleAssignments array = [] + module pid_cuaId './.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -51,11 +54,20 @@ resource secret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { } } -@description('The Name of the secret.') +module secret_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${deployment().name}-rbac-${index}' + params: { + principalIds: roleAssignment.principalIds + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + resourceId: secret.id + } +}] + +@description('The name of the secret.') output secretName string = secret.name -@description('The Resource ID of the secret.') +@description('The resource ID of the secret.') output secretResourceId string = secret.id -@description('The name of the Resource Group the secret was created in.') +@description('The name of the resource group the secret was created in.') output secretResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.KeyVault/vaults/secrets/readme.md b/arm/Microsoft.KeyVault/vaults/secrets/readme.md index 90399bb5e6..c9ef73a1f7 100644 --- a/arm/Microsoft.KeyVault/vaults/secrets/readme.md +++ b/arm/Microsoft.KeyVault/vaults/secrets/readme.md @@ -6,6 +6,7 @@ This module deploys a key vault secret. | Resource Type | API Version | | :-- | :-- | +| `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.KeyVault/vaults/secrets` | 2019-09-01 | ## Parameters @@ -19,6 +20,7 @@ This module deploys a key vault secret. | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | | `keyVaultName` | string | | | Required. The name of the key vault | | `name` | string | | | Required. The name of the secret | +| `roleAssignments` | array | `[]` | | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | | `tags` | object | `{object}` | | Optional. Resource tags. | | `value` | secureString | | | Required. The value of the secret. NOTE: "value" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets. | @@ -39,14 +41,37 @@ Tag names and tag values can be provided as needed. A tag can be left without a } ``` +### Parameter Usage: `roleAssignments` + +```json +"roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "12345678-1234-1234-1234-123456789012", // object 1 + "78945612-1234-1234-1234-123456789012" // object 2 + ] + }, + { + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11", + "principalIds": [ + "12345678-1234-1234-1234-123456789012" // object 1 + ] + } + ] +} +``` + ## Outputs | Output Name | Type | Description | | :-- | :-- | :-- | -| `secretName` | string | The Name of the secret. | -| `secretResourceGroup` | string | The name of the Resource Group the secret was created in. | -| `secretResourceId` | string | The Resource ID of the secret. | +| `secretName` | string | The name of the secret. | +| `secretResourceGroup` | string | The name of the resource group the secret was created in. | +| `secretResourceId` | string | The resource ID of the secret. | ## Template references +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Vaults/Secrets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/secrets)