From 832fec277bdf8d6c0ae3812817f15f82542e8d28 Mon Sep 17 00:00:00 2001 From: Bernie White Date: Tue, 26 Oct 2021 02:02:40 +1000 Subject: [PATCH] Updates (#2) --- .ps-rule/Org.Rule.ps1 | 2 +- .ps-rule/Org.Rule.yaml | 17 +- .../rg-app-001/st001.parameters.json | 5 +- .../subscription-1/rg-app-002/main.bicep | 6 +- ps-rule.yaml | 4 +- templates/keyvault/v2/README.md | 180 ------------- templates/policy-exemption/v1/README.md | 128 ---------- templates/storage/v2/README.md | 212 ---------------- templates/storage/v2/template.bicep | 238 ++---------------- 9 files changed, 32 insertions(+), 760 deletions(-) delete mode 100644 templates/keyvault/v2/README.md delete mode 100644 templates/policy-exemption/v1/README.md delete mode 100644 templates/storage/v2/README.md diff --git a/.ps-rule/Org.Rule.ps1 b/.ps-rule/Org.Rule.ps1 index 1a219c6..6731d23 100644 --- a/.ps-rule/Org.Rule.ps1 +++ b/.ps-rule/Org.Rule.ps1 @@ -2,7 +2,7 @@ # Licensed under the MIT License. # Note: -# This script demonstrates using PowerShell based rules. +# This script demonstrates using PowerShell-based rules. # Synopsis: Policy exemptions must be approved by the security team and stored within deployments/contoso/landing-zones/subscription-1/policy/. Rule 'Org.CodeOwners' -Type 'Microsoft.Authorization/policyExemptions' { diff --git a/.ps-rule/Org.Rule.yaml b/.ps-rule/Org.Rule.yaml index fa2c968..05aaf79 100644 --- a/.ps-rule/Org.Rule.yaml +++ b/.ps-rule/Org.Rule.yaml @@ -2,7 +2,7 @@ # Licensed under the MIT License. # Note: -# This files demonstrates using PowerShell based rules. +# This files demonstrates using YAML-based rules. --- # Synopsis: Azure resource must have an valid env tag set. @@ -11,8 +11,8 @@ kind: Rule metadata: name: Org.Azure.Tags spec: - with: - - 'Org.Azure.Resources' + type: + - 'Microsoft.Storage/storageAccounts' condition: allOf: - in: @@ -20,14 +20,3 @@ spec: - 'test' - 'dev' field: 'tags.env' - ---- -# Synopsis: Select all Azure resources. -apiVersion: github.com/microsoft/PSRule/v1 -kind: Selector -metadata: - name: Org.Azure.Resources -spec: - if: - field: type - match: Microsoft\.\w+\/.+ diff --git a/deployments/contoso/landing-zones/subscription-1/rg-app-001/st001.parameters.json b/deployments/contoso/landing-zones/subscription-1/rg-app-001/st001.parameters.json index 28ad870..b961f87 100644 --- a/deployments/contoso/landing-zones/subscription-1/rg-app-001/st001.parameters.json +++ b/deployments/contoso/landing-zones/subscription-1/rg-app-001/st001.parameters.json @@ -8,11 +8,8 @@ "storageAccountName": { "value": "st001" }, - "blobSoftDeleteDays": { - "value": 7 - }, "sku": { - "value": "Standard_GRS" + "value": "Standard_LRS" }, "tags": { "value": { diff --git a/deployments/contoso/landing-zones/subscription-1/rg-app-002/main.bicep b/deployments/contoso/landing-zones/subscription-1/rg-app-002/main.bicep index 653d423..cb71786 100644 --- a/deployments/contoso/landing-zones/subscription-1/rg-app-002/main.bicep +++ b/deployments/contoso/landing-zones/subscription-1/rg-app-002/main.bicep @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. - // Note: // This Azure Bicep code demonistrates a deployment of one or more modules. // This file has multiple template errors to show validation. @@ -12,9 +11,8 @@ module storage '../../../../../templates/storage/v2/template.bicep' = { params: { storageAccountName: 'st002' - // An env tag is required at a minimum - tags: { - } + // Don't allow anonymous access types of blob or container + allowBlobPublicAccess: false } } diff --git a/ps-rule.yaml b/ps-rule.yaml index 2bcb1f4..ad4bf4a 100644 --- a/ps-rule.yaml +++ b/ps-rule.yaml @@ -31,6 +31,6 @@ configuration: # Suppression ignores rules for a specific Azure resource by name suppression: Azure.Storage.UseReplication: - - st002 + - st001 Azure.Storage.SoftDelete: - - st002 + - st001 diff --git a/templates/keyvault/v2/README.md b/templates/keyvault/v2/README.md deleted file mode 100644 index c43e032..0000000 --- a/templates/keyvault/v2/README.md +++ /dev/null @@ -1,180 +0,0 @@ -# Key Vault - -Create or update a Key Vault. - -## Parameters - -Parameter name | Required | Description --------------- | -------- | ----------- -vaultName | Yes | The name of the Key Vault. -location | No | The Azure region to deploy to. -accessPolicies | No | The access policies defined for this vault. -useDeployment | No | Determines if Azure can deploy certificates from this Key Vault. -useTemplate | No | Determines if templates can reference secrets from this Key Vault. -useDiskEncryption | No | Determines if this Key Vault can be used for Azure Disk Encryption. -useSoftDelete | No | Determine if soft delete is enabled on this Key Vault. -usePurgeProtection | No | Determine if purge protection is enabled on this Key Vault. -softDeleteDays | No | The number of days to retain soft deleted vaults and vault objects. -useRBAC | No | Determines if access to the objects granted using RBAC. When true, access policies are ignored. -networkAcls | No | The network firewall defined for this vault. -workspaceId | No | The workspace to store audit logs. -tags | Yes | Tags to apply to the resource. - -### vaultName - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The name of the Key Vault. - -### location - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The Azure region to deploy to. - -- Default value: `[resourceGroup().location]` - -### accessPolicies - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The access policies defined for this vault. - -### useDeployment - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if Azure can deploy certificates from this Key Vault. - -- Default value: `True` - -### useTemplate - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if templates can reference secrets from this Key Vault. - -- Default value: `True` - -### useDiskEncryption - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if this Key Vault can be used for Azure Disk Encryption. - -- Default value: `True` - -### useSoftDelete - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determine if soft delete is enabled on this Key Vault. - -- Default value: `True` - -### usePurgeProtection - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determine if purge protection is enabled on this Key Vault. - -- Default value: `True` - -### softDeleteDays - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The number of days to retain soft deleted vaults and vault objects. - -- Default value: `90` - -### useRBAC - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if access to the objects granted using RBAC. When true, access policies are ignored. - -- Default value: `False` - -### networkAcls - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The network firewall defined for this vault. - -- Default value: `@{defaultAction=Allow; bypass=AzureServices; ipRules=System.Object[]; virtualNetworkRules=System.Object[]}` - -### workspaceId - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The workspace to store audit logs. - -### tags - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -Tags to apply to the resource. - -## Outputs - -Name | Type | Description ----- | ---- | ----------- -resourceId | string | A unique resource identifier for the Key Vault. - -## Snippets - -### Parameter file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "template": "templates/keyvault/v2/template.json" - }, - "parameters": { - "vaultName": { - "value": "" - }, - "accessPolicies": { - "value": [ - { - "objectId": "", - "tenantId": "", - "permissions": { - "secrets": [ - "Get", - "List", - "Set" - ] - } - } - ] - }, - "softDeleteDays": { - "value": 90 - }, - "useRBAC": { - "value": false - }, - "networkAcls": { - "value": { - "defaultAction": "Allow", - "bypass": "AzureServices", - "ipRules": [], - "virtualNetworkRules": [] - } - }, - "workspaceId": { - "value": "/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/" - }, - "tags": { - "value": { - "service": "", - "env": "prod" - } - } - } -} -``` diff --git a/templates/policy-exemption/v1/README.md b/templates/policy-exemption/v1/README.md deleted file mode 100644 index 3461eba..0000000 --- a/templates/policy-exemption/v1/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# Policy Exemption - -Create or update an Azure Policy exemption for a Resource Group. - -## Parameters - -Parameter name | Required | Description --------------- | -------- | ----------- -exemptionNameSuffix | Yes | This value will be added as a suffix to the exemption name. -assignmentId | Yes | The resource identifier to the policy assignment that will be exempt. -resourceGroup | No | The name of the Resource Group where the exemption will be scoped. -exemptionCategory | No | The type of exemption. -description | Yes | A description for the policy exemption. -displayName | Yes | The display name of the policy exemption. -requestedBy | Yes | The team that own the resource that the exemption is being created for. -approvedBy | Yes | The team that approved the exemption. -expiresOnDate | Yes | The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. -policyDefinitionReferenceIds | Yes | An array of definition references that this resource is exempt from. - -### exemptionNameSuffix - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -This value will be added as a suffix to the exemption name. - -### assignmentId - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The resource identifier to the policy assignment that will be exempt. - -### resourceGroup - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The name of the Resource Group where the exemption will be scoped. - -### exemptionCategory - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The type of exemption. - -- Default value: `Waiver` - -- Allowed values: `Waiver`, `Mitigated` - -### description - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -A description for the policy exemption. - -### displayName - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The display name of the policy exemption. - -### requestedBy - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The team that own the resource that the exemption is being created for. - -### approvedBy - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The team that approved the exemption. - -### expiresOnDate - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. - -### policyDefinitionReferenceIds - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -An array of definition references that this resource is exempt from. - -## Snippets - -### Parameter file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "template": "templates/policy-exemption/v1/template.json" - }, - "parameters": { - "exemptionNameSuffix": { - "value": "" - }, - "assignmentId": { - "value": "" - }, - "resourceGroup": { - "value": "" - }, - "exemptionCategory": { - "value": "Waiver" - }, - "description": { - "value": "" - }, - "displayName": { - "value": "" - }, - "requestedBy": { - "value": "" - }, - "approvedBy": { - "value": "" - }, - "expiresOnDate": { - "value": "2021-04-28T00:00:00+10:00" - }, - "policyDefinitionReferenceIds": { - "value": [] - } - } -} -``` diff --git a/templates/storage/v2/README.md b/templates/storage/v2/README.md deleted file mode 100644 index 7ddec9d..0000000 --- a/templates/storage/v2/README.md +++ /dev/null @@ -1,212 +0,0 @@ -# Storage Account - -Create or update a Storage Account. - -## Parameters - -Parameter name | Required | Description --------------- | -------- | ----------- -storageAccountName | Yes | The name of the Storage Account. -location | No | The Azure region to deploy to. -sku | No | Create the Storage Account as LRS or GRS. -suffixLength | No | Determine how many additional characters are added to the storage account name as a suffix. -containers | No | An array of storage containers to create on the storage account. -lifecycleRules | No | An array of lifecycle management policies for the storage account. -blobSoftDeleteDays | No | The number of days to retain deleted blobs. When set to 0, soft delete is disabled. -containerSoftDeleteDays | No | The number of days to retain deleted containers. When set to 0, soft delete is disabled. -shares | No | An array of file shares to create on the storage account. -useLargeFileShares | No | Determines if large file shares are enabled. This can not be disabled once enabled. -shareSoftDeleteDays | No | The number of days to retain deleted shares. When set to 0, soft delete is disabled. -allowBlobPublicAccess | No | Determines if any containers can be configured with the anonymous access types of blob or container. -keyVaultPrincipalId | No | Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts. -tags | Yes | Tags to apply to the resource. - -### storageAccountName - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -The name of the Storage Account. - -### location - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The Azure region to deploy to. - -- Default value: `[resourceGroup().location]` - -### sku - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Create the Storage Account as LRS or GRS. - -- Default value: `Standard_LRS` - -- Allowed values: `Standard_LRS`, `Standard_GRS` - -### suffixLength - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determine how many additional characters are added to the storage account name as a suffix. - -- Default value: `0` - -### containers - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -An array of storage containers to create on the storage account. - -### lifecycleRules - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -An array of lifecycle management policies for the storage account. - -### blobSoftDeleteDays - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The number of days to retain deleted blobs. When set to 0, soft delete is disabled. - -- Default value: `0` - -### containerSoftDeleteDays - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The number of days to retain deleted containers. When set to 0, soft delete is disabled. - -- Default value: `0` - -### shares - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -An array of file shares to create on the storage account. - -### useLargeFileShares - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if large file shares are enabled. This can not be disabled once enabled. - -- Default value: `False` - -### shareSoftDeleteDays - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -The number of days to retain deleted shares. When set to 0, soft delete is disabled. - -- Default value: `0` - -### allowBlobPublicAccess - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Determines if any containers can be configured with the anonymous access types of blob or container. - -- Default value: `False` - -### keyVaultPrincipalId - -![Parameter Setting](https://img.shields.io/badge/parameter-optional-green?style=flat-square) - -Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts. - -### tags - -![Parameter Setting](https://img.shields.io/badge/parameter-required-orange?style=flat-square) - -Tags to apply to the resource. - -## Outputs - -Name | Type | Description ----- | ---- | ----------- -resourceId | string | A unique resource identifier for the Storage Account. - -## Snippets - -### Parameter file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "template": "templates/storage/v2/template.json" - }, - "parameters": { - "storageAccountName": { - "value": "" - }, - "sku": { - "value": "Standard_LRS" - }, - "containers": { - "value": [ - { - "name": "logs", - "publicAccess": "None", - "metadata": {} - } - ] - }, - "lifecycleRules": { - "value": { - "enabled": true, - "name": "", - "type": "Lifecycle", - "definition": { - "actions": { - "baseBlob": { - "delete": { - "daysAfterModificationGreaterThan": 7 - } - } - }, - "filters": { - "blobTypes": [ - "blockBlob" - ], - "prefixMatch": [ - "logs/" - ] - } - } - } - }, - "blobSoftDeleteDays": { - "value": 7 - }, - "containerSoftDeleteDays": { - "value": 7 - }, - "shares": { - "value": [ - { - "name": "", - "shareQuota": 5, - "metadata": {} - } - ] - }, - "shareSoftDeleteDays": { - "value": 7 - }, - "allowBlobPublicAccess": { - "value": false - }, - "tags": { - "value": { - "service": "", - "env": "prod" - } - } - } -} -``` diff --git a/templates/storage/v2/template.bicep b/templates/storage/v2/template.bicep index 1fb5b90..0072148 100644 --- a/templates/storage/v2/template.bicep +++ b/templates/storage/v2/template.bicep @@ -1,169 +1,24 @@ -// Azure Storage Account +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -@metadata({ - description: 'The name of the Storage Account.' - example: '' -}) +@description('The name of the Storage Account.') param storageAccountName string -@metadata({ - description: 'The Azure region to deploy to.' - strongType: 'location' - example: 'EastUS' - ignore: true -}) +@description('The Azure region to deploy to.') param location string = resourceGroup().location -@allowed([ - 'Standard_LRS' - 'Standard_GRS' -]) @description('Create the Storage Account as LRS or GRS.') -param sku string = 'Standard_LRS' - -@minValue(0) -@maxValue(13) -@metadata({ - description: 'Determine how many additional characters are added to the storage account name as a suffix.' - ignore: true -}) -param suffixLength int = 0 - -@metadata({ - description: 'An array of storage containers to create on the storage account.' - example: [ - { - name: 'logs' - publicAccess: 'None' - metadata: {} - } - ] -}) -param containers array = [] - -@metadata({ - description: 'An array of lifecycle management policies for the storage account.' - example: { - enabled: true - name: '' - type: 'Lifecycle' - definition: { - actions: { - baseBlob: { - delete: { - daysAfterModificationGreaterThan: 7 - } - } - } - filters: { - blobTypes: [ - 'blockBlob' - ] - prefixMatch: [ - 'logs/' - ] - } - } - } -}) -param lifecycleRules array = [] - -@minValue(0) -@maxValue(365) -@metadata({ - description: 'The number of days to retain deleted blobs. When set to 0, soft delete is disabled.' - example: 7 -}) -param blobSoftDeleteDays int = 0 - -@minValue(0) -@maxValue(365) -@metadata({ - description: 'The number of days to retain deleted containers. When set to 0, soft delete is disabled.' - example: 7 -}) -param containerSoftDeleteDays int = 0 - -@metadata({ - description: 'An array of file shares to create on the storage account.' - example: [ - { - name: '' - shareQuota: 5 - metadata: {} - } - ] -}) -param shares array = [] - -@metadata({ - description: 'Determines if large file shares are enabled. This can not be disabled once enabled.' - ignore: true -}) -param useLargeFileShares bool = false - -@minValue(0) -@maxValue(365) -@metadata({ - description: 'The number of days to retain deleted shares. When set to 0, soft delete is disabled.' - example: 7 -}) -param shareSoftDeleteDays int = 0 +param sku string = 'Standard_GRS' @description('Determines if any containers can be configured with the anonymous access types of blob or container.') -param allowBlobPublicAccess bool = false - -@metadata({ - description: 'Set to the objectId of Azure Key Vault to delegated permission for use with Key Managed Storage Accounts.' - ignore: true -}) -param keyVaultPrincipalId string = '' - -@metadata({ - description: 'Tags to apply to the resource.' - example: { - service: '' - env: 'prod' - } -}) -param tags object - -var normalName = concat(storageAccountName, ((suffixLength > 0) ? substring(uniqueString(resourceGroup().id), 0, suffixLength) : '')) - -var blobSoftDeleteLookup = { - 'true': { - enabled: true - days: blobSoftDeleteDays - } - 'false': { - enabled: false - } -} -var containerSoftDeleteLookup = { - 'true': { - enabled: true - days: containerSoftDeleteDays - } - 'false': null -} -var shareSoftDeleteLookup = { - 'true': { - enabled: true - days: shareSoftDeleteDays - } - 'false': { - enabled: false - } -} -var largeFileSharesState = (useLargeFileShares ? 'Enabled' : 'Disabled') -var storageAccountKeyOperatorRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12') +param allowBlobPublicAccess bool = true +// Define a Storage Account resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = { - name: normalName + name: storageAccountName location: location sku: { name: sku - tier: 'Standard' } kind: 'StorageV2' properties: { @@ -171,26 +26,16 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = { bypass: 'AzureServices' virtualNetworkRules: [] ipRules: [] - defaultAction: 'Allow' + defaultAction: 'Deny' } supportsHttpsTrafficOnly: true - encryption: { - services: { - file: { - enabled: true - } - blob: { - enabled: true - } - } - keySource: 'Microsoft.Storage' - } accessTier: 'Hot' - largeFileSharesState: largeFileSharesState allowBlobPublicAccess: allowBlobPublicAccess minimumTlsVersion: 'TLS1_2' } - tags: tags + tags: { + env: 'test' + } } resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = { @@ -200,8 +45,14 @@ resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01 cors: { corsRules: [] } - deleteRetentionPolicy: blobSoftDeleteLookup[string((blobSoftDeleteDays > 0))] - containerDeleteRetentionPolicy: containerSoftDeleteLookup[string((containerSoftDeleteDays > 0))] + deleteRetentionPolicy: { + enabled: true + days: 7 + } + containerDeleteRetentionPolicy: { + enabled: true + days: 7 + } } } @@ -209,52 +60,9 @@ resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2019-06-01 parent: storageAccount name: 'default' properties: { - shareDeleteRetentionPolicy: shareSoftDeleteLookup[string((shareSoftDeleteDays > 0))] - } -} - -resource storageAccountContainers 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = [for i in range(0, ((length(containers) == 0) ? 1 : length(containers))): if (!(length(containers) == 0)) { - name: ((length(containers) == 0) ? '${normalName}/default/empty' : '${normalName}/default/${containers[i].name}') - properties: { - metadata: containers[i].metadata - publicAccess: containers[i].publicAccess - } - dependsOn: [ - blobServices - storageAccount - ] -}] - -resource managementPolicies 'Microsoft.Storage/storageAccounts/managementPolicies@2019-06-01' = if (!empty(lifecycleRules)) { - parent: storageAccount - name: 'default' - properties: { - policy: { - rules: lifecycleRules + shareDeleteRetentionPolicy: { + enabled: true + days: 7 } } } - -resource storageAccountShares 'Microsoft.Storage/storageAccounts/fileServices/shares@2019-06-01' = [for i in range(0, ((length(shares) == 0) ? 1 : length(shares))): if (!(length(shares) == 0)) { - name: ((length(shares) == 0) ? '${normalName}/default/empty' : '${normalName}/default/${shares[i].name}') - properties: { - metadata: shares[i].metadata - shareQuota: shares[i].shareQuota - } - dependsOn: [ - fileServices - storageAccount - ] -}] - -resource storageAccountKeyOperatorRole 'Microsoft.Storage/storageAccounts/providers/roleAssignments@2018-09-01-preview' = if (!empty(keyVaultPrincipalId)) { - name: '${normalName}/Microsoft.Authorization/${guid(keyVaultPrincipalId, storageAccountKeyOperatorRoleId)}' - properties: { - roleDefinitionId: storageAccountKeyOperatorRoleId - principalId: keyVaultPrincipalId - scope: storageAccount.id - principalType: 'ServicePrincipal' - } -} - -output storageAccountResourceId string = storageAccount.id