You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// storage account properties @description('The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.')
param name string
@description('Azure Location for deployment, uses resource group location by default.')
param location string = resourceGroup().location @description('If environment type is prd, dr and UAT, then standardGRS is deployed. If not prod. then LRS is deployed')
param environmentType string
@description('Gets or sets the SKU name. ') @Allowed([
'Standard_LRS'
'Standard_GRS'
'Standard_RAGRS'
'Standard_ZRS'
'Premium_LRS'
'Premium_ZRS'
])
param sku string = 'Standard_GRS'
@description('Indicates the type of storage account.') @Allowed([
'Storage'
'StorageV2'
'BlobStorage'
'FileStorage'
'BlockBlobStorage'
])
param kind string = 'StorageV2'
@description('Allow or disallow public access to all blobs or containers in the storage account.')
param allowBlobPublicAccess bool = false
@description('Required for storage accounts where kind = BlobStorage. The access tier used for billing. - Hot or Cool') @Allowed([
'Hot'
'Cool'
])
param blobAccessTier string = 'Hot'
// Storage account firewall settings @description('Specifies the default action of allow or deny when no other rules match. - Allow or Deny') @Allowed([
'Allow'
'Deny'
])
param networkAccessDefaultAction string = 'Deny'
@description('resourceIds for subnet ids that require subnet integration')
param networkIntegrationSubnetIds array = []
@description('Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true.')
param allowSharedKeyAccess bool = false
@description('Indicates whether this storage account is used for Azure Site Recovery cache')
param isAsrCache bool = false
/*
variables
*/
//network settings
var vnetRules = [for subnetId in networkIntegrationSubnetIds: {
id: subnetId
action: 'Allow'
}]
@description('private Endpoint Group Id')
param privateEPGroupId array @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 = []
output id string = storageAccount.id
output name string = storageAccount.name
Now the file i bring the landing zone too uses this:
module asrStorageAccount 'modules/storageAccount.bicep' = [
for (subnet, i) in subnetArray: if (startsWith(toLower(subnet.subnetName), 'siterecovery')) {
name: '${pipelineId}-${asrStorageAccountName}-${subnet.subnetName}'
scope: resourceGroupBackup
params: {
name: asrStorageAccountName
location: location
kind: 'BlockBlobStorage'
sku: 'Premium_LRS'
environmentType: environmentType
privateEPSubnetId: siterecovery_subnet.id
allowSharedKeyAccess: true
privateEPGroupId: [
'Blob'
]
roleAssignments: !empty(siterecovery[i].outputs.principalId) ? [
{
description: 'ASR Storage Account Storage Account Blob Data Owner ${baseTime}'
principalIds: [ siterecovery[i].outputs.principalId ]
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: 'Storage Account Blob Data Owner'
}
] : []
}
}
]
All together i am trying to deploy two permissions: Storage Account Blob Data Owner and contributor to this for the ASR vault?
this doesn't work i am getting this error:
At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details. (Code: DeploymentFailed, Target: /providers/Microsoft.Resources/deployments/krtlsctwbdeu4-storage-Rbac-0), The request was incorrectly formatted. (Code: BadRequestFormat)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is my module for storage account:
/*
*/
// storage account properties
@description('The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.')
param name string
@description('Azure Location for deployment, uses resource group location by default.')
param location string = resourceGroup().location
@description('If environment type is prd, dr and UAT, then standardGRS is deployed. If not prod. then LRS is deployed')
param environmentType string
@description('Gets or sets the SKU name. ')
@Allowed([
'Standard_LRS'
'Standard_GRS'
'Standard_RAGRS'
'Standard_ZRS'
'Premium_LRS'
'Premium_ZRS'
])
param sku string = 'Standard_GRS'
@description('Indicates the type of storage account.')
@Allowed([
'Storage'
'StorageV2'
'BlobStorage'
'FileStorage'
'BlockBlobStorage'
])
param kind string = 'StorageV2'
@description('Allow or disallow public access to all blobs or containers in the storage account.')
param allowBlobPublicAccess bool = false
@description('Required for storage accounts where kind = BlobStorage. The access tier used for billing. - Hot or Cool')
@Allowed([
'Hot'
'Cool'
])
param blobAccessTier string = 'Hot'
// Storage account firewall settings
@description('Specifies the default action of allow or deny when no other rules match. - Allow or Deny')
@Allowed([
'Allow'
'Deny'
])
param networkAccessDefaultAction string = 'Deny'
@description('resourceIds for subnet ids that require subnet integration')
param networkIntegrationSubnetIds array = []
// logging settings
@description('enter the log analytics workspace Id')
param logAnalyticsWorkspaceId string = ''
@description('enter the mail receivers for metricsalerts. expects array of emailaddresses')
param emailReceivers array = []
@description('object containing tag information')
param tags object = {}
@description('Routing choice for networks')
@Allowed([
'InternetRouting'
'MicrosoftRouting'
])
param routingChoice string = 'MicrosoftRouting'
@description('Subnet ResourceId for the private EP to be created, only when you Specify the parameter')
param privateEPSubnetId string = ''
@description('Enable datalake Gen 2 feature')
param isHnsEnabled bool = false
@description('skipHnsParameter feature')
param skipHnsParameter bool = false
@description('Optional. Indicates whether the storage account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). The default value is null, which is equivalent to true.')
param allowSharedKeyAccess bool = false
@description('Indicates whether this storage account is used for Azure Site Recovery cache')
param isAsrCache bool = false
/*
*/
//network settings
var vnetRules = [for subnetId in networkIntegrationSubnetIds: {
id: subnetId
action: 'Allow'
}]
var networkAcls = {
bypass: 'AzureServices'
virtualNetworkRules: vnetRules
ipRules: []
defaultAction: networkAccessDefaultAction
}
//diagnosticsettings
var diagnosticsettingName = '${name}Diagnostics'
var storageAccountMetricCategories = [
{
category: 'Transaction'
enabled: true
}
]
var storageServiceLogCategories = [
{
category: 'StorageRead'
enabled: true
}
{
category: 'StorageWrite'
enabled: true
}
{
category: 'StorageDelete'
enabled: true
}
]
var storageServiceDiagnosticsProperties = {
workspaceId : logAnalyticsWorkspaceId
logs: storageServiceLogCategories
metrics: storageAccountMetricCategories
}
var emailReceiversObj = [for email in emailReceivers: {
name: first(split(email,'@'))
emailAddress: email
}]
/*
*/
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = {
name: name
sku: {
name: sku
}
kind: kind
location: location
tags: tags
properties: union ( {
minimumTlsVersion: 'TLS1_2'
allowSharedKeyAccess: allowSharedKeyAccess
allowCrossTenantReplication: false
allowBlobPublicAccess: allowBlobPublicAccess
accessTier: kind == 'BlockBlobStorage' ? json('null') : (contains(kind, 'BlobStorage') ? blobAccessTier : json('null'))
supportsHttpsTrafficOnly: true
isHnsEnabled : skipHnsParameter ? null : isHnsEnabled
networkAcls: networkAcls
encryption: {
services: {
blob: {
enabled: true
}
file: {
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
}, !(contains(sku, 'Premium') || contains(sku, 'ZRS')) ? {
routingPreference: {
routingChoice: routingChoice
publishMicrosoftEndpoints: true
publishInternetEndpoints: true
}
} : {})
resource blobServices 'blobServices' existing = {
name: 'default'
}
resource tableServices 'tableServices' existing = {
name: 'default'
}
resource fileServices 'fileServices' existing = {
name: 'default'
}
resource queueServices 'queueServices' existing = {
name: 'default'
}
}
@description('private Endpoint Group Id')
param privateEPGroupId array
@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 = []
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-02-01' = [for (groupid, index) in privateEPGroupId: if (!(empty(privateEPSubnetId))) {
name: '${storageAccount.name}-${index}-pep'
location: location
tags: tags
properties: {
subnet: {
id: privateEPSubnetId
}
privateLinkServiceConnections: [
{
name: '${storageAccount.name}-plink'
properties: {
privateLinkServiceId: storageAccount.id
groupIds: [groupid]
}
}
]
}
}
]
//diagnosticsettings
resource storageAccountDiagnositics 'Microsoft.Insights/diagnosticSettings@2017-05-01-preview' = if (logAnalyticsWorkspaceId != ''){
scope: storageAccount
name: diagnosticsettingName
properties: {
workspaceId: logAnalyticsWorkspaceId
metrics: storageAccountMetricCategories
}
}
resource storageAccountblobServicesDiagnositics 'Microsoft.Insights/diagnosticSettings@2017-05-01-preview' = if (logAnalyticsWorkspaceId != '') {
scope: storageAccount::blobServices
name: diagnosticsettingName
properties: storageServiceDiagnosticsProperties
}
resource storageAccountTableServicesDiagnositics 'Microsoft.Insights/diagnosticSettings@2017-05-01-preview' = if (logAnalyticsWorkspaceId != '') {
scope: storageAccount::tableServices
name: diagnosticsettingName
properties: storageServiceDiagnosticsProperties
}
resource storageAccountFileServicesDiagnositics 'Microsoft.Insights/diagnosticSettings@2017-05-01-preview' = if (logAnalyticsWorkspaceId != '') {
scope: storageAccount::fileServices
name: diagnosticsettingName
properties: storageServiceDiagnosticsProperties
}
resource storageAccountQueueServicesDiagnositics 'Microsoft.Insights/diagnosticSettings@2017-05-01-preview' = if (logAnalyticsWorkspaceId != ''){
scope: storageAccount::queueServices
name: diagnosticsettingName
properties: storageServiceDiagnosticsProperties
}
resource emailAlert 'Microsoft.Insights/actionGroups@2018-03-01' = if (length(emailReceivers) != 0) {
name: '${name}-EmailAlert'
location: 'Global'
tags: tags
properties: {
groupShortName: 'EmailAlert'
enabled: true
emailReceivers: emailReceiversObj
}
}
resource Availability_Check 'microsoft.insights/metricAlerts@2018-03-01' = if (length(emailReceivers) != 0) {
name: 'Availability Check'
location: 'global'
properties: {
severity: 3
enabled: true
scopes: [
storageAccount.id
]
evaluationFrequency: 'PT5M'
windowSize: 'PT5M'
criteria: {
allOf: [
{
threshold: 95
name: 'Metric1'
metricNamespace: 'microsoft.storage/storageaccounts'
metricName: 'Availability'
operator: 'LessThan'
timeAggregation: 'Average'
criterionType: 'StaticThresholdCriterion'
}
]
'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
}
autoMitigate: true
targetResourceType: 'microsoft.storage/storageaccounts'
actions: [
{
actionGroupId: emailAlert.id
webHookProperties: {}
}
]
}
}
module storage_roleAssignments 'role-assignment.bicep' = [for (roleAssignment, index) in roleAssignments: {
name: '${uniqueString(deployment().name, location)}-storage-Rbac-${index}'
params: {
description: contains(roleAssignment, 'description') ? roleAssignment.description : ''
principalIds: roleAssignment.principalIds
principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : ''
roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
condition: contains(roleAssignment, 'condition') ? roleAssignment.condition : ''
delegatedManagedIdentityResourceId: contains(roleAssignment, 'delegatedManagedIdentityResourceId') ? roleAssignment.delegatedManagedIdentityResourceId : ''
resourceId: storageAccount.id
}
}]
output id string = storageAccount.id
output name string = storageAccount.name
Now the file i bring the landing zone too uses this:
module asrStorageAccount 'modules/storageAccount.bicep' = [
for (subnet, i) in subnetArray: if (startsWith(toLower(subnet.subnetName), 'siterecovery')) {
name: '${pipelineId}-${asrStorageAccountName}-${subnet.subnetName}'
scope: resourceGroupBackup
params: {
name: asrStorageAccountName
location: location
kind: 'BlockBlobStorage'
sku: 'Premium_LRS'
environmentType: environmentType
privateEPSubnetId: siterecovery_subnet.id
allowSharedKeyAccess: true
privateEPGroupId: [
'Blob'
]
roleAssignments: !empty(siterecovery[i].outputs.principalId) ? [
{
description: 'ASR Storage Account Storage Account Blob Data Owner ${baseTime}'
principalIds: [ siterecovery[i].outputs.principalId ]
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: 'Storage Account Blob Data Owner'
}
] : []
}
}
]
All together i am trying to deploy two permissions: Storage Account Blob Data Owner and contributor to this for the ASR vault?
this doesn't work i am getting this error:
At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details. (Code: DeploymentFailed, Target: /providers/Microsoft.Resources/deployments/krtlsctwbdeu4-storage-Rbac-0), The request was incorrectly formatted. (Code: BadRequestFormat)
any ideas why this is failing?
Beta Was this translation helpful? Give feedback.
All reactions