diff --git a/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json b/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json index f7dd177740..09f382a7c6 100644 --- a/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json +++ b/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json @@ -11,6 +11,9 @@ "allowBlobPublicAccess": { "value": false }, + "publicNetworkAccess": { + "value": "Disabled" + }, "requireInfrastructureEncryption": { "value": true }, diff --git a/arm/Microsoft.Storage/storageAccounts/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/deploy.bicep index fab95df512..854dcc7b97 100644 --- a/arm/Microsoft.Storage/storageAccounts/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/deploy.bicep @@ -122,6 +122,14 @@ param cuaId string = '' @description('Generated. Do not provide a value! This date value is used to generate a SAS token to access the modules.') param basetime string = utcNow('u') +@allowed([ + 'Enabled' + 'Disabled' +]) + +@description('Optional. Enable or disallow public network access to Storage Account..') +param publicNetworkAccess string = 'Enabled' + @description('Optional. Allows https traffic only to storage service if sets to true.') param supportsHttpsTrafficOnly bool = true @@ -146,41 +154,15 @@ var diagnosticsMetrics = [for metric in metricsToEnable: { var virtualNetworkRules = [for index in range(0, (empty(networkAcls) ? 0 : length(networkAcls.virtualNetworkRules))): { id: '${vNetId}/subnets/${networkAcls.virtualNetworkRules[index].subnet}' }] -var networkAcls_var = { - bypass: (empty(networkAcls) ? null : networkAcls.bypass) - defaultAction: (empty(networkAcls) ? null : networkAcls.defaultAction) - virtualNetworkRules: (empty(networkAcls) ? null : virtualNetworkRules) - ipRules: (empty(networkAcls) ? null : ((length(networkAcls.ipRules) == 0) ? null : networkAcls.ipRules)) -} -var azureFilesIdentityBasedAuthentication_var = azureFilesIdentityBasedAuthentication var maxNameLength = 24 -var uniqueStoragenameUntrim = '${uniqueString('Storage Account${basetime}')}' -var uniqueStoragename = length(uniqueStoragenameUntrim) > maxNameLength ? substring(uniqueStoragenameUntrim, 0, maxNameLength) : uniqueStoragenameUntrim - -var saBaseProperties = { - encryption: { - keySource: 'Microsoft.Storage' - services: { - blob: (((storageAccountKind == 'BlockBlobStorage') || (storageAccountKind == 'BlobStorage') || (storageAccountKind == 'StorageV2') || (storageAccountKind == 'Storage')) ? json('{"enabled": true}') : null) - file: (((storageAccountKind == 'FileStorage') || (storageAccountKind == 'StorageV2') || (storageAccountKind == 'Storage')) ? json('{"enabled": true}') : null) - } - } - accessTier: (storageAccountKind == 'Storage') ? null : storageAccountAccessTier - supportsHttpsTrafficOnly: supportsHttpsTrafficOnly - isHnsEnabled: ((!enableHierarchicalNamespace) ? null : enableHierarchicalNamespace) - minimumTlsVersion: minimumTlsVersion - networkAcls: (empty(networkAcls) ? null : networkAcls_var) - allowBlobPublicAccess: allowBlobPublicAccess - requireInfrastructureEncryption: requireInfrastructureEncryption -} -var saOptIdBasedAuthProperties = { - azureFilesIdentityBasedAuthentication: azureFilesIdentityBasedAuthentication_var -} -var saProperties = (empty(azureFilesIdentityBasedAuthentication) ? saBaseProperties : union(saBaseProperties, saOptIdBasedAuthProperties)) +var uniqueStorageNameUntrim = '${uniqueString('Storage Account${basetime}')}' +var uniqueStorageName = length(uniqueStorageNameUntrim) > maxNameLength ? substring(uniqueStorageNameUntrim, 0, maxNameLength) : uniqueStorageNameUntrim -var identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None') +var supportsBlobService = storageAccountKind == 'BlockBlobStorage' || storageAccountKind == 'BlobStorage' || storageAccountKind == 'StorageV2' || storageAccountKind == 'Storage' +var supportsFileService = storageAccountKind == 'FileStorage' || storageAccountKind == 'StorageV2' || storageAccountKind == 'Storage' +var identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None') var identity = identityType != 'None' ? { type: identityType userAssignedIdentities: !empty(userAssignedIdentities) ? userAssignedIdentities : null @@ -191,8 +173,8 @@ module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { params: {} } -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = { - name: !empty(name) ? name : uniqueStoragename +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = { + name: !empty(name) ? name : uniqueStorageName location: location kind: storageAccountKind sku: { @@ -200,16 +182,42 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = { } identity: identity tags: tags - properties: saProperties + properties: { + encryption: { + keySource: 'Microsoft.Storage' + services: { + blob: supportsBlobService ? { + enabled: true + } : null + file: supportsFileService ? { + enabled: true + } : null + } + requireInfrastructureEncryption: storageAccountKind != 'Storage' ? requireInfrastructureEncryption : null + } + accessTier: storageAccountKind != 'Storage' ? storageAccountAccessTier : null + supportsHttpsTrafficOnly: supportsHttpsTrafficOnly + isHnsEnabled: enableHierarchicalNamespace ? enableHierarchicalNamespace : null + minimumTlsVersion: minimumTlsVersion + networkAcls: !empty(networkAcls) ? { + bypass: !empty(networkAcls) ? networkAcls.bypass : null + defaultAction: !empty(networkAcls) ? networkAcls.defaultAction : null + virtualNetworkRules: !empty(networkAcls) ? virtualNetworkRules : null + ipRules: !empty(networkAcls) ? (length(networkAcls.ipRules) != 0 ? networkAcls.ipRules : null) : null + } : null + allowBlobPublicAccess: allowBlobPublicAccess + publicNetworkAccess: publicNetworkAccess + azureFilesIdentityBasedAuthentication: !empty(azureFilesIdentityBasedAuthentication) ? azureFilesIdentityBasedAuthentication : null + } } resource storageAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(diagnosticWorkspaceId)) || (!empty(diagnosticEventHubAuthorizationRuleId)) || (!empty(diagnosticEventHubName))) { name: '${storageAccount.name}-diagnosticSettings' properties: { - storageAccountId: empty(diagnosticStorageAccountId) ? null : diagnosticStorageAccountId - workspaceId: empty(diagnosticWorkspaceId) ? null : diagnosticWorkspaceId - eventHubAuthorizationRuleId: empty(diagnosticEventHubAuthorizationRuleId) ? null : diagnosticEventHubAuthorizationRuleId - eventHubName: empty(diagnosticEventHubName) ? null : diagnosticEventHubName + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null + eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null + eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null metrics: diagnosticsMetrics } scope: storageAccount @@ -219,7 +227,7 @@ resource storageAccount_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lo name: '${storageAccount.name}-${lock}-lock' properties: { level: lock - notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' } scope: storageAccount } @@ -237,7 +245,7 @@ module storageAccount_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [ name: '${uniqueString(deployment().name, location)}-Storage-PrivateEndpoints-${index}' params: { privateEndpointResourceId: storageAccount.id - privateEndpointVnetLocation: (empty(privateEndpoints) ? 'dummy' : reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location) + privateEndpointVnetLocation: !empty(privateEndpoints) ? reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location : 'dummy' privateEndpointObj: endpoint tags: tags } diff --git a/arm/Microsoft.Storage/storageAccounts/readme.md b/arm/Microsoft.Storage/storageAccounts/readme.md index cc59f86366..57f8ab849f 100644 --- a/arm/Microsoft.Storage/storageAccounts/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/readme.md @@ -11,7 +11,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Network/privateEndpoints` | 2021-05-01 | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | 2021-02-01 | -| `Microsoft.Storage/storageAccounts` | 2021-06-01 | +| `Microsoft.Storage/storageAccounts` | 2021-08-01 | | `Microsoft.Storage/storageAccounts/blobServices` | 2021-06-01 | | `Microsoft.Storage/storageAccounts/blobServices/containers` | 2019-06-01 | | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | 2019-06-01 | @@ -47,6 +47,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `name` | string | | | Optional. Name of the Storage Account. | | `networkAcls` | object | `{object}` | | Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. For security reasons, it is recommended to set the DefaultAction Deny | | `privateEndpoints` | array | `[]` | | Optional. Configuration Details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible | +| `publicNetworkAccess` | string | `Enabled` | `[Enabled, Disabled]` | Optional. Enable or disallow public network access to Storage Account.. | | `queueServices` | _[queueServices](queueServices/readme.md)_ object | `{object}` | | Optional. Queue service and queues to create. | | `requireInfrastructureEncryption` | bool | `True` | | Optional. A boolean indicating whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest. For security reasons, it is recommended to set it to true. | | `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' | @@ -187,7 +188,7 @@ The hierarchical namespace of the storage account (see parameter `enableHierarch - [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) - [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments) -- [Storageaccounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts) +- [Storageaccounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-08-01/storageAccounts) - [Storageaccounts/Blobservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts/blobServices) - [Storageaccounts/Blobservices/Containers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/blobServices/containers) - [Storageaccounts/Blobservices/Containers/Immutabilitypolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/blobServices/containers/immutabilityPolicies)