From de3e67d6315c5d32de9def20900d01e9fd13292f Mon Sep 17 00:00:00 2001 From: ChrisSidebotham-MSFT <48600046+ChrisSidebotham@users.noreply.github.com> Date: Wed, 22 May 2024 10:45:42 +0100 Subject: [PATCH] fix: Several Storage Account fixes included replacement for #1508 - `avm/res/storage/storage-account` (#1987) ## Description ported changes from #1508 following comment from core team and fblix Fixes #1508 Closes #1674 Closes #1731 Closes #1385 Closes #1346 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.storage.storage-account](https://github.com/ChrisSidebotham/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg?branch=storage-fix)](https://github.com/ChrisSidebotham/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) | ## Type of Change - [ ] Update to CI Environment or utlities (Non-module effecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change (#1508 is open but should be abandoned) - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/storage/storage-account/README.md | 322 ++++++++------ .../storage-account/blob-service/README.md | 4 +- .../container/immutability-policy/main.json | 4 +- .../blob-service/container/main.json | 8 +- .../storage-account/blob-service/main.bicep | 122 ++--- .../storage-account/blob-service/main.json | 16 +- .../storage-account/file-service/README.md | 2 +- .../storage-account/file-service/main.bicep | 80 ++-- .../storage-account/file-service/main.json | 22 +- .../file-service/share/main.bicep | 4 +- .../file-service/share/main.json | 12 +- .../storage-account/local-user/README.md | 2 +- .../storage-account/local-user/main.bicep | 5 +- .../storage-account/local-user/main.json | 8 +- avm/res/storage/storage-account/main.bicep | 228 +++++----- avm/res/storage/storage-account/main.json | 128 +++--- .../management-policy/main.json | 4 +- .../storage-account/queue-service/README.md | 4 +- .../storage-account/queue-service/main.bicep | 72 +-- .../storage-account/queue-service/main.json | 18 +- .../queue-service/queue/README.md | 2 +- .../queue-service/queue/main.bicep | 86 ++-- .../queue-service/queue/main.json | 10 +- .../storage-account/table-service/README.md | 4 +- .../storage-account/table-service/main.bicep | 70 +-- .../storage-account/table-service/main.json | 18 +- .../table-service/table/README.md | 2 +- .../table-service/table/main.bicep | 76 +++- .../table-service/table/main.json | 10 +- .../tests/e2e/changefeed/main.test.bicep | 52 +++ .../tests/e2e/waf-aligned/main.test.bicep | 418 +++++++++--------- avm/res/storage/storage-account/version.json | 4 +- 32 files changed, 1025 insertions(+), 792 deletions(-) create mode 100644 avm/res/storage/storage-account/tests/e2e/changefeed/main.test.bicep diff --git a/avm/res/storage/storage-account/README.md b/avm/res/storage/storage-account/README.md index 83fba9bd49..6f0250fa03 100644 --- a/avm/res/storage/storage-account/README.md +++ b/avm/res/storage/storage-account/README.md @@ -25,14 +25,14 @@ This module deploys a Storage Account. | `Microsoft.Storage/storageAccounts/blobServices` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices) | | `Microsoft.Storage/storageAccounts/blobServices/containers` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers) | | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | [2022-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-09-01/storageAccounts/blobServices/containers/immutabilityPolicies) | -| `Microsoft.Storage/storageAccounts/fileServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices) | +| `Microsoft.Storage/storageAccounts/fileServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices) | | `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | -| `Microsoft.Storage/storageAccounts/localUsers` | [2022-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-05-01/storageAccounts/localUsers) | +| `Microsoft.Storage/storageAccounts/localUsers` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/localUsers) | | `Microsoft.Storage/storageAccounts/managementPolicies` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/managementPolicies) | -| `Microsoft.Storage/storageAccounts/queueServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices) | -| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices/queues) | -| `Microsoft.Storage/storageAccounts/tableServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices) | -| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices/tables) | +| `Microsoft.Storage/storageAccounts/queueServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices) | +| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices/queues) | +| `Microsoft.Storage/storageAccounts/tableServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices) | +| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices/tables) | ## Usage examples @@ -44,13 +44,14 @@ The following section provides usage examples for the module, which were used to - [Deploying as a Blob Storage](#example-1-deploying-as-a-blob-storage) - [Deploying as a Block Blob Storage](#example-2-deploying-as-a-block-blob-storage) -- [Using only defaults](#example-3-using-only-defaults) -- [Using large parameter set](#example-4-using-large-parameter-set) -- [Deploying with a NFS File Share](#example-5-deploying-with-a-nfs-file-share) -- [Using Customer-Managed-Keys with System-Assigned identity](#example-6-using-customer-managed-keys-with-system-assigned-identity) -- [Using Customer-Managed-Keys with User-Assigned identity](#example-7-using-customer-managed-keys-with-user-assigned-identity) -- [Deploying as Storage Account version 1](#example-8-deploying-as-storage-account-version-1) -- [WAF-aligned](#example-9-waf-aligned) +- [Using only changefeed configuration](#example-3-using-only-changefeed-configuration) +- [Using only defaults](#example-4-using-only-defaults) +- [Using large parameter set](#example-5-using-large-parameter-set) +- [Deploying with a NFS File Share](#example-6-deploying-with-a-nfs-file-share) +- [Using Customer-Managed-Keys with System-Assigned identity](#example-7-using-customer-managed-keys-with-system-assigned-identity) +- [Using Customer-Managed-Keys with User-Assigned identity](#example-8-using-customer-managed-keys-with-user-assigned-identity) +- [Deploying as Storage Account version 1](#example-9-deploying-as-storage-account-version-1) +- [WAF-aligned](#example-10-waf-aligned) ### Example 1: _Deploying as a Blob Storage_ @@ -164,7 +165,67 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 3: _Using only defaults_ +### Example 3: _Using only changefeed configuration_ + +This instance deploys the module with the minimum set of required parameters for the changefeed configuration. + + +

+ +via Bicep module + +```bicep +module storageAccount 'br/public:avm/res/storage/storage-account:' = { + name: 'storageAccountDeployment' + params: { + // Required parameters + name: 'ssachf001' + // Non-required parameters + allowBlobPublicAccess: false + blobServices: { + changeFeedEnabled: true + } + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ssachf001" + }, + // Non-required parameters + "allowBlobPublicAccess": { + "value": false + }, + "blobServices": { + "value": { + "changeFeedEnabled": true + } + }, + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 4: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. @@ -226,7 +287,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 4: _Using large parameter set_ +### Example 5: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -1092,7 +1153,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 5: _Deploying with a NFS File Share_ +### Example 6: _Deploying with a NFS File Share_ This instance deploys the module with a NFS File Share. @@ -1166,7 +1227,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 6: _Using Customer-Managed-Keys with System-Assigned identity_ +### Example 7: _Using Customer-Managed-Keys with System-Assigned identity_ This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity. This required the service to be deployed twice, once as a pre-requisite to create the System-Assigned Identity, and once to use it for accessing the Customer-Managed-Key secret. @@ -1270,7 +1331,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 7: _Using Customer-Managed-Keys with User-Assigned identity_ +### Example 8: _Using Customer-Managed-Keys with User-Assigned identity_ This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. @@ -1390,7 +1451,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 8: _Deploying as Storage Account version 1_ +### Example 9: _Deploying as Storage Account version 1_ This instance deploys the module as Storage Account version 1. @@ -1442,7 +1503,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = {

-### Example 9: _WAF-aligned_ +### Example 10: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -1663,7 +1724,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { } requireInfrastructureEncryption: true sasExpirationPeriod: '180.00:00:00' - skuName: 'Standard_LRS' + skuName: 'Standard_ZRS' tableServices: { diagnosticSettings: [ { @@ -1954,7 +2015,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { "value": "180.00:00:00" }, "skuName": { - "value": "Standard_LRS" + "value": "Standard_ZRS" }, "tableServices": { "value": { @@ -2004,7 +2065,6 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { | Parameter | Type | Description | | :-- | :-- | :-- | | [`name`](#parameter-name) | string | Name of the Storage Account. Must be lower-case. | -| [`networkAcls`](#parameter-networkacls) | object | Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. | **Conditional parameters** @@ -2034,6 +2094,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`fileServices`](#parameter-fileservices) | object | File service and shares to deploy. | | [`isLocalUserEnabled`](#parameter-islocaluserenabled) | bool | Enables local users feature, if set to true. | +| [`keyType`](#parameter-keytype) | string | The keyType to use with Queue & Table services. | | [`kind`](#parameter-kind) | string | Type of Storage Account to create. | | [`largeFileSharesState`](#parameter-largefilesharesstate) | string | Allow large file shares if sets to 'Enabled'. It cannot be disabled once it is enabled. Only supported on locally redundant and zone redundant file shares. It cannot be set on FileStorage storage accounts (storage accounts for premium file shares). | | [`localUsers`](#parameter-localusers) | array | Local users to deploy for SFTP authentication. | @@ -2042,6 +2103,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:' = { | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | | [`managementPolicyRules`](#parameter-managementpolicyrules) | array | The Storage Account ManagementPolicies Rules. | | [`minimumTlsVersion`](#parameter-minimumtlsversion) | string | Set the minimum TLS version on request to storage. | +| [`networkAcls`](#parameter-networkacls) | object | Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. | | [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | | [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkAcls are not set. | | [`queueServices`](#parameter-queueservices) | object | Queue service and queues to create. | @@ -2060,111 +2122,6 @@ Name of the Storage Account. Must be lower-case. - Required: Yes - Type: string -### Parameter: `networkAcls` - -Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. - -- Required: No -- Type: object -- Default: - ```Bicep - { - bypass: 'AzureServices' - defaultAction: 'Deny' - } - ``` - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`bypass`](#parameter-networkaclsbypass) | string | Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. | -| [`defaultAction`](#parameter-networkaclsdefaultaction) | string | Specifies the default action of allow or deny when no other rules match. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`ipRules`](#parameter-networkaclsiprules) | array | Sets the IP ACL rules. | -| [`resourceAccessRules`](#parameter-networkaclsresourceaccessrules) | array | Sets the resource access rules. Array entries must consist of "tenantId" and "resourceId" fields only. | -| [`virtualNetworkRules`](#parameter-networkaclsvirtualnetworkrules) | array | Sets the virtual network rules. | - -### Parameter: `networkAcls.bypass` - -Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. - -- Required: Yes -- Type: string -- Allowed: - ```Bicep - [ - 'AzureServices' - 'AzureServices, Logging' - 'AzureServices, Logging, Metrics' - 'AzureServices, Metrics' - 'Logging' - 'Logging, Metrics' - 'Metrics' - 'None' - ] - ``` - -### Parameter: `networkAcls.defaultAction` - -Specifies the default action of allow or deny when no other rules match. - -- Required: Yes -- Type: string -- Allowed: - ```Bicep - [ - 'Allow' - 'Deny' - ] - ``` - -### Parameter: `networkAcls.ipRules` - -Sets the IP ACL rules. - -- Required: No -- Type: array - -### Parameter: `networkAcls.resourceAccessRules` - -Sets the resource access rules. Array entries must consist of "tenantId" and "resourceId" fields only. - -- Required: No -- Type: array - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`resourceId`](#parameter-networkaclsresourceaccessrulesresourceid) | string | The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included. | -| [`tenantId`](#parameter-networkaclsresourceaccessrulestenantid) | string | The ID of the tenant in which the resource resides in. | - -### Parameter: `networkAcls.resourceAccessRules.resourceId` - -The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included. - -- Required: Yes -- Type: string - -### Parameter: `networkAcls.resourceAccessRules.tenantId` - -The ID of the tenant in which the resource resides in. - -- Required: Yes -- Type: string - -### Parameter: `networkAcls.virtualNetworkRules` - -Sets the virtual network rules. - -- Required: No -- Type: array - ### Parameter: `accessTier` Required if the Storage Account kind is set to BlobStorage. The access tier is used for billing. The "Premium" access tier is the default value for premium block blobs storage account type and it cannot be changed for the premium block blobs storage account type. @@ -2483,6 +2440,20 @@ Enables local users feature, if set to true. - Type: bool - Default: `False` +### Parameter: `keyType` + +The keyType to use with Queue & Table services. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Account' + 'Service' + ] + ``` + ### Parameter: `kind` Type of Storage Account to create. @@ -2619,6 +2590,99 @@ Set the minimum TLS version on request to storage. ] ``` +### Parameter: `networkAcls` + +Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`bypass`](#parameter-networkaclsbypass) | string | Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. | +| [`defaultAction`](#parameter-networkaclsdefaultaction) | string | Specifies the default action of allow or deny when no other rules match. | +| [`ipRules`](#parameter-networkaclsiprules) | array | Sets the IP ACL rules. | +| [`resourceAccessRules`](#parameter-networkaclsresourceaccessrules) | array | Sets the resource access rules. Array entries must consist of "tenantId" and "resourceId" fields only. | +| [`virtualNetworkRules`](#parameter-networkaclsvirtualnetworkrules) | array | Sets the virtual network rules. | + +### Parameter: `networkAcls.bypass` + +Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureServices' + 'AzureServices, Logging' + 'AzureServices, Logging, Metrics' + 'AzureServices, Metrics' + 'Logging' + 'Logging, Metrics' + 'Metrics' + 'None' + ] + ``` + +### Parameter: `networkAcls.defaultAction` + +Specifies the default action of allow or deny when no other rules match. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Allow' + 'Deny' + ] + ``` + +### Parameter: `networkAcls.ipRules` + +Sets the IP ACL rules. + +- Required: No +- Type: array + +### Parameter: `networkAcls.resourceAccessRules` + +Sets the resource access rules. Array entries must consist of "tenantId" and "resourceId" fields only. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`resourceId`](#parameter-networkaclsresourceaccessrulesresourceid) | string | The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included. | +| [`tenantId`](#parameter-networkaclsresourceaccessrulestenantid) | string | The ID of the tenant in which the resource resides in. | + +### Parameter: `networkAcls.resourceAccessRules.resourceId` + +The resource ID of the target service. Can also contain a wildcard, if multiple services e.g. in a resource group should be included. + +- Required: Yes +- Type: string + +### Parameter: `networkAcls.resourceAccessRules.tenantId` + +The ID of the tenant in which the resource resides in. + +- Required: Yes +- Type: string + +### Parameter: `networkAcls.virtualNetworkRules` + +Sets the virtual network rules. + +- Required: No +- Type: array + ### Parameter: `privateEndpoints` Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. @@ -3137,7 +3201,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.4.0` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.4.1` | Remote reference | ## Notes diff --git a/avm/res/storage/storage-account/blob-service/README.md b/avm/res/storage/storage-account/blob-service/README.md index f66c244ced..93e379cf70 100644 --- a/avm/res/storage/storage-account/blob-service/README.md +++ b/avm/res/storage/storage-account/blob-service/README.md @@ -34,7 +34,7 @@ This module deploys a Storage Account Blob Service. | :-- | :-- | :-- | | [`automaticSnapshotPolicyEnabled`](#parameter-automaticsnapshotpolicyenabled) | bool | Automatic Snapshot is enabled if set to true. | | [`changeFeedEnabled`](#parameter-changefeedenabled) | bool | The blob service properties for change feed events. Indicates whether change feed event logging is enabled for the Blob service. | -| [`changeFeedRetentionInDays`](#parameter-changefeedretentionindays) | int | Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. A "0" value indicates an infinite retention of the change feed. | +| [`changeFeedRetentionInDays`](#parameter-changefeedretentionindays) | int | Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed. | | [`containerDeleteRetentionPolicyAllowPermanentDelete`](#parameter-containerdeleteretentionpolicyallowpermanentdelete) | bool | This property when set to true allows deletion of the soft deleted blob versions and snapshots. This property cannot be used with blob restore policy. This property only applies to blob service and does not apply to containers or file share. | | [`containerDeleteRetentionPolicyDays`](#parameter-containerdeleteretentionpolicydays) | int | Indicates the number of days that the deleted item should be retained. | | [`containerDeleteRetentionPolicyEnabled`](#parameter-containerdeleteretentionpolicyenabled) | bool | The blob service properties for container soft delete. Indicates whether DeleteRetentionPolicy is enabled. | @@ -75,7 +75,7 @@ The blob service properties for change feed events. Indicates whether change fee ### Parameter: `changeFeedRetentionInDays` -Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. A "0" value indicates an infinite retention of the change feed. +Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed. - Required: No - Type: int diff --git a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json index a45e614327..1d3a01403a 100644 --- a/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json +++ b/avm/res/storage/storage-account/blob-service/container/immutability-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12849754295459852309" + "version": "0.27.1.19265", + "templateHash": "7418870035820197377" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/blob-service/container/main.json b/avm/res/storage/storage-account/blob-service/container/main.json index 0d487d2827..d759f9ab84 100644 --- a/avm/res/storage/storage-account/blob-service/container/main.json +++ b/avm/res/storage/storage-account/blob-service/container/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "3805384021483033369" + "version": "0.27.1.19265", + "templateHash": "7167285049910521671" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -274,8 +274,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12849754295459852309" + "version": "0.27.1.19265", + "templateHash": "7418870035820197377" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/blob-service/main.bicep b/avm/res/storage/storage-account/blob-service/main.bicep index 4a71845d32..c02c02f6fa 100644 --- a/avm/res/storage/storage-account/blob-service/main.bicep +++ b/avm/res/storage/storage-account/blob-service/main.bicep @@ -12,9 +12,9 @@ param automaticSnapshotPolicyEnabled bool = false @description('Optional. The blob service properties for change feed events. Indicates whether change feed event logging is enabled for the Blob service.') param changeFeedEnabled bool = false -@minValue(0) +@minValue(1) @maxValue(146000) -@description('Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. A "0" value indicates an infinite retention of the change feed.') +@description('Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed.') param changeFeedRetentionInDays int? @description('Optional. The blob service properties for container soft delete. Indicates whether DeleteRetentionPolicy is enabled.') @@ -76,14 +76,18 @@ resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01 parent: storageAccount properties: { automaticSnapshotPolicyEnabled: automaticSnapshotPolicyEnabled - changeFeed: changeFeedEnabled ? { - enabled: true - retentionInDays: changeFeedRetentionInDays - } : null + changeFeed: changeFeedEnabled + ? { + enabled: true + retentionInDays: changeFeedRetentionInDays + } + : null containerDeleteRetentionPolicy: { enabled: containerDeleteRetentionPolicyEnabled days: containerDeleteRetentionPolicyDays - allowPermanentDelete: containerDeleteRetentionPolicyEnabled == true ? containerDeleteRetentionPolicyAllowPermanentDelete : null + allowPermanentDelete: containerDeleteRetentionPolicyEnabled == true + ? containerDeleteRetentionPolicyAllowPermanentDelete + : null } cors: { corsRules: corsRules @@ -95,57 +99,69 @@ resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01 allowPermanentDelete: deleteRetentionPolicyEnabled && deleteRetentionPolicyAllowPermanentDelete ? true : null } isVersioningEnabled: isVersioningEnabled - lastAccessTimeTrackingPolicy: storageAccount.kind != 'Storage' ? { - enable: lastAccessTimeTrackingPolicyEnabled - name: lastAccessTimeTrackingPolicyEnabled == true ? 'AccessTimeTracking' : null - trackingGranularityInDays: lastAccessTimeTrackingPolicyEnabled == true ? 1 : null - } : null - restorePolicy: restorePolicyEnabled ? { - enabled: true - days: restorePolicyDays - } : null + lastAccessTimeTrackingPolicy: storageAccount.kind != 'Storage' + ? { + enable: lastAccessTimeTrackingPolicyEnabled + name: lastAccessTimeTrackingPolicyEnabled == true ? 'AccessTimeTracking' : null + trackingGranularityInDays: lastAccessTimeTrackingPolicyEnabled == true ? 1 : null + } + : null + restorePolicy: restorePolicyEnabled + ? { + enabled: true + days: restorePolicyDays + } + : null } } -resource blobServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { - name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' - properties: { - storageAccountId: diagnosticSetting.?storageAccountResourceId - workspaceId: diagnosticSetting.?workspaceResourceId - eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId - eventHubName: diagnosticSetting.?eventHubName - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { - categoryGroup: group.?categoryGroup - category: group.?category - enabled: group.?enabled ?? true - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource blobServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [ + for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + logs: [ + for group in (diagnosticSetting.?logCategoriesAndGroups ?? [{ categoryGroup: 'allLogs' }]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: blobServices } - scope: blobServices -}] - -module blobServices_container 'container/main.bicep' = [for (container, index) in (containers ?? []): { - name: '${deployment().name}-Container-${index}' - params: { - storageAccountName: storageAccount.name - name: container.name - defaultEncryptionScope: container.?defaultEncryptionScope - denyEncryptionScopeOverride: container.?denyEncryptionScopeOverride - enableNfsV3AllSquash: container.?enableNfsV3AllSquash - enableNfsV3RootSquash: container.?enableNfsV3RootSquash - immutableStorageWithVersioningEnabled: container.?immutableStorageWithVersioningEnabled - metadata: container.?metadata - publicAccess: container.?publicAccess - roleAssignments: container.?roleAssignments - immutabilityPolicyProperties: container.?immutabilityPolicyProperties +] + +module blobServices_container 'container/main.bicep' = [ + for (container, index) in (containers ?? []): { + name: '${deployment().name}-Container-${index}' + params: { + storageAccountName: storageAccount.name + name: container.name + defaultEncryptionScope: container.?defaultEncryptionScope + denyEncryptionScopeOverride: container.?denyEncryptionScopeOverride + enableNfsV3AllSquash: container.?enableNfsV3AllSquash + enableNfsV3RootSquash: container.?enableNfsV3RootSquash + immutableStorageWithVersioningEnabled: container.?immutableStorageWithVersioningEnabled + metadata: container.?metadata + publicAccess: container.?publicAccess + roleAssignments: container.?roleAssignments + immutabilityPolicyProperties: container.?immutabilityPolicyProperties + } } -}] +] @description('The name of the deployed blob service.') output name string = blobServices.name diff --git a/avm/res/storage/storage-account/blob-service/main.json b/avm/res/storage/storage-account/blob-service/main.json index 1ffa10179f..5ec121ad9a 100644 --- a/avm/res/storage/storage-account/blob-service/main.json +++ b/avm/res/storage/storage-account/blob-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "7278814029590745003" + "version": "0.27.1.19265", + "templateHash": "14376792680036937652" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", @@ -159,10 +159,10 @@ "changeFeedRetentionInDays": { "type": "int", "nullable": true, - "minValue": 0, + "minValue": 1, "maxValue": 146000, "metadata": { - "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. A \"0\" value indicates an infinite retention of the change feed." + "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed." } }, "containerDeleteRetentionPolicyEnabled": { @@ -403,8 +403,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "3805384021483033369" + "version": "0.27.1.19265", + "templateHash": "7167285049910521671" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -672,8 +672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12849754295459852309" + "version": "0.27.1.19265", + "templateHash": "7418870035820197377" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", diff --git a/avm/res/storage/storage-account/file-service/README.md b/avm/res/storage/storage-account/file-service/README.md index dbcfac9607..06532a47bc 100644 --- a/avm/res/storage/storage-account/file-service/README.md +++ b/avm/res/storage/storage-account/file-service/README.md @@ -15,7 +15,7 @@ This module deploys a Storage Account File Share Service. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Storage/storageAccounts/fileServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/fileServices) | +| `Microsoft.Storage/storageAccounts/fileServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/fileServices) | | `Microsoft.Storage/storageAccounts/fileServices/shares` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2023-01-01/storageAccounts/fileServices/shares) | ## Parameters diff --git a/avm/res/storage/storage-account/file-service/main.bicep b/avm/res/storage/storage-account/file-service/main.bicep index 541f8a475e..63954599a6 100644 --- a/avm/res/storage/storage-account/file-service/main.bicep +++ b/avm/res/storage/storage-account/file-service/main.bicep @@ -26,11 +26,11 @@ param shares array? var defaultShareAccessTier = storageAccount.kind == 'FileStorage' ? 'Premium' : 'TransactionOptimized' // default share accessTier depends on the Storage Account kind: 'Premium' for 'FileStorage' kind, 'TransactionOptimized' otherwise -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName } -resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2021-09-01' = { +resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2023-04-01' = { name: name parent: storageAccount properties: { @@ -39,42 +39,50 @@ resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2021-09-01 } } -resource fileServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { - name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' - properties: { - storageAccountId: diagnosticSetting.?storageAccountResourceId - workspaceId: diagnosticSetting.?workspaceResourceId - eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId - eventHubName: diagnosticSetting.?eventHubName - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { - categoryGroup: group.?categoryGroup - category: group.?category - enabled: group.?enabled ?? true - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource fileServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [ + for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + logs: [ + for group in (diagnosticSetting.?logCategoriesAndGroups ?? [{ categoryGroup: 'allLogs' }]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: fileServices } - scope: fileServices -}] - -module fileServices_shares 'share/main.bicep' = [for (share, index) in (shares ?? []): { - name: '${deployment().name}-shares-${index}' - params: { - storageAccountName: storageAccount.name - fileServicesName: fileServices.name - name: share.name - accessTier: share.?accessTier ?? defaultShareAccessTier - enabledProtocols: share.?enabledProtocols - rootSquash: share.?rootSquash - shareQuota: share.?shareQuota - roleAssignments: share.?roleAssignments +] + +module fileServices_shares 'share/main.bicep' = [ + for (share, index) in (shares ?? []): { + name: '${deployment().name}-shares-${index}' + params: { + storageAccountName: storageAccount.name + fileServicesName: fileServices.name + name: share.name + accessTier: share.?accessTier ?? defaultShareAccessTier + enabledProtocols: share.?enabledProtocols + rootSquash: share.?rootSquash + shareQuota: share.?shareQuota + roleAssignments: share.?roleAssignments + } } -}] +] @description('The name of the deployed file share service.') output name string = fileServices.name diff --git a/avm/res/storage/storage-account/file-service/main.json b/avm/res/storage/storage-account/file-service/main.json index 31a38bc821..8a78aa2117 100644 --- a/avm/res/storage/storage-account/file-service/main.json +++ b/avm/res/storage/storage-account/file-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4306536926065797375" + "version": "0.27.1.19265", + "templateHash": "2249966746510096150" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", @@ -184,12 +184,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "fileServices": { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", "properties": { "protocolSettings": "[parameters('protocolSettings')]", @@ -264,7 +264,7 @@ "value": "[coalesce(parameters('shares'), createArray())[copyIndex()].name]" }, "accessTier": { - "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2021-09-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]" + "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2023-04-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]" }, "enabledProtocols": { "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'enabledProtocols')]" @@ -286,8 +286,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "13618261904162439978" + "version": "0.27.1.19265", + "templateHash": "7785463723571874765" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -436,7 +436,7 @@ "storageAccount::fileService": { "existing": true, "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]", "dependsOn": [ "storageAccount" @@ -445,7 +445,7 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "fileShare": { @@ -486,8 +486,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "6057169747302051267" + "version": "0.27.1.19265", + "templateHash": "8943543243348777065" } }, "parameters": { diff --git a/avm/res/storage/storage-account/file-service/share/main.bicep b/avm/res/storage/storage-account/file-service/share/main.bicep index c5201745c0..dc84824652 100644 --- a/avm/res/storage/storage-account/file-service/share/main.bicep +++ b/avm/res/storage/storage-account/file-service/share/main.bicep @@ -42,10 +42,10 @@ param rootSquash string = 'NoRootSquash' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName - resource fileService 'fileServices@2021-09-01' existing = { + resource fileService 'fileServices@2023-04-01' existing = { name: fileServicesName } } diff --git a/avm/res/storage/storage-account/file-service/share/main.json b/avm/res/storage/storage-account/file-service/share/main.json index 5e5f8ff5c6..0c623fd5bf 100644 --- a/avm/res/storage/storage-account/file-service/share/main.json +++ b/avm/res/storage/storage-account/file-service/share/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "13618261904162439978" + "version": "0.27.1.19265", + "templateHash": "7785463723571874765" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -155,7 +155,7 @@ "storageAccount::fileService": { "existing": true, "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]", "dependsOn": [ "storageAccount" @@ -164,7 +164,7 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "fileShare": { @@ -205,8 +205,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "6057169747302051267" + "version": "0.27.1.19265", + "templateHash": "8943543243348777065" } }, "parameters": { diff --git a/avm/res/storage/storage-account/local-user/README.md b/avm/res/storage/storage-account/local-user/README.md index 778c80e1b0..281c98643f 100644 --- a/avm/res/storage/storage-account/local-user/README.md +++ b/avm/res/storage/storage-account/local-user/README.md @@ -14,7 +14,7 @@ This module deploys a Storage Account Local User, which is used for SFTP authent | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Storage/storageAccounts/localUsers` | [2022-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2022-05-01/storageAccounts/localUsers) | +| `Microsoft.Storage/storageAccounts/localUsers` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/localUsers) | ## Parameters diff --git a/avm/res/storage/storage-account/local-user/main.bicep b/avm/res/storage/storage-account/local-user/main.bicep index 464546e9fb..605e5c2f99 100644 --- a/avm/res/storage/storage-account/local-user/main.bicep +++ b/avm/res/storage/storage-account/local-user/main.bicep @@ -27,11 +27,11 @@ param permissionScopes array @description('Optional. The local user SSH authorized keys for SFTP.') param sshAuthorizedKeys sshAuthorizedKeysType -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName } -resource localUsers 'Microsoft.Storage/storageAccounts/localUsers@2022-05-01' = { +resource localUsers 'Microsoft.Storage/storageAccounts/localUsers@2023-04-01' = { name: name parent: storageAccount properties: { @@ -59,7 +59,6 @@ output resourceId string = localUsers.id @secure() type sshAuthorizedKeysType = { - @description('Optional. The list of SSH authorized keys.') secureList: { @description('Optional. Description used to store the function/usage of the key.') diff --git a/avm/res/storage/storage-account/local-user/main.json b/avm/res/storage/storage-account/local-user/main.json index c5936241dd..68088b74d3 100644 --- a/avm/res/storage/storage-account/local-user/main.json +++ b/avm/res/storage/storage-account/local-user/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "14593329616022153178" + "version": "0.27.1.19265", + "templateHash": "1776027493778195392" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", @@ -101,12 +101,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "localUsers": { "type": "Microsoft.Storage/storageAccounts/localUsers", - "apiVersion": "2022-05-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", "properties": { "hasSharedKey": "[parameters('hasSharedKey')]", diff --git a/avm/res/storage/storage-account/main.bicep b/avm/res/storage/storage-account/main.bicep index 58ba1d817e..d17193cf6d 100644 --- a/avm/res/storage/storage-account/main.bicep +++ b/avm/res/storage/storage-account/main.bicep @@ -68,11 +68,8 @@ param privateEndpoints privateEndpointType @description('Optional. The Storage Account ManagementPolicies Rules.') param managementPolicyRules array? -@description('Required. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny.') -param networkAcls networkAclsType = { - bypass: 'AzureServices' - defaultAction: 'Deny' -} +@description('Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny.') +param networkAcls networkAclsType? @description('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.') param requireInfrastructureEncryption bool = true @@ -176,6 +173,13 @@ param customerManagedKey customerManagedKeyType @description('Optional. The SAS expiration period. DD.HH:MM:SS.') param sasExpirationPeriod string = '' +@description('Optional. The keyType to use with Queue & Table services.') +@allowed([ + 'Account' + 'Service' +]) +param keyType string? + var supportsBlobService = kind == 'BlockBlobStorage' || kind == 'BlobStorage' || kind == 'StorageV2' || kind == 'Storage' var supportsFileService = kind == 'FileStorage' || kind == 'StorageV2' || kind == 'Storage' @@ -276,47 +280,43 @@ var builtInRoleNames = { ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = - if (enableTelemetry) { - name: '46d3xbcp.res.storage-storageaccount.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' - properties: { - mode: 'Incremental' - template: { - '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' - contentVersion: '1.0.0.0' - resources: [] - outputs: { - telemetry: { - type: 'String' - value: 'For more information, see https://aka.ms/avm/TelemetryInfo' - } +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.storage-storageaccount.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' } } } } +} -resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = - if (!empty(customerManagedKey.?keyVaultResourceId)) { - name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) - scope: resourceGroup( - split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], - split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4] - ) +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId)) { + name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup( + split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], + split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4] + ) - resource cMKKey 'keys@2023-02-01' existing = - if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { - name: customerManagedKey.?keyName ?? 'dummyKey' - } + resource cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { + name: customerManagedKey.?keyName ?? 'dummyKey' } +} -resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = - if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { - name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) - scope: resourceGroup( - split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], - split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4] - ) - } +resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup( + split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], + split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4] + ) +} resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { name: name @@ -354,9 +354,11 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { : null table: { enabled: true + keyType: keyType } queue: { enabled: true + keyType: keyType } } keyvaultproperties: !empty(customerManagedKey) @@ -397,11 +399,15 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { ? { resourceAccessRules: networkAcls.?resourceAccessRules bypass: networkAcls.?bypass - defaultAction: networkAcls.?defaultAction + defaultAction: networkAcls.?defaultAction ?? 'Deny' virtualNetworkRules: networkAcls.?virtualNetworkRules ipRules: networkAcls.?ipRules } - : null + : { + // New default case that enables the firewall by default + bypass: 'AzureServices' + defaultAction: 'Deny' + } allowBlobPublicAccess: allowBlobPublicAccess publicNetworkAccess: !empty(publicNetworkAccess) ? any(publicNetworkAccess) @@ -434,17 +440,16 @@ resource storageAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSetting } ] -resource storageAccount_lock 'Microsoft.Authorization/locks@2020-05-01' = - if (!empty(lock ?? {}) && lock.?kind != 'None') { - name: lock.?name ?? 'lock-${name}' - properties: { - level: lock.?kind ?? '' - notes: lock.?kind == 'CanNotDelete' - ? 'Cannot delete resource or child resources.' - : 'Cannot delete or modify the resource or child resources.' - } - scope: storageAccount +resource storageAccount_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' + ? 'Cannot delete resource or child resources.' + : 'Cannot delete or modify the resource or child resources.' } + scope: storageAccount +} resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ for (roleAssignment, index) in (roleAssignments ?? []): { @@ -466,7 +471,7 @@ resource storageAccount_roleAssignments 'Microsoft.Authorization/roleAssignments } ] -module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ +module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-StorageAccount-PrivateEndpoint-${index}' params: { @@ -519,17 +524,16 @@ module storageAccount_privateEndpoints 'br/public:avm/res/network/private-endpoi ] // Lifecycle Policy -module storageAccount_managementPolicies 'management-policy/main.bicep' = - if (!empty(managementPolicyRules ?? [])) { - name: '${uniqueString(deployment().name, location)}-Storage-ManagementPolicies' - params: { - storageAccountName: storageAccount.name - rules: managementPolicyRules ?? [] - } - dependsOn: [ - storageAccount_blobServices // To ensure the lastAccessTimeTrackingPolicy is set first (if used in rule) - ] +module storageAccount_managementPolicies 'management-policy/main.bicep' = if (!empty(managementPolicyRules ?? [])) { + name: '${uniqueString(deployment().name, location)}-Storage-ManagementPolicies' + params: { + storageAccountName: storageAccount.name + rules: managementPolicyRules ?? [] } + dependsOn: [ + storageAccount_blobServices // To ensure the lastAccessTimeTrackingPolicy is set first (if used in rule) + ] +} // SFTP user settings module storageAccount_localUsers 'local-user/main.bicep' = [ @@ -549,65 +553,61 @@ module storageAccount_localUsers 'local-user/main.bicep' = [ ] // Containers -module storageAccount_blobServices 'blob-service/main.bicep' = - if (!empty(blobServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-BlobServices' - params: { - storageAccountName: storageAccount.name - containers: blobServices.?containers - automaticSnapshotPolicyEnabled: blobServices.?automaticSnapshotPolicyEnabled - changeFeedEnabled: blobServices.?changeFeedEnabled - changeFeedRetentionInDays: blobServices.?changeFeedRetentionInDays - containerDeleteRetentionPolicyEnabled: blobServices.?containerDeleteRetentionPolicyEnabled - containerDeleteRetentionPolicyDays: blobServices.?containerDeleteRetentionPolicyDays - containerDeleteRetentionPolicyAllowPermanentDelete: blobServices.?containerDeleteRetentionPolicyAllowPermanentDelete - corsRules: blobServices.?corsRules - defaultServiceVersion: blobServices.?defaultServiceVersion - deleteRetentionPolicyAllowPermanentDelete: blobServices.?deleteRetentionPolicyAllowPermanentDelete - deleteRetentionPolicyEnabled: blobServices.?deleteRetentionPolicyEnabled - deleteRetentionPolicyDays: blobServices.?deleteRetentionPolicyDays - isVersioningEnabled: blobServices.?isVersioningEnabled - lastAccessTimeTrackingPolicyEnabled: blobServices.?lastAccessTimeTrackingPolicyEnabled - restorePolicyEnabled: blobServices.?restorePolicyEnabled - restorePolicyDays: blobServices.?restorePolicyDays - diagnosticSettings: blobServices.?diagnosticSettings - } +module storageAccount_blobServices 'blob-service/main.bicep' = if (!empty(blobServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-BlobServices' + params: { + storageAccountName: storageAccount.name + containers: blobServices.?containers + automaticSnapshotPolicyEnabled: blobServices.?automaticSnapshotPolicyEnabled + changeFeedEnabled: blobServices.?changeFeedEnabled + changeFeedRetentionInDays: blobServices.?changeFeedRetentionInDays + containerDeleteRetentionPolicyEnabled: blobServices.?containerDeleteRetentionPolicyEnabled + containerDeleteRetentionPolicyDays: blobServices.?containerDeleteRetentionPolicyDays + containerDeleteRetentionPolicyAllowPermanentDelete: blobServices.?containerDeleteRetentionPolicyAllowPermanentDelete + corsRules: blobServices.?corsRules + defaultServiceVersion: blobServices.?defaultServiceVersion + deleteRetentionPolicyAllowPermanentDelete: blobServices.?deleteRetentionPolicyAllowPermanentDelete + deleteRetentionPolicyEnabled: blobServices.?deleteRetentionPolicyEnabled + deleteRetentionPolicyDays: blobServices.?deleteRetentionPolicyDays + isVersioningEnabled: blobServices.?isVersioningEnabled + lastAccessTimeTrackingPolicyEnabled: blobServices.?lastAccessTimeTrackingPolicyEnabled + restorePolicyEnabled: blobServices.?restorePolicyEnabled + restorePolicyDays: blobServices.?restorePolicyDays + diagnosticSettings: blobServices.?diagnosticSettings } +} // File Shares -module storageAccount_fileServices 'file-service/main.bicep' = - if (!empty(fileServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-FileServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: fileServices.?diagnosticSettings - protocolSettings: fileServices.?protocolSettings - shareDeleteRetentionPolicy: fileServices.?shareDeleteRetentionPolicy - shares: fileServices.?shares - } +module storageAccount_fileServices 'file-service/main.bicep' = if (!empty(fileServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-FileServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: fileServices.?diagnosticSettings + protocolSettings: fileServices.?protocolSettings + shareDeleteRetentionPolicy: fileServices.?shareDeleteRetentionPolicy + shares: fileServices.?shares } +} // Queue -module storageAccount_queueServices 'queue-service/main.bicep' = - if (!empty(queueServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-QueueServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: queueServices.?diagnosticSettings - queues: queueServices.?queues - } +module storageAccount_queueServices 'queue-service/main.bicep' = if (!empty(queueServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-QueueServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: queueServices.?diagnosticSettings + queues: queueServices.?queues } +} // Table -module storageAccount_tableServices 'table-service/main.bicep' = - if (!empty(tableServices)) { - name: '${uniqueString(deployment().name, location)}-Storage-TableServices' - params: { - storageAccountName: storageAccount.name - diagnosticSettings: tableServices.?diagnosticSettings - tables: tableServices.?tables - } +module storageAccount_tableServices 'table-service/main.bicep' = if (!empty(tableServices)) { + name: '${uniqueString(deployment().name, location)}-Storage-TableServices' + params: { + storageAccountName: storageAccount.name + diagnosticSettings: tableServices.?diagnosticSettings + tables: tableServices.?tables } +} @description('The resource ID of the deployed storage account.') output resourceId string = storageAccount.id @@ -682,7 +682,7 @@ type networkAclsType = { resourceId: string }[]? - @description('Required. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics.') + @description('Optional. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, "Logging, Metrics"), or None to bypass none of those traffics.') bypass: ( | 'None' | 'AzureServices' @@ -691,7 +691,7 @@ type networkAclsType = { | 'AzureServices, Logging' | 'AzureServices, Metrics' | 'AzureServices, Logging, Metrics' - | 'Logging, Metrics') + | 'Logging, Metrics')? @description('Optional. Sets the virtual network rules.') virtualNetworkRules: array? @@ -699,8 +699,8 @@ type networkAclsType = { @description('Optional. Sets the IP ACL rules.') ipRules: array? - @description('Required. Specifies the default action of allow or deny when no other rules match.') - defaultAction: ('Allow' | 'Deny') + @description('Optional. Specifies the default action of allow or deny when no other rules match.') + defaultAction: ('Allow' | 'Deny')? } type privateEndpointType = { diff --git a/avm/res/storage/storage-account/main.json b/avm/res/storage/storage-account/main.json index 91eb9c9f57..2e541bd98a 100644 --- a/avm/res/storage/storage-account/main.json +++ b/avm/res/storage/storage-account/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "8863225181818962940" + "version": "0.27.1.19265", + "templateHash": "8254230526893780963" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account.", @@ -166,8 +166,9 @@ "Metrics", "None" ], + "nullable": true, "metadata": { - "description": "Required. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, \"Logging, Metrics\"), or None to bypass none of those traffics." + "description": "Optional. Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Possible values are any combination of Logging,Metrics,AzureServices (For example, \"Logging, Metrics\"), or None to bypass none of those traffics." } }, "virtualNetworkRules": { @@ -190,8 +191,9 @@ "Allow", "Deny" ], + "nullable": true, "metadata": { - "description": "Required. Specifies the default action of allow or deny when no other rules match." + "description": "Optional. Specifies the default action of allow or deny when no other rules match." } } } @@ -615,12 +617,9 @@ }, "networkAcls": { "$ref": "#/definitions/networkAclsType", - "defaultValue": { - "bypass": "AzureServices", - "defaultAction": "Deny" - }, + "nullable": true, "metadata": { - "description": "Required. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." + "description": "Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. If in use, bypass needs to be supplied. For security reasons, it is recommended to set the DefaultAction Deny." } }, "requireInfrastructureEncryption": { @@ -814,6 +813,17 @@ "metadata": { "description": "Optional. The SAS expiration period. DD.HH:MM:SS." } + }, + "keyType": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Account", + "Service" + ], + "metadata": { + "description": "Optional. The keyType to use with Queue & Table services." + } } }, "variables": { @@ -919,7 +929,7 @@ }, "dnsEndpointType": "[if(not(empty(parameters('dnsEndpointType'))), parameters('dnsEndpointType'), null())]", "isLocalUserEnabled": "[parameters('isLocalUserEnabled')]", - "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true()), 'queue', createObject('enabled', true())), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", + "encryption": "[union(createObject('keySource', if(not(empty(parameters('customerManagedKey'))), 'Microsoft.Keyvault', 'Microsoft.Storage'), 'services', createObject('blob', if(variables('supportsBlobService'), createObject('enabled', true()), null()), 'file', if(variables('supportsFileService'), createObject('enabled', true()), null()), 'table', createObject('enabled', true(), 'keyType', parameters('keyType')), 'queue', createObject('enabled', true(), 'keyType', parameters('keyType'))), 'keyvaultproperties', if(not(empty(parameters('customerManagedKey'))), createObject('keyname', parameters('customerManagedKey').keyName, 'keyvaulturi', reference('cMKKeyVault').vaultUri, 'keyversion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')))), null()), 'identity', createObject('userAssignedIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))), null()))), if(parameters('requireInfrastructureEncryption'), createObject('requireInfrastructureEncryption', if(not(equals(parameters('kind'), 'Storage')), parameters('requireInfrastructureEncryption'), null())), createObject()))]", "accessTier": "[if(and(not(equals(parameters('kind'), 'Storage')), not(equals(parameters('kind'), 'BlockBlobStorage'))), parameters('accessTier'), null())]", "sasPolicy": "[if(not(empty(parameters('sasExpirationPeriod'))), createObject('expirationAction', 'Log', 'sasExpirationPeriod', parameters('sasExpirationPeriod')), null())]", "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]", @@ -928,7 +938,7 @@ "isNfsV3Enabled": "[if(parameters('enableNfsV3'), parameters('enableNfsV3'), '')]", "largeFileSharesState": "[if(or(equals(parameters('skuName'), 'Standard_LRS'), equals(parameters('skuName'), 'Standard_ZRS')), parameters('largeFileSharesState'), null())]", "minimumTlsVersion": "[parameters('minimumTlsVersion')]", - "networkAcls": "[if(not(empty(parameters('networkAcls'))), createObject('resourceAccessRules', tryGet(parameters('networkAcls'), 'resourceAccessRules'), 'bypass', tryGet(parameters('networkAcls'), 'bypass'), 'defaultAction', tryGet(parameters('networkAcls'), 'defaultAction'), 'virtualNetworkRules', tryGet(parameters('networkAcls'), 'virtualNetworkRules'), 'ipRules', tryGet(parameters('networkAcls'), 'ipRules')), null())]", + "networkAcls": "[if(not(empty(parameters('networkAcls'))), createObject('resourceAccessRules', tryGet(parameters('networkAcls'), 'resourceAccessRules'), 'bypass', tryGet(parameters('networkAcls'), 'bypass'), 'defaultAction', coalesce(tryGet(parameters('networkAcls'), 'defaultAction'), 'Deny'), 'virtualNetworkRules', tryGet(parameters('networkAcls'), 'virtualNetworkRules'), 'ipRules', tryGet(parameters('networkAcls'), 'ipRules')), createObject('bypass', 'AzureServices', 'defaultAction', 'Deny'))]", "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]", "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkAcls'))), 'Disabled', null()))]", "azureFilesIdentityBasedAuthentication": "[if(not(empty(parameters('azureFilesIdentityBasedAuthentication'))), parameters('azureFilesIdentityBasedAuthentication'), null())]" @@ -1069,8 +1079,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2592884001616184297" + "version": "0.25.53.49325", + "templateHash": "4120048060064073955" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", @@ -1435,7 +1445,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1540,8 +1550,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "9321937464667207030" + "version": "0.25.53.49325", + "templateHash": "11244630631275470040" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1691,8 +1701,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4153955640795225346" + "version": "0.27.1.19265", + "templateHash": "9379936754195214669" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", @@ -1801,8 +1811,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "14593329616022153178" + "version": "0.27.1.19265", + "templateHash": "1776027493778195392" }, "name": "Storage Account Local Users", "description": "This module deploys a Storage Account Local User, which is used for SFTP authentication.", @@ -1897,12 +1907,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "localUsers": { "type": "Microsoft.Storage/storageAccounts/localUsers", - "apiVersion": "2022-05-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", "properties": { "hasSharedKey": "[parameters('hasSharedKey')]", @@ -2019,8 +2029,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "7278814029590745003" + "version": "0.27.1.19265", + "templateHash": "14376792680036937652" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service.", @@ -2173,10 +2183,10 @@ "changeFeedRetentionInDays": { "type": "int", "nullable": true, - "minValue": 0, + "minValue": 1, "maxValue": 146000, "metadata": { - "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. A \"0\" value indicates an infinite retention of the change feed." + "description": "Optional. Indicates whether change feed event logging is enabled for the Blob service. Indicates the duration of changeFeed retention in days. If left blank, it indicates an infinite retention of the change feed." } }, "containerDeleteRetentionPolicyEnabled": { @@ -2417,8 +2427,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "3805384021483033369" + "version": "0.27.1.19265", + "templateHash": "7167285049910521671" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container.", @@ -2686,8 +2696,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12849754295459852309" + "version": "0.27.1.19265", + "templateHash": "7418870035820197377" }, "name": "Storage Account Blob Container Immutability Policies", "description": "This module deploys a Storage Account Blob Container Immutability Policy.", @@ -2865,8 +2875,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4306536926065797375" + "version": "0.27.1.19265", + "templateHash": "2249966746510096150" }, "name": "Storage Account File Share Services", "description": "This module deploys a Storage Account File Share Service.", @@ -3044,12 +3054,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "fileServices": { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('name'))]", "properties": { "protocolSettings": "[parameters('protocolSettings')]", @@ -3124,7 +3134,7 @@ "value": "[coalesce(parameters('shares'), createArray())[copyIndex()].name]" }, "accessTier": { - "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2021-09-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]" + "value": "[coalesce(tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'accessTier'), if(equals(reference('storageAccount', '2023-04-01', 'full').kind, 'FileStorage'), 'Premium', 'TransactionOptimized'))]" }, "enabledProtocols": { "value": "[tryGet(coalesce(parameters('shares'), createArray())[copyIndex()], 'enabledProtocols')]" @@ -3146,8 +3156,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "13618261904162439978" + "version": "0.27.1.19265", + "templateHash": "7785463723571874765" }, "name": "Storage Account File Shares", "description": "This module deploys a Storage Account File Share.", @@ -3296,7 +3306,7 @@ "storageAccount::fileService": { "existing": true, "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), parameters('fileServicesName'))]", "dependsOn": [ "storageAccount" @@ -3305,7 +3315,7 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "fileShare": { @@ -3346,8 +3356,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "6057169747302051267" + "version": "0.27.1.19265", + "templateHash": "8943543243348777065" } }, "parameters": { @@ -3615,8 +3625,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4494965320132257914" + "version": "0.27.1.19265", + "templateHash": "8505361210488414487" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service.", @@ -3773,12 +3783,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "queueServices": { "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", "properties": {}, "dependsOn": [ @@ -3860,8 +3870,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "2870814699283520878" + "version": "0.27.1.19265", + "templateHash": "11111133794570176541" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", @@ -3984,7 +3994,7 @@ "storageAccount::queueServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -3993,12 +4003,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "queue": { "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "properties": { "metadata": "[parameters('metadata')]" @@ -4117,8 +4127,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "6806949296172999226" + "version": "0.27.1.19265", + "templateHash": "6164468877254681063" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service.", @@ -4275,12 +4285,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "tableServices": { "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", "properties": {}, "dependsOn": [ @@ -4359,8 +4369,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "5583637725561111612" + "version": "0.27.1.19265", + "templateHash": "10885620503239852206" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", @@ -4474,7 +4484,7 @@ "storageAccount::tableServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -4483,12 +4493,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "table": { "type": "Microsoft.Storage/storageAccounts/tableServices/tables", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "dependsOn": [ "storageAccount::tableServices" diff --git a/avm/res/storage/storage-account/management-policy/main.json b/avm/res/storage/storage-account/management-policy/main.json index d751651d08..e2dda43057 100644 --- a/avm/res/storage/storage-account/management-policy/main.json +++ b/avm/res/storage/storage-account/management-policy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4153955640795225346" + "version": "0.27.1.19265", + "templateHash": "9379936754195214669" }, "name": "Storage Account Management Policies", "description": "This module deploys a Storage Account Management Policy.", diff --git a/avm/res/storage/storage-account/queue-service/README.md b/avm/res/storage/storage-account/queue-service/README.md index 74a831bd19..eec41a0e4c 100644 --- a/avm/res/storage/storage-account/queue-service/README.md +++ b/avm/res/storage/storage-account/queue-service/README.md @@ -16,8 +16,8 @@ This module deploys a Storage Account Queue Service. | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Storage/storageAccounts/queueServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices) | -| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices/queues) | +| `Microsoft.Storage/storageAccounts/queueServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices) | +| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices/queues) | ## Parameters diff --git a/avm/res/storage/storage-account/queue-service/main.bicep b/avm/res/storage/storage-account/queue-service/main.bicep index 046bbd45f3..8bb3d4f8f2 100644 --- a/avm/res/storage/storage-account/queue-service/main.bicep +++ b/avm/res/storage/storage-account/queue-service/main.bicep @@ -15,48 +15,56 @@ param diagnosticSettings diagnosticSettingType // The name of the blob services var name = 'default' -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName } -resource queueServices 'Microsoft.Storage/storageAccounts/queueServices@2021-09-01' = { +resource queueServices 'Microsoft.Storage/storageAccounts/queueServices@2023-04-01' = { name: name parent: storageAccount properties: {} } -resource queueServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { - name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' - properties: { - storageAccountId: diagnosticSetting.?storageAccountResourceId - workspaceId: diagnosticSetting.?workspaceResourceId - eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId - eventHubName: diagnosticSetting.?eventHubName - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { - categoryGroup: group.?categoryGroup - category: group.?category - enabled: group.?enabled ?? true - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource queueServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [ + for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + logs: [ + for group in (diagnosticSetting.?logCategoriesAndGroups ?? [{ categoryGroup: 'allLogs' }]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: queueServices } - scope: queueServices -}] - -module queueServices_queues 'queue/main.bicep' = [for (queue, index) in (queues ?? []): { - name: '${deployment().name}-Queue-${index}' - params: { - storageAccountName: storageAccount.name - name: queue.name - metadata: queue.?metadata - roleAssignments: queue.?roleAssignments +] + +module queueServices_queues 'queue/main.bicep' = [ + for (queue, index) in (queues ?? []): { + name: '${deployment().name}-Queue-${index}' + params: { + storageAccountName: storageAccount.name + name: queue.name + metadata: queue.?metadata + roleAssignments: queue.?roleAssignments + } } -}] +] @description('The name of the deployed file share service.') output name string = queueServices.name diff --git a/avm/res/storage/storage-account/queue-service/main.json b/avm/res/storage/storage-account/queue-service/main.json index b1ddfd7258..a605a234ac 100644 --- a/avm/res/storage/storage-account/queue-service/main.json +++ b/avm/res/storage/storage-account/queue-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4494965320132257914" + "version": "0.27.1.19265", + "templateHash": "8505361210488414487" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service.", @@ -163,12 +163,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "queueServices": { "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", "properties": {}, "dependsOn": [ @@ -250,8 +250,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "2870814699283520878" + "version": "0.27.1.19265", + "templateHash": "11111133794570176541" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", @@ -374,7 +374,7 @@ "storageAccount::queueServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -383,12 +383,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "queue": { "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "properties": { "metadata": "[parameters('metadata')]" diff --git a/avm/res/storage/storage-account/queue-service/queue/README.md b/avm/res/storage/storage-account/queue-service/queue/README.md index 7e393ed284..760a6f70a4 100644 --- a/avm/res/storage/storage-account/queue-service/queue/README.md +++ b/avm/res/storage/storage-account/queue-service/queue/README.md @@ -15,7 +15,7 @@ This module deploys a Storage Account Queue. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/queueServices/queues) | +| `Microsoft.Storage/storageAccounts/queueServices/queues` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/queueServices/queues) | ## Parameters diff --git a/avm/res/storage/storage-account/queue-service/queue/main.bicep b/avm/res/storage/storage-account/queue-service/queue/main.bicep index 73a0decb98..9b1aba392c 100644 --- a/avm/res/storage/storage-account/queue-service/queue/main.bicep +++ b/avm/res/storage/storage-account/queue-service/queue/main.bicep @@ -19,27 +19,57 @@ var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Reader and Data Access': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Storage Account Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1') - 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') - 'Storage Account Key Operator Service Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12') - 'Storage Queue Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88') - 'Storage Queue Data Message Processor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed') - 'Storage Queue Data Message Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a') - 'Storage Queue Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Reader and Data Access': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c12c1c16-33a1-487b-954d-41c89c60f349' + ) + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Storage Account Backup Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1' + ) + 'Storage Account Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '17d1049b-9a84-46fb-8f53-869881c3d3ab' + ) + 'Storage Account Key Operator Service Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '81a9662b-bebf-436f-a333-f67b29880f12' + ) + 'Storage Queue Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '974c5e8b-45b9-4653-ba55-5f855dd0fb88' + ) + 'Storage Queue Data Message Processor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8a0f0c08-91a1-4084-bc3d-661d67233fed' + ) + 'Storage Queue Data Message Sender': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a' + ) + 'Storage Queue Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '19e7f393-937e-4f77-808e-94535e297925' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName - resource queueServices 'queueServices@2021-09-01' existing = { + resource queueServices 'queueServices@2023-04-01' existing = { name: 'default' } } -resource queue 'Microsoft.Storage/storageAccounts/queueServices/queues@2021-09-01' = { +resource queue 'Microsoft.Storage/storageAccounts/queueServices/queues@2023-04-01' = { name: name parent: storageAccount::queueServices properties: { @@ -47,19 +77,25 @@ resource queue 'Microsoft.Storage/storageAccounts/queueServices/queues@2021-09-0 } } -resource queue_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(queue.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) - properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) - principalId: roleAssignment.principalId - description: roleAssignment.?description - principalType: roleAssignment.?principalType - condition: roleAssignment.?condition - conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set - delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId +resource queue_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(queue.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) + ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] + : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') + ? roleAssignment.roleDefinitionIdOrName + : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: queue } - scope: queue -}] +] @description('The name of the deployed queue.') output name string = queue.name diff --git a/avm/res/storage/storage-account/queue-service/queue/main.json b/avm/res/storage/storage-account/queue-service/queue/main.json index 7463266ec4..751b9fdd67 100644 --- a/avm/res/storage/storage-account/queue-service/queue/main.json +++ b/avm/res/storage/storage-account/queue-service/queue/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "2870814699283520878" + "version": "0.27.1.19265", + "templateHash": "11111133794570176541" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue.", @@ -129,7 +129,7 @@ "storageAccount::queueServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/queueServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -138,12 +138,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "queue": { "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "properties": { "metadata": "[parameters('metadata')]" diff --git a/avm/res/storage/storage-account/table-service/README.md b/avm/res/storage/storage-account/table-service/README.md index 2d118753cb..b7c9ae7c1c 100644 --- a/avm/res/storage/storage-account/table-service/README.md +++ b/avm/res/storage/storage-account/table-service/README.md @@ -16,8 +16,8 @@ This module deploys a Storage Account Table Service. | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Storage/storageAccounts/tableServices` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices) | -| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices/tables) | +| `Microsoft.Storage/storageAccounts/tableServices` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices) | +| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices/tables) | ## Parameters diff --git a/avm/res/storage/storage-account/table-service/main.bicep b/avm/res/storage/storage-account/table-service/main.bicep index 0ff60b095b..061dbb9ca0 100644 --- a/avm/res/storage/storage-account/table-service/main.bicep +++ b/avm/res/storage/storage-account/table-service/main.bicep @@ -15,47 +15,55 @@ param diagnosticSettings diagnosticSettingType // The name of the table service var name = 'default' -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName } -resource tableServices 'Microsoft.Storage/storageAccounts/tableServices@2021-09-01' = { +resource tableServices 'Microsoft.Storage/storageAccounts/tableServices@2023-04-01' = { name: name parent: storageAccount properties: {} } -resource tableServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { - name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' - properties: { - storageAccountId: diagnosticSetting.?storageAccountResourceId - workspaceId: diagnosticSetting.?workspaceResourceId - eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId - eventHubName: diagnosticSetting.?eventHubName - metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { - category: group.category - enabled: group.?enabled ?? true - timeGrain: null - }] - logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { - categoryGroup: group.?categoryGroup - category: group.?category - enabled: group.?enabled ?? true - }] - marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId - logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType +resource tableServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [ + for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: [ + for group in (diagnosticSetting.?metricCategories ?? [{ category: 'AllMetrics' }]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + } + ] + logs: [ + for group in (diagnosticSetting.?logCategoriesAndGroups ?? [{ categoryGroup: 'allLogs' }]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: tableServices } - scope: tableServices -}] - -module tableServices_tables 'table/main.bicep' = [for (table, index) in tables: { - name: '${deployment().name}-Table-${index}' - params: { - name: table.name - storageAccountName: storageAccount.name - roleAssignments: table.?roleAssignments +] + +module tableServices_tables 'table/main.bicep' = [ + for (table, index) in tables: { + name: '${deployment().name}-Table-${index}' + params: { + name: table.name + storageAccountName: storageAccount.name + roleAssignments: table.?roleAssignments + } } -}] +] @description('The name of the deployed table service.') output name string = tableServices.name diff --git a/avm/res/storage/storage-account/table-service/main.json b/avm/res/storage/storage-account/table-service/main.json index cd4f72dbef..98e3d5924b 100644 --- a/avm/res/storage/storage-account/table-service/main.json +++ b/avm/res/storage/storage-account/table-service/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "6806949296172999226" + "version": "0.27.1.19265", + "templateHash": "6164468877254681063" }, "name": "Storage Account Table Services", "description": "This module deploys a Storage Account Table Service.", @@ -163,12 +163,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "tableServices": { "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), variables('name'))]", "properties": {}, "dependsOn": [ @@ -247,8 +247,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "5583637725561111612" + "version": "0.27.1.19265", + "templateHash": "10885620503239852206" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", @@ -362,7 +362,7 @@ "storageAccount::tableServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -371,12 +371,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "table": { "type": "Microsoft.Storage/storageAccounts/tableServices/tables", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "dependsOn": [ "storageAccount::tableServices" diff --git a/avm/res/storage/storage-account/table-service/table/README.md b/avm/res/storage/storage-account/table-service/table/README.md index 16945292b2..d3b39dff00 100644 --- a/avm/res/storage/storage-account/table-service/table/README.md +++ b/avm/res/storage/storage-account/table-service/table/README.md @@ -15,7 +15,7 @@ This module deploys a Storage Account Table. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2021-09-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-09-01/storageAccounts/tableServices/tables) | +| `Microsoft.Storage/storageAccounts/tableServices/tables` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts/tableServices/tables) | ## Parameters diff --git a/avm/res/storage/storage-account/table-service/table/main.bicep b/avm/res/storage/storage-account/table-service/table/main.bicep index a413238f5c..6553a048a3 100644 --- a/avm/res/storage/storage-account/table-service/table/main.bicep +++ b/avm/res/storage/storage-account/table-service/table/main.bicep @@ -16,42 +16,72 @@ var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Reader and Data Access': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Storage Account Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1') - 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') - 'Storage Account Key Operator Service Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12') - 'Storage Table Data Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3') - 'Storage Table Data Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Reader and Data Access': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'c12c1c16-33a1-487b-954d-41c89c60f349' + ) + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'Storage Account Backup Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1' + ) + 'Storage Account Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '17d1049b-9a84-46fb-8f53-869881c3d3ab' + ) + 'Storage Account Key Operator Service Role': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '81a9662b-bebf-436f-a333-f67b29880f12' + ) + 'Storage Table Data Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3' + ) + 'Storage Table Data Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '76199698-9eea-4c19-bc75-cec21354c6b6' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) } -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { +resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = { name: storageAccountName - resource tableServices 'tableServices@2021-09-01' existing = { + resource tableServices 'tableServices@2023-04-01' existing = { name: 'default' } } -resource table 'Microsoft.Storage/storageAccounts/tableServices/tables@2021-09-01' = { +resource table 'Microsoft.Storage/storageAccounts/tableServices/tables@2023-04-01' = { name: name parent: storageAccount::tableServices } -resource table_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(table.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) - properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) - principalId: roleAssignment.principalId - description: roleAssignment.?description - principalType: roleAssignment.?principalType - condition: roleAssignment.?condition - conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set - delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId +resource table_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(table.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) + ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] + : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') + ? roleAssignment.roleDefinitionIdOrName + : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: table } - scope: table -}] +] @description('The name of the deployed file share service.') output name string = table.name diff --git a/avm/res/storage/storage-account/table-service/table/main.json b/avm/res/storage/storage-account/table-service/table/main.json index 0abcc4d463..894889268d 100644 --- a/avm/res/storage/storage-account/table-service/table/main.json +++ b/avm/res/storage/storage-account/table-service/table/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "5583637725561111612" + "version": "0.27.1.19265", + "templateHash": "10885620503239852206" }, "name": "Storage Account Table", "description": "This module deploys a Storage Account Table.", @@ -120,7 +120,7 @@ "storageAccount::tableServices": { "existing": true, "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', parameters('storageAccountName'), 'default')]", "dependsOn": [ "storageAccount" @@ -129,12 +129,12 @@ "storageAccount": { "existing": true, "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[parameters('storageAccountName')]" }, "table": { "type": "Microsoft.Storage/storageAccounts/tableServices/tables", - "apiVersion": "2021-09-01", + "apiVersion": "2023-04-01", "name": "[format('{0}/{1}/{2}', parameters('storageAccountName'), 'default', parameters('name'))]", "dependsOn": [ "storageAccount::tableServices" diff --git a/avm/res/storage/storage-account/tests/e2e/changefeed/main.test.bicep b/avm/res/storage/storage-account/tests/e2e/changefeed/main.test.bicep new file mode 100644 index 0000000000..d4ab99d73a --- /dev/null +++ b/avm/res/storage/storage-account/tests/e2e/changefeed/main.test.bicep @@ -0,0 +1,52 @@ +targetScope = 'subscription' + +metadata name = 'Using only changefeed configuration' +metadata description = 'This instance deploys the module with the minimum set of required parameters for the changefeed configuration.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-storage.storageaccounts-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'ssachf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + allowBlobPublicAccess: false + location: resourceLocation + blobServices: { + changeFeedEnabled: true + } + } + } +] diff --git a/avm/res/storage/storage-account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/storage/storage-account/tests/e2e/waf-aligned/main.test.bicep index 0fdbb91dff..e610d70df3 100644 --- a/avm/res/storage/storage-account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/storage/storage-account/tests/e2e/waf-aligned/main.test.bicep @@ -60,158 +60,194 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - location: resourceLocation - name: '${namePrefix}${serviceShort}001' - skuName: 'Standard_LRS' - allowBlobPublicAccess: false - requireInfrastructureEncryption: true - largeFileSharesState: 'Enabled' - enableHierarchicalNamespace: true - enableSftp: true - enableNfsV3: true - privateEndpoints: [ - { - service: 'blob' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - ] - networkAcls: { - bypass: 'AzureServices' - defaultAction: 'Deny' - virtualNetworkRules: [ - { - action: 'Allow' - id: nestedDependencies.outputs.subnetResourceId - } - ] - ipRules: [ +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + name: '${namePrefix}${serviceShort}001' + skuName: 'Standard_ZRS' + allowBlobPublicAccess: false + requireInfrastructureEncryption: true + largeFileSharesState: 'Enabled' + enableHierarchicalNamespace: true + enableSftp: true + enableNfsV3: true + privateEndpoints: [ { - action: 'Allow' - value: '1.1.1.1' + service: 'blob' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } ] - } - localUsers: [ - { - storageAccountName: '${namePrefix}${serviceShort}001' - name: 'testuser' - hasSharedKey: false - hasSshKey: true - hasSshPassword: false - homeDirectory: 'avdscripts' - permissionScopes: [ + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Deny' + virtualNetworkRules: [ { - permissions: 'r' - service: 'blob' - resourceName: 'avdscripts' + action: 'Allow' + id: nestedDependencies.outputs.subnetResourceId + } + ] + ipRules: [ + { + action: 'Allow' + value: '1.1.1.1' } ] } - ] - blobServices: { - lastAccessTimeTrackingPolicyEnabled: true - diagnosticSettings: [ + localUsers: [ { - name: 'customSetting' - metricCategories: [ + storageAccountName: '${namePrefix}${serviceShort}001' + name: 'testuser' + hasSharedKey: false + hasSshKey: true + hasSshPassword: false + homeDirectory: 'avdscripts' + permissionScopes: [ { - category: 'AllMetrics' + permissions: 'r' + service: 'blob' + resourceName: 'avdscripts' } ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - containers: [ - { - name: 'avdscripts' - enableNfsV3AllSquash: true - enableNfsV3RootSquash: true - publicAccess: 'None' - } - { - name: 'archivecontainer' - publicAccess: 'None' - metadata: { - testKey: 'testValue' + blobServices: { + lastAccessTimeTrackingPolicyEnabled: true + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } - enableWORM: true - WORMRetention: 666 - allowProtectedAppendWrites: false - } - ] - automaticSnapshotPolicyEnabled: true - containerDeleteRetentionPolicyEnabled: true - containerDeleteRetentionPolicyDays: 10 - deleteRetentionPolicyEnabled: true - deleteRetentionPolicyDays: 9 - } - fileServices: { - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + ] + containers: [ + { + name: 'avdscripts' + enableNfsV3AllSquash: true + enableNfsV3RootSquash: true + publicAccess: 'None' + } + { + name: 'archivecontainer' + publicAccess: 'None' + metadata: { + testKey: 'testValue' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - shares: [ - { - name: 'avdprofiles' - accessTier: 'Hot' - shareQuota: 5120 - } - { - name: 'avdprofiles2' - shareQuota: 102400 - } - ] - } - tableServices: { - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' + enableWORM: true + WORMRetention: 666 + allowProtectedAppendWrites: false + } + ] + automaticSnapshotPolicyEnabled: true + containerDeleteRetentionPolicyEnabled: true + containerDeleteRetentionPolicyDays: 10 + deleteRetentionPolicyEnabled: true + deleteRetentionPolicyDays: 9 + } + fileServices: { + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + shares: [ + { + name: 'avdprofiles' + accessTier: 'Hot' + shareQuota: 5120 + } + { + name: 'avdprofiles2' + shareQuota: 102400 + } + ] + } + tableServices: { + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + tables: [ + { + name: 'table1' + } + { + name: 'table2' + } + ] + } + queueServices: { + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + queues: [ + { + name: 'queue1' + metadata: { + key1: 'value1' + key2: 'value2' } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - tables: [ - { - name: 'table1' - } - { - name: 'table2' - } - ] - } - queueServices: { + } + { + name: 'queue2' + metadata: {} + } + ] + } + sasExpirationPeriod: '180.00:00:00' + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } diagnosticSettings: [ { name: 'customSetting' @@ -226,83 +262,49 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - queues: [ - { - name: 'queue1' - metadata: { - key1: 'value1' - key2: 'value2' - } - } + managementPolicyRules: [ { - name: 'queue2' - metadata: {} - } - ] - } - sasExpirationPeriod: '180.00:00:00' - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - managementPolicyRules: [ - { - enabled: true - name: 'FirstRule' - type: 'Lifecycle' - definition: { - actions: { - baseBlob: { - delete: { - daysAfterModificationGreaterThan: 30 - } - tierToCool: { - daysAfterLastAccessTimeGreaterThan: 5 + enabled: true + name: 'FirstRule' + type: 'Lifecycle' + definition: { + actions: { + baseBlob: { + delete: { + daysAfterModificationGreaterThan: 30 + } + tierToCool: { + daysAfterLastAccessTimeGreaterThan: 5 + } } } - } - filters: { - blobIndexMatch: [ - { - name: 'BlobIndex' - op: '==' - value: '1' - } - ] - blobTypes: [ - 'blockBlob' - ] - prefixMatch: [ - 'sample-container/log' - ] + filters: { + blobIndexMatch: [ + { + name: 'BlobIndex' + op: '==' + value: '1' + } + ] + blobTypes: [ + 'blockBlob' + ] + prefixMatch: [ + 'sample-container/log' + ] + } } } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/storage/storage-account/version.json b/avm/res/storage/storage-account/version.json index 0f81d22abc..20e1887127 100644 --- a/avm/res/storage/storage-account/version.json +++ b/avm/res/storage/storage-account/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.8", + "version": "0.9", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +}