diff --git a/modules/Microsoft.Storage/storageAccounts/.test/common/deploy.test.bicep b/modules/Microsoft.Storage/storageAccounts/.test/common/deploy.test.bicep index 20379c8bda..cad8abf616 100644 --- a/modules/Microsoft.Storage/storageAccounts/.test/common/deploy.test.bicep +++ b/modules/Microsoft.Storage/storageAccounts/.test/common/deploy.test.bicep @@ -64,6 +64,9 @@ module testDeployment '../../deploy.bicep' = { allowBlobPublicAccess: false requireInfrastructureEncryption: true lock: 'CanNotDelete' + enableHierarchicalNamespace: true + enableSftp: true + enableNfsV3: true privateEndpoints: [ { service: 'blob' @@ -91,6 +94,24 @@ module testDeployment '../../deploy.bicep' = { } ] } + localUsers: [ + { + storageAccountName: '<>${serviceShort}001' + name: 'testuser' + hasSharedKey: false + hasSshKey: true + hasSshPassword: false + homeDirectory: 'avdscripts' + permissionScopes: [ + { + permissions: 'r' + service: 'blob' + resourceName: 'avdscripts' + } + ] + } + ] + blobServices: { diagnosticLogsRetentionInDays: 7 diagnosticStorageAccountId: diagnosticDependencies.outputs.storageAccountResourceId diff --git a/modules/Microsoft.Storage/storageAccounts/deploy.bicep b/modules/Microsoft.Storage/storageAccounts/deploy.bicep index 37b148ec5e..078aa4dde8 100644 --- a/modules/Microsoft.Storage/storageAccounts/deploy.bicep +++ b/modules/Microsoft.Storage/storageAccounts/deploy.bicep @@ -82,9 +82,18 @@ param allowBlobPublicAccess bool = false @description('Optional. Set the minimum TLS version on request to storage.') param minimumTlsVersion string = 'TLS1_2' -@description('Optional. If true, enables Hierarchical Namespace for the storage account.') +@description('Conditional. If true, enables Hierarchical Namespace for the storage account. Required if enableSftp or enableNfsV3 is set to true.') param enableHierarchicalNamespace bool = false +@description('Optional. If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true.') +param enableSftp bool = false + +@description('Optional. Local users to deploy for SFTP authentication.') +param localUsers array = [] + +@description('Optional. If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true.') +param enableNfsV3 bool = false + @description('Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.') @minValue(0) @maxValue(365) @@ -227,6 +236,8 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { accessTier: storageAccountKind != 'Storage' ? storageAccountAccessTier : null supportsHttpsTrafficOnly: supportsHttpsTrafficOnly isHnsEnabled: enableHierarchicalNamespace ? enableHierarchicalNamespace : null + isSftpEnabled: enableSftp + isNfsV3Enabled: enableNfsV3 minimumTlsVersion: minimumTlsVersion networkAcls: !empty(networkAcls) ? { bypass: contains(networkAcls, 'bypass') ? networkAcls.bypass : null @@ -307,6 +318,22 @@ module storageAccount_managementPolicies 'managementPolicies/deploy.bicep' = if } } +// SFTP user settings +module storageAccount_localUsers 'localUsers/deploy.bicep' = [for (localUser, index) in localUsers: { + name: '${uniqueString(deployment().name, location)}-Storage-LocalUsers-${index}' + params: { + storageAccountName: storageAccount.name + name: localUser.name + hasSharedKey: contains(localUser, 'hasSharedKey') ? localUser.hasSharedKey : false + hasSshKey: contains(localUser, 'hasSshPassword') ? localUser.hasSshPassword : true + hasSshPassword: contains(localUser, 'hasSshPassword') ? localUser.hasSshPassword : false + homeDirectory: contains(localUser, 'homeDirectory') ? localUser.homeDirectory : '' + permissionScopes: contains(localUser, 'permissionScopes') ? localUser.permissionScopes : [] + sshAuthorizedKeys: contains(localUser, 'sshAuthorizedKeys') ? localUser.sshAuthorizedKeys : [] + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +}] + // Containers module storageAccount_blobServices 'blobServices/deploy.bicep' = if (!empty(blobServices)) { name: '${uniqueString(deployment().name, location)}-Storage-BlobServices' diff --git a/modules/Microsoft.Storage/storageAccounts/localUsers/deploy.bicep b/modules/Microsoft.Storage/storageAccounts/localUsers/deploy.bicep new file mode 100644 index 0000000000..0178e044ee --- /dev/null +++ b/modules/Microsoft.Storage/storageAccounts/localUsers/deploy.bicep @@ -0,0 +1,65 @@ +@maxLength(24) +@description('Conditional. The name of the parent Storage Account. Required if the template is used in a standalone deployment.') +param storageAccountName string + +@description('Required. The name of the local user used for SFTP Authentication.') +param name string + +@description('Optional. Indicates whether shared key exists. Set it to false to remove existing shared key.') +param hasSharedKey bool = false + +@description('Required. Indicates whether SSH key exists. Set it to false to remove existing SSH key.') +param hasSshKey bool + +@description('Required. Indicates whether SSH password exists. Set it to false to remove existing SSH password.') +param hasSshPassword bool + +@description('Optional. The local user home directory.') +param homeDirectory string = '' + +@description('Required. The permission scopes of the local user.') +param permissionScopes array + +@description('Optional. The local user SSH authorized keys for SFTP.') +param sshAuthorizedKeys array = [] + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { + name: storageAccountName +} + +resource localUsers 'Microsoft.Storage/storageAccounts/localUsers@2022-05-01' = { + name: name + parent: storageAccount + properties: { + hasSharedKey: hasSharedKey + hasSshKey: hasSshKey + hasSshPassword: hasSshPassword + homeDirectory: homeDirectory + permissionScopes: permissionScopes + sshAuthorizedKeys: !empty(sshAuthorizedKeys) ? sshAuthorizedKeys : null + } +} + +@description('The name of the deployed local user.') +output name string = localUsers.name + +@description('The resource group of the deployed local user.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the deployed local user.') +output resourceId string = localUsers.id diff --git a/modules/Microsoft.Storage/storageAccounts/localUsers/readme.md b/modules/Microsoft.Storage/storageAccounts/localUsers/readme.md new file mode 100644 index 0000000000..4daeb1659a --- /dev/null +++ b/modules/Microsoft.Storage/storageAccounts/localUsers/readme.md @@ -0,0 +1,55 @@ +# StorageAccounts LocalUsers `[Microsoft.Storage/storageAccounts/localUsers]` + +This module deploys LocalUsers used for SFTP authentication. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Storage/storageAccounts/localUsers` | [2022-05-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-05-01/storageAccounts/localUsers) | + +## Parameters + +**Required parameters** + +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `hasSshKey` | bool | Indicates whether SSH key exists. Set it to false to remove existing SSH key. | +| `hasSshPassword` | bool | Indicates whether SSH password exists. Set it to false to remove existing SSH password. | +| `name` | string | The name of the local user used for SFTP Authentication. | +| `permissionScopes` | array | The permission scopes of the local user. | + +**Conditional parameters** + +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `storageAccountName` | string | The name of the parent Storage Account. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter Name | Type | Default Value | Description | +| :-- | :-- | :-- | :-- | +| `enableDefaultTelemetry` | bool | `True` | Enable telemetry via a Globally Unique Identifier (GUID). | +| `hasSharedKey` | bool | `False` | Indicates whether shared key exists. Set it to false to remove existing shared key. | +| `homeDirectory` | string | `''` | The local user home directory. | +| `sshAuthorizedKeys` | array | `[]` | The local user SSH authorized keys for SFTP. | + + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the deployed local user. | +| `resourceGroupName` | string | The resource group of the deployed local user. | +| `resourceId` | string | The resource ID of the deployed local user. | + +## Cross-referenced modules + +_None_ diff --git a/modules/Microsoft.Storage/storageAccounts/localUsers/version.json b/modules/Microsoft.Storage/storageAccounts/localUsers/version.json new file mode 100644 index 0000000000..41f66cc990 --- /dev/null +++ b/modules/Microsoft.Storage/storageAccounts/localUsers/version.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", + "version": "0.1" +} diff --git a/modules/Microsoft.Storage/storageAccounts/readme.md b/modules/Microsoft.Storage/storageAccounts/readme.md index d7b1e917af..5f2557a89f 100644 --- a/modules/Microsoft.Storage/storageAccounts/readme.md +++ b/modules/Microsoft.Storage/storageAccounts/readme.md @@ -26,6 +26,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/blobServices/containers/immutabilityPolicies) | | `Microsoft.Storage/storageAccounts/fileServices` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices) | | `Microsoft.Storage/storageAccounts/fileServices/shares` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices/shares) | +| `Microsoft.Storage/storageAccounts/localUsers` | [2022-05-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-05-01/storageAccounts/localUsers) | | `Microsoft.Storage/storageAccounts/managementPolicies` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/managementPolicies) | | `Microsoft.Storage/storageAccounts/queueServices` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices) | | `Microsoft.Storage/storageAccounts/queueServices/queues` | [2021-09-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices/queues) | @@ -46,6 +47,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | :-- | :-- | :-- | :-- | | `cMKKeyVaultResourceId` | string | `''` | The resource ID of a key vault to reference a customer managed key for encryption from. Required if 'cMKKeyName' is not empty. | | `cMKUserAssignedIdentityResourceId` | string | `''` | User assigned identity to use when fetching the customer managed key. Required if 'cMKKeyName' is not empty. | +| `enableHierarchicalNamespace` | bool | `False` | If true, enables Hierarchical Namespace for the storage account. Required if enableSftp or enableNfsV3 is set to true. | **Optional parameters** @@ -64,8 +66,10 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. | | `diagnosticWorkspaceId` | string | `''` | | Resource ID of the diagnostic log analytics workspace. | | `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | -| `enableHierarchicalNamespace` | bool | `False` | | If true, enables Hierarchical Namespace for the storage account. | +| `enableNfsV3` | bool | `False` | | If true, enables NFS 3.0 support for the storage account. Requires enableHierarchicalNamespace to be true. | +| `enableSftp` | bool | `False` | | If true, enables Secure File Transfer Protocol for the storage account. Requires enableHierarchicalNamespace to be true. | | `fileServices` | _[fileServices](fileServices/readme.md)_ object | `{object}` | | File service and shares to deploy. | +| `localUsers` | _[localUsers](localUsers/readme.md)_ array | `[]` | | Local users to deploy for SFTP authentication. | | `location` | string | `[resourceGroup().location]` | | Location for all resources. | | `lock` | string | `''` | `['', CanNotDelete, ReadOnly]` | Specify the type of lock. | | `managementPolicyRules` | array | `[]` | | The Storage Account ManagementPolicies Rules. | @@ -454,6 +458,9 @@ module storageAccounts './Microsoft.Storage/storageAccounts/deploy.bicep' = { diagnosticStorageAccountId: '' diagnosticWorkspaceId: '' enableDefaultTelemetry: '' + enableHierarchicalNamespace: true + enableNfsV3: true + enableSftp: true fileServices: { diagnosticEventHubAuthorizationRuleId: '' diagnosticEventHubName: '' @@ -480,6 +487,23 @@ module storageAccounts './Microsoft.Storage/storageAccounts/deploy.bicep' = { } ] } + localUsers: [ + { + hasSharedKey: false + hasSshKey: true + hasSshPassword: false + homeDirectory: 'avdscripts' + name: 'testuser' + permissionScopes: [ + { + permissions: 'r' + resourceName: 'avdscripts' + service: 'blob' + } + ] + storageAccountName: '<>ssacom001' + } + ] lock: 'CanNotDelete' networkAcls: { bypass: 'AzureServices' @@ -636,6 +660,15 @@ module storageAccounts './Microsoft.Storage/storageAccounts/deploy.bicep' = { "enableDefaultTelemetry": { "value": "" }, + "enableHierarchicalNamespace": { + "value": true + }, + "enableNfsV3": { + "value": true + }, + "enableSftp": { + "value": true + }, "fileServices": { "value": { "diagnosticEventHubAuthorizationRuleId": "", @@ -664,6 +697,25 @@ module storageAccounts './Microsoft.Storage/storageAccounts/deploy.bicep' = { ] } }, + "localUsers": { + "value": [ + { + "hasSharedKey": false, + "hasSshKey": true, + "hasSshPassword": false, + "homeDirectory": "avdscripts", + "name": "testuser", + "permissionScopes": [ + { + "permissions": "r", + "resourceName": "avdscripts", + "service": "blob" + } + ], + "storageAccountName": "<>ssacom001" + } + ] + }, "lock": { "value": "CanNotDelete" },