From 8ad13c92a3ca3a6f8b61fd02a581c2eeebb618b5 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Mon, 27 Jan 2025 23:26:58 +0100 Subject: [PATCH] feat: NetApp - Restructured as per ResourceType structure to & to enable additional capabilities (#4043) ## Description - Restructured the deployment of backup to enable shared policies & future child-module publishing - Updated removal logic to handle backups - Introduced numerous UDTs - Aligned with several AVM specs (e.g., regarding naming) Depends on #4204 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.net-app.net-app-account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.net-app.net-app-account.yml/badge.svg?branch=users%2Falsehr%2FnetAppStructure&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.net-app.net-app-account.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting 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. - [ ] 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 --- avm/res/net-app/net-app-account/README.md | 1861 +++++- .../net-app-account/backup-policies/README.md | 77 +- .../backup-policies/main.bicep | 30 +- .../net-app-account/backup-policies/main.json | 40 +- .../net-app-account/backup-vault/README.md | 121 + .../backup-vault/backup/README.md | 97 + .../backup-vault/backup/main.bicep | 58 + .../backup-vault/backup/main.json | 120 + .../net-app-account/backup-vault/main.bicep | 75 + .../net-app-account/backup-vault/main.json | 296 + .../net-app-account/capacity-pool/README.md | 585 +- .../net-app-account/capacity-pool/main.bicep | 133 +- .../net-app-account/capacity-pool/main.json | 1663 +++--- .../capacity-pool/volume/README.md | 436 +- .../capacity-pool/volume/main.bicep | 425 +- .../capacity-pool/volume/main.json | 1043 ++-- avm/res/net-app/net-app-account/main.bicep | 185 +- avm/res/net-app/net-app-account/main.json | 4995 ++++++++++++----- .../snapshot-policies/README.md | 262 +- .../snapshot-policies/main.bicep | 191 +- .../snapshot-policies/main.json | 335 +- .../tests/e2e/max/main.test.bicep | 106 +- .../tests/e2e/nfs3/main.test.bicep | 35 +- avm/res/net-app/net-app-account/version.json | 4 +- 24 files changed, 8989 insertions(+), 4184 deletions(-) create mode 100644 avm/res/net-app/net-app-account/backup-vault/README.md create mode 100644 avm/res/net-app/net-app-account/backup-vault/backup/README.md create mode 100644 avm/res/net-app/net-app-account/backup-vault/backup/main.bicep create mode 100644 avm/res/net-app/net-app-account/backup-vault/backup/main.json create mode 100644 avm/res/net-app/net-app-account/backup-vault/main.bicep create mode 100644 avm/res/net-app/net-app-account/backup-vault/main.json diff --git a/avm/res/net-app/net-app-account/README.md b/avm/res/net-app/net-app-account/README.md index 4dd635b8c4..ced70ad857 100644 --- a/avm/res/net-app/net-app-account/README.md +++ b/avm/res/net-app/net-app-account/README.md @@ -118,9 +118,25 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { // Required parameters name: 'nanaamax001' // Non-required parameters + backupPolicies: [ + { + name: 'myBackupPolicy' + } + ] + backupVault: { + backups: [ + { + capacityPoolName: 'cp-001' + label: 'myLabel' + name: 'myBackup01' + volumeName: 'vol-001' + } + ] + name: 'myVault' + } capacityPools: [ { - name: 'nanaamax-cp-001' + name: 'cp-001' roleAssignments: [ { principalId: '' @@ -132,18 +148,36 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { size: 4398046511104 volumes: [ { - encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true + dataProtection: { + backup: { + backupPolicyName: 'myBackupPolicy' + backupVaultName: 'myVault' + policyEnforced: false } - ] - name: 'nanaamax-vol-001' + snapshot: { + snapshotPolicyName: 'mySnapshotPolicy' + } + } + encryptionKeySource: '' + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + } + ] + } + name: 'vol-001' networkFeatures: 'Standard' protocolTypes: [ 'NFSv4.1' @@ -158,22 +192,31 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } { encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] - name: 'nanaamax-vol-002' + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: false + } + ] + } + kerberosEnabled: false + name: 'vol-002' networkFeatures: 'Standard' protocolTypes: [ 'NFSv4.1' @@ -184,13 +227,13 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } ] } { - name: 'nanaamax-cp-002' + name: 'cp-002' roleAssignments: [ { principalId: '' @@ -228,6 +271,16 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { roleDefinitionIdOrName: '' } ] + snapshotPolicies: [ + { + dailySchedule: { + hour: 0 + minute: 0 + snapshotsToKeep: 1 + } + name: 'mySnapshotPolicy' + } + ] tags: { Contact: 'test.user@testcompany.com' CostCenter: '7890' @@ -258,10 +311,30 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "value": "nanaamax001" }, // Non-required parameters + "backupPolicies": { + "value": [ + { + "name": "myBackupPolicy" + } + ] + }, + "backupVault": { + "value": { + "backups": [ + { + "capacityPoolName": "cp-001", + "label": "myLabel", + "name": "myBackup01", + "volumeName": "vol-001" + } + ], + "name": "myVault" + } + }, "capacityPools": { "value": [ { - "name": "nanaamax-cp-001", + "name": "cp-001", "roleAssignments": [ { "principalId": "", @@ -273,18 +346,36 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "size": 4398046511104, "volumes": [ { - "encryptionKeySource": "", - "exportPolicyRules": [ - { - "allowedClients": "0.0.0.0/0", - "nfsv3": false, - "nfsv41": true, - "ruleIndex": 1, - "unixReadOnly": false, - "unixReadWrite": true + "dataProtection": { + "backup": { + "backupPolicyName": "myBackupPolicy", + "backupVaultName": "myVault", + "policyEnforced": false + }, + "snapshot": { + "snapshotPolicyName": "mySnapshotPolicy" } - ], - "name": "nanaamax-vol-001", + }, + "encryptionKeySource": "", + "exportPolicy": { + "rules": [ + { + "allowedClients": "0.0.0.0/0", + "kerberos5iReadOnly": false, + "kerberos5iReadWrite": false, + "kerberos5pReadOnly": false, + "kerberos5pReadWrite": false, + "kerberos5ReadOnly": false, + "kerberos5ReadWrite": false, + "nfsv3": false, + "nfsv41": true, + "ruleIndex": 1, + "unixReadOnly": false, + "unixReadWrite": true + } + ] + }, + "name": "vol-001", "networkFeatures": "Standard", "protocolTypes": [ "NFSv4.1" @@ -299,22 +390,31 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "subnetResourceId": "", "usageThreshold": 107374182400, "zones": [ - "1" + 1 ] }, { "encryptionKeySource": "", - "exportPolicyRules": [ - { - "allowedClients": "0.0.0.0/0", - "nfsv3": false, - "nfsv41": true, - "ruleIndex": 1, - "unixReadOnly": false, - "unixReadWrite": true - } - ], - "name": "nanaamax-vol-002", + "exportPolicy": { + "rules": [ + { + "allowedClients": "0.0.0.0/0", + "kerberos5iReadOnly": false, + "kerberos5iReadWrite": false, + "kerberos5pReadOnly": false, + "kerberos5pReadWrite": false, + "kerberos5ReadOnly": false, + "kerberos5ReadWrite": false, + "nfsv3": false, + "nfsv41": true, + "ruleIndex": 1, + "unixReadOnly": false, + "unixReadWrite": false + } + ] + }, + "kerberosEnabled": false, + "name": "vol-002", "networkFeatures": "Standard", "protocolTypes": [ "NFSv4.1" @@ -325,13 +425,13 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "subnetResourceId": "", "usageThreshold": 107374182400, "zones": [ - "1" + 1 ] } ] }, { - "name": "nanaamax-cp-002", + "name": "cp-002", "roleAssignments": [ { "principalId": "", @@ -376,6 +476,18 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { } ] }, + "snapshotPolicies": { + "value": [ + { + "dailySchedule": { + "hour": 0, + "minute": 0, + "snapshotsToKeep": 1 + }, + "name": "mySnapshotPolicy" + } + ] + }, "tags": { "value": { "Contact": "test.user@testcompany.com", @@ -404,9 +516,25 @@ using 'br/public:avm/res/net-app/net-app-account:' // Required parameters param name = 'nanaamax001' // Non-required parameters +param backupPolicies = [ + { + name: 'myBackupPolicy' + } +] +param backupVault = { + backups: [ + { + capacityPoolName: 'cp-001' + label: 'myLabel' + name: 'myBackup01' + volumeName: 'vol-001' + } + ] + name: 'myVault' +} param capacityPools = [ { - name: 'nanaamax-cp-001' + name: 'cp-001' roleAssignments: [ { principalId: '' @@ -418,18 +546,36 @@ param capacityPools = [ size: 4398046511104 volumes: [ { - encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true + dataProtection: { + backup: { + backupPolicyName: 'myBackupPolicy' + backupVaultName: 'myVault' + policyEnforced: false } - ] - name: 'nanaamax-vol-001' + snapshot: { + snapshotPolicyName: 'mySnapshotPolicy' + } + } + encryptionKeySource: '' + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + } + ] + } + name: 'vol-001' networkFeatures: 'Standard' protocolTypes: [ 'NFSv4.1' @@ -444,22 +590,31 @@ param capacityPools = [ subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } { encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] - name: 'nanaamax-vol-002' + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: false + } + ] + } + kerberosEnabled: false + name: 'vol-002' networkFeatures: 'Standard' protocolTypes: [ 'NFSv4.1' @@ -470,13 +625,13 @@ param capacityPools = [ subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } ] } { - name: 'nanaamax-cp-002' + name: 'cp-002' roleAssignments: [ { principalId: '' @@ -514,6 +669,16 @@ param roleAssignments = [ roleDefinitionIdOrName: '' } ] +param snapshotPolicies = [ + { + dailySchedule: { + hour: 0 + minute: 0 + snapshotsToKeep: 1 + } + name: 'mySnapshotPolicy' + } +] param tags = { Contact: 'test.user@testcompany.com' CostCenter: '7890' @@ -559,16 +724,24 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { volumes: [ { encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: true - nfsv41: false - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: true + nfsv41: false + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + } + ] + } name: 'nanaanfs3-vol-001' networkFeatures: 'Standard' protocolTypes: [ @@ -584,7 +757,7 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } { @@ -597,7 +770,7 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } ] @@ -684,16 +857,24 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "volumes": [ { "encryptionKeySource": "", - "exportPolicyRules": [ - { - "allowedClients": "0.0.0.0/0", - "nfsv3": true, - "nfsv41": false, - "ruleIndex": 1, - "unixReadOnly": false, - "unixReadWrite": true - } - ], + "exportPolicy": { + "rules": [ + { + "allowedClients": "0.0.0.0/0", + "kerberos5iReadOnly": false, + "kerberos5iReadWrite": false, + "kerberos5pReadOnly": false, + "kerberos5pReadWrite": false, + "kerberos5ReadOnly": false, + "kerberos5ReadWrite": false, + "nfsv3": true, + "nfsv41": false, + "ruleIndex": 1, + "unixReadOnly": false, + "unixReadWrite": true + } + ] + }, "name": "nanaanfs3-vol-001", "networkFeatures": "Standard", "protocolTypes": [ @@ -709,7 +890,7 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "subnetResourceId": "", "usageThreshold": 107374182400, "zones": [ - "1" + 1 ] }, { @@ -722,7 +903,7 @@ module netAppAccount 'br/public:avm/res/net-app/net-app-account:' = { "subnetResourceId": "", "usageThreshold": 107374182400, "zones": [ - "1" + 1 ] } ] @@ -813,16 +994,24 @@ param capacityPools = [ volumes: [ { encryptionKeySource: '' - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: true - nfsv41: false - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + nfsv3: true + nfsv41: false + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + } + ] + } name: 'nanaanfs3-vol-001' networkFeatures: 'Standard' protocolTypes: [ @@ -838,7 +1027,7 @@ param capacityPools = [ subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } { @@ -851,7 +1040,7 @@ param capacityPools = [ subnetResourceId: '' usageThreshold: 107374182400 zones: [ - '1' + 1 ] } ] @@ -995,6 +1184,8 @@ param tags = { | :-- | :-- | :-- | | [`adName`](#parameter-adname) | string | Name of the active directory host as part of Kerberos Realm used for Kerberos authentication. | | [`aesEncryption`](#parameter-aesencryption) | bool | Enable AES encryption on the SMB Server. | +| [`backupPolicies`](#parameter-backuppolicies) | array | The backup policies to create. | +| [`backupVault`](#parameter-backupvault) | object | The netapp backup vault to create & configure. | | [`capacityPools`](#parameter-capacitypools) | array | Capacity pools to create. | | [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | | [`dnsServers`](#parameter-dnsservers) | string | Required if domainName is specified. Comma separated list of DNS server IP addresses (IPv4 only) required for the Active Directory (AD) domain join and SMB authentication operations to succeed. | @@ -1013,6 +1204,7 @@ param tags = { | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`serverRootCACertificate`](#parameter-serverrootcacertificate) | string | A server Root certificate is required of ldapOverTLS is enabled. | | [`smbServerNamePrefix`](#parameter-smbservernameprefix) | string | Required if domainName is specified. NetBIOS name of the SMB server. A computer account with this prefix will be registered in the AD and used to mount volumes. | +| [`snapshotPolicies`](#parameter-snapshotpolicies) | array | The snapshot policies to create. | | [`tags`](#parameter-tags) | object | Tags for all resources. | ### Parameter: `name` @@ -1038,208 +1230,248 @@ Enable AES encryption on the SMB Server. - Type: bool - Default: `False` -### Parameter: `capacityPools` +### Parameter: `backupPolicies` -Capacity pools to create. +The backup policies to create. - Required: No - Type: array -- Default: `[]` - -### Parameter: `customerManagedKey` - -The customer managed key definition. - -- Required: No -- Type: object - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | -| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time. | -| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | +| [`dailyBackupsToKeep`](#parameter-backuppoliciesdailybackupstokeep) | int | The daily backups to keep. | +| [`enabled`](#parameter-backuppoliciesenabled) | bool | Indicates whether the backup policy is enabled. | +| [`location`](#parameter-backuppolicieslocation) | string | The location of the backup policy. | +| [`monthlyBackupsToKeep`](#parameter-backuppoliciesmonthlybackupstokeep) | int | The monthly backups to keep. | +| [`name`](#parameter-backuppoliciesname) | string | The name of the backup policy. | +| [`weeklyBackupsToKeep`](#parameter-backuppoliciesweeklybackupstokeep) | int | The weekly backups to keep. | -### Parameter: `customerManagedKey.keyName` +### Parameter: `backupPolicies.dailyBackupsToKeep` -The name of the customer managed key to use for encryption. +The daily backups to keep. -- Required: Yes -- Type: string +- Required: No +- Type: int +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `customerManagedKey.keyVaultResourceId` +### Parameter: `backupPolicies.enabled` -The resource ID of a key vault to reference a customer managed key for encryption from. +Indicates whether the backup policy is enabled. -- Required: Yes -- Type: string +- Required: No +- Type: bool +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `customerManagedKey.keyVersion` +### Parameter: `backupPolicies.location` -The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time. +The location of the backup policy. - Required: No - Type: string +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `customerManagedKey.userAssignedIdentityResourceId` +### Parameter: `backupPolicies.monthlyBackupsToKeep` -User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. +The monthly backups to keep. - Required: No -- Type: string +- Type: int +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `dnsServers` +### Parameter: `backupPolicies.name` -Required if domainName is specified. Comma separated list of DNS server IP addresses (IPv4 only) required for the Active Directory (AD) domain join and SMB authentication operations to succeed. +The name of the backup policy. - Required: No - Type: string -- Default: `''` +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `domainJoinOU` +### Parameter: `backupPolicies.weeklyBackupsToKeep` -Used only if domainName is specified. LDAP Path for the Organization Unit (OU) where SMB Server machine accounts will be created (i.e. 'OU=SecondLevel,OU=FirstLevel'). +The weekly backups to keep. - Required: No -- Type: string -- Default: `''` +- Type: int +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `domainJoinPassword` +### Parameter: `backupVault` -Required if domainName is specified. Password of the user specified in domainJoinUser parameter. +The netapp backup vault to create & configure. - Required: No -- Type: securestring -- Default: `''` +- Type: object -### Parameter: `domainJoinUser` +**Optional parameters** -Required if domainName is specified. Username of Active Directory domain administrator, with permissions to create SMB server machine account in the AD domain. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backups`](#parameter-backupvaultbackups) | array | The list of backups to create. | +| [`location`](#parameter-backupvaultlocation) | string | Location of the backup vault. | +| [`name`](#parameter-backupvaultname) | string | The name of the backup vault. | + +### Parameter: `backupVault.backups` + +The list of backups to create. - Required: No -- Type: string -- Default: `''` +- Type: array -### Parameter: `domainName` +**Required parameters** -Fully Qualified Active Directory DNS Domain Name (e.g. 'contoso.com'). +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacityPoolName`](#parameter-backupvaultbackupscapacitypoolname) | string | The name of the capacity pool containing the volume. | +| [`volumeName`](#parameter-backupvaultbackupsvolumename) | string | The name of the volume to backup. | -- Required: No +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`label`](#parameter-backupvaultbackupslabel) | string | Label for backup. | +| [`name`](#parameter-backupvaultbackupsname) | string | The name of the backup. | +| [`snapshotName`](#parameter-backupvaultbackupssnapshotname) | string | The name of the snapshot. | + +### Parameter: `backupVault.backups.capacityPoolName` + +The name of the capacity pool containing the volume. + +- Required: Yes - Type: string -- Default: `''` -### Parameter: `enableTelemetry` +### Parameter: `backupVault.backups.volumeName` -Enable/Disable usage telemetry for module. +The name of the volume to backup. -- Required: No -- Type: bool -- Default: `True` +- Required: Yes +- Type: string -### Parameter: `encryptDCConnections` +### Parameter: `backupVault.backups.label` -Specifies whether encryption should be used for communication between SMB server and domain controller (DC). SMB3 only. +Label for backup. - Required: No -- Type: bool -- Default: `False` +- Type: string -### Parameter: `kdcIP` +### Parameter: `backupVault.backups.name` -Kerberos Key Distribution Center (KDC) as part of Kerberos Realm used for Kerberos authentication. +The name of the backup. - Required: No - Type: string -- Default: `''` -### Parameter: `ldapOverTLS` +### Parameter: `backupVault.backups.snapshotName` -Specifies whether to use TLS when NFS (with/without Kerberos) and SMB volumes communicate with an LDAP server. A server root CA certificate must be uploaded if enabled (serverRootCACertificate). +The name of the snapshot. - Required: No -- Type: bool -- Default: `False` +- Type: string -### Parameter: `ldapSigning` +### Parameter: `backupVault.location` -Specifies whether or not the LDAP traffic needs to be signed. +Location of the backup vault. - Required: No -- Type: bool -- Default: `False` +- Type: string -### Parameter: `location` +### Parameter: `backupVault.name` -Location for all resources. +The name of the backup vault. - Required: No - Type: string -- Default: `[resourceGroup().location]` -### Parameter: `lock` +### Parameter: `capacityPools` -The lock settings of the service. +Capacity pools to create. - Required: No -- Type: object +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-capacitypoolsname) | string | The name of the capacity pool. | +| [`size`](#parameter-capacitypoolssize) | int | Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104). | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | -| [`name`](#parameter-lockname) | string | Specify the name of lock. | +| [`coolAccess`](#parameter-capacitypoolscoolaccess) | bool | If enabled (true) the pool can contain cool Access enabled volumes. | +| [`encryptionType`](#parameter-capacitypoolsencryptiontype) | string | Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool. | +| [`location`](#parameter-capacitypoolslocation) | string | Location of the pool volume. | +| [`qosType`](#parameter-capacitypoolsqostype) | string | The qos type of the pool. | +| [`roleAssignments`](#parameter-capacitypoolsroleassignments) | array | Array of role assignments to create. | +| [`serviceLevel`](#parameter-capacitypoolsservicelevel) | string | The pool service level. | +| [`tags`](#parameter-capacitypoolstags) | object | Tags for the capcity pool. | +| [`volumes`](#parameter-capacitypoolsvolumes) | array | List of volumes to create in the capacity pool. | -### Parameter: `lock.kind` +### Parameter: `capacityPools.name` -Specify the type of lock. +The name of the capacity pool. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.size` + +Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104). + +- Required: Yes +- Type: int + +### Parameter: `capacityPools.coolAccess` + +If enabled (true) the pool can contain cool Access enabled volumes. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.encryptionType` + +Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool. - Required: No - Type: string - Allowed: ```Bicep [ - 'CanNotDelete' - 'None' - 'ReadOnly' + 'Double' + 'Single' ] ``` -### Parameter: `lock.name` +### Parameter: `capacityPools.location` -Specify the name of lock. +Location of the pool volume. - Required: No - Type: string -### Parameter: `managedIdentities` - -The managed identity definition for this resource. - -- Required: No -- Type: object - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | - -### Parameter: `managedIdentities.userAssignedResourceIds` +### Parameter: `capacityPools.qosType` -The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. +The qos type of the pool. - Required: No -- Type: array +- Type: string +- Allowed: + ```Bicep + [ + 'Auto' + 'Manual' + ] + ``` -### Parameter: `roleAssignments` +### Parameter: `capacityPools.roleAssignments` Array of role assignments to create. @@ -1256,17 +1488,915 @@ Array of role assignments to create. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | -| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | +| [`principalId`](#parameter-capacitypoolsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-capacitypoolsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | -| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | -| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | -| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`condition`](#parameter-capacitypoolsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-capacitypoolsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-capacitypoolsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-capacitypoolsroleassignmentsdescription) | string | The description of the role assignment. | +| [`name`](#parameter-capacitypoolsroleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | +| [`principalType`](#parameter-capacitypoolsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `capacityPools.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `capacityPools.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `capacityPools.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `capacityPools.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `capacityPools.roleAssignments.name` + +The name (as GUID) of the role assignment. If not provided, a GUID will be generated. + +- Required: No +- Type: string + +### Parameter: `capacityPools.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `capacityPools.serviceLevel` + +The pool service level. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Premium' + 'Standard' + 'StandardZRS' + 'Ultra' + ] + ``` + +### Parameter: `capacityPools.tags` + +Tags for the capcity pool. + +- Required: No +- Type: object + +### Parameter: `capacityPools.volumes` + +List of volumes to create in the capacity pool. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-capacitypoolsvolumesname) | string | The name of the pool volume. | +| [`subnetResourceId`](#parameter-capacitypoolsvolumessubnetresourceid) | string | The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. | +| [`usageThreshold`](#parameter-capacitypoolsvolumesusagethreshold) | int | Maximum storage quota allowed for a file system in bytes. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`coolAccess`](#parameter-capacitypoolsvolumescoolaccess) | bool | If enabled (true) the pool can contain cool Access enabled volumes. | +| [`coolAccessRetrievalPolicy`](#parameter-capacitypoolsvolumescoolaccessretrievalpolicy) | string | Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). | +| [`coolnessPeriod`](#parameter-capacitypoolsvolumescoolnessperiod) | int | Specifies the number of days after which data that is not accessed by clients will be tiered. | +| [`creationToken`](#parameter-capacitypoolsvolumescreationtoken) | string | A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. | +| [`dataProtection`](#parameter-capacitypoolsvolumesdataprotection) | object | DataProtection type volumes include an object containing details of the replication. | +| [`encryptionKeySource`](#parameter-capacitypoolsvolumesencryptionkeysource) | string | The source of the encryption key. | +| [`exportPolicy`](#parameter-capacitypoolsvolumesexportpolicy) | object | Export policy rules. | +| [`kerberosEnabled`](#parameter-capacitypoolsvolumeskerberosenabled) | bool | Define if a volume is KerberosEnabled. | +| [`keyVaultPrivateEndpointResourceId`](#parameter-capacitypoolsvolumeskeyvaultprivateendpointresourceid) | string | The resource ID of the key vault private endpoint. | +| [`location`](#parameter-capacitypoolsvolumeslocation) | string | Location of the pool volume. | +| [`networkFeatures`](#parameter-capacitypoolsvolumesnetworkfeatures) | string | Network feature for the volume. | +| [`protocolTypes`](#parameter-capacitypoolsvolumesprotocoltypes) | array | Set of protocol types. | +| [`roleAssignments`](#parameter-capacitypoolsvolumesroleassignments) | array | Array of role assignments to create. | +| [`serviceLevel`](#parameter-capacitypoolsvolumesservicelevel) | string | The pool service level. Must match the one of the parent capacity pool. | +| [`smbContinuouslyAvailable`](#parameter-capacitypoolsvolumessmbcontinuouslyavailable) | bool | Enables continuously available share property for SMB volume. Only applicable for SMB volume. | +| [`smbEncryption`](#parameter-capacitypoolsvolumessmbencryption) | bool | Enables SMB encryption. Only applicable for SMB/DualProtocol volume. | +| [`smbNonBrowsable`](#parameter-capacitypoolsvolumessmbnonbrowsable) | string | Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. | +| [`zones`](#parameter-capacitypoolsvolumeszones) | array | Zone where the volume will be placed. | + +### Parameter: `capacityPools.volumes.name` + +The name of the pool volume. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.subnetResourceId` + +The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.usageThreshold` + +Maximum storage quota allowed for a file system in bytes. + +- Required: Yes +- Type: int + +### Parameter: `capacityPools.volumes.coolAccess` + +If enabled (true) the pool can contain cool Access enabled volumes. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.coolAccessRetrievalPolicy` + +Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.coolnessPeriod` + +Specifies the number of days after which data that is not accessed by clients will be tiered. + +- Required: No +- Type: int + +### Parameter: `capacityPools.volumes.creationToken` + +A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection` + +DataProtection type volumes include an object containing details of the replication. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backup`](#parameter-capacitypoolsvolumesdataprotectionbackup) | object | Backup properties. | +| [`replication`](#parameter-capacitypoolsvolumesdataprotectionreplication) | object | Replication properties. | +| [`snapshot`](#parameter-capacitypoolsvolumesdataprotectionsnapshot) | object | Snapshot properties. | + +### Parameter: `capacityPools.volumes.dataProtection.backup` + +Backup properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupPolicyName`](#parameter-capacitypoolsvolumesdataprotectionbackupbackuppolicyname) | string | The name of the backup policy to link. | +| [`backupVaultName`](#parameter-capacitypoolsvolumesdataprotectionbackupbackupvaultname) | string | The name of the Backup Vault. | +| [`policyEnforced`](#parameter-capacitypoolsvolumesdataprotectionbackuppolicyenforced) | bool | Enable to enforce the policy. | + +### Parameter: `capacityPools.volumes.dataProtection.backup.backupPolicyName` + +The name of the backup policy to link. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.backup.backupVaultName` + +The name of the Backup Vault. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.backup.policyEnforced` + +Enable to enforce the policy. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.dataProtection.replication` + +Replication properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`endpointType`](#parameter-capacitypoolsvolumesdataprotectionreplicationendpointtype) | string | Indicates whether the local volume is the source or destination for the Volume Replication. | +| [`remoteVolumeRegion`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotevolumeregion) | string | The remote region for the other end of the Volume Replication. | +| [`remoteVolumeResourceId`](#parameter-capacitypoolsvolumesdataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | +| [`replicationSchedule`](#parameter-capacitypoolsvolumesdataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | + +### Parameter: `capacityPools.volumes.dataProtection.replication.endpointType` + +Indicates whether the local volume is the source or destination for the Volume Replication. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'dst' + 'src' + ] + ``` + +### Parameter: `capacityPools.volumes.dataProtection.replication.remoteVolumeRegion` + +The remote region for the other end of the Volume Replication. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.replication.remoteVolumeResourceId` + +The resource ID of the remote volume. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.dataProtection.replication.replicationSchedule` + +The replication schedule for the volume. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + '_10minutely' + 'daily' + 'hourly' + ] + ``` + +### Parameter: `capacityPools.volumes.dataProtection.snapshot` + +Snapshot properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`snapshotPolicyName`](#parameter-capacitypoolsvolumesdataprotectionsnapshotsnapshotpolicyname) | string | The name of the snapshot policy to link. | + +### Parameter: `capacityPools.volumes.dataProtection.snapshot.snapshotPolicyName` + +The name of the snapshot policy to link. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.encryptionKeySource` + +The source of the encryption key. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.exportPolicy` + +Export policy rules. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rules`](#parameter-capacitypoolsvolumesexportpolicyrules) | array | The Export policy rules. | + +### Parameter: `capacityPools.volumes.exportPolicy.rules` + +The Export policy rules. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kerberos5iReadOnly`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5ireadonly) | bool | Kerberos5i Read only access. | +| [`kerberos5iReadWrite`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5ireadwrite) | bool | Kerberos5i Read and write access. | +| [`kerberos5pReadOnly`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5preadonly) | bool | Kerberos5p Read only access. | +| [`kerberos5pReadWrite`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5preadwrite) | bool | Kerberos5p Read and write access. | +| [`kerberos5ReadOnly`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5readonly) | bool | Kerberos5 Read only access. | +| [`kerberos5ReadWrite`](#parameter-capacitypoolsvolumesexportpolicyruleskerberos5readwrite) | bool | Kerberos5 Read and write access. | +| [`nfsv3`](#parameter-capacitypoolsvolumesexportpolicyrulesnfsv3) | bool | Allows NFSv3 protocol. Enable only for NFSv3 type volumes. | +| [`nfsv41`](#parameter-capacitypoolsvolumesexportpolicyrulesnfsv41) | bool | Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. | +| [`ruleIndex`](#parameter-capacitypoolsvolumesexportpolicyrulesruleindex) | int | Order index. | +| [`unixReadOnly`](#parameter-capacitypoolsvolumesexportpolicyrulesunixreadonly) | bool | Read only access. | +| [`unixReadWrite`](#parameter-capacitypoolsvolumesexportpolicyrulesunixreadwrite) | bool | Read and write access. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowedClients`](#parameter-capacitypoolsvolumesexportpolicyrulesallowedclients) | string | Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. | +| [`chownMode`](#parameter-capacitypoolsvolumesexportpolicyruleschownmode) | string | This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. | +| [`cifs`](#parameter-capacitypoolsvolumesexportpolicyrulescifs) | bool | Allows CIFS protocol. | +| [`hasRootAccess`](#parameter-capacitypoolsvolumesexportpolicyruleshasrootaccess) | bool | Has root access to volume. | + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5iReadOnly` + +Kerberos5i Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5iReadWrite` + +Kerberos5i Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5pReadOnly` + +Kerberos5p Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5pReadWrite` + +Kerberos5p Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5ReadOnly` + +Kerberos5 Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.kerberos5ReadWrite` + +Kerberos5 Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.nfsv3` + +Allows NFSv3 protocol. Enable only for NFSv3 type volumes. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.nfsv41` + +Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.ruleIndex` + +Order index. + +- Required: Yes +- Type: int + +### Parameter: `capacityPools.volumes.exportPolicy.rules.unixReadOnly` + +Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.unixReadWrite` + +Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.allowedClients` + +Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.exportPolicy.rules.chownMode` + +This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Restricted' + 'Unrestricted' + ] + ``` + +### Parameter: `capacityPools.volumes.exportPolicy.rules.cifs` + +Allows CIFS protocol. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.exportPolicy.rules.hasRootAccess` + +Has root access to volume. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.kerberosEnabled` + +Define if a volume is KerberosEnabled. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.keyVaultPrivateEndpointResourceId` + +The resource ID of the key vault private endpoint. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.location` + +Location of the pool volume. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.networkFeatures` + +Network feature for the volume. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Basic' + 'Basic_Standard' + 'Standard' + 'Standard_Basic' + ] + ``` + +### Parameter: `capacityPools.volumes.protocolTypes` + +Set of protocol types. + +- Required: No +- Type: array + +### Parameter: `capacityPools.volumes.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array +- Roles configurable by name: + - `'Contributor'` + - `'Owner'` + - `'Reader'` + - `'Role Based Access Control Administrator'` + - `'User Access Administrator'` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-capacitypoolsvolumesroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-capacitypoolsvolumesroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-capacitypoolsvolumesroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-capacitypoolsvolumesroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-capacitypoolsvolumesroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-capacitypoolsvolumesroleassignmentsdescription) | string | The description of the role assignment. | +| [`name`](#parameter-capacitypoolsvolumesroleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | +| [`principalType`](#parameter-capacitypoolsvolumesroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `capacityPools.volumes.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `capacityPools.volumes.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.name` + +The name (as GUID) of the role assignment. If not provided, a GUID will be generated. + +- Required: No +- Type: string + +### Parameter: `capacityPools.volumes.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `capacityPools.volumes.serviceLevel` + +The pool service level. Must match the one of the parent capacity pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Premium' + 'Standard' + 'StandardZRS' + 'Ultra' + ] + ``` + +### Parameter: `capacityPools.volumes.smbContinuouslyAvailable` + +Enables continuously available share property for SMB volume. Only applicable for SMB volume. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.smbEncryption` + +Enables SMB encryption. Only applicable for SMB/DualProtocol volume. + +- Required: No +- Type: bool + +### Parameter: `capacityPools.volumes.smbNonBrowsable` + +Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `capacityPools.volumes.zones` + +Zone where the volume will be placed. + +- Required: No +- Type: array + +### Parameter: `customerManagedKey` + +The customer managed key definition. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | +| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time. | +| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | + +### Parameter: `customerManagedKey.keyName` + +The name of the customer managed key to use for encryption. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVersion` + +The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time. + +- Required: No +- Type: string + +### Parameter: `customerManagedKey.userAssignedIdentityResourceId` + +User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. + +- Required: No +- Type: string + +### Parameter: `dnsServers` + +Required if domainName is specified. Comma separated list of DNS server IP addresses (IPv4 only) required for the Active Directory (AD) domain join and SMB authentication operations to succeed. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `domainJoinOU` + +Used only if domainName is specified. LDAP Path for the Organization Unit (OU) where SMB Server machine accounts will be created (i.e. 'OU=SecondLevel,OU=FirstLevel'). + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `domainJoinPassword` + +Required if domainName is specified. Password of the user specified in domainJoinUser parameter. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `domainJoinUser` + +Required if domainName is specified. Username of Active Directory domain administrator, with permissions to create SMB server machine account in the AD domain. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `domainName` + +Fully Qualified Active Directory DNS Domain Name (e.g. 'contoso.com'). + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `encryptDCConnections` + +Specifies whether encryption should be used for communication between SMB server and domain controller (DC). SMB3 only. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `kdcIP` + +Kerberos Key Distribution Center (KDC) as part of Kerberos Realm used for Kerberos authentication. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ldapOverTLS` + +Specifies whether to use TLS when NFS (with/without Kerberos) and SMB volumes communicate with an LDAP server. A server root CA certificate must be uploaded if enabled (serverRootCACertificate). + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `ldapSigning` + +Specifies whether or not the LDAP traffic needs to be signed. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. + +- Required: No +- Type: array + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array +- Roles configurable by name: + - `'Contributor'` + - `'Owner'` + - `'Reader'` + - `'Role Based Access Control Administrator'` + - `'User Access Administrator'` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | | [`name`](#parameter-roleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | | [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | @@ -1358,6 +2488,289 @@ Required if domainName is specified. NetBIOS name of the SMB server. A computer - Type: string - Default: `''` +### Parameter: `snapshotPolicies` + +The snapshot policies to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-snapshotpoliciesname) | string | The name of the snapshot policy. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`dailySchedule`](#parameter-snapshotpoliciesdailyschedule) | object | Daily schedule for the snapshot policy. | +| [`hourlySchedule`](#parameter-snapshotpolicieshourlyschedule) | object | Hourly schedule for the snapshot policy. | +| [`location`](#parameter-snapshotpolicieslocation) | string | Location of the snapshot policy. | +| [`monthlySchedule`](#parameter-snapshotpoliciesmonthlyschedule) | object | Monthly schedule for the snapshot policy. | +| [`weeklySchedule`](#parameter-snapshotpoliciesweeklyschedule) | object | Weekly schedule for the snapshot policy. | + +### Parameter: `snapshotPolicies.name` + +The name of the snapshot policy. + +- Required: Yes +- Type: string + +### Parameter: `snapshotPolicies.dailySchedule` + +Daily schedule for the snapshot policy. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`hour`](#parameter-snapshotpoliciesdailyschedulehour) | int | The daily snapshot hour. | +| [`minute`](#parameter-snapshotpoliciesdailyscheduleminute) | int | The daily snapshot minute. | +| [`snapshotsToKeep`](#parameter-snapshotpoliciesdailyschedulesnapshotstokeep) | int | Daily snapshot count to keep. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-snapshotpoliciesdailyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `snapshotPolicies.dailySchedule.hour` + +The daily snapshot hour. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 23 + +### Parameter: `snapshotPolicies.dailySchedule.minute` + +The daily snapshot minute. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 59 + +### Parameter: `snapshotPolicies.dailySchedule.snapshotsToKeep` + +Daily snapshot count to keep. + +- Required: Yes +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.dailySchedule.usedBytes` + +Resource size in bytes, current storage usage for the volume in bytes. + +- Required: No +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.hourlySchedule` + +Hourly schedule for the snapshot policy. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`minute`](#parameter-snapshotpolicieshourlyscheduleminute) | int | The hourly snapshot minute. | +| [`snapshotsToKeep`](#parameter-snapshotpolicieshourlyschedulesnapshotstokeep) | int | Hourly snapshot count to keep. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-snapshotpolicieshourlyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `snapshotPolicies.hourlySchedule.minute` + +The hourly snapshot minute. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 59 + +### Parameter: `snapshotPolicies.hourlySchedule.snapshotsToKeep` + +Hourly snapshot count to keep. + +- Required: Yes +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.hourlySchedule.usedBytes` + +Resource size in bytes, current storage usage for the volume in bytes. + +- Required: No +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.location` + +Location of the snapshot policy. + +- Required: No +- Type: string + +### Parameter: `snapshotPolicies.monthlySchedule` + +Monthly schedule for the snapshot policy. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`daysOfMonth`](#parameter-snapshotpoliciesmonthlyscheduledaysofmonth) | string | Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'. | +| [`hour`](#parameter-snapshotpoliciesmonthlyschedulehour) | int | The monthly snapshot hour. | +| [`minute`](#parameter-snapshotpoliciesmonthlyscheduleminute) | int | The monthly snapshot minute. | +| [`snapshotsToKeep`](#parameter-snapshotpoliciesmonthlyschedulesnapshotstokeep) | int | Monthly snapshot count to keep. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-snapshotpoliciesmonthlyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `snapshotPolicies.monthlySchedule.daysOfMonth` + +Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'. + +- Required: Yes +- Type: string + +### Parameter: `snapshotPolicies.monthlySchedule.hour` + +The monthly snapshot hour. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 23 + +### Parameter: `snapshotPolicies.monthlySchedule.minute` + +The monthly snapshot minute. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 59 + +### Parameter: `snapshotPolicies.monthlySchedule.snapshotsToKeep` + +Monthly snapshot count to keep. + +- Required: Yes +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.monthlySchedule.usedBytes` + +Resource size in bytes, current storage usage for the volume in bytes. + +- Required: No +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.weeklySchedule` + +Weekly schedule for the snapshot policy. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`day`](#parameter-snapshotpoliciesweeklyscheduleday) | string | The weekly snapshot day. | +| [`hour`](#parameter-snapshotpoliciesweeklyschedulehour) | int | The weekly snapshot hour. | +| [`minute`](#parameter-snapshotpoliciesweeklyscheduleminute) | int | The weekly snapshot minute. | +| [`snapshotsToKeep`](#parameter-snapshotpoliciesweeklyschedulesnapshotstokeep) | int | Weekly snapshot count to keep. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-snapshotpoliciesweeklyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `snapshotPolicies.weeklySchedule.day` + +The weekly snapshot day. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Friday' + 'Monday' + 'Saturday' + 'Sunday' + 'Thursday' + 'Tuesday' + 'Wednesday' + ] + ``` + +### Parameter: `snapshotPolicies.weeklySchedule.hour` + +The weekly snapshot hour. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 23 + +### Parameter: `snapshotPolicies.weeklySchedule.minute` + +The weekly snapshot minute. + +- Required: Yes +- Type: int +- MinValue: 0 +- MaxValue: 59 + +### Parameter: `snapshotPolicies.weeklySchedule.snapshotsToKeep` + +Weekly snapshot count to keep. + +- Required: Yes +- Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `snapshotPolicies.weeklySchedule.usedBytes` + +Resource size in bytes, current storage usage for the volume in bytes. + +- Required: No +- Type: int +- MinValue: 1 +- MaxValue: 255 + ### Parameter: `tags` Tags for all resources. @@ -1369,11 +2782,11 @@ Tags for all resources. | Output | Type | Description | | :-- | :-- | :-- | +| `capacityPoolResourceIds` | array | The resource IDs of the created capacity pools & their volumes. | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the NetApp account. | | `resourceGroupName` | string | The name of the Resource Group the NetApp account was created in. | | `resourceId` | string | The Resource ID of the NetApp account. | -| `volumeResourceId` | string | The resource IDs of the volume created in the capacity pool. | ## Cross-referenced modules diff --git a/avm/res/net-app/net-app-account/backup-policies/README.md b/avm/res/net-app/net-app-account/backup-policies/README.md index 16fed5137d..f575f4f788 100644 --- a/avm/res/net-app/net-app-account/backup-policies/README.md +++ b/avm/res/net-app/net-app-account/backup-policies/README.md @@ -16,15 +16,6 @@ This module deploys a Backup Policy for Azure NetApp File. ## Parameters -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`backupPolicyLocation`](#parameter-backuppolicylocation) | string | The location of the backup policy. Required if the template is used in a standalone deployment. | -| [`dailyBackupsToKeep`](#parameter-dailybackupstokeep) | int | The daily backups to keep. | -| [`monthlyBackupsToKeep`](#parameter-monthlybackupstokeep) | int | The monthly backups to keep. | -| [`weeklyBackupsToKeep`](#parameter-weeklybackupstokeep) | int | The weekly backups to keep. | - **Conditional parameters** | Parameter | Type | Description | @@ -35,12 +26,16 @@ This module deploys a Backup Policy for Azure NetApp File. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`backupEnabled`](#parameter-backupenabled) | bool | Indicates whether the backup policy is enabled. | -| [`backupPolicyName`](#parameter-backuppolicyname) | string | The name of the backup policy. | +| [`dailyBackupsToKeep`](#parameter-dailybackupstokeep) | int | The daily backups to keep. | +| [`enabled`](#parameter-enabled) | bool | Indicates whether the backup policy is enabled. | +| [`location`](#parameter-location) | string | The location of the backup policy. | +| [`monthlyBackupsToKeep`](#parameter-monthlybackupstokeep) | int | The monthly backups to keep. | +| [`name`](#parameter-name) | string | The name of the backup policy. | +| [`weeklyBackupsToKeep`](#parameter-weeklybackupstokeep) | int | The weekly backups to keep. | -### Parameter: `backupPolicyLocation` +### Parameter: `netAppAccountName` -The location of the backup policy. Required if the template is used in a standalone deployment. +The name of the parent NetApp account. Required if the template is used in a standalone deployment. - Required: Yes - Type: string @@ -49,45 +44,61 @@ The location of the backup policy. Required if the template is used in a standal The daily backups to keep. -- Required: Yes -- Type: int - -### Parameter: `monthlyBackupsToKeep` - -The monthly backups to keep. - -- Required: Yes +- Required: No - Type: int +- Default: `2` +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `weeklyBackupsToKeep` +### Parameter: `enabled` -The weekly backups to keep. +Indicates whether the backup policy is enabled. -- Required: Yes -- Type: int +- Required: No +- Type: bool +- Default: `True` +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `netAppAccountName` +### Parameter: `location` -The name of the parent NetApp account. Required if the template is used in a standalone deployment. +The location of the backup policy. -- Required: Yes +- Required: No - Type: string +- Default: `[resourceGroup().location]` +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `backupEnabled` +### Parameter: `monthlyBackupsToKeep` -Indicates whether the backup policy is enabled. +The monthly backups to keep. - Required: No -- Type: bool -- Default: `False` +- Type: int +- Default: `0` +- MinValue: 2 +- MaxValue: 1019 -### Parameter: `backupPolicyName` +### Parameter: `name` The name of the backup policy. - Required: No - Type: string - Default: `'backupPolicy'` +- MinValue: 2 +- MaxValue: 1019 + +### Parameter: `weeklyBackupsToKeep` + +The weekly backups to keep. + +- Required: No +- Type: int +- Default: `0` +- MinValue: 2 +- MaxValue: 1019 ## Outputs diff --git a/avm/res/net-app/net-app-account/backup-policies/main.bicep b/avm/res/net-app/net-app-account/backup-policies/main.bicep index f5d04883af..561876f59f 100644 --- a/avm/res/net-app/net-app-account/backup-policies/main.bicep +++ b/avm/res/net-app/net-app-account/backup-policies/main.bicep @@ -5,36 +5,38 @@ metadata description = 'This module deploys a Backup Policy for Azure NetApp Fil param netAppAccountName string @description('Optional. The name of the backup policy.') -param backupPolicyName string = 'backupPolicy' +param name string = 'backupPolicy' -@description('Required. The location of the backup policy. Required if the template is used in a standalone deployment.') -param backupPolicyLocation string +@description('Optional. The location of the backup policy.') +param location string = resourceGroup().location -@description('Required. The daily backups to keep.') -param dailyBackupsToKeep int +@description('Optional. The daily backups to keep.') +@minValue(2) +@maxValue(1019) +param dailyBackupsToKeep int = 2 -@description('Required. The monthly backups to keep.') -param monthlyBackupsToKeep int +@description('Optional. The monthly backups to keep.') +param monthlyBackupsToKeep int = 0 -@description('Required. The weekly backups to keep.') -param weeklyBackupsToKeep int +@description('Optional. The weekly backups to keep.') +param weeklyBackupsToKeep int = 0 @description('Optional. Indicates whether the backup policy is enabled.') -param backupEnabled bool = false +param enabled bool = true resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { name: netAppAccountName } resource backupPolicies 'Microsoft.NetApp/netAppAccounts/backupPolicies@2024-03-01' = { - name: backupPolicyName + name: name parent: netAppAccount - location: backupPolicyLocation + location: location properties: { + enabled: enabled dailyBackupsToKeep: dailyBackupsToKeep - enabled: backupEnabled - monthlyBackupsToKeep: monthlyBackupsToKeep weeklyBackupsToKeep: weeklyBackupsToKeep + monthlyBackupsToKeep: monthlyBackupsToKeep } } @description('The resource IDs of the backup Policy created within volume.') diff --git a/avm/res/net-app/net-app-account/backup-policies/main.json b/avm/res/net-app/net-app-account/backup-policies/main.json index 5a9477decb..2b6c463c6b 100644 --- a/avm/res/net-app/net-app-account/backup-policies/main.json +++ b/avm/res/net-app/net-app-account/backup-policies/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2321320275404095362" + "version": "0.33.13.18514", + "templateHash": "1799863578493793686" }, "name": "Azure NetApp Files Backup Policy", "description": "This module deploys a Backup Policy for Azure NetApp File." @@ -17,40 +17,46 @@ "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." } }, - "backupPolicyName": { + "name": { "type": "string", "defaultValue": "backupPolicy", "metadata": { "description": "Optional. The name of the backup policy." } }, - "backupPolicyLocation": { + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Required. The location of the backup policy. Required if the template is used in a standalone deployment." + "description": "Optional. The location of the backup policy." } }, "dailyBackupsToKeep": { "type": "int", + "defaultValue": 2, + "minValue": 2, + "maxValue": 1019, "metadata": { - "description": "Required. The daily backups to keep." + "description": "Optional. The daily backups to keep." } }, "monthlyBackupsToKeep": { "type": "int", + "defaultValue": 0, "metadata": { - "description": "Required. The monthly backups to keep." + "description": "Optional. The monthly backups to keep." } }, "weeklyBackupsToKeep": { "type": "int", + "defaultValue": 0, "metadata": { - "description": "Required. The weekly backups to keep." + "description": "Optional. The weekly backups to keep." } }, - "backupEnabled": { + "enabled": { "type": "bool", - "defaultValue": false, + "defaultValue": true, "metadata": { "description": "Optional. Indicates whether the backup policy is enabled." } @@ -60,13 +66,13 @@ { "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupPolicyName'))]", - "location": "[parameters('backupPolicyLocation')]", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", "properties": { + "enabled": "[parameters('enabled')]", "dailyBackupsToKeep": "[parameters('dailyBackupsToKeep')]", - "enabled": "[parameters('backupEnabled')]", - "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]", - "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]" + "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]", + "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]" } } ], @@ -76,14 +82,14 @@ "metadata": { "description": "The resource IDs of the backup Policy created within volume." }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('backupPolicyName'))]" + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('name'))]" }, "name": { "type": "string", "metadata": { "description": "The name of the Backup Policy." }, - "value": "[parameters('backupPolicyName')]" + "value": "[parameters('name')]" }, "resourceGroupName": { "type": "string", diff --git a/avm/res/net-app/net-app-account/backup-vault/README.md b/avm/res/net-app/net-app-account/backup-vault/README.md new file mode 100644 index 0000000000..1a2fe38075 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/README.md @@ -0,0 +1,121 @@ +# Azure NetApp Files Volume Backup Vault `[Microsoft.NetApp/netAppAccounts/backupVaults]` + +This module deploys a NetApp Files Backup Vault. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults) | +| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | + +## Parameters + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`netAppAccountName`](#parameter-netappaccountname) | string | The name of the parent NetApp account. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backups`](#parameter-backups) | array | The list of backups to create. | +| [`location`](#parameter-location) | string | Location of the backup vault. | +| [`name`](#parameter-name) | string | The name of the backup vault. | + +### Parameter: `netAppAccountName` + +The name of the parent NetApp account. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `backups` + +The list of backups to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacityPoolName`](#parameter-backupscapacitypoolname) | string | The name of the capacity pool containing the volume. | +| [`volumeName`](#parameter-backupsvolumename) | string | The name of the volume to backup. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`label`](#parameter-backupslabel) | string | Label for backup. | +| [`name`](#parameter-backupsname) | string | The name of the backup. | +| [`snapshotName`](#parameter-backupssnapshotname) | string | The name of the snapshot. | + +### Parameter: `backups.capacityPoolName` + +The name of the capacity pool containing the volume. + +- Required: Yes +- Type: string + +### Parameter: `backups.volumeName` + +The name of the volume to backup. + +- Required: Yes +- Type: string + +### Parameter: `backups.label` + +Label for backup. + +- Required: No +- Type: string + +### Parameter: `backups.name` + +The name of the backup. + +- Required: No +- Type: string + +### Parameter: `backups.snapshotName` + +The name of the snapshot. + +- Required: No +- Type: string + +### Parameter: `location` + +Location of the backup vault. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `name` + +The name of the backup vault. + +- Required: No +- Type: string +- Default: `'vault'` + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the backup vault. | +| `resourceGroupName` | string | The name of the Resource Group the backup vault was created in. | +| `resourceId` | string | The Resource ID of the backup vault. | diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/README.md b/avm/res/net-app/net-app-account/backup-vault/backup/README.md new file mode 100644 index 0000000000..5769fd7385 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/backup/README.md @@ -0,0 +1,97 @@ +# Azure NetApp Files Volume Backup `[Microsoft.NetApp/netAppAccounts/backupVaults/backups]` + +This module deploys a backup of a NetApp Files Volume. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`capacityPoolName`](#parameter-capacitypoolname) | string | The name of the capacity pool containing the volume. | +| [`volumeName`](#parameter-volumename) | string | The name of the volume to backup. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupVaultName`](#parameter-backupvaultname) | string | The name of the parent backup vault. Required if the template is used in a standalone deployment. | +| [`netAppAccountName`](#parameter-netappaccountname) | string | The name of the parent NetApp account. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`label`](#parameter-label) | string | Label for backup. | +| [`name`](#parameter-name) | string | The name of the backup. | +| [`snapshotName`](#parameter-snapshotname) | string | The name of the snapshot. | + +### Parameter: `capacityPoolName` + +The name of the capacity pool containing the volume. + +- Required: Yes +- Type: string + +### Parameter: `volumeName` + +The name of the volume to backup. + +- Required: Yes +- Type: string + +### Parameter: `backupVaultName` + +The name of the parent backup vault. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `netAppAccountName` + +The name of the parent NetApp account. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `label` + +Label for backup. + +- Required: No +- Type: string + +### Parameter: `name` + +The name of the backup. + +- Required: No +- Type: string +- Default: `'backup'` + +### Parameter: `snapshotName` + +The name of the snapshot. + +- Required: No +- Type: string + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the backup. | +| `resourceGroupName` | string | The name of the Resource Group the backup was created in. | +| `resourceId` | string | The Resource ID of the backup. | diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep b/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep new file mode 100644 index 0000000000..accde9c313 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/backup/main.bicep @@ -0,0 +1,58 @@ +metadata name = 'Azure NetApp Files Volume Backup' +metadata description = 'This module deploys a backup of a NetApp Files Volume.' + +@description('Optional. The name of the backup.') +param name string = 'backup' + +@description('Conditional. The name of the parent backup vault. Required if the template is used in a standalone deployment.') +param backupVaultName string + +@description('Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment.') +param netAppAccountName string + +@description('Optional. Label for backup.') +param label string? + +@description('Optional. The name of the snapshot.') +param snapshotName string? + +@description('Required. The name of the volume to backup.') +param volumeName string + +@description('Required. The name of the capacity pool containing the volume.') +param capacityPoolName string + +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { + name: netAppAccountName + + resource backupVault 'backupVaults@2024-03-01' existing = { + name: backupVaultName + } + + resource remoteCapacityPool 'capacityPools@2024-03-01' existing = { + name: capacityPoolName + + resource volume 'volumes@2024-07-01' existing = { + name: volumeName + } + } +} + +resource backup 'Microsoft.NetApp/netAppAccounts/backupVaults/backups@2024-03-01' = { + name: name + parent: netAppAccount::backupVault + properties: { + label: label + snapshotName: snapshotName + volumeResourceId: netAppAccount::remoteCapacityPool::volume.id + } +} + +@description('The name of the backup.') +output name string = backup.name + +@description('The Resource ID of the backup.') +output resourceId string = backup.id + +@description('The name of the Resource Group the backup was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/net-app/net-app-account/backup-vault/backup/main.json b/avm/res/net-app/net-app-account/backup-vault/backup/main.json new file mode 100644 index 0000000000..fa434a3da1 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/backup/main.json @@ -0,0 +1,120 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "10519572323483923146" + }, + "name": "Azure NetApp Files Volume Backup", + "description": "This module deploys a backup of a NetApp Files Volume." + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "backup", + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent backup vault. Required if the template is used in a standalone deployment." + } + }, + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } + }, + "resources": { + "netAppAccount::remoteCapacityPool::volume": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" + }, + "netAppAccount::backupVault": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" + }, + "netAppAccount::remoteCapacityPool": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" + }, + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "backup": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", + "properties": { + "label": "[parameters('label')]", + "snapshotName": "[parameters('snapshotName')]", + "volumeResourceId": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the backup." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the backup." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults/backups', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the backup was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/backup-vault/main.bicep b/avm/res/net-app/net-app-account/backup-vault/main.bicep new file mode 100644 index 0000000000..7ad087ceb6 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/main.bicep @@ -0,0 +1,75 @@ +metadata name = 'Azure NetApp Files Volume Backup Vault' +metadata description = 'This module deploys a NetApp Files Backup Vault.' + +@description('Optional. The name of the backup vault.') +param name string = 'vault' + +@description('Optional. Location of the backup vault.') +param location string = resourceGroup().location + +@description('Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment.') +param netAppAccountName string + +@description('Optional. The list of backups to create.') +param backups backupType[]? + +resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { + name: netAppAccountName +} + +resource backupVault 'Microsoft.NetApp/netAppAccounts/backupVaults@2024-03-01' = { + name: name + parent: netAppAccount + location: location + properties: {} +} + +module backupVault_backups 'backup/main.bicep' = [ + for (backup, index) in (backups ?? []): { + name: '${uniqueString(deployment().name, location)}-ANF-Backup-${index}' + params: { + netAppAccountName: netAppAccount.name + backupVaultName: backupVault.name + name: backup.?name + label: backup.?label + snapshotName: backup.?snapshotName + volumeName: backup.volumeName + capacityPoolName: backup.capacityPoolName + } + } +] + +@description('The name of the backup vault.') +output name string = backupVault.name + +@description('The Resource ID of the backup vault.') +output resourceId string = backupVault.id + +@description('The name of the Resource Group the backup vault was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = backupVault.location + +// ================ // +// Definitions // +// ================ // + +@export() +@description('The type for a backup.') +type backupType = { + @description('Optional. The name of the backup.') + name: string? + + @description('Optional. Label for backup.') + label: string? + + @description('Optional. The name of the snapshot.') + snapshotName: string? + + @description('Required. The name of the volume to backup.') + volumeName: string + + @description('Required. The name of the capacity pool containing the volume.') + capacityPoolName: string +} diff --git a/avm/res/net-app/net-app-account/backup-vault/main.json b/avm/res/net-app/net-app-account/backup-vault/main.json new file mode 100644 index 0000000000..20b96fb9a2 --- /dev/null +++ b/avm/res/net-app/net-app-account/backup-vault/main.json @@ -0,0 +1,296 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "1432647773332765235" + }, + "name": "Azure NetApp Files Volume Backup Vault", + "description": "This module deploys a NetApp Files Backup Vault." + }, + "definitions": { + "backupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup." + } + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "vault", + "metadata": { + "description": "Optional. The name of the backup vault." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the backup vault." + } + }, + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "backups": { + "type": "array", + "items": { + "$ref": "#/definitions/backupType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of backups to create." + } + } + }, + "resources": { + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "backupVault": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": {} + }, + "backupVault_backups": { + "copy": { + "name": "backupVault_backups", + "count": "[length(coalesce(parameters('backups'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANF-Backup-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('netAppAccountName')]" + }, + "backupVaultName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'name')]" + }, + "label": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'label')]" + }, + "snapshotName": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'snapshotName')]" + }, + "volumeName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].volumeName]" + }, + "capacityPoolName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].capacityPoolName]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "10519572323483923146" + }, + "name": "Azure NetApp Files Volume Backup", + "description": "This module deploys a backup of a NetApp Files Volume." + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "backup", + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent backup vault. Required if the template is used in a standalone deployment." + } + }, + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } + }, + "resources": { + "netAppAccount::remoteCapacityPool::volume": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" + }, + "netAppAccount::backupVault": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" + }, + "netAppAccount::remoteCapacityPool": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" + }, + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "backup": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", + "properties": { + "label": "[parameters('label')]", + "snapshotName": "[parameters('snapshotName')]", + "volumeResourceId": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the backup." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the backup." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults/backups', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the backup was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "backupVault" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the backup vault." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the backup vault." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the backup vault was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('backupVault', '2024-03-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/capacity-pool/README.md b/avm/res/net-app/net-app-account/capacity-pool/README.md index d28779f5b1..120723a2df 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/README.md +++ b/avm/res/net-app/net-app-account/capacity-pool/README.md @@ -14,12 +14,8 @@ This module deploys an Azure NetApp Files Capacity Pool. | 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.NetApp/netAppAccounts/backupPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupPolicies) | -| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults) | -| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | | `Microsoft.NetApp/netAppAccounts/capacityPools` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools) | | `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools/volumes) | -| `Microsoft.NetApp/netAppAccounts/snapshotPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/snapshotPolicies) | ## Parameters @@ -47,7 +43,7 @@ This module deploys an Azure NetApp Files Capacity Pool. | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`serviceLevel`](#parameter-servicelevel) | string | The pool service level. | | [`tags`](#parameter-tags) | object | Tags for all resources. | -| [`volumes`](#parameter-volumes) | array | List of volumnes to create in the capacity pool. | +| [`volumes`](#parameter-volumes) | array | List of volumes to create in the capacity pool. | ### Parameter: `name` @@ -245,11 +241,582 @@ Tags for all resources. ### Parameter: `volumes` -List of volumnes to create in the capacity pool. +List of volumes to create in the capacity pool. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-volumesname) | string | The name of the pool volume. | +| [`subnetResourceId`](#parameter-volumessubnetresourceid) | string | The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. | +| [`usageThreshold`](#parameter-volumesusagethreshold) | int | Maximum storage quota allowed for a file system in bytes. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`coolAccess`](#parameter-volumescoolaccess) | bool | If enabled (true) the pool can contain cool Access enabled volumes. | +| [`coolAccessRetrievalPolicy`](#parameter-volumescoolaccessretrievalpolicy) | string | Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). | +| [`coolnessPeriod`](#parameter-volumescoolnessperiod) | int | Specifies the number of days after which data that is not accessed by clients will be tiered. | +| [`creationToken`](#parameter-volumescreationtoken) | string | A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. | +| [`dataProtection`](#parameter-volumesdataprotection) | object | DataProtection type volumes include an object containing details of the replication. | +| [`encryptionKeySource`](#parameter-volumesencryptionkeysource) | string | The source of the encryption key. | +| [`exportPolicy`](#parameter-volumesexportpolicy) | object | Export policy rules. | +| [`kerberosEnabled`](#parameter-volumeskerberosenabled) | bool | Define if a volume is KerberosEnabled. | +| [`keyVaultPrivateEndpointResourceId`](#parameter-volumeskeyvaultprivateendpointresourceid) | string | The resource ID of the key vault private endpoint. | +| [`location`](#parameter-volumeslocation) | string | Location of the pool volume. | +| [`networkFeatures`](#parameter-volumesnetworkfeatures) | string | Network feature for the volume. | +| [`protocolTypes`](#parameter-volumesprotocoltypes) | array | Set of protocol types. | +| [`roleAssignments`](#parameter-volumesroleassignments) | array | Array of role assignments to create. | +| [`serviceLevel`](#parameter-volumesservicelevel) | string | The pool service level. Must match the one of the parent capacity pool. | +| [`smbContinuouslyAvailable`](#parameter-volumessmbcontinuouslyavailable) | bool | Enables continuously available share property for SMB volume. Only applicable for SMB volume. | +| [`smbEncryption`](#parameter-volumessmbencryption) | bool | Enables SMB encryption. Only applicable for SMB/DualProtocol volume. | +| [`smbNonBrowsable`](#parameter-volumessmbnonbrowsable) | string | Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. | +| [`zones`](#parameter-volumeszones) | array | Zone where the volume will be placed. | + +### Parameter: `volumes.name` + +The name of the pool volume. + +- Required: Yes +- Type: string + +### Parameter: `volumes.subnetResourceId` + +The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. + +- Required: Yes +- Type: string + +### Parameter: `volumes.usageThreshold` + +Maximum storage quota allowed for a file system in bytes. + +- Required: Yes +- Type: int + +### Parameter: `volumes.coolAccess` + +If enabled (true) the pool can contain cool Access enabled volumes. + +- Required: No +- Type: bool + +### Parameter: `volumes.coolAccessRetrievalPolicy` + +Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). + +- Required: No +- Type: string + +### Parameter: `volumes.coolnessPeriod` + +Specifies the number of days after which data that is not accessed by clients will be tiered. + +- Required: No +- Type: int + +### Parameter: `volumes.creationToken` + +A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. + +- Required: No +- Type: string + +### Parameter: `volumes.dataProtection` + +DataProtection type volumes include an object containing details of the replication. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backup`](#parameter-volumesdataprotectionbackup) | object | Backup properties. | +| [`replication`](#parameter-volumesdataprotectionreplication) | object | Replication properties. | +| [`snapshot`](#parameter-volumesdataprotectionsnapshot) | object | Snapshot properties. | + +### Parameter: `volumes.dataProtection.backup` + +Backup properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupPolicyName`](#parameter-volumesdataprotectionbackupbackuppolicyname) | string | The name of the backup policy to link. | +| [`backupVaultName`](#parameter-volumesdataprotectionbackupbackupvaultname) | string | The name of the Backup Vault. | +| [`policyEnforced`](#parameter-volumesdataprotectionbackuppolicyenforced) | bool | Enable to enforce the policy. | + +### Parameter: `volumes.dataProtection.backup.backupPolicyName` + +The name of the backup policy to link. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.backup.backupVaultName` + +The name of the Backup Vault. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.backup.policyEnforced` + +Enable to enforce the policy. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.dataProtection.replication` + +Replication properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`endpointType`](#parameter-volumesdataprotectionreplicationendpointtype) | string | Indicates whether the local volume is the source or destination for the Volume Replication. | +| [`remoteVolumeRegion`](#parameter-volumesdataprotectionreplicationremotevolumeregion) | string | The remote region for the other end of the Volume Replication. | +| [`remoteVolumeResourceId`](#parameter-volumesdataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | +| [`replicationSchedule`](#parameter-volumesdataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | + +### Parameter: `volumes.dataProtection.replication.endpointType` + +Indicates whether the local volume is the source or destination for the Volume Replication. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'dst' + 'src' + ] + ``` + +### Parameter: `volumes.dataProtection.replication.remoteVolumeRegion` + +The remote region for the other end of the Volume Replication. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.replication.remoteVolumeResourceId` + +The resource ID of the remote volume. + +- Required: Yes +- Type: string + +### Parameter: `volumes.dataProtection.replication.replicationSchedule` + +The replication schedule for the volume. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + '_10minutely' + 'daily' + 'hourly' + ] + ``` + +### Parameter: `volumes.dataProtection.snapshot` + +Snapshot properties. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`snapshotPolicyName`](#parameter-volumesdataprotectionsnapshotsnapshotpolicyname) | string | The name of the snapshot policy to link. | + +### Parameter: `volumes.dataProtection.snapshot.snapshotPolicyName` + +The name of the snapshot policy to link. + +- Required: Yes +- Type: string + +### Parameter: `volumes.encryptionKeySource` + +The source of the encryption key. + +- Required: No +- Type: string + +### Parameter: `volumes.exportPolicy` + +Export policy rules. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rules`](#parameter-volumesexportpolicyrules) | array | The Export policy rules. | + +### Parameter: `volumes.exportPolicy.rules` + +The Export policy rules. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kerberos5iReadOnly`](#parameter-volumesexportpolicyruleskerberos5ireadonly) | bool | Kerberos5i Read only access. | +| [`kerberos5iReadWrite`](#parameter-volumesexportpolicyruleskerberos5ireadwrite) | bool | Kerberos5i Read and write access. | +| [`kerberos5pReadOnly`](#parameter-volumesexportpolicyruleskerberos5preadonly) | bool | Kerberos5p Read only access. | +| [`kerberos5pReadWrite`](#parameter-volumesexportpolicyruleskerberos5preadwrite) | bool | Kerberos5p Read and write access. | +| [`kerberos5ReadOnly`](#parameter-volumesexportpolicyruleskerberos5readonly) | bool | Kerberos5 Read only access. | +| [`kerberos5ReadWrite`](#parameter-volumesexportpolicyruleskerberos5readwrite) | bool | Kerberos5 Read and write access. | +| [`nfsv3`](#parameter-volumesexportpolicyrulesnfsv3) | bool | Allows NFSv3 protocol. Enable only for NFSv3 type volumes. | +| [`nfsv41`](#parameter-volumesexportpolicyrulesnfsv41) | bool | Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. | +| [`ruleIndex`](#parameter-volumesexportpolicyrulesruleindex) | int | Order index. | +| [`unixReadOnly`](#parameter-volumesexportpolicyrulesunixreadonly) | bool | Read only access. | +| [`unixReadWrite`](#parameter-volumesexportpolicyrulesunixreadwrite) | bool | Read and write access. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowedClients`](#parameter-volumesexportpolicyrulesallowedclients) | string | Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. | +| [`chownMode`](#parameter-volumesexportpolicyruleschownmode) | string | This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. | +| [`cifs`](#parameter-volumesexportpolicyrulescifs) | bool | Allows CIFS protocol. | +| [`hasRootAccess`](#parameter-volumesexportpolicyruleshasrootaccess) | bool | Has root access to volume. | + +### Parameter: `volumes.exportPolicy.rules.kerberos5iReadOnly` + +Kerberos5i Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.kerberos5iReadWrite` + +Kerberos5i Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.kerberos5pReadOnly` + +Kerberos5p Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.kerberos5pReadWrite` + +Kerberos5p Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.kerberos5ReadOnly` + +Kerberos5 Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.kerberos5ReadWrite` + +Kerberos5 Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.nfsv3` + +Allows NFSv3 protocol. Enable only for NFSv3 type volumes. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.nfsv41` + +Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.ruleIndex` + +Order index. + +- Required: Yes +- Type: int + +### Parameter: `volumes.exportPolicy.rules.unixReadOnly` + +Read only access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.unixReadWrite` + +Read and write access. + +- Required: Yes +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.allowedClients` + +Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. + +- Required: No +- Type: string + +### Parameter: `volumes.exportPolicy.rules.chownMode` + +This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Restricted' + 'Unrestricted' + ] + ``` + +### Parameter: `volumes.exportPolicy.rules.cifs` + +Allows CIFS protocol. + +- Required: No +- Type: bool + +### Parameter: `volumes.exportPolicy.rules.hasRootAccess` + +Has root access to volume. + +- Required: No +- Type: bool + +### Parameter: `volumes.kerberosEnabled` + +Define if a volume is KerberosEnabled. + +- Required: No +- Type: bool + +### Parameter: `volumes.keyVaultPrivateEndpointResourceId` + +The resource ID of the key vault private endpoint. + +- Required: No +- Type: string + +### Parameter: `volumes.location` + +Location of the pool volume. + +- Required: No +- Type: string + +### Parameter: `volumes.networkFeatures` + +Network feature for the volume. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Basic' + 'Basic_Standard' + 'Standard' + 'Standard_Basic' + ] + ``` + +### Parameter: `volumes.protocolTypes` + +Set of protocol types. + +- Required: No +- Type: array + +### Parameter: `volumes.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array +- Roles configurable by name: + - `'Contributor'` + - `'Owner'` + - `'Reader'` + - `'Role Based Access Control Administrator'` + - `'User Access Administrator'` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-volumesroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-volumesroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-volumesroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-volumesroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-volumesroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-volumesroleassignmentsdescription) | string | The description of the role assignment. | +| [`name`](#parameter-volumesroleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | +| [`principalType`](#parameter-volumesroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `volumes.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `volumes.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `volumes.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `volumes.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `volumes.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `volumes.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `volumes.roleAssignments.name` + +The name (as GUID) of the role assignment. If not provided, a GUID will be generated. + +- Required: No +- Type: string + +### Parameter: `volumes.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `volumes.serviceLevel` + +The pool service level. Must match the one of the parent capacity pool. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Premium' + 'Standard' + 'StandardZRS' + 'Ultra' + ] + ``` + +### Parameter: `volumes.smbContinuouslyAvailable` + +Enables continuously available share property for SMB volume. Only applicable for SMB volume. + +- Required: No +- Type: bool + +### Parameter: `volumes.smbEncryption` + +Enables SMB encryption. Only applicable for SMB/DualProtocol volume. + +- Required: No +- Type: bool + +### Parameter: `volumes.smbNonBrowsable` + +Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `volumes.zones` + +Zone where the volume will be placed. - Required: No - Type: array -- Default: `[]` ## Outputs @@ -259,7 +826,7 @@ List of volumnes to create in the capacity pool. | `name` | string | The name of the Capacity Pool. | | `resourceGroupName` | string | The name of the Resource Group the Capacity Pool was created in. | | `resourceId` | string | The resource ID of the Capacity Pool. | -| `volumeResourceId` | string | The resource IDs of the volume created in the capacity pool. | +| `volumeResourceIds` | array | The resource IDs of the volume created in the capacity pool. | ## Cross-referenced modules @@ -267,6 +834,4 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `avm/res/net-app/net-app-account/backup-policies` | Local reference | -| `avm/res/net-app/net-app-account/snapshot-policies` | Local reference | | `br/public:avm/utl/types/avm-common-types:0.4.0` | Remote reference | diff --git a/avm/res/net-app/net-app-account/capacity-pool/main.bicep b/avm/res/net-app/net-app-account/capacity-pool/main.bicep index 83191a1e88..216cf0e333 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/main.bicep +++ b/avm/res/net-app/net-app-account/capacity-pool/main.bicep @@ -32,8 +32,8 @@ param size int ]) param qosType string = 'Auto' -@description('Optional. List of volumnes to create in the capacity pool.') -param volumes array = [] +@description('Optional. List of volumes to create in the capacity pool.') +param volumes volumeType[]? @description('Optional. If enabled (true) the pool can contain cool Access enabled volumes.') param coolAccess bool = false @@ -94,7 +94,7 @@ resource capacityPool 'Microsoft.NetApp/netAppAccounts/capacityPools@2024-03-01' @batchSize(1) module capacityPool_volumes 'volume/main.bicep' = [ - for (volume, index) in volumes: { + for (volume, index) in (volumes ?? []): { name: '${deployment().name}-Vol-${index}' params: { netAppAccountName: netAppAccount.name @@ -104,57 +104,18 @@ module capacityPool_volumes 'volume/main.bicep' = [ serviceLevel: serviceLevel creationToken: volume.?creationToken ?? volume.name usageThreshold: volume.usageThreshold - protocolTypes: volume.?protocolTypes ?? [] + protocolTypes: volume.?protocolTypes subnetResourceId: volume.subnetResourceId - exportPolicyRules: volume.?exportPolicyRules ?? [] - roleAssignments: volume.?roleAssignments ?? [] + exportPolicy: volume.?exportPolicy + roleAssignments: volume.?roleAssignments networkFeatures: volume.?networkFeatures zones: volume.?zones coolAccess: volume.?coolAccess ?? false - coolAccessRetrievalPolicy: volume.?coolAccessRetrievalPolicy ?? 'Default' + coolAccessRetrievalPolicy: volume.?coolAccessRetrievalPolicy coolnessPeriod: volume.?coolnessPeriod ?? 0 encryptionKeySource: volume.?encryptionKeySource ?? 'Microsoft.NetApp' - keyVaultPrivateEndpointResourceId: volume.?keyVaultPrivateEndpointResourceId ?? '' - endpointType: volume.?endpointType ?? '' - remoteVolumeRegion: volume.?remoteVolumeRegion ?? '' - remoteVolumeResourceId: volume.?remoteVolumeResourceId ?? '' - replicationSchedule: volume.?replicationSchedule ?? '' - snapshotPolicyName: volume.?snapshotPolicyName ?? 'snapshotPolicy' - snapshotPolicyLocation: volume.?snapshotPolicyLocation ?? '' - snapEnabled: volume.?snapEnabled ?? false - dailyHour: volume.?dailyHour ?? 0 - dailyMinute: volume.?dailyMinute ?? 0 - dailySnapshotsToKeep: volume.?dailySnapshotsToKeep ?? 0 - dailyUsedBytes: volume.?dailyUsedBytes ?? 0 - hourlyMinute: volume.?hourlyMinute ?? 0 - hourlySnapshotsToKeep: volume.?hourlySnapshotsToKeep ?? 0 - hourlyUsedBytes: volume.?hourlyUsedBytes ?? 0 - daysOfMonth: volume.?daysOfMonth ?? '' - monthlyHour: volume.?monthlyHour ?? 0 - monthlyMinute: volume.?monthlyMinute ?? 0 - monthlySnapshotsToKeep: volume.?monthlySnapshotsToKeep ?? 0 - monthlyUsedBytes: volume.?monthlyUsedBytes ?? 0 - weeklyDay: volume.?weeklyDay ?? '' - weeklyHour: volume.?weeklyHour ?? 0 - weeklyMinute: volume.?weeklyMinute ?? 0 - weeklySnapshotsToKeep: volume.?weeklySnapshotsToKeep ?? 0 - weeklyUsedBytes: volume.?weeklyUsedBytes ?? 0 - backupPolicyName: volume.?backupPolicyName ?? 'backupPolicy' - backupPolicyLocation: volume.?backupPolicyLocation ?? '' - dailyBackupsToKeep: volume.?dailyBackupsToKeep ?? 0 - backupEnabled: volume.?backupEnabled ?? false - monthlyBackupsToKeep: volume.?monthlyBackupsToKeep ?? 0 - weeklyBackupsToKeep: volume.?weeklyBackupsToKeep ?? 0 - backupVaultName: volume.?backupVaultName ?? 'vault' - backupVaultLocation: volume.?backupVaultLocation ?? '' - backupName: volume.?backupName ?? 'backup' - backupLabel: volume.?backupLabel ?? '' - snapshotName: volume.?snapshotName ?? 'snapshot' - useExistingSnapshot: volume.?useExistingSnapshot ?? false - volumeResourceId: volume.?volumeResourceId ?? '' - volumeType: volume.?volumeType ?? '' - backupVaultResourceId: volume.?backupVaultResourceId ?? '' - replicationEnabled: volume.?replicationEnabled ?? false + keyVaultPrivateEndpointResourceId: volume.?keyVaultPrivateEndpointResourceId + dataProtection: volume.?dataProtection } } ] @@ -188,4 +149,78 @@ output resourceGroupName string = resourceGroup().name output location string = capacityPool.location @description('The resource IDs of the volume created in the capacity pool.') -output volumeResourceId string = (volumes != []) ? capacityPool_volumes[0].outputs.resourceId : '' +output volumeResourceIds string[] = [ + for (volume, index) in (volumes ?? []): capacityPool_volumes[index].outputs.resourceId +] + +// ================ // +// Definitions // +// ================ // + +import { dataProtectionType, exportPolicyType } from 'volume/main.bicep' +@export() +@description('The type for a volume in the capacity pool.') +type volumeType = { + @description('Required. The name of the pool volume.') + name: string + + @description('Optional. If enabled (true) the pool can contain cool Access enabled volumes.') + coolAccess: bool? + + @description('Optional. Specifies the number of days after which data that is not accessed by clients will be tiered.') + coolnessPeriod: int? + + @description('Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read).') + coolAccessRetrievalPolicy: string? + + @description('Optional. The source of the encryption key.') + encryptionKeySource: string? + + @description('Optional. The resource ID of the key vault private endpoint.') + keyVaultPrivateEndpointResourceId: string? + + @description('Optional. DataProtection type volumes include an object containing details of the replication.') + dataProtection: dataProtectionType? + + @description('Optional. Location of the pool volume.') + location: string? + + @description('Optional. Zone where the volume will be placed.') + zones: int[]? + + @description('Optional. The pool service level. Must match the one of the parent capacity pool.') + serviceLevel: ('Premium' | 'Standard' | 'StandardZRS' | 'Ultra')? + + @description('Optional. Network feature for the volume.') + networkFeatures: ('Basic' | 'Basic_Standard' | 'Standard' | 'Standard_Basic')? + + @description('Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription.') + creationToken: string? + + @description('Required. Maximum storage quota allowed for a file system in bytes.') + usageThreshold: int + + @description('Optional. Set of protocol types.') + protocolTypes: string[]? + + @description('Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes.') + subnetResourceId: string + + @description('Optional. Export policy rules.') + exportPolicy: exportPolicyType? + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType[]? + + @description('Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume.') + smbEncryption: bool? + + @description('Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume.') + smbContinuouslyAvailable: bool? + + @description('Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume.') + smbNonBrowsable: ('Enabled' | 'Disabled')? + + @description('Optional. Define if a volume is KerberosEnabled.') + kerberosEnabled: bool? +} diff --git a/avm/res/net-app/net-app-account/capacity-pool/main.json b/avm/res/net-app/net-app-account/capacity-pool/main.json index e6820e2950..24da0da165 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/main.json @@ -5,13 +5,433 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17937651504078156143" + "version": "0.33.13.18514", + "templateHash": "2539920372355196545" }, "name": "Azure NetApp Files Capacity Pools", "description": "This module deploys an Azure NetApp Files Capacity Pool." }, "definitions": { + "volumeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "coolAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "coolnessPeriod": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the number of days after which data that is not accessed by clients will be tiered." + } + }, + "coolAccessRetrievalPolicy": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + } + }, + "encryptionKeySource": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The source of the encryption key." + } + }, + "keyVaultPrivateEndpointResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the key vault private endpoint." + } + }, + "dataProtection": { + "$ref": "#/definitions/dataProtectionType", + "nullable": true, + "metadata": { + "description": "Optional. DataProtection type volumes include an object containing details of the replication." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, + "zones": { + "type": "array", + "items": { + "type": "int" + }, + "nullable": true, + "metadata": { + "description": "Optional. Zone where the volume will be placed." + } + }, + "serviceLevel": { + "type": "string", + "allowedValues": [ + "Premium", + "Standard", + "StandardZRS", + "Ultra" + ], + "nullable": true, + "metadata": { + "description": "Optional. The pool service level. Must match the one of the parent capacity pool." + } + }, + "networkFeatures": { + "type": "string", + "allowedValues": [ + "Basic", + "Basic_Standard", + "Standard", + "Standard_Basic" + ], + "nullable": true, + "metadata": { + "description": "Optional. Network feature for the volume." + } + }, + "creationToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription." + } + }, + "usageThreshold": { + "type": "int", + "metadata": { + "description": "Required. Maximum storage quota allowed for a file system in bytes." + } + }, + "protocolTypes": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Set of protocol types." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." + } + }, + "exportPolicy": { + "$ref": "#/definitions/exportPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. Export policy rules." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "smbEncryption": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume." + } + }, + "smbContinuouslyAvailable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume." + } + }, + "smbNonBrowsable": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." + } + }, + "kerberosEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a volume in the capacity pool." + } + }, + "_1.backupType": { + "type": "object", + "properties": { + "backupPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the backup policy to link." + } + }, + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Backup Vault." + } + } + }, + "metadata": { + "description": "The type for the backup properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "_1.replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, + "metadata": { + "description": "The type for the replication properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "_1.snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, + "metadata": { + "description": "The type for the snapshot properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/_1.replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/_1.backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/_1.snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, + "metadata": { + "description": "The type for the data protection properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, + "metadata": { + "description": "The type for export policy rules.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, "roleAssignmentType": { "type": "object", "properties": { @@ -147,9 +567,12 @@ }, "volumes": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/volumeType" + }, + "nullable": true, "metadata": { - "description": "Optional. List of volumnes to create in the capacity pool." + "description": "Optional. List of volumes to create in the capacity pool." } }, "coolAccess": { @@ -243,7 +666,7 @@ "capacityPool_volumes": { "copy": { "name": "capacityPool_volumes", - "count": "[length(parameters('volumes'))]", + "count": "[length(coalesce(parameters('volumes'), createArray()))]", "mode": "serial", "batchSize": 1 }, @@ -263,7 +686,7 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('volumes')[copyIndex()].name]" + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].name]" }, "location": { "value": "[parameters('location')]" @@ -272,179 +695,291 @@ "value": "[parameters('serviceLevel')]" }, "creationToken": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'creationToken'), parameters('volumes')[copyIndex()].name)]" + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'creationToken'), coalesce(parameters('volumes'), createArray())[copyIndex()].name)]" }, "usageThreshold": { - "value": "[parameters('volumes')[copyIndex()].usageThreshold]" + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].usageThreshold]" }, "protocolTypes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'protocolTypes'), createArray())]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'protocolTypes')]" }, "subnetResourceId": { - "value": "[parameters('volumes')[copyIndex()].subnetResourceId]" + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].subnetResourceId]" }, - "exportPolicyRules": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'exportPolicyRules'), createArray())]" + "exportPolicy": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'exportPolicy')]" }, "roleAssignments": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'roleAssignments'), createArray())]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'roleAssignments')]" }, "networkFeatures": { - "value": "[tryGet(parameters('volumes')[copyIndex()], 'networkFeatures')]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'networkFeatures')]" }, "zones": { - "value": "[tryGet(parameters('volumes')[copyIndex()], 'zones')]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'zones')]" }, "coolAccess": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolAccess'), false())]" + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolAccess'), false())]" }, "coolAccessRetrievalPolicy": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolAccessRetrievalPolicy'), 'Default')]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolAccessRetrievalPolicy')]" }, "coolnessPeriod": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolnessPeriod'), 0)]" + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolnessPeriod'), 0)]" }, "encryptionKeySource": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'encryptionKeySource'), 'Microsoft.NetApp')]" + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'encryptionKeySource'), 'Microsoft.NetApp')]" }, "keyVaultPrivateEndpointResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'keyVaultPrivateEndpointResourceId'), '')]" - }, - "endpointType": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'endpointType'), '')]" - }, - "remoteVolumeRegion": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'remoteVolumeRegion'), '')]" - }, - "remoteVolumeResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'remoteVolumeResourceId'), '')]" - }, - "replicationSchedule": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'replicationSchedule'), '')]" - }, - "snapshotPolicyName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotPolicyName'), 'snapshotPolicy')]" - }, - "snapshotPolicyLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotPolicyLocation'), '')]" - }, - "snapEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapEnabled'), false())]" - }, - "dailyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyHour'), 0)]" + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'keyVaultPrivateEndpointResourceId')]" }, - "dailyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyMinute'), 0)]" - }, - "dailySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailySnapshotsToKeep'), 0)]" - }, - "dailyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyUsedBytes'), 0)]" - }, - "hourlyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlyMinute'), 0)]" - }, - "hourlySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlySnapshotsToKeep'), 0)]" - }, - "hourlyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlyUsedBytes'), 0)]" - }, - "daysOfMonth": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'daysOfMonth'), '')]" - }, - "monthlyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyHour'), 0)]" - }, - "monthlyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyMinute'), 0)]" - }, - "monthlySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlySnapshotsToKeep'), 0)]" - }, - "monthlyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyUsedBytes'), 0)]" - }, - "weeklyDay": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyDay'), '')]" - }, - "weeklyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyHour'), 0)]" - }, - "weeklyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyMinute'), 0)]" - }, - "weeklySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklySnapshotsToKeep'), 0)]" - }, - "weeklyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyUsedBytes'), 0)]" - }, - "backupPolicyName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupPolicyName'), 'backupPolicy')]" - }, - "backupPolicyLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupPolicyLocation'), '')]" - }, - "dailyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyBackupsToKeep'), 0)]" - }, - "backupEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupEnabled'), false())]" - }, - "monthlyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyBackupsToKeep'), 0)]" - }, - "weeklyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyBackupsToKeep'), 0)]" - }, - "backupVaultName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultName'), 'vault')]" - }, - "backupVaultLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultLocation'), '')]" - }, - "backupName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupName'), 'backup')]" - }, - "backupLabel": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupLabel'), '')]" - }, - "snapshotName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotName'), 'snapshot')]" - }, - "useExistingSnapshot": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'useExistingSnapshot'), false())]" - }, - "volumeResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'volumeResourceId'), '')]" - }, - "volumeType": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'volumeType'), '')]" - }, - "backupVaultResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultResourceId'), '')]" - }, - "replicationEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'replicationEnabled'), false())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15336007196805099128" - }, - "name": "Azure NetApp Files Capacity Pool Volumes", - "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." + "dataProtection": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'dataProtection')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "8045934107791458590" + }, + "name": "Azure NetApp Files Capacity Pool Volumes", + "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." }, "definitions": { + "dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for the data protection properties." + } + }, + "replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, + "metadata": { + "description": "The type for the replication properties." + } + }, + "backupType": { + "type": "object", + "properties": { + "backupPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the backup policy to link." + } + }, + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Backup Vault." + } + } + }, + "metadata": { + "description": "The type for the backup properties." + } + }, + "snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, + "metadata": { + "description": "The type for the snapshot properties." + } + }, + "exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for export policy rules." + } + }, "roleAssignmentType": { "type": "object", "properties": { @@ -534,6 +1069,19 @@ "description": "Conditional. The name of the parent capacity pool. Required if the template is used in a standalone deployment." } }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, "coolAccess": { "type": "bool", "metadata": { @@ -550,7 +1098,7 @@ "type": "string", "defaultValue": "Default", "metadata": { - "description": "Optional. determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." } }, "encryptionKeySource": { @@ -561,272 +1109,32 @@ }, "keyVaultPrivateEndpointResourceId": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The resource ID of the key vault private endpoint." - } - }, - "endpointType": { - "type": "string", - "metadata": { - "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication (src/dst)." - } - }, - "remoteVolumeRegion": { - "type": "string", - "metadata": { - "description": "Required. The remote region for the other end of the Volume Replication." - } - }, - "remoteVolumeResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the remote volume." - } - }, - "replicationSchedule": { - "type": "string", - "metadata": { - "description": "Required. The replication schedule for the volume." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." - } - }, - "backupVaultName": { - "type": "string", - "defaultValue": "vault", - "metadata": { - "description": "Optional. The name of the backup vault." - } - }, - "backupVaultLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the backup vault." - } - }, - "backupName": { - "type": "string", - "metadata": { - "description": "Required. The name of the backup." - } - }, - "backupLabel": { - "type": "string", - "metadata": { - "description": "Required. The label of the backup." - } - }, - "useExistingSnapshot": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether to use an existing snapshot." - } - }, - "snapshotName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot." - } - }, - "volumeResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the volume." + "description": "Optional. The resource ID of the key vault private endpoint." } }, "volumeType": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The type of the volume. DataProtection volumes are used for replication." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the pool volume." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location of the pool volume." + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." } }, "zones": { "type": "array", + "items": { + "type": "int" + }, "defaultValue": [ - "1" + 1, + 2, + 3 ], "metadata": { "description": "Optional. Zone where the volume will be placed." } }, - "policyEnforced": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If Backup policy is enforced." - } - }, - "backupPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The backup policy location." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The location of snashot policies." - } - }, "serviceLevel": { "type": "string", "defaultValue": "Standard", @@ -879,11 +1187,11 @@ "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." } }, - "exportPolicyRules": { - "type": "array", - "defaultValue": [], + "exportPolicy": { + "$ref": "#/definitions/exportPolicyType", + "nullable": true, "metadata": { - "description": "Optional. Export policy rules." + "description": "Optional. The export policy rules." } }, "roleAssignments": { @@ -896,17 +1204,11 @@ "description": "Optional. Array of role assignments to create." } }, - "backupVaultResourceId": { - "type": "string", - "metadata": { - "description": "Required. The Id of the Backup Vault." - } - }, - "replicationEnabled": { - "type": "bool", - "defaultValue": true, + "dataProtection": { + "$ref": "#/definitions/dataProtectionType", + "nullable": true, "metadata": { - "description": "Optional. Enables replication." + "description": "Optional. DataProtection type volumes include an object containing details of the replication." } }, "smbEncryption": { @@ -933,6 +1235,13 @@ "metadata": { "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." } + }, + "kerberosEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } } }, "variables": { @@ -958,43 +1267,92 @@ "apiVersion": "2024-03-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, + "netAppAccount::backupVault": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))]" + }, + "netAppAccount::backupPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName'))]" + }, + "netAppAccount::snapshotPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'snapshot')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))]" + }, + "remoteNetAppAccount::remoteCapacityPool::remoteVolume": { + "condition": "[and(and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication')))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}/{2}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/')))]" + }, + "remoteNetAppAccount::remoteCapacityPool": { + "condition": "[and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10])]" + }, + "vnet::subnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[format('{0}/{1}', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/')))]" + }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", "apiVersion": "2024-03-01", "name": "[parameters('netAppAccountName')]" }, - "volume": { - "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "keyVaultPrivateEndpoint": { + "condition": "[not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp'))]", + "existing": true, + "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', parameters('keyVaultPrivateEndpointResourceId')), createObject()), if(not(equals(parameters('volumeType'), '')), createObject('volumeType', parameters('volumeType'), 'dataProtection', createObject('replication', if(parameters('replicationEnabled'), createObject('endpointType', parameters('endpointType'), 'remoteVolumeRegion', parameters('remoteVolumeRegion'), 'remoteVolumeResourceId', parameters('remoteVolumeResourceId'), 'replicationSchedule', parameters('replicationSchedule')), createObject()), 'backup', if(parameters('backupEnabled'), createObject('backupPolicyId', reference('backupPolicies').outputs.resourceId.value, 'policyEnforced', parameters('policyEnforced'), 'backupVaultId', parameters('backupVaultResourceId')), createObject()), 'snapshot', if(parameters('snapEnabled'), createObject('snapshotPolicyId', reference('snapshotPolicies').outputs.resourceId.value), createObject()))), createObject()), createObject('networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', parameters('subnetResourceId'), 'exportPolicy', if(not(empty(parameters('exportPolicyRules'))), createObject('rules', parameters('exportPolicyRules')), null()), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'))))]", - "zones": "[parameters('zones')]", - "dependsOn": [ - "backupPolicies", - "backupVaults", - "snapshotPolicies" - ] + "subscriptionId": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/'))]" }, - "backupVaults": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "remoteNetAppAccount": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'replication')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]", - "location": "[parameters('backupVaultLocation')]", - "properties": {} + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8]]" }, - "backups": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", + "vnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('backupName'))]", - "properties": "[if(parameters('backupEnabled'), createObject('label', parameters('backupLabel'), 'snapshotName', parameters('snapshotName'), 'useExistingSnapshot', parameters('useExistingSnapshot'), 'volumeResourceId', parameters('volumeResourceId')), createObject())]", - "dependsOn": [ - "backupVaults", - "volume" - ] + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[split(parameters('subnetResourceId'), '/')[8]]" + }, + "volume": { + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" }, "volume_roleAssignments": { "copy": { @@ -1017,411 +1375,6 @@ "dependsOn": [ "volume" ] - }, - "backupPolicies": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[parameters('backupPolicyName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyBackupsToKeep": { - "value": "[parameters('dailyBackupsToKeep')]" - }, - "monthlyBackupsToKeep": { - "value": "[parameters('monthlyBackupsToKeep')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "weeklyBackupsToKeep": { - "value": "[parameters('weeklyBackupsToKeep')]" - }, - "backupEnabled": { - "value": "[parameters('backupEnabled')]" - }, - "backupPolicyLocation": { - "value": "[parameters('backupPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2321320275404095362" - }, - "name": "Azure NetApp Files Backup Policy", - "description": "This module deploys a Backup Policy for Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "backupPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The location of the backup policy. Required if the template is used in a standalone deployment." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - } - }, - "resources": [ - { - "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupPolicyName'))]", - "location": "[parameters('backupPolicyLocation')]", - "properties": { - "dailyBackupsToKeep": "[parameters('dailyBackupsToKeep')]", - "enabled": "[parameters('backupEnabled')]", - "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]", - "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]" - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the backup Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('backupPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('backupPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Backup Policy was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - } - }, - "snapshotPolicies": { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[uniqueString(parameters('snapshotPolicyName'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyHour": { - "value": "[parameters('dailyHour')]" - }, - "dailyMinute": { - "value": "[parameters('dailyMinute')]" - }, - "dailySnapshotsToKeep": { - "value": "[parameters('dailySnapshotsToKeep')]" - }, - "dailyUsedBytes": { - "value": "[parameters('dailyUsedBytes')]" - }, - "daysOfMonth": { - "value": "[parameters('daysOfMonth')]" - }, - "hourlyMinute": { - "value": "[parameters('hourlyMinute')]" - }, - "hourlySnapshotsToKeep": { - "value": "[parameters('hourlySnapshotsToKeep')]" - }, - "hourlyUsedBytes": { - "value": "[parameters('hourlyUsedBytes')]" - }, - "monthlyHour": { - "value": "[parameters('monthlyHour')]" - }, - "monthlyMinute": { - "value": "[parameters('monthlyMinute')]" - }, - "monthlySnapshotsToKeep": { - "value": "[parameters('monthlySnapshotsToKeep')]" - }, - "monthlyUsedBytes": { - "value": "[parameters('monthlyUsedBytes')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "snapshotPolicyName": { - "value": "[parameters('snapshotPolicyName')]" - }, - "weeklyDay": { - "value": "[parameters('weeklyDay')]" - }, - "weeklyHour": { - "value": "[parameters('weeklyHour')]" - }, - "weeklyMinute": { - "value": "[parameters('weeklyMinute')]" - }, - "weeklySnapshotsToKeep": { - "value": "[parameters('weeklySnapshotsToKeep')]" - }, - "weeklyUsedBytes": { - "value": "[parameters('weeklyUsedBytes')]" - }, - "snapshotPolicyLocation": { - "value": "[parameters('snapshotPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17538391796648994915" - }, - "name": "Azure NetApp Files Snapshot Policy", - "description": "This module deploys a Snapshot Policy for an Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the snapshot policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - } - }, - "resources": [ - { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]", - "location": "[parameters('snapshotPolicyLocation')]", - "properties": { - "enabled": "[parameters('snapEnabled')]", - "dailySchedule": { - "hour": "[parameters('dailyHour')]", - "minute": "[parameters('dailyMinute')]", - "snapshotsToKeep": "[parameters('dailySnapshotsToKeep')]", - "usedBytes": "[parameters('dailyUsedBytes')]" - }, - "hourlySchedule": { - "minute": "[parameters('hourlyMinute')]", - "snapshotsToKeep": "[parameters('hourlySnapshotsToKeep')]", - "usedBytes": "[parameters('hourlyUsedBytes')]" - }, - "monthlySchedule": { - "daysOfMonth": "[parameters('daysOfMonth')]", - "hour": "[parameters('monthlyHour')]", - "minute": "[parameters('monthlyMinute')]", - "snapshotsToKeep": "[parameters('monthlySnapshotsToKeep')]", - "usedBytes": "[parameters('monthlyUsedBytes')]" - }, - "weeklySchedule": { - "day": "[parameters('weeklyDay')]", - "hour": "[parameters('weeklyHour')]", - "minute": "[parameters('weeklyMinute')]", - "snapshotsToKeep": "[parameters('weeklySnapshotsToKeep')]", - "usedBytes": "[parameters('weeklyUsedBytes')]" - } - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the snapshot Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('snapshotPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Snapshot was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - } } }, "outputs": { @@ -1490,12 +1443,18 @@ }, "value": "[reference('capacityPool', '2024-03-01', 'full').location]" }, - "volumeResourceId": { - "type": "string", + "volumeResourceIds": { + "type": "array", + "items": { + "type": "string" + }, "metadata": { "description": "The resource IDs of the volume created in the capacity pool." }, - "value": "[if(not(equals(parameters('volumes'), createArray())), reference(format('capacityPool_volumes[{0}]', 0)).outputs.resourceId.value, '')]" + "copy": { + "count": "[length(coalesce(parameters('volumes'), createArray()))]", + "input": "[reference(format('capacityPool_volumes[{0}]', copyIndex())).outputs.resourceId.value]" + } } } } \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/README.md b/avm/res/net-app/net-app-account/capacity-pool/volume/README.md index c7e044a53c..c6cc4dd229 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/README.md +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/README.md @@ -14,11 +14,7 @@ This module deploys an Azure NetApp Files Capacity Pool Volume. | 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.NetApp/netAppAccounts/backupPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupPolicies) | -| `Microsoft.NetApp/netAppAccounts/backupVaults` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults) | -| `Microsoft.NetApp/netAppAccounts/backupVaults/backups` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/backupVaults/backups) | | `Microsoft.NetApp/netAppAccounts/capacityPools/volumes` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/capacityPools/volumes) | -| `Microsoft.NetApp/netAppAccounts/snapshotPolicies` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.NetApp/2024-03-01/netAppAccounts/snapshotPolicies) | ## Parameters @@ -26,47 +22,12 @@ This module deploys an Azure NetApp Files Capacity Pool Volume. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`backupLabel`](#parameter-backuplabel) | string | The label of the backup. | -| [`backupName`](#parameter-backupname) | string | The name of the backup. | -| [`backupPolicyLocation`](#parameter-backuppolicylocation) | string | The backup policy location. | -| [`backupVaultResourceId`](#parameter-backupvaultresourceid) | string | The Id of the Backup Vault. | | [`coolAccess`](#parameter-coolaccess) | bool | If enabled (true) the pool can contain cool Access enabled volumes. | | [`coolnessPeriod`](#parameter-coolnessperiod) | int | Specifies the number of days after which data that is not accessed by clients will be tiered. | -| [`dailyBackupsToKeep`](#parameter-dailybackupstokeep) | int | The daily backups to keep. | -| [`dailyHour`](#parameter-dailyhour) | int | The daily snapshot hour. | -| [`dailyMinute`](#parameter-dailyminute) | int | The daily snapshot minute. | -| [`dailySnapshotsToKeep`](#parameter-dailysnapshotstokeep) | int | Daily snapshot count to keep. | -| [`dailyUsedBytes`](#parameter-dailyusedbytes) | int | Daily snapshot used bytes. | -| [`daysOfMonth`](#parameter-daysofmonth) | string | The monthly snapshot day. | | [`encryptionKeySource`](#parameter-encryptionkeysource) | string | The source of the encryption key. | -| [`endpointType`](#parameter-endpointtype) | string | Indicates whether the local volume is the source or destination for the Volume Replication (src/dst). | -| [`hourlyMinute`](#parameter-hourlyminute) | int | The hourly snapshot minute. | -| [`hourlySnapshotsToKeep`](#parameter-hourlysnapshotstokeep) | int | Hourly snapshot count to keep. | -| [`hourlyUsedBytes`](#parameter-hourlyusedbytes) | int | Hourly snapshot used bytes. | -| [`keyVaultPrivateEndpointResourceId`](#parameter-keyvaultprivateendpointresourceid) | string | The resource ID of the key vault private endpoint. | -| [`monthlyBackupsToKeep`](#parameter-monthlybackupstokeep) | int | The monthly backups to keep. | -| [`monthlyHour`](#parameter-monthlyhour) | int | The monthly snapshot hour. | -| [`monthlyMinute`](#parameter-monthlyminute) | int | The monthly snapshot minute. | -| [`monthlySnapshotsToKeep`](#parameter-monthlysnapshotstokeep) | int | Monthly snapshot count to keep. | -| [`monthlyUsedBytes`](#parameter-monthlyusedbytes) | int | Monthly snapshot used bytes. | | [`name`](#parameter-name) | string | The name of the pool volume. | -| [`remoteVolumeRegion`](#parameter-remotevolumeregion) | string | The remote region for the other end of the Volume Replication. | -| [`remoteVolumeResourceId`](#parameter-remotevolumeresourceid) | string | The resource ID of the remote volume. | -| [`replicationSchedule`](#parameter-replicationschedule) | string | The replication schedule for the volume. | -| [`snapshotName`](#parameter-snapshotname) | string | The name of the snapshot. | -| [`snapshotPolicyLocation`](#parameter-snapshotpolicylocation) | string | The location of snashot policies. | -| [`snapshotPolicyName`](#parameter-snapshotpolicyname) | string | The name of the snapshot policy. | | [`subnetResourceId`](#parameter-subnetresourceid) | string | The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. | | [`usageThreshold`](#parameter-usagethreshold) | int | Maximum storage quota allowed for a file system in bytes. | -| [`useExistingSnapshot`](#parameter-useexistingsnapshot) | bool | Indicates whether to use an existing snapshot. | -| [`volumeResourceId`](#parameter-volumeresourceid) | string | The resource ID of the volume. | -| [`volumeType`](#parameter-volumetype) | string | The type of the volume. DataProtection volumes are used for replication. | -| [`weeklyBackupsToKeep`](#parameter-weeklybackupstokeep) | int | The weekly backups to keep. | -| [`weeklyDay`](#parameter-weeklyday) | string | The weekly snapshot day. | -| [`weeklyHour`](#parameter-weeklyhour) | int | The weekly snapshot hour. | -| [`weeklyMinute`](#parameter-weeklyminute) | int | The weekly snapshot minute. | -| [`weeklySnapshotsToKeep`](#parameter-weeklysnapshotstokeep) | int | Weekly snapshot count to keep. | -| [`weeklyUsedBytes`](#parameter-weeklyusedbytes) | int | Weekly snapshot used bytes. | **Conditional parameters** @@ -79,54 +40,23 @@ This module deploys an Azure NetApp Files Capacity Pool Volume. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`backupEnabled`](#parameter-backupenabled) | bool | Indicates whether the backup policy is enabled. | -| [`backupPolicyName`](#parameter-backuppolicyname) | string | The name of the backup policy. | -| [`backupVaultLocation`](#parameter-backupvaultlocation) | string | The location of the backup vault. | -| [`backupVaultName`](#parameter-backupvaultname) | string | The name of the backup vault. | -| [`coolAccessRetrievalPolicy`](#parameter-coolaccessretrievalpolicy) | string | determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). | +| [`coolAccessRetrievalPolicy`](#parameter-coolaccessretrievalpolicy) | string | Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). | | [`creationToken`](#parameter-creationtoken) | string | A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. | -| [`exportPolicyRules`](#parameter-exportpolicyrules) | array | Export policy rules. | +| [`dataProtection`](#parameter-dataprotection) | object | DataProtection type volumes include an object containing details of the replication. | +| [`exportPolicy`](#parameter-exportpolicy) | object | The export policy rules. | +| [`kerberosEnabled`](#parameter-kerberosenabled) | bool | Define if a volume is KerberosEnabled. | +| [`keyVaultPrivateEndpointResourceId`](#parameter-keyvaultprivateendpointresourceid) | string | The resource ID of the key vault private endpoint. | | [`location`](#parameter-location) | string | Location of the pool volume. | | [`networkFeatures`](#parameter-networkfeatures) | string | Network feature for the volume. | -| [`policyEnforced`](#parameter-policyenforced) | bool | If Backup policy is enforced. | | [`protocolTypes`](#parameter-protocoltypes) | array | Set of protocol types. | -| [`replicationEnabled`](#parameter-replicationenabled) | bool | Enables replication. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`serviceLevel`](#parameter-servicelevel) | string | The pool service level. Must match the one of the parent capacity pool. | | [`smbContinuouslyAvailable`](#parameter-smbcontinuouslyavailable) | bool | Enables continuously available share property for SMB volume. Only applicable for SMB volume. | | [`smbEncryption`](#parameter-smbencryption) | bool | Enables SMB encryption. Only applicable for SMB/DualProtocol volume. | | [`smbNonBrowsable`](#parameter-smbnonbrowsable) | string | Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume. | -| [`snapEnabled`](#parameter-snapenabled) | bool | Indicates whether the snapshot policy is enabled. | +| [`volumeType`](#parameter-volumetype) | string | The type of the volume. DataProtection volumes are used for replication. | | [`zones`](#parameter-zones) | array | Zone where the volume will be placed. | -### Parameter: `backupLabel` - -The label of the backup. - -- Required: Yes -- Type: string - -### Parameter: `backupName` - -The name of the backup. - -- Required: Yes -- Type: string - -### Parameter: `backupPolicyLocation` - -The backup policy location. - -- Required: Yes -- Type: string - -### Parameter: `backupVaultResourceId` - -The Id of the Backup Vault. - -- Required: Yes -- Type: string - ### Parameter: `coolAccess` If enabled (true) the pool can contain cool Access enabled volumes. @@ -141,320 +71,365 @@ Specifies the number of days after which data that is not accessed by clients wi - Required: Yes - Type: int -### Parameter: `dailyBackupsToKeep` +### Parameter: `encryptionKeySource` -The daily backups to keep. +The source of the encryption key. - Required: Yes -- Type: int +- Type: string -### Parameter: `dailyHour` +### Parameter: `name` -The daily snapshot hour. +The name of the pool volume. - Required: Yes -- Type: int +- Type: string -### Parameter: `dailyMinute` +### Parameter: `subnetResourceId` -The daily snapshot minute. +The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. - Required: Yes -- Type: int +- Type: string -### Parameter: `dailySnapshotsToKeep` +### Parameter: `usageThreshold` -Daily snapshot count to keep. +Maximum storage quota allowed for a file system in bytes. - Required: Yes - Type: int -### Parameter: `dailyUsedBytes` +### Parameter: `capacityPoolName` -Daily snapshot used bytes. +The name of the parent capacity pool. Required if the template is used in a standalone deployment. - Required: Yes -- Type: int +- Type: string -### Parameter: `daysOfMonth` +### Parameter: `netAppAccountName` -The monthly snapshot day. +The name of the parent NetApp account. Required if the template is used in a standalone deployment. - Required: Yes - Type: string -### Parameter: `encryptionKeySource` +### Parameter: `coolAccessRetrievalPolicy` -The source of the encryption key. +Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). -- Required: Yes +- Required: No - Type: string +- Default: `'Default'` -### Parameter: `endpointType` +### Parameter: `creationToken` -Indicates whether the local volume is the source or destination for the Volume Replication (src/dst). +A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. -- Required: Yes +- Required: No - Type: string +- Default: `[parameters('name')]` -### Parameter: `hourlyMinute` +### Parameter: `dataProtection` -The hourly snapshot minute. +DataProtection type volumes include an object containing details of the replication. -- Required: Yes -- Type: int - -### Parameter: `hourlySnapshotsToKeep` - -Hourly snapshot count to keep. +- Required: No +- Type: object -- Required: Yes -- Type: int +**Optional parameters** -### Parameter: `hourlyUsedBytes` +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backup`](#parameter-dataprotectionbackup) | object | Backup properties. | +| [`replication`](#parameter-dataprotectionreplication) | object | Replication properties. | +| [`snapshot`](#parameter-dataprotectionsnapshot) | object | Snapshot properties. | -Hourly snapshot used bytes. +### Parameter: `dataProtection.backup` -- Required: Yes -- Type: int +Backup properties. -### Parameter: `keyVaultPrivateEndpointResourceId` +- Required: No +- Type: object -The resource ID of the key vault private endpoint. +**Required parameters** -- Required: Yes -- Type: string +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`backupPolicyName`](#parameter-dataprotectionbackupbackuppolicyname) | string | The name of the backup policy to link. | +| [`backupVaultName`](#parameter-dataprotectionbackupbackupvaultname) | string | The name of the Backup Vault. | +| [`policyEnforced`](#parameter-dataprotectionbackuppolicyenforced) | bool | Enable to enforce the policy. | -### Parameter: `monthlyBackupsToKeep` +### Parameter: `dataProtection.backup.backupPolicyName` -The monthly backups to keep. +The name of the backup policy to link. - Required: Yes -- Type: int +- Type: string -### Parameter: `monthlyHour` +### Parameter: `dataProtection.backup.backupVaultName` -The monthly snapshot hour. +The name of the Backup Vault. - Required: Yes -- Type: int +- Type: string -### Parameter: `monthlyMinute` +### Parameter: `dataProtection.backup.policyEnforced` -The monthly snapshot minute. +Enable to enforce the policy. - Required: Yes -- Type: int +- Type: bool -### Parameter: `monthlySnapshotsToKeep` +### Parameter: `dataProtection.replication` -Monthly snapshot count to keep. +Replication properties. -- Required: Yes -- Type: int - -### Parameter: `monthlyUsedBytes` +- Required: No +- Type: object -Monthly snapshot used bytes. +**Required parameters** -- Required: Yes -- Type: int +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`endpointType`](#parameter-dataprotectionreplicationendpointtype) | string | Indicates whether the local volume is the source or destination for the Volume Replication. | +| [`remoteVolumeRegion`](#parameter-dataprotectionreplicationremotevolumeregion) | string | The remote region for the other end of the Volume Replication. | +| [`remoteVolumeResourceId`](#parameter-dataprotectionreplicationremotevolumeresourceid) | string | The resource ID of the remote volume. | +| [`replicationSchedule`](#parameter-dataprotectionreplicationreplicationschedule) | string | The replication schedule for the volume. | -### Parameter: `name` +### Parameter: `dataProtection.replication.endpointType` -The name of the pool volume. +Indicates whether the local volume is the source or destination for the Volume Replication. - Required: Yes - Type: string +- Allowed: + ```Bicep + [ + 'dst' + 'src' + ] + ``` -### Parameter: `remoteVolumeRegion` +### Parameter: `dataProtection.replication.remoteVolumeRegion` The remote region for the other end of the Volume Replication. - Required: Yes - Type: string -### Parameter: `remoteVolumeResourceId` +### Parameter: `dataProtection.replication.remoteVolumeResourceId` The resource ID of the remote volume. - Required: Yes - Type: string -### Parameter: `replicationSchedule` +### Parameter: `dataProtection.replication.replicationSchedule` The replication schedule for the volume. - Required: Yes - Type: string +- Allowed: + ```Bicep + [ + '_10minutely' + 'daily' + 'hourly' + ] + ``` -### Parameter: `snapshotName` +### Parameter: `dataProtection.snapshot` -The name of the snapshot. +Snapshot properties. -- Required: Yes -- Type: string +- Required: No +- Type: object -### Parameter: `snapshotPolicyLocation` +**Required parameters** -The location of snashot policies. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`snapshotPolicyName`](#parameter-dataprotectionsnapshotsnapshotpolicyname) | string | The name of the snapshot policy to link. | + +### Parameter: `dataProtection.snapshot.snapshotPolicyName` + +The name of the snapshot policy to link. - Required: Yes - Type: string -### Parameter: `snapshotPolicyName` +### Parameter: `exportPolicy` -The name of the snapshot policy. +The export policy rules. -- Required: Yes -- Type: string +- Required: No +- Type: object -### Parameter: `subnetResourceId` +**Required parameters** -The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rules`](#parameter-exportpolicyrules) | array | The Export policy rules. | + +### Parameter: `exportPolicy.rules` + +The Export policy rules. - Required: Yes -- Type: string +- Type: array -### Parameter: `usageThreshold` +**Required parameters** -Maximum storage quota allowed for a file system in bytes. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kerberos5iReadOnly`](#parameter-exportpolicyruleskerberos5ireadonly) | bool | Kerberos5i Read only access. | +| [`kerberos5iReadWrite`](#parameter-exportpolicyruleskerberos5ireadwrite) | bool | Kerberos5i Read and write access. | +| [`kerberos5pReadOnly`](#parameter-exportpolicyruleskerberos5preadonly) | bool | Kerberos5p Read only access. | +| [`kerberos5pReadWrite`](#parameter-exportpolicyruleskerberos5preadwrite) | bool | Kerberos5p Read and write access. | +| [`kerberos5ReadOnly`](#parameter-exportpolicyruleskerberos5readonly) | bool | Kerberos5 Read only access. | +| [`kerberos5ReadWrite`](#parameter-exportpolicyruleskerberos5readwrite) | bool | Kerberos5 Read and write access. | +| [`nfsv3`](#parameter-exportpolicyrulesnfsv3) | bool | Allows NFSv3 protocol. Enable only for NFSv3 type volumes. | +| [`nfsv41`](#parameter-exportpolicyrulesnfsv41) | bool | Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. | +| [`ruleIndex`](#parameter-exportpolicyrulesruleindex) | int | Order index. | +| [`unixReadOnly`](#parameter-exportpolicyrulesunixreadonly) | bool | Read only access. | +| [`unixReadWrite`](#parameter-exportpolicyrulesunixreadwrite) | bool | Read and write access. | -- Required: Yes -- Type: int +**Optional parameters** -### Parameter: `useExistingSnapshot` +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowedClients`](#parameter-exportpolicyrulesallowedclients) | string | Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. | +| [`chownMode`](#parameter-exportpolicyruleschownmode) | string | This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. | +| [`cifs`](#parameter-exportpolicyrulescifs) | bool | Allows CIFS protocol. | +| [`hasRootAccess`](#parameter-exportpolicyruleshasrootaccess) | bool | Has root access to volume. | -Indicates whether to use an existing snapshot. +### Parameter: `exportPolicy.rules.kerberos5iReadOnly` + +Kerberos5i Read only access. - Required: Yes - Type: bool -### Parameter: `volumeResourceId` +### Parameter: `exportPolicy.rules.kerberos5iReadWrite` -The resource ID of the volume. +Kerberos5i Read and write access. - Required: Yes -- Type: string +- Type: bool -### Parameter: `volumeType` +### Parameter: `exportPolicy.rules.kerberos5pReadOnly` -The type of the volume. DataProtection volumes are used for replication. +Kerberos5p Read only access. - Required: Yes -- Type: string +- Type: bool -### Parameter: `weeklyBackupsToKeep` +### Parameter: `exportPolicy.rules.kerberos5pReadWrite` -The weekly backups to keep. +Kerberos5p Read and write access. - Required: Yes -- Type: int +- Type: bool -### Parameter: `weeklyDay` +### Parameter: `exportPolicy.rules.kerberos5ReadOnly` -The weekly snapshot day. +Kerberos5 Read only access. - Required: Yes -- Type: string +- Type: bool -### Parameter: `weeklyHour` +### Parameter: `exportPolicy.rules.kerberos5ReadWrite` -The weekly snapshot hour. +Kerberos5 Read and write access. - Required: Yes -- Type: int +- Type: bool -### Parameter: `weeklyMinute` +### Parameter: `exportPolicy.rules.nfsv3` -The weekly snapshot minute. +Allows NFSv3 protocol. Enable only for NFSv3 type volumes. - Required: Yes -- Type: int +- Type: bool -### Parameter: `weeklySnapshotsToKeep` +### Parameter: `exportPolicy.rules.nfsv41` -Weekly snapshot count to keep. +Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes. - Required: Yes -- Type: int +- Type: bool -### Parameter: `weeklyUsedBytes` +### Parameter: `exportPolicy.rules.ruleIndex` -Weekly snapshot used bytes. +Order index. - Required: Yes - Type: int -### Parameter: `capacityPoolName` +### Parameter: `exportPolicy.rules.unixReadOnly` -The name of the parent capacity pool. Required if the template is used in a standalone deployment. +Read only access. - Required: Yes -- Type: string +- Type: bool -### Parameter: `netAppAccountName` +### Parameter: `exportPolicy.rules.unixReadWrite` -The name of the parent NetApp account. Required if the template is used in a standalone deployment. +Read and write access. - Required: Yes -- Type: string - -### Parameter: `backupEnabled` - -Indicates whether the backup policy is enabled. - -- Required: No - Type: bool -- Default: `False` -### Parameter: `backupPolicyName` +### Parameter: `exportPolicy.rules.allowedClients` -The name of the backup policy. +Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names. - Required: No - Type: string -- Default: `'backupPolicy'` -### Parameter: `backupVaultLocation` +### Parameter: `exportPolicy.rules.chownMode` -The location of the backup vault. +This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own. - Required: No - Type: string -- Default: `[resourceGroup().location]` +- Allowed: + ```Bicep + [ + 'Restricted' + 'Unrestricted' + ] + ``` -### Parameter: `backupVaultName` +### Parameter: `exportPolicy.rules.cifs` -The name of the backup vault. +Allows CIFS protocol. - Required: No -- Type: string -- Default: `'vault'` +- Type: bool -### Parameter: `coolAccessRetrievalPolicy` +### Parameter: `exportPolicy.rules.hasRootAccess` -determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read). +Has root access to volume. - Required: No -- Type: string -- Default: `'Default'` +- Type: bool -### Parameter: `creationToken` +### Parameter: `kerberosEnabled` -A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription. +Define if a volume is KerberosEnabled. - Required: No -- Type: string -- Default: `[parameters('name')]` +- Type: bool +- Default: `False` -### Parameter: `exportPolicyRules` +### Parameter: `keyVaultPrivateEndpointResourceId` -Export policy rules. +The resource ID of the key vault private endpoint. - Required: No -- Type: array -- Default: `[]` +- Type: string ### Parameter: `location` @@ -481,14 +456,6 @@ Network feature for the volume. ] ``` -### Parameter: `policyEnforced` - -If Backup policy is enforced. - -- Required: No -- Type: bool -- Default: `False` - ### Parameter: `protocolTypes` Set of protocol types. @@ -497,14 +464,6 @@ Set of protocol types. - Type: array - Default: `[]` -### Parameter: `replicationEnabled` - -Enables replication. - -- Required: No -- Type: bool -- Default: `True` - ### Parameter: `roleAssignments` Array of role assignments to create. @@ -656,13 +615,12 @@ Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProto ] ``` -### Parameter: `snapEnabled` +### Parameter: `volumeType` -Indicates whether the snapshot policy is enabled. +The type of the volume. DataProtection volumes are used for replication. - Required: No -- Type: bool -- Default: `True` +- Type: string ### Parameter: `zones` @@ -673,7 +631,9 @@ Zone where the volume will be placed. - Default: ```Bicep [ - '1' + 1 + 2 + 3 ] ``` @@ -692,6 +652,4 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `avm/res/net-app/net-app-account/backup-policies` | Local reference | -| `avm/res/net-app/net-app-account/snapshot-policies` | Local reference | | `br/public:avm/utl/types/avm-common-types:0.4.0` | Remote reference | diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep b/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep index 6b63ee8ec3..8d8b520830 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/main.bicep @@ -7,146 +7,32 @@ param netAppAccountName string @description('Conditional. The name of the parent capacity pool. Required if the template is used in a standalone deployment.') param capacityPoolName string +@description('Required. The name of the pool volume.') +param name string + +@description('Optional. Location of the pool volume.') +param location string = resourceGroup().location + @description('Required. If enabled (true) the pool can contain cool Access enabled volumes.') param coolAccess bool @description('Required. Specifies the number of days after which data that is not accessed by clients will be tiered.') param coolnessPeriod int -@description('Optional. determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read).') +@description('Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read).') param coolAccessRetrievalPolicy string = 'Default' @description('Required. The source of the encryption key.') param encryptionKeySource string -@description('Required. The resource ID of the key vault private endpoint.') -param keyVaultPrivateEndpointResourceId string - -@description('Required. Indicates whether the local volume is the source or destination for the Volume Replication (src/dst).') -param endpointType string - -@description('Required. The remote region for the other end of the Volume Replication.') -param remoteVolumeRegion string - -@description('Required. The resource ID of the remote volume.') -param remoteVolumeResourceId string - -@description('Required. The replication schedule for the volume.') -param replicationSchedule string - -@description('Optional. Indicates whether the backup policy is enabled.') -param backupEnabled bool = false - -@description('Optional. The name of the backup policy.') -param backupPolicyName string = 'backupPolicy' - -@description('Required. The daily snapshot hour.') -param dailyHour int - -@description('Required. The daily snapshot minute.') -param dailyMinute int - -@description('Required. Daily snapshot count to keep.') -param dailySnapshotsToKeep int - -@description('Required. Daily snapshot used bytes.') -param dailyUsedBytes int - -@description('Required. The hourly snapshot minute.') -param hourlyMinute int - -@description('Required. Hourly snapshot count to keep.') -param hourlySnapshotsToKeep int - -@description('Required. Hourly snapshot used bytes.') -param hourlyUsedBytes int - -@description('Required. The monthly snapshot day.') -param daysOfMonth string - -@description('Required. The monthly snapshot hour.') -param monthlyHour int - -@description('Required. The monthly snapshot minute.') -param monthlyMinute int - -@description('Required. Monthly snapshot count to keep.') -param monthlySnapshotsToKeep int - -@description('Required. Monthly snapshot used bytes.') -param monthlyUsedBytes int - -@description('Required. The weekly snapshot day.') -param weeklyDay string - -@description('Required. The weekly snapshot hour.') -param weeklyHour int - -@description('Required. The weekly snapshot minute.') -param weeklyMinute int - -@description('Required. Weekly snapshot count to keep.') -param weeklySnapshotsToKeep int - -@description('Required. Weekly snapshot used bytes.') -param weeklyUsedBytes int - -@description('Optional. Indicates whether the snapshot policy is enabled.') -param snapEnabled bool = true +@description('Optional. The resource ID of the key vault private endpoint.') +param keyVaultPrivateEndpointResourceId string? -@description('Required. The name of the snapshot policy.') -param snapshotPolicyName string - -@description('Required. The daily backups to keep.') -param dailyBackupsToKeep int - -@description('Required. The monthly backups to keep.') -param monthlyBackupsToKeep int - -@description('Required. The weekly backups to keep.') -param weeklyBackupsToKeep int - -@description('Optional. The name of the backup vault.') -param backupVaultName string = 'vault' - -@description('Optional. The location of the backup vault.') -param backupVaultLocation string = resourceGroup().location - -@description('Required. The name of the backup.') -param backupName string - -@description('Required. The label of the backup.') -param backupLabel string - -@description('Required. Indicates whether to use an existing snapshot.') -param useExistingSnapshot bool - -@description('Required. The name of the snapshot.') -param snapshotName string - -@description('Required. The resource ID of the volume.') -param volumeResourceId string - -@description('Required. The type of the volume. DataProtection volumes are used for replication.') -param volumeType string - -@description('Required. The name of the pool volume.') -param name string - -@description('Optional. Location of the pool volume.') -param location string = resourceGroup().location +@description('Optional. The type of the volume. DataProtection volumes are used for replication.') +param volumeType string? @description('Optional. Zone where the volume will be placed.') -param zones array = ['1'] - -@description('Optional. If Backup policy is enforced.') -param policyEnforced bool = false - -@description('Required. The backup policy location.') -param backupPolicyLocation string - -@description('Required. The location of snashot policies.') -param snapshotPolicyLocation string +param zones int[] = [1, 2, 3] @description('Optional. The pool service level. Must match the one of the parent capacity pool.') @allowed([ @@ -178,18 +64,15 @@ param protocolTypes array = [] @description('Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes.') param subnetResourceId string -@description('Optional. Export policy rules.') -param exportPolicyRules array = [] +@description('Optional. The export policy rules.') +param exportPolicy exportPolicyType? import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType[]? -@description('Required. The Id of the Backup Vault.') -param backupVaultResourceId string - -@description('Optional. Enables replication.') -param replicationEnabled bool = true +@description('Optional. DataProtection type volumes include an object containing details of the replication.') +param dataProtection dataProtectionType? @description('Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume.') param smbEncryption bool = false @@ -204,6 +87,9 @@ param smbContinuouslyAvailable bool = false ]) param smbNonBrowsable string = 'Disabled' +@description('Optional. Define if a volume is KerberosEnabled.') +param kerberosEnabled bool = false + var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') @@ -235,16 +121,57 @@ resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { resource capacityPool 'capacityPools@2024-03-01' existing = { name: capacityPoolName } + + resource backupVault 'backupVaults@2024-07-01' existing = if (!empty(dataProtection.?backup)) { + name: dataProtection.?backup!.backupVaultName + } + + resource backupPolicy 'backupPolicies@2024-03-01' existing = if (!empty(dataProtection.?backup)) { + name: dataProtection.?backup!.backupPolicyName + } + + resource snapshotPolicy 'snapshotPolicies@2024-03-01' existing = if (!empty(dataProtection.?snapshot)) { + name: dataProtection.?snapshot!.snapshotPolicyName + } +} + +resource keyVaultPrivateEndpoint 'Microsoft.Network/privateEndpoints@2024-03-01' existing = if (encryptionKeySource != 'Microsoft.NetApp') { + name: last(split(keyVaultPrivateEndpointResourceId ?? 'dummyVault', '/')) + scope: resourceGroup( + split((keyVaultPrivateEndpointResourceId ?? '//'), '/')[2], + split((keyVaultPrivateEndpointResourceId ?? '////'), '/')[4] + ) +} + +resource remoteNetAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = if (!empty(dataProtection.?replication)) { + name: split((dataProtection.?replication.?remoteVolumeResourceId ?? '//'), '/')[8] + scope: resourceGroup( + split((dataProtection.?replication.?remoteVolumeResourceId ?? '//'), '/')[2], + split((dataProtection.?replication.?remoteVolumeResourceId ?? '////'), '/')[4] + ) + + resource remoteCapacityPool 'capacityPools@2024-03-01' existing = if (!empty(dataProtection.?replication)) { + name: split((dataProtection.?replication.?remoteVolumeResourceId ?? '//'), '/')[10] + + resource remoteVolume 'volumes@2024-07-01' existing = if (!empty(dataProtection.?replication)) { + name: last(split(dataProtection.?replication.?remoteVolumeResourceId ?? 'dummyvolume', '/')) + } + } +} + +resource vnet 'Microsoft.Network/virtualNetworks@2024-03-01' existing = { + name: split(subnetResourceId, '/')[8] + scope: resourceGroup(split(subnetResourceId, '/')[2], split(subnetResourceId, '/')[4]) + + resource subnet 'subnets@2024-03-01' existing = { + name: last(split(subnetResourceId, '/')) + } } resource volume 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes@2024-03-01' = { name: name parent: netAppAccount::capacityPool location: location - dependsOn: [ - backupVaults - backupPolicies - ] properties: { coolAccess: coolAccess coolAccessRetrievalPolicy: coolAccessRetrievalPolicy @@ -252,114 +179,51 @@ resource volume 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes@2024-03-0 encryptionKeySource: encryptionKeySource ...(encryptionKeySource != 'Microsoft.NetApp' ? { - keyVaultPrivateEndpointResourceId: keyVaultPrivateEndpointResourceId + keyVaultPrivateEndpointResourceId: keyVaultPrivateEndpoint.id } : {}) - ...(volumeType != '' + ...(!empty(volumeType) ? { volumeType: volumeType - dataProtection: { - replication: replicationEnabled - ? { - endpointType: endpointType - remoteVolumeRegion: remoteVolumeRegion - remoteVolumeResourceId: remoteVolumeResourceId - replicationSchedule: replicationSchedule - } - : {} - - backup: backupEnabled - ? { - backupPolicyId: backupPolicies.outputs.resourceId - policyEnforced: policyEnforced - backupVaultId: backupVaultResourceId - } - : {} - snapshot: snapEnabled - ? { - snapshotPolicyId: snapshotPolicies.outputs.resourceId - } - : {} - } } : {}) + dataProtection: !empty(dataProtection) + ? { + replication: !empty(dataProtection.?replication) + ? { + endpointType: dataProtection.?replication!.endpointType + remoteVolumeRegion: remoteNetAppAccount::remoteCapacityPool::remoteVolume.id + remoteVolumeResourceId: dataProtection.?replication!.remoteVolumeResourceId + replicationSchedule: dataProtection.?replication!.replicationSchedule + } + : {} + backup: !empty(dataProtection.?backup) + ? { + backupPolicyId: netAppAccount::backupPolicy.id + policyEnforced: dataProtection.?backup.policyEnforced ?? false + backupVaultId: netAppAccount::backupVault.id + } + : {} + snapshot: !empty(dataProtection.?snapshot) + ? { + snapshotPolicyId: netAppAccount::snapshotPolicy.id + } + : {} + } + : null networkFeatures: networkFeatures serviceLevel: serviceLevel creationToken: creationToken usageThreshold: usageThreshold protocolTypes: protocolTypes - subnetId: subnetResourceId - exportPolicy: !empty(exportPolicyRules) - ? { - rules: exportPolicyRules - } - : null + subnetId: vnet::subnet.id + exportPolicy: exportPolicy smbContinuouslyAvailable: smbContinuouslyAvailable smbEncryption: smbEncryption smbNonBrowsable: smbNonBrowsable + kerberosEnabled: kerberosEnabled } - zones: zones -} - -module backupPolicies '../../backup-policies/main.bicep' = if (backupEnabled) { - name: backupPolicyName - params: { - dailyBackupsToKeep: dailyBackupsToKeep - monthlyBackupsToKeep: monthlyBackupsToKeep - netAppAccountName: netAppAccountName - weeklyBackupsToKeep: weeklyBackupsToKeep - backupEnabled: backupEnabled - backupPolicyLocation: backupPolicyLocation - } -} - -module snapshotPolicies '../../snapshot-policies/main.bicep' = if (snapEnabled) { - name: uniqueString(snapshotPolicyName) - params: { - dailyHour: dailyHour - dailyMinute: dailyMinute - dailySnapshotsToKeep: dailySnapshotsToKeep - dailyUsedBytes: dailyUsedBytes - daysOfMonth: daysOfMonth - hourlyMinute: hourlyMinute - hourlySnapshotsToKeep: hourlySnapshotsToKeep - hourlyUsedBytes: hourlyUsedBytes - monthlyHour: monthlyHour - monthlyMinute: monthlyMinute - monthlySnapshotsToKeep: monthlySnapshotsToKeep - monthlyUsedBytes: monthlyUsedBytes - netAppAccountName: netAppAccountName - snapshotPolicyName: snapshotPolicyName - weeklyDay: weeklyDay - weeklyHour: weeklyHour - weeklyMinute: weeklyMinute - weeklySnapshotsToKeep: weeklySnapshotsToKeep - weeklyUsedBytes: weeklyUsedBytes - snapshotPolicyLocation: snapshotPolicyLocation - } -} - -resource backupVaults 'Microsoft.NetApp/netAppAccounts/backupVaults@2024-03-01' = if (backupEnabled) { - name: backupVaultName - parent: netAppAccount - location: backupVaultLocation - properties: {} -} - -resource backups 'Microsoft.NetApp/netAppAccounts/backupVaults/backups@2024-03-01' = if (backupEnabled) { - name: backupName - parent: backupVaults - dependsOn: [ - volume - ] - properties: backupEnabled - ? { - label: backupLabel - snapshotName: snapshotName - useExistingSnapshot: useExistingSnapshot - volumeResourceId: volumeResourceId - } - : {} + zones: map(zones, zone => '${zone}') } resource volume_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ @@ -389,3 +253,104 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = volume.location + +// ================ // +// Definitions // +// ================ // +@export() +@description('The type for the data protection properties.') +type dataProtectionType = { + @description('Optional. Replication properties.') + replication: replicationType? + + @description('Optional. Backup properties.') + backup: backupType? + + @description('Optional. Snapshot properties.') + snapshot: snapshotType? +} + +@description('The type for the replication properties.') +type replicationType = { + @description('Required. Indicates whether the local volume is the source or destination for the Volume Replication.') + endpointType: ('dst' | 'src') + + @description('Required. The remote region for the other end of the Volume Replication.') + remoteVolumeRegion: string + + @description('Required. The resource ID of the remote volume.') + remoteVolumeResourceId: string + + @description('Required. The replication schedule for the volume.') + replicationSchedule: ('_10minutely' | 'daily' | 'hourly') +} + +@description('The type for the backup properties.') +type backupType = { + @description('Required. The name of the backup policy to link.') + backupPolicyName: string + + @description('Required. Enable to enforce the policy.') + policyEnforced: bool + + @description('Required. The name of the Backup Vault.') + backupVaultName: string +} + +@description('The type for the snapshot properties.') +type snapshotType = { + @description('Required. The name of the snapshot policy to link.') + snapshotPolicyName: string +} + +@export() +@description('The type for export policy rules.') +type exportPolicyType = { + @description('Required. The Export policy rules.') + rules: { + @description('Required. Order index.') + ruleIndex: int + + @description('Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names.') + allowedClients: string? + + @description('Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own.') + chownMode: ('Restricted' | 'Unrestricted')? + + @description('Optional. Allows CIFS protocol.') + cifs: bool? + + @description('Optional. Has root access to volume.') + hasRootAccess: bool? + + @description('Required. Kerberos5 Read only access.') + kerberos5ReadOnly: bool + + @description('Required. Kerberos5 Read and write access.') + kerberos5ReadWrite: bool + + @description('Required. Kerberos5i Read only access.') + kerberos5iReadOnly: bool + + @description('Required. Kerberos5i Read and write access.') + kerberos5iReadWrite: bool + + @description('Required. Kerberos5p Read only access.') + kerberos5pReadOnly: bool + + @description('Required. Kerberos5p Read and write access.') + kerberos5pReadWrite: bool + + @description('Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes.') + nfsv3: bool + + @description('Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes.') + nfsv41: bool + + @description('Required. Read only access.') + unixReadOnly: bool + + @description('Required. Read and write access.') + unixReadWrite: bool + }[] +} diff --git a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json index 7c0f8357ba..fbc1d6f298 100644 --- a/avm/res/net-app/net-app-account/capacity-pool/volume/main.json +++ b/avm/res/net-app/net-app-account/capacity-pool/volume/main.json @@ -5,13 +5,242 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15336007196805099128" + "version": "0.33.13.18514", + "templateHash": "8045934107791458590" }, "name": "Azure NetApp Files Capacity Pool Volumes", "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." }, "definitions": { + "dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for the data protection properties." + } + }, + "replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, + "metadata": { + "description": "The type for the replication properties." + } + }, + "backupType": { + "type": "object", + "properties": { + "backupPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the backup policy to link." + } + }, + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Backup Vault." + } + } + }, + "metadata": { + "description": "The type for the backup properties." + } + }, + "snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, + "metadata": { + "description": "The type for the snapshot properties." + } + }, + "exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for export policy rules." + } + }, "roleAssignmentType": { "type": "object", "properties": { @@ -101,6 +330,19 @@ "description": "Conditional. The name of the parent capacity pool. Required if the template is used in a standalone deployment." } }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, "coolAccess": { "type": "bool", "metadata": { @@ -117,7 +359,7 @@ "type": "string", "defaultValue": "Default", "metadata": { - "description": "Optional. determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." } }, "encryptionKeySource": { @@ -128,272 +370,32 @@ }, "keyVaultPrivateEndpointResourceId": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The resource ID of the key vault private endpoint." - } - }, - "endpointType": { - "type": "string", - "metadata": { - "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication (src/dst)." - } - }, - "remoteVolumeRegion": { - "type": "string", - "metadata": { - "description": "Required. The remote region for the other end of the Volume Replication." - } - }, - "remoteVolumeResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the remote volume." - } - }, - "replicationSchedule": { - "type": "string", - "metadata": { - "description": "Required. The replication schedule for the volume." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." - } - }, - "backupVaultName": { - "type": "string", - "defaultValue": "vault", - "metadata": { - "description": "Optional. The name of the backup vault." - } - }, - "backupVaultLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the backup vault." - } - }, - "backupName": { - "type": "string", - "metadata": { - "description": "Required. The name of the backup." - } - }, - "backupLabel": { - "type": "string", - "metadata": { - "description": "Required. The label of the backup." - } - }, - "useExistingSnapshot": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether to use an existing snapshot." - } - }, - "snapshotName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot." - } - }, - "volumeResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the volume." + "description": "Optional. The resource ID of the key vault private endpoint." } }, "volumeType": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The type of the volume. DataProtection volumes are used for replication." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the pool volume." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location of the pool volume." + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." } }, "zones": { "type": "array", + "items": { + "type": "int" + }, "defaultValue": [ - "1" + 1, + 2, + 3 ], "metadata": { "description": "Optional. Zone where the volume will be placed." } }, - "policyEnforced": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If Backup policy is enforced." - } - }, - "backupPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The backup policy location." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The location of snashot policies." - } - }, "serviceLevel": { "type": "string", "defaultValue": "Standard", @@ -446,11 +448,11 @@ "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." } }, - "exportPolicyRules": { - "type": "array", - "defaultValue": [], + "exportPolicy": { + "$ref": "#/definitions/exportPolicyType", + "nullable": true, "metadata": { - "description": "Optional. Export policy rules." + "description": "Optional. The export policy rules." } }, "roleAssignments": { @@ -463,17 +465,11 @@ "description": "Optional. Array of role assignments to create." } }, - "backupVaultResourceId": { - "type": "string", - "metadata": { - "description": "Required. The Id of the Backup Vault." - } - }, - "replicationEnabled": { - "type": "bool", - "defaultValue": true, + "dataProtection": { + "$ref": "#/definitions/dataProtectionType", + "nullable": true, "metadata": { - "description": "Optional. Enables replication." + "description": "Optional. DataProtection type volumes include an object containing details of the replication." } }, "smbEncryption": { @@ -500,6 +496,13 @@ "metadata": { "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." } + }, + "kerberosEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } } }, "variables": { @@ -525,43 +528,92 @@ "apiVersion": "2024-03-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, + "netAppAccount::backupVault": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))]" + }, + "netAppAccount::backupPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName'))]" + }, + "netAppAccount::snapshotPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'snapshot')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))]" + }, + "remoteNetAppAccount::remoteCapacityPool::remoteVolume": { + "condition": "[and(and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication')))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}/{2}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/')))]" + }, + "remoteNetAppAccount::remoteCapacityPool": { + "condition": "[and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10])]" + }, + "vnet::subnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[format('{0}/{1}', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/')))]" + }, "netAppAccount": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts", "apiVersion": "2024-03-01", "name": "[parameters('netAppAccountName')]" }, - "volume": { - "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "keyVaultPrivateEndpoint": { + "condition": "[not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp'))]", + "existing": true, + "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', parameters('keyVaultPrivateEndpointResourceId')), createObject()), if(not(equals(parameters('volumeType'), '')), createObject('volumeType', parameters('volumeType'), 'dataProtection', createObject('replication', if(parameters('replicationEnabled'), createObject('endpointType', parameters('endpointType'), 'remoteVolumeRegion', parameters('remoteVolumeRegion'), 'remoteVolumeResourceId', parameters('remoteVolumeResourceId'), 'replicationSchedule', parameters('replicationSchedule')), createObject()), 'backup', if(parameters('backupEnabled'), createObject('backupPolicyId', reference('backupPolicies').outputs.resourceId.value, 'policyEnforced', parameters('policyEnforced'), 'backupVaultId', parameters('backupVaultResourceId')), createObject()), 'snapshot', if(parameters('snapEnabled'), createObject('snapshotPolicyId', reference('snapshotPolicies').outputs.resourceId.value), createObject()))), createObject()), createObject('networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', parameters('subnetResourceId'), 'exportPolicy', if(not(empty(parameters('exportPolicyRules'))), createObject('rules', parameters('exportPolicyRules')), null()), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'))))]", - "zones": "[parameters('zones')]", - "dependsOn": [ - "backupPolicies", - "backupVaults", - "snapshotPolicies" - ] + "subscriptionId": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/'))]" }, - "backupVaults": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "remoteNetAppAccount": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'replication')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]", - "location": "[parameters('backupVaultLocation')]", - "properties": {} + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8]]" }, - "backups": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", + "vnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('backupName'))]", - "properties": "[if(parameters('backupEnabled'), createObject('label', parameters('backupLabel'), 'snapshotName', parameters('snapshotName'), 'useExistingSnapshot', parameters('useExistingSnapshot'), 'volumeResourceId', parameters('volumeResourceId')), createObject())]", - "dependsOn": [ - "backupVaults", - "volume" - ] + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[split(parameters('subnetResourceId'), '/')[8]]" + }, + "volume": { + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" }, "volume_roleAssignments": { "copy": { @@ -584,411 +636,6 @@ "dependsOn": [ "volume" ] - }, - "backupPolicies": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[parameters('backupPolicyName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyBackupsToKeep": { - "value": "[parameters('dailyBackupsToKeep')]" - }, - "monthlyBackupsToKeep": { - "value": "[parameters('monthlyBackupsToKeep')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "weeklyBackupsToKeep": { - "value": "[parameters('weeklyBackupsToKeep')]" - }, - "backupEnabled": { - "value": "[parameters('backupEnabled')]" - }, - "backupPolicyLocation": { - "value": "[parameters('backupPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2321320275404095362" - }, - "name": "Azure NetApp Files Backup Policy", - "description": "This module deploys a Backup Policy for Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "backupPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The location of the backup policy. Required if the template is used in a standalone deployment." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - } - }, - "resources": [ - { - "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupPolicyName'))]", - "location": "[parameters('backupPolicyLocation')]", - "properties": { - "dailyBackupsToKeep": "[parameters('dailyBackupsToKeep')]", - "enabled": "[parameters('backupEnabled')]", - "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]", - "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]" - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the backup Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('backupPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('backupPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Backup Policy was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - } - }, - "snapshotPolicies": { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[uniqueString(parameters('snapshotPolicyName'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyHour": { - "value": "[parameters('dailyHour')]" - }, - "dailyMinute": { - "value": "[parameters('dailyMinute')]" - }, - "dailySnapshotsToKeep": { - "value": "[parameters('dailySnapshotsToKeep')]" - }, - "dailyUsedBytes": { - "value": "[parameters('dailyUsedBytes')]" - }, - "daysOfMonth": { - "value": "[parameters('daysOfMonth')]" - }, - "hourlyMinute": { - "value": "[parameters('hourlyMinute')]" - }, - "hourlySnapshotsToKeep": { - "value": "[parameters('hourlySnapshotsToKeep')]" - }, - "hourlyUsedBytes": { - "value": "[parameters('hourlyUsedBytes')]" - }, - "monthlyHour": { - "value": "[parameters('monthlyHour')]" - }, - "monthlyMinute": { - "value": "[parameters('monthlyMinute')]" - }, - "monthlySnapshotsToKeep": { - "value": "[parameters('monthlySnapshotsToKeep')]" - }, - "monthlyUsedBytes": { - "value": "[parameters('monthlyUsedBytes')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "snapshotPolicyName": { - "value": "[parameters('snapshotPolicyName')]" - }, - "weeklyDay": { - "value": "[parameters('weeklyDay')]" - }, - "weeklyHour": { - "value": "[parameters('weeklyHour')]" - }, - "weeklyMinute": { - "value": "[parameters('weeklyMinute')]" - }, - "weeklySnapshotsToKeep": { - "value": "[parameters('weeklySnapshotsToKeep')]" - }, - "weeklyUsedBytes": { - "value": "[parameters('weeklyUsedBytes')]" - }, - "snapshotPolicyLocation": { - "value": "[parameters('snapshotPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17538391796648994915" - }, - "name": "Azure NetApp Files Snapshot Policy", - "description": "This module deploys a Snapshot Policy for an Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the snapshot policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - } - }, - "resources": [ - { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]", - "location": "[parameters('snapshotPolicyLocation')]", - "properties": { - "enabled": "[parameters('snapEnabled')]", - "dailySchedule": { - "hour": "[parameters('dailyHour')]", - "minute": "[parameters('dailyMinute')]", - "snapshotsToKeep": "[parameters('dailySnapshotsToKeep')]", - "usedBytes": "[parameters('dailyUsedBytes')]" - }, - "hourlySchedule": { - "minute": "[parameters('hourlyMinute')]", - "snapshotsToKeep": "[parameters('hourlySnapshotsToKeep')]", - "usedBytes": "[parameters('hourlyUsedBytes')]" - }, - "monthlySchedule": { - "daysOfMonth": "[parameters('daysOfMonth')]", - "hour": "[parameters('monthlyHour')]", - "minute": "[parameters('monthlyMinute')]", - "snapshotsToKeep": "[parameters('monthlySnapshotsToKeep')]", - "usedBytes": "[parameters('monthlyUsedBytes')]" - }, - "weeklySchedule": { - "day": "[parameters('weeklyDay')]", - "hour": "[parameters('weeklyHour')]", - "minute": "[parameters('weeklyMinute')]", - "snapshotsToKeep": "[parameters('weeklySnapshotsToKeep')]", - "usedBytes": "[parameters('weeklyUsedBytes')]" - } - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the snapshot Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('snapshotPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Snapshot was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - } } }, "outputs": { diff --git a/avm/res/net-app/net-app-account/main.bicep b/avm/res/net-app/net-app-account/main.bicep index 2b9c1a66c9..d6be205c6e 100644 --- a/avm/res/net-app/net-app-account/main.bicep +++ b/avm/res/net-app/net-app-account/main.bicep @@ -37,7 +37,7 @@ param encryptDCConnections bool = false param smbServerNamePrefix string = '' @description('Optional. Capacity pools to create.') -param capacityPools array = [] +param capacityPools capacityPoolType[]? import { managedIdentityOnlyUserAssignedType } from 'br/public:avm/utl/types/avm-common-types:0.4.0' @description('Optional. The managed identity definition for this resource.') @@ -72,6 +72,15 @@ param tags object? @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +@description('Optional. The netapp backup vault to create & configure.') +param backupVault backupVaultType? + +@description('Optional. The snapshot policies to create.') +param snapshotPolicies snapshotPolicyType[]? + +@description('Optional. The backup policies to create.') +param backupPolicies backupPolicyType[]? + var activeDirectoryConnectionProperties = [ { adName: !empty(domainName) ? adName : null @@ -219,14 +228,54 @@ resource netAppAccount_roleAssignments 'Microsoft.Authorization/roleAssignments@ } ] +module netAppAccount_backupPolicies 'backup-policies/main.bicep' = [ + for (backupPolicy, index) in (backupPolicies ?? []): { + name: '${uniqueString(deployment().name, location)}-ANFAccount-backupPolicy-${index}' + params: { + netAppAccountName: netAppAccount.name + name: backupPolicy.?name + dailyBackupsToKeep: backupPolicy.?dailyBackupsToKeep + monthlyBackupsToKeep: backupPolicy.?monthlyBackupsToKeep + weeklyBackupsToKeep: backupPolicy.?weeklyBackupsToKeep + enabled: backupPolicy.?enabled + location: backupPolicy.?location ?? location + } + } +] + +module netAppAccount_snapshotPolicies 'snapshot-policies/main.bicep' = [ + for (snapshotPolicy, index) in (snapshotPolicies ?? []): { + name: '${uniqueString(deployment().name, location)}-ANFAccount-snapshotPolicy-${index}' + params: { + netAppAccountName: netAppAccount.name + name: snapshotPolicy.?name + location: snapshotPolicy.?location ?? location + snapEnabled: snapshotPolicy.?snapEnabled + dailySchedule: snapshotPolicy.?dailySchedule + hourlySchedule: snapshotPolicy.?hourlySchedule + monthlySchedule: snapshotPolicy.?monthlySchedule + weeklySchedule: snapshotPolicy.?weeklySchedule + } + } +] + +module netAppAccount_backupVault 'backup-vault/main.bicep' = if (!empty(backupVault)) { + name: '${uniqueString(deployment().name, location)}-ANFAccount-BackupVault' + params: { + netAppAccountName: netAppAccount.name + name: backupVault.?name + location: backupVault.?location ?? location + } +} + module netAppAccount_capacityPools 'capacity-pool/main.bicep' = [ - for (capacityPool, index) in capacityPools: { + for (capacityPool, index) in (capacityPools ?? []): { name: '${uniqueString(deployment().name, location)}-ANFAccount-CapPool-${index}' params: { netAppAccountName: netAppAccount.name name: capacityPool.name - location: location size: capacityPool.size + location: capacityPool.?location ?? location serviceLevel: capacityPool.?serviceLevel ?? 'Standard' qosType: capacityPool.?qosType ?? 'Auto' volumes: capacityPool.?volumes ?? [] @@ -235,9 +284,27 @@ module netAppAccount_capacityPools 'capacity-pool/main.bicep' = [ encryptionType: capacityPool.?encryptionType ?? 'Single' tags: capacityPool.?tags ?? tags } + dependsOn: [ + netAppAccount_backupPolicies + netAppAccount_snapshotPolicies + netAppAccount_backupVault + ] } ] +module netAppAccount_backupVaultBackups 'backup-vault/main.bicep' = if (!empty(backupVault.?backups)) { + name: '${uniqueString(deployment().name, location)}-ANFAccount-BackupVault-Backups' + params: { + netAppAccountName: netAppAccount.name + name: backupVault.?name + backups: backupVault.?backups + location: backupVault.?location ?? location + } + dependsOn: [ + netAppAccount_capacityPools + ] +} + @description('The name of the NetApp account.') output name string = netAppAccount.name @@ -250,5 +317,113 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = netAppAccount.location -@description('The resource IDs of the volume created in the capacity pool.') -output volumeResourceId string = (capacityPools != []) ? netAppAccount_capacityPools[0].outputs.volumeResourceId : '' +@description('The resource IDs of the created capacity pools & their volumes.') +output capacityPoolResourceIds { + resourceId: string + volumeResourceIds: string[] +}[] = [ + for (capacityPools, index) in (capacityPools ?? []): { + resourceId: netAppAccount_capacityPools[index].outputs.resourceId + volumeResourceIds: netAppAccount_capacityPools[index].outputs.volumeResourceIds + } +] + +// ================ // +// Definitions // +// ================ // + +import { backupType } from 'backup-vault/main.bicep' +@export() +@description('The type for a backup vault.') +type backupVaultType = { + @description('Optional. The name of the backup vault.') + name: string? + + @description('Optional. The list of backups to create.') + backups: backupType[]? + + @description('Optional. Location of the backup vault.') + location: string? +} + +import { volumeType } from 'capacity-pool/main.bicep' +@export() +@description('The type for a capacity pool.') +type capacityPoolType = { + @description('Required. The name of the capacity pool.') + name: string + + @description('Optional. Location of the pool volume.') + location: string? + + @description('Optional. Tags for the capcity pool.') + tags: object? + + @description('Optional. The pool service level.') + serviceLevel: ('Premium' | 'Standard' | 'StandardZRS' | 'Ultra')? + + @description('Required. Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104).') + size: int + + @description('Optional. The qos type of the pool.') + qosType: ('Auto' | 'Manual')? + + @description('Optional. List of volumes to create in the capacity pool.') + volumes: volumeType[]? + + @description('Optional. If enabled (true) the pool can contain cool Access enabled volumes.') + coolAccess: bool? + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType[]? + + @description('Optional. Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool.') + encryptionType: ('Single' | 'Double')? +} + +import { dailyScheduleType, hourlyScheduleType, monthlyScheduleType, weeklyScheduleType } from 'snapshot-policies/main.bicep' +@export() +@description('The type for a snapshot policy.') +type snapshotPolicyType = { + @description('Required. The name of the snapshot policy.') + name: string + + @description('Optional. Location of the snapshot policy.') + location: string? + + @description('Optional. Daily schedule for the snapshot policy.') + dailySchedule: dailyScheduleType? + + @description('Optional. Hourly schedule for the snapshot policy.') + hourlySchedule: hourlyScheduleType? + + @description('Optional. Monthly schedule for the snapshot policy.') + monthlySchedule: monthlyScheduleType? + + @description('Optional. Weekly schedule for the snapshot policy.') + weeklySchedule: weeklyScheduleType? +} + +@export() +@description('The type for a backup policy.') +type backupPolicyType = { + @description('Optional. The name of the backup policy.') + name: string? + + @description('Optional. The location of the backup policy.') + location: string? + + @description('Optional. The daily backups to keep.') + @minValue(2) + @maxValue(1019) + dailyBackupsToKeep: int? + + @description('Optional. The monthly backups to keep.') + monthlyBackupsToKeep: int? + + @description('Optional. The weekly backups to keep.') + weeklyBackupsToKeep: int? + + @description('Optional. Indicates whether the backup policy is enabled.') + enabled: bool? +} diff --git a/avm/res/net-app/net-app-account/main.json b/avm/res/net-app/net-app-account/main.json index df28e3855a..c22e363075 100644 --- a/avm/res/net-app/net-app-account/main.json +++ b/avm/res/net-app/net-app-account/main.json @@ -5,347 +5,1257 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "4975644618849979197" + "version": "0.33.13.18514", + "templateHash": "6509519164461633683" }, "name": "Azure NetApp Files", "description": "This module deploys an Azure NetApp File." }, "definitions": { - "customerManagedKeyType": { + "backupVaultType": { "type": "object", "properties": { - "keyVaultResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." - } - }, - "keyName": { + "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the customer managed key to use for encryption." + "description": "Optional. The name of the backup vault." } }, - "keyVersion": { - "type": "string", + "backups": { + "type": "array", + "items": { + "$ref": "#/definitions/backupType" + }, "nullable": true, "metadata": { - "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time." + "description": "Optional. The list of backups to create." } }, - "userAssignedIdentityResourceId": { + "location": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + "description": "Optional. Location of the backup vault." } } }, "metadata": { - "description": "An AVM-aligned type for a customer-managed key. To be used if the resource type does not support auto-rotation of the customer-managed key.", - "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" - } + "__bicep_export!": true, + "description": "The type for a backup vault." } }, - "lockType": { + "capacityPoolType": { "type": "object", "properties": { "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool." + } + }, + "location": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "Optional. Location of the pool volume." } }, - "kind": { + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags for the capcity pool." + } + }, + "serviceLevel": { "type": "string", "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" + "Premium", + "Standard", + "StandardZRS", + "Ultra" ], "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The pool service level." + } + }, + "size": { + "type": "int", + "metadata": { + "description": "Required. Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104)." + } + }, + "qosType": { + "type": "string", + "allowedValues": [ + "Auto", + "Manual" + ], + "nullable": true, + "metadata": { + "description": "Optional. The qos type of the pool." + } + }, + "volumes": { + "type": "array", + "items": { + "$ref": "#/definitions/volumeType" + }, + "nullable": true, + "metadata": { + "description": "Optional. List of volumes to create in the capacity pool." + } + }, + "coolAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "encryptionType": { + "type": "string", + "allowedValues": [ + "Double", + "Single" + ], + "nullable": true, + "metadata": { + "description": "Optional. Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool." } } }, "metadata": { - "description": "An AVM-aligned type for a lock.", - "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" - } + "__bicep_export!": true, + "description": "The type for a capacity pool." } }, - "managedIdentityOnlyUserAssignedType": { + "snapshotPolicyType": { "type": "object", "properties": { - "userAssignedResourceIds": { - "type": "array", - "items": { - "type": "string" - }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy." + } + }, + "location": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + "description": "Optional. Location of the snapshot policy." + } + }, + "dailySchedule": { + "$ref": "#/definitions/dailyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Daily schedule for the snapshot policy." + } + }, + "hourlySchedule": { + "$ref": "#/definitions/hourlyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Hourly schedule for the snapshot policy." + } + }, + "monthlySchedule": { + "$ref": "#/definitions/monthlyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Monthly schedule for the snapshot policy." + } + }, + "weeklySchedule": { + "$ref": "#/definitions/weeklyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Weekly schedule for the snapshot policy." } } }, "metadata": { - "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", - "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" - } + "__bicep_export!": true, + "description": "The type for a snapshot policy." } }, - "roleAssignmentType": { + "backupPolicyType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + "description": "Optional. The name of the backup policy." } }, - "roleDefinitionIdOrName": { + "location": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + "description": "Optional. The location of the backup policy." } }, - "principalId": { - "type": "string", + "dailyBackupsToKeep": { + "type": "int", + "nullable": true, + "minValue": 2, + "maxValue": 1019, "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + "description": "Optional. The daily backups to keep." } }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], + "monthlyBackupsToKeep": { + "type": "int", "nullable": true, "metadata": { - "description": "Optional. The principal type of the assigned principal ID." + "description": "Optional. The monthly backups to keep." } }, - "description": { - "type": "string", + "weeklyBackupsToKeep": { + "type": "int", "nullable": true, "metadata": { - "description": "Optional. The description of the role assignment." + "description": "Optional. The weekly backups to keep." } }, - "condition": { - "type": "string", + "enabled": { + "type": "bool", "nullable": true, "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + "description": "Optional. Indicates whether the backup policy is enabled." } - }, - "conditionVersion": { + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup policy." + } + }, + "_1.backupType": { + "type": "object", + "properties": { + "backupPolicyName": { "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, "metadata": { - "description": "Optional. Version of the condition." + "description": "Required. The name of the backup policy to link." } }, - "delegatedManagedIdentityResourceId": { + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." + "description": "Required. The name of the Backup Vault." } } }, "metadata": { - "description": "An AVM-aligned type for a role assignment.", + "description": "The type for the backup properties.", "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + "sourceTemplate": "capacity-pool/volume/main.bicep" } } - } - }, - "parameters": { - "name": { - "type": "string", + }, + "_1.dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/_1.replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/_1.backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/_1.snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, "metadata": { - "description": "Required. The name of the NetApp account." + "description": "The type for the data protection properties.", + "__bicep_imported_from!": { + "sourceTemplate": "capacity-pool/volume/main.bicep" + } } }, - "adName": { - "type": "string", - "defaultValue": "", + "_1.exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, "metadata": { - "description": "Optional. Name of the active directory host as part of Kerberos Realm used for Kerberos authentication." + "description": "The type for export policy rules.", + "__bicep_imported_from!": { + "sourceTemplate": "capacity-pool/volume/main.bicep" + } } }, - "aesEncryption": { - "type": "bool", - "defaultValue": false, + "_1.replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, "metadata": { - "description": "Optional. Enable AES encryption on the SMB Server." + "description": "The type for the replication properties.", + "__bicep_imported_from!": { + "sourceTemplate": "capacity-pool/volume/main.bicep" + } } }, - "customerManagedKey": { - "$ref": "#/definitions/customerManagedKeyType", - "nullable": true, - "metadata": { - "description": "Optional. The customer managed key definition." - } - }, - "domainName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Fully Qualified Active Directory DNS Domain Name (e.g. 'contoso.com')." - } - }, - "domainJoinUser": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Required if domainName is specified. Username of Active Directory domain administrator, with permissions to create SMB server machine account in the AD domain." - } - }, - "domainJoinPassword": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Optional. Required if domainName is specified. Password of the user specified in domainJoinUser parameter." - } - }, - "domainJoinOU": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Used only if domainName is specified. LDAP Path for the Organization Unit (OU) where SMB Server machine accounts will be created (i.e. 'OU=SecondLevel,OU=FirstLevel')." - } - }, - "dnsServers": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Required if domainName is specified. Comma separated list of DNS server IP addresses (IPv4 only) required for the Active Directory (AD) domain join and SMB authentication operations to succeed." - } - }, - "encryptDCConnections": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Specifies whether encryption should be used for communication between SMB server and domain controller (DC). SMB3 only." - } - }, - "smbServerNamePrefix": { - "type": "string", - "defaultValue": "", + "_1.snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, "metadata": { - "description": "Optional. Required if domainName is specified. NetBIOS name of the SMB server. A computer account with this prefix will be registered in the AD and used to mount volumes." + "description": "The type for the snapshot properties.", + "__bicep_imported_from!": { + "sourceTemplate": "capacity-pool/volume/main.bicep" + } } }, - "capacityPools": { - "type": "array", - "defaultValue": [], + "backupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } + }, "metadata": { - "description": "Optional. Capacity pools to create." + "description": "The type for a backup.", + "__bicep_imported_from!": { + "sourceTemplate": "backup-vault/main.bicep" + } } }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", - "nullable": true, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, the deployment will use the latest version available at deployment time." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, "metadata": { - "description": "Optional. The managed identity definition for this resource." + "description": "An AVM-aligned type for a customer-managed key. To be used if the resource type does not support auto-rotation of the customer-managed key.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "roleAssignments": { - "type": "array", - "items": { - "$ref": "#/definitions/roleAssignmentType" + "dailyScheduleType": { + "type": "object", + "properties": { + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The daily snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The daily snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Daily snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } }, - "nullable": true, "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "The type for a daily schedule for the snapshot policy.", + "__bicep_imported_from!": { + "sourceTemplate": "snapshot-policies/main.bicep" + } } }, - "kdcIP": { - "type": "string", - "defaultValue": "", + "hourlyScheduleType": { + "type": "object", + "properties": { + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The hourly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Hourly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. Kerberos Key Distribution Center (KDC) as part of Kerberos Realm used for Kerberos authentication." + "description": "The type for an hourly schedule for the snapshot policy.", + "__bicep_imported_from!": { + "sourceTemplate": "snapshot-policies/main.bicep" + } } }, - "ldapOverTLS": { - "type": "bool", - "defaultValue": false, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, "metadata": { - "description": "Optional. Specifies whether to use TLS when NFS (with/without Kerberos) and SMB volumes communicate with an LDAP server. A server root CA certificate must be uploaded if enabled (serverRootCACertificate)." + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "ldapSigning": { - "type": "bool", - "defaultValue": false, + "managedIdentityOnlyUserAssignedType": { + "type": "object", + "properties": { + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." + } + } + }, "metadata": { - "description": "Optional. Specifies whether or not the LDAP traffic needs to be signed." + "description": "An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", + "monthlyScheduleType": { + "type": "object", + "properties": { + "daysOfMonth": { + "type": "string", + "metadata": { + "description": "Required. Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The monthly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The monthly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Monthly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. Location for all resources." + "description": "The type for a monthly schedule for the snapshot policy.", + "__bicep_imported_from!": { + "sourceTemplate": "snapshot-policies/main.bicep" + } } }, - "lock": { - "$ref": "#/definitions/lockType", - "nullable": true, + "roleAssignmentType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + }, "metadata": { - "description": "Optional. The lock settings of the service." + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } } }, - "serverRootCACertificate": { - "type": "string", - "defaultValue": "", + "volumeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "coolAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "coolnessPeriod": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the number of days after which data that is not accessed by clients will be tiered." + } + }, + "coolAccessRetrievalPolicy": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + } + }, + "encryptionKeySource": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The source of the encryption key." + } + }, + "keyVaultPrivateEndpointResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the key vault private endpoint." + } + }, + "dataProtection": { + "$ref": "#/definitions/_1.dataProtectionType", + "nullable": true, + "metadata": { + "description": "Optional. DataProtection type volumes include an object containing details of the replication." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, + "zones": { + "type": "array", + "items": { + "type": "int" + }, + "nullable": true, + "metadata": { + "description": "Optional. Zone where the volume will be placed." + } + }, + "serviceLevel": { + "type": "string", + "allowedValues": [ + "Premium", + "Standard", + "StandardZRS", + "Ultra" + ], + "nullable": true, + "metadata": { + "description": "Optional. The pool service level. Must match the one of the parent capacity pool." + } + }, + "networkFeatures": { + "type": "string", + "allowedValues": [ + "Basic", + "Basic_Standard", + "Standard", + "Standard_Basic" + ], + "nullable": true, + "metadata": { + "description": "Optional. Network feature for the volume." + } + }, + "creationToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription." + } + }, + "usageThreshold": { + "type": "int", + "metadata": { + "description": "Required. Maximum storage quota allowed for a file system in bytes." + } + }, + "protocolTypes": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Set of protocol types." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." + } + }, + "exportPolicy": { + "$ref": "#/definitions/_1.exportPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. Export policy rules." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "smbEncryption": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume." + } + }, + "smbContinuouslyAvailable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume." + } + }, + "smbNonBrowsable": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." + } + }, + "kerberosEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } + } + }, "metadata": { - "description": "Optional. A server Root certificate is required of ldapOverTLS is enabled." + "description": "The type for a volume in the capacity pool.", + "__bicep_imported_from!": { + "sourceTemplate": "capacity-pool/main.bicep" + } } }, - "tags": { + "weeklyScheduleType": { "type": "object", - "nullable": true, + "properties": { + "day": { + "type": "string", + "allowedValues": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "metadata": { + "description": "Required. The weekly snapshot day." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The weekly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The weekly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Weekly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. Tags for all resources." + "description": "The type for a weekly schedule for the snapshot policy.", + "__bicep_imported_from!": { + "sourceTemplate": "snapshot-policies/main.bicep" + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the NetApp account." } }, - "enableTelemetry": { + "adName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the active directory host as part of Kerberos Realm used for Kerberos authentication." + } + }, + "aesEncryption": { "type": "bool", - "defaultValue": true, + "defaultValue": false, "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "description": "Optional. Enable AES encryption on the SMB Server." } - } - }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "nullable": true, + "metadata": { + "description": "Optional. The customer managed key definition." } - ], - "activeDirectoryConnectionProperties": [ - { - "adName": "[if(not(empty(parameters('domainName'))), parameters('adName'), null())]", - "aesEncryption": "[if(not(empty(parameters('domainName'))), parameters('aesEncryption'), false())]", + }, + "domainName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Fully Qualified Active Directory DNS Domain Name (e.g. 'contoso.com')." + } + }, + "domainJoinUser": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if domainName is specified. Username of Active Directory domain administrator, with permissions to create SMB server machine account in the AD domain." + } + }, + "domainJoinPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if domainName is specified. Password of the user specified in domainJoinUser parameter." + } + }, + "domainJoinOU": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Used only if domainName is specified. LDAP Path for the Organization Unit (OU) where SMB Server machine accounts will be created (i.e. 'OU=SecondLevel,OU=FirstLevel')." + } + }, + "dnsServers": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if domainName is specified. Comma separated list of DNS server IP addresses (IPv4 only) required for the Active Directory (AD) domain join and SMB authentication operations to succeed." + } + }, + "encryptDCConnections": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether encryption should be used for communication between SMB server and domain controller (DC). SMB3 only." + } + }, + "smbServerNamePrefix": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if domainName is specified. NetBIOS name of the SMB server. A computer account with this prefix will be registered in the AD and used to mount volumes." + } + }, + "capacityPools": { + "type": "array", + "items": { + "$ref": "#/definitions/capacityPoolType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Capacity pools to create." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentityOnlyUserAssignedType", + "nullable": true, + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "kdcIP": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Kerberos Key Distribution Center (KDC) as part of Kerberos Realm used for Kerberos authentication." + } + }, + "ldapOverTLS": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether to use TLS when NFS (with/without Kerberos) and SMB volumes communicate with an LDAP server. A server root CA certificate must be uploaded if enabled (serverRootCACertificate)." + } + }, + "ldapSigning": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether or not the LDAP traffic needs to be signed." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "nullable": true, + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "serverRootCACertificate": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. A server Root certificate is required of ldapOverTLS is enabled." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags for all resources." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "backupVault": { + "$ref": "#/definitions/backupVaultType", + "nullable": true, + "metadata": { + "description": "Optional. The netapp backup vault to create & configure." + } + }, + "snapshotPolicies": { + "type": "array", + "items": { + "$ref": "#/definitions/snapshotPolicyType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The snapshot policies to create." + } + }, + "backupPolicies": { + "type": "array", + "items": { + "$ref": "#/definitions/backupPolicyType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The backup policies to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "activeDirectoryConnectionProperties": [ + { + "adName": "[if(not(empty(parameters('domainName'))), parameters('adName'), null())]", + "aesEncryption": "[if(not(empty(parameters('domainName'))), parameters('aesEncryption'), false())]", "username": "[if(not(empty(parameters('domainName'))), parameters('domainJoinUser'), null())]", "password": "[if(not(empty(parameters('domainName'))), parameters('domainJoinPassword'), null())]", "domain": "[if(not(empty(parameters('domainName'))), parameters('domainName'), null())]", @@ -468,14 +1378,14 @@ "netAppAccount" ] }, - "netAppAccount_capacityPools": { + "netAppAccount_backupPolicies": { "copy": { - "name": "netAppAccount_capacityPools", - "count": "[length(parameters('capacityPools'))]" + "name": "netAppAccount_backupPolicies", + "count": "[length(coalesce(parameters('backupPolicies'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-ANFAccount-CapPool-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-ANFAccount-backupPolicy-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -486,233 +1396,413 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('capacityPools')[copyIndex()].name]" - }, - "location": { - "value": "[parameters('location')]" + "value": "[tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'name')]" }, - "size": { - "value": "[parameters('capacityPools')[copyIndex()].size]" - }, - "serviceLevel": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'serviceLevel'), 'Standard')]" - }, - "qosType": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'qosType'), 'Auto')]" - }, - "volumes": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'volumes'), createArray())]" + "dailyBackupsToKeep": { + "value": "[tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'dailyBackupsToKeep')]" }, - "coolAccess": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'coolAccess'), false())]" + "monthlyBackupsToKeep": { + "value": "[tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'monthlyBackupsToKeep')]" }, - "roleAssignments": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'roleAssignments'), createArray())]" + "weeklyBackupsToKeep": { + "value": "[tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'weeklyBackupsToKeep')]" }, - "encryptionType": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'encryptionType'), 'Single')]" + "enabled": { + "value": "[tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'enabled')]" }, - "tags": { - "value": "[coalesce(tryGet(parameters('capacityPools')[copyIndex()], 'tags'), parameters('tags'))]" + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('backupPolicies'), createArray())[copyIndex()], 'location'), parameters('location'))]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17937651504078156143" + "version": "0.33.13.18514", + "templateHash": "1799863578493793686" }, - "name": "Azure NetApp Files Capacity Pools", - "description": "This module deploys an Azure NetApp Files Capacity Pool." + "name": "Azure NetApp Files Backup Policy", + "description": "This module deploys a Backup Policy for Azure NetApp File." }, - "definitions": { - "roleAssignmentType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - }, - "metadata": { - "description": "An AVM-aligned type for a role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" - } - } - } - }, - "parameters": { - "netAppAccountName": { - "type": "string", + "parameters": { + "netAppAccountName": { + "type": "string", "metadata": { "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." } }, "name": { "type": "string", + "defaultValue": "backupPolicy", "metadata": { - "description": "Required. The name of the capacity pool." + "description": "Optional. The name of the backup policy." } }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Location of the pool volume." + "description": "Optional. The location of the backup policy." } }, - "tags": { - "type": "object", - "nullable": true, + "dailyBackupsToKeep": { + "type": "int", + "defaultValue": 2, + "minValue": 2, + "maxValue": 1019, "metadata": { - "description": "Optional. Tags for all resources." + "description": "Optional. The daily backups to keep." } }, - "serviceLevel": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Premium", - "Standard", - "StandardZRS", - "Ultra" - ], + "monthlyBackupsToKeep": { + "type": "int", + "defaultValue": 0, "metadata": { - "description": "Optional. The pool service level." + "description": "Optional. The monthly backups to keep." } }, - "size": { + "weeklyBackupsToKeep": { "type": "int", + "defaultValue": 0, "metadata": { - "description": "Required. Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104)." + "description": "Optional. The weekly backups to keep." } }, - "qosType": { - "type": "string", - "defaultValue": "Auto", - "allowedValues": [ - "Auto", - "Manual" - ], + "enabled": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "Optional. The qos type of the pool." + "description": "Optional. Indicates whether the backup policy is enabled." + } + } + }, + "resources": [ + { + "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": { + "enabled": "[parameters('enabled')]", + "dailyBackupsToKeep": "[parameters('dailyBackupsToKeep')]", + "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]", + "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]" } + } + ], + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource IDs of the backup Policy created within volume." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('name'))]" }, - "volumes": { - "type": "array", - "defaultValue": [], + "name": { + "type": "string", + "metadata": { + "description": "The name of the Backup Policy." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Backup Policy was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "netAppAccount" + ] + }, + "netAppAccount_snapshotPolicies": { + "copy": { + "name": "netAppAccount_snapshotPolicies", + "count": "[length(coalesce(parameters('snapshotPolicies'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANFAccount-snapshotPolicy-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'name')]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'location'), parameters('location'))]" + }, + "snapEnabled": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'snapEnabled')]" + }, + "dailySchedule": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'dailySchedule')]" + }, + "hourlySchedule": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'hourlySchedule')]" + }, + "monthlySchedule": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'monthlySchedule')]" + }, + "weeklySchedule": { + "value": "[tryGet(coalesce(parameters('snapshotPolicies'), createArray())[copyIndex()], 'weeklySchedule')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "14119927784920096194" + }, + "name": "Azure NetApp Files Snapshot Policy", + "description": "This module deploys a Snapshot Policy for an Azure NetApp File." + }, + "definitions": { + "dailyScheduleType": { + "type": "object", + "properties": { + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The daily snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The daily snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Daily snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. List of volumnes to create in the capacity pool." + "__bicep_export!": true, + "description": "The type for a daily schedule for the snapshot policy." } }, - "coolAccess": { - "type": "bool", - "defaultValue": false, + "hourlyScheduleType": { + "type": "object", + "properties": { + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The hourly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Hourly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + "__bicep_export!": true, + "description": "The type for an hourly schedule for the snapshot policy." } }, - "roleAssignments": { - "type": "array", - "items": { - "$ref": "#/definitions/roleAssignmentType" + "weeklyScheduleType": { + "type": "object", + "properties": { + "day": { + "type": "string", + "allowedValues": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "metadata": { + "description": "Required. The weekly snapshot day." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The weekly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The weekly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Weekly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } }, - "nullable": true, "metadata": { - "description": "Optional. Array of role assignments to create." + "__bicep_export!": true, + "description": "The type for a weekly schedule for the snapshot policy." } }, - "encryptionType": { - "type": "string", - "defaultValue": "Single", - "allowedValues": [ - "Double", - "Single" - ], + "monthlyScheduleType": { + "type": "object", + "properties": { + "daysOfMonth": { + "type": "string", + "metadata": { + "description": "Required. Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The monthly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The monthly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Monthly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Optional. Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool." + "__bicep_export!": true, + "description": "The type for a monthly schedule for the snapshot policy." } } }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + "parameters": { + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "snapshotPolicy", + "metadata": { + "description": "Optional. The name of the snapshot policy." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location of the snapshot policy." + } + }, + "hourlySchedule": { + "$ref": "#/definitions/hourlyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Schedule for hourly snapshots." + } + }, + "dailySchedule": { + "$ref": "#/definitions/dailyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Schedule for daily snapshots." + } + }, + "monthlySchedule": { + "$ref": "#/definitions/monthlyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Schedule for monthly snapshots." + } + }, + "weeklySchedule": { + "$ref": "#/definitions/weeklyScheduleType", + "nullable": true, + "metadata": { + "description": "Optional. Schedule for weekly snapshots." + } + }, + "snapEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether the snapshot policy is enabled." } - ], - "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')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" } }, "resources": { @@ -722,52 +1812,181 @@ "apiVersion": "2024-03-01", "name": "[parameters('netAppAccountName')]" }, - "capacityPool": { - "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "snapshotPolicies": { + "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", "apiVersion": "2024-03-01", "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", "location": "[parameters('location')]", - "tags": "[parameters('tags')]", "properties": { - "serviceLevel": "[parameters('serviceLevel')]", - "size": "[parameters('size')]", - "qosType": "[parameters('qosType')]", - "coolAccess": "[parameters('coolAccess')]", - "encryptionType": "[parameters('encryptionType')]" + "enabled": "[parameters('snapEnabled')]", + "dailySchedule": "[parameters('dailySchedule')]", + "hourlySchedule": "[parameters('hourlySchedule')]", + "monthlySchedule": "[parameters('monthlySchedule')]", + "weeklySchedule": "[parameters('weeklySchedule')]" } - }, - "capacityPool_roleAssignments": { - "copy": { - "name": "capacityPool_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource IDs of the snapshot Policy created within volume." }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.NetApp/netAppAccounts/{0}/capacityPools/{1}', parameters('netAppAccountName'), parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.NetApp/netAppAccounts/capacityPools', parameters('netAppAccountName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Backup Policy." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Snapshot was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "netAppAccount" + ] + }, + "netAppAccount_backupVault": { + "condition": "[not(empty(parameters('backupVault')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANFAccount-BackupVault', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[tryGet(parameters('backupVault'), 'name')]" + }, + "location": { + "value": "[coalesce(tryGet(parameters('backupVault'), 'location'), parameters('location'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "1432647773332765235" + }, + "name": "Azure NetApp Files Volume Backup Vault", + "description": "This module deploys a NetApp Files Backup Vault." + }, + "definitions": { + "backupType": { + "type": "object", "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } }, - "dependsOn": [ - "capacityPool" - ] + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup." + } + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "vault", + "metadata": { + "description": "Optional. The name of the backup vault." + } }, - "capacityPool_volumes": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the backup vault." + } + }, + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "backups": { + "type": "array", + "items": { + "$ref": "#/definitions/backupType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of backups to create." + } + } + }, + "resources": { + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "backupVault": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": {} + }, + "backupVault_backups": { "copy": { - "name": "capacityPool_volumes", - "count": "[length(parameters('volumes'))]", - "mode": "serial", - "batchSize": 1 + "name": "backupVault_backups", + "count": "[length(coalesce(parameters('backups'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Vol-{1}', deployment().name, copyIndex())]", + "name": "[format('{0}-ANF-Backup-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -777,176 +1996,23 @@ "netAppAccountName": { "value": "[parameters('netAppAccountName')]" }, - "capacityPoolName": { + "backupVaultName": { "value": "[parameters('name')]" }, "name": { - "value": "[parameters('volumes')[copyIndex()].name]" - }, - "location": { - "value": "[parameters('location')]" - }, - "serviceLevel": { - "value": "[parameters('serviceLevel')]" - }, - "creationToken": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'creationToken'), parameters('volumes')[copyIndex()].name)]" - }, - "usageThreshold": { - "value": "[parameters('volumes')[copyIndex()].usageThreshold]" - }, - "protocolTypes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'protocolTypes'), createArray())]" - }, - "subnetResourceId": { - "value": "[parameters('volumes')[copyIndex()].subnetResourceId]" - }, - "exportPolicyRules": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'exportPolicyRules'), createArray())]" - }, - "roleAssignments": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'roleAssignments'), createArray())]" - }, - "networkFeatures": { - "value": "[tryGet(parameters('volumes')[copyIndex()], 'networkFeatures')]" - }, - "zones": { - "value": "[tryGet(parameters('volumes')[copyIndex()], 'zones')]" - }, - "coolAccess": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolAccess'), false())]" - }, - "coolAccessRetrievalPolicy": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolAccessRetrievalPolicy'), 'Default')]" - }, - "coolnessPeriod": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'coolnessPeriod'), 0)]" - }, - "encryptionKeySource": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'encryptionKeySource'), 'Microsoft.NetApp')]" - }, - "keyVaultPrivateEndpointResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'keyVaultPrivateEndpointResourceId'), '')]" - }, - "endpointType": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'endpointType'), '')]" - }, - "remoteVolumeRegion": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'remoteVolumeRegion'), '')]" - }, - "remoteVolumeResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'remoteVolumeResourceId'), '')]" - }, - "replicationSchedule": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'replicationSchedule'), '')]" - }, - "snapshotPolicyName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotPolicyName'), 'snapshotPolicy')]" - }, - "snapshotPolicyLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotPolicyLocation'), '')]" - }, - "snapEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapEnabled'), false())]" - }, - "dailyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyHour'), 0)]" - }, - "dailyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyMinute'), 0)]" - }, - "dailySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailySnapshotsToKeep'), 0)]" - }, - "dailyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyUsedBytes'), 0)]" - }, - "hourlyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlyMinute'), 0)]" - }, - "hourlySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlySnapshotsToKeep'), 0)]" - }, - "hourlyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'hourlyUsedBytes'), 0)]" - }, - "daysOfMonth": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'daysOfMonth'), '')]" - }, - "monthlyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyHour'), 0)]" - }, - "monthlyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyMinute'), 0)]" - }, - "monthlySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlySnapshotsToKeep'), 0)]" - }, - "monthlyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyUsedBytes'), 0)]" - }, - "weeklyDay": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyDay'), '')]" - }, - "weeklyHour": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyHour'), 0)]" + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'name')]" }, - "weeklyMinute": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyMinute'), 0)]" - }, - "weeklySnapshotsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklySnapshotsToKeep'), 0)]" - }, - "weeklyUsedBytes": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyUsedBytes'), 0)]" - }, - "backupPolicyName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupPolicyName'), 'backupPolicy')]" - }, - "backupPolicyLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupPolicyLocation'), '')]" - }, - "dailyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'dailyBackupsToKeep'), 0)]" - }, - "backupEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupEnabled'), false())]" - }, - "monthlyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'monthlyBackupsToKeep'), 0)]" - }, - "weeklyBackupsToKeep": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'weeklyBackupsToKeep'), 0)]" - }, - "backupVaultName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultName'), 'vault')]" - }, - "backupVaultLocation": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultLocation'), '')]" - }, - "backupName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupName'), 'backup')]" - }, - "backupLabel": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupLabel'), '')]" + "label": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'label')]" }, "snapshotName": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'snapshotName'), 'snapshot')]" - }, - "useExistingSnapshot": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'useExistingSnapshot'), false())]" - }, - "volumeResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'volumeResourceId'), '')]" - }, - "volumeType": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'volumeType'), '')]" + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'snapshotName')]" }, - "backupVaultResourceId": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'backupVaultResourceId'), '')]" + "volumeName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].volumeName]" }, - "replicationEnabled": { - "value": "[coalesce(tryGet(parameters('volumes')[copyIndex()], 'replicationEnabled'), false())]" + "capacityPoolName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].capacityPoolName]" } }, "template": { @@ -956,521 +2022,1914 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15336007196805099128" + "version": "0.33.13.18514", + "templateHash": "10519572323483923146" }, - "name": "Azure NetApp Files Capacity Pool Volumes", - "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." - }, - "definitions": { - "roleAssignmentType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - }, - "metadata": { - "description": "An AVM-aligned type for a role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" - } - } - } + "name": "Azure NetApp Files Volume Backup", + "description": "This module deploys a backup of a NetApp Files Volume." }, "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "capacityPoolName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent capacity pool. Required if the template is used in a standalone deployment." - } - }, - "coolAccess": { - "type": "bool", - "metadata": { - "description": "Required. If enabled (true) the pool can contain cool Access enabled volumes." - } - }, - "coolnessPeriod": { - "type": "int", - "metadata": { - "description": "Required. Specifies the number of days after which data that is not accessed by clients will be tiered." - } - }, - "coolAccessRetrievalPolicy": { - "type": "string", - "defaultValue": "Default", - "metadata": { - "description": "Optional. determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." - } - }, - "encryptionKeySource": { - "type": "string", - "metadata": { - "description": "Required. The source of the encryption key." - } - }, - "keyVaultPrivateEndpointResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the key vault private endpoint." - } - }, - "endpointType": { - "type": "string", - "metadata": { - "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication (src/dst)." - } - }, - "remoteVolumeRegion": { - "type": "string", - "metadata": { - "description": "Required. The remote region for the other end of the Volume Replication." - } - }, - "remoteVolumeResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the remote volume." - } - }, - "replicationSchedule": { - "type": "string", - "metadata": { - "description": "Required. The replication schedule for the volume." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - }, - "snapshotPolicyName": { + "name": { "type": "string", + "defaultValue": "backup", "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." + "description": "Optional. The name of the backup." } }, "backupVaultName": { "type": "string", - "defaultValue": "vault", - "metadata": { - "description": "Optional. The name of the backup vault." - } - }, - "backupVaultLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. The location of the backup vault." + "description": "Conditional. The name of the parent backup vault. Required if the template is used in a standalone deployment." } }, - "backupName": { + "netAppAccountName": { "type": "string", "metadata": { - "description": "Required. The name of the backup." + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." } }, - "backupLabel": { + "label": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The label of the backup." - } - }, - "useExistingSnapshot": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether to use an existing snapshot." + "description": "Optional. Label for backup." } }, "snapshotName": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The name of the snapshot." + "description": "Optional. The name of the snapshot." } }, - "volumeResourceId": { + "volumeName": { "type": "string", "metadata": { - "description": "Required. The resource ID of the volume." + "description": "Required. The name of the volume to backup." } }, - "volumeType": { + "capacityPoolName": { "type": "string", "metadata": { - "description": "Required. The type of the volume. DataProtection volumes are used for replication." + "description": "Required. The name of the capacity pool containing the volume." } + } + }, + "resources": { + "netAppAccount::remoteCapacityPool::volume": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the pool volume." - } + "netAppAccount::backupVault": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location of the pool volume." - } + "netAppAccount::remoteCapacityPool": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" }, - "zones": { - "type": "array", - "defaultValue": [ - "1" - ], - "metadata": { - "description": "Optional. Zone where the volume will be placed." - } + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" }, - "policyEnforced": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If Backup policy is enforced." + "backup": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", + "properties": { + "label": "[parameters('label')]", + "snapshotName": "[parameters('snapshotName')]", + "volumeResourceId": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" } - }, - "backupPolicyLocation": { + } + }, + "outputs": { + "name": { "type": "string", "metadata": { - "description": "Required. The backup policy location." - } + "description": "The name of the backup." + }, + "value": "[parameters('name')]" }, - "snapshotPolicyLocation": { + "resourceId": { "type": "string", "metadata": { - "description": "Required. The location of snashot policies." - } + "description": "The Resource ID of the backup." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults/backups', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]" }, - "serviceLevel": { + "resourceGroupName": { "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Premium", - "Standard", + "metadata": { + "description": "The name of the Resource Group the backup was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "backupVault" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the backup vault." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the backup vault." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the backup vault was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('backupVault', '2024-03-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "netAppAccount" + ] + }, + "netAppAccount_capacityPools": { + "copy": { + "name": "netAppAccount_capacityPools", + "count": "[length(coalesce(parameters('capacityPools'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANFAccount-CapPool-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('capacityPools'), createArray())[copyIndex()].name]" + }, + "size": { + "value": "[coalesce(parameters('capacityPools'), createArray())[copyIndex()].size]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'location'), parameters('location'))]" + }, + "serviceLevel": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'serviceLevel'), 'Standard')]" + }, + "qosType": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'qosType'), 'Auto')]" + }, + "volumes": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'volumes'), createArray())]" + }, + "coolAccess": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'coolAccess'), false())]" + }, + "roleAssignments": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'roleAssignments'), createArray())]" + }, + "encryptionType": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'encryptionType'), 'Single')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('capacityPools'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "2539920372355196545" + }, + "name": "Azure NetApp Files Capacity Pools", + "description": "This module deploys an Azure NetApp Files Capacity Pool." + }, + "definitions": { + "volumeType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "coolAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "coolnessPeriod": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the number of days after which data that is not accessed by clients will be tiered." + } + }, + "coolAccessRetrievalPolicy": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + } + }, + "encryptionKeySource": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The source of the encryption key." + } + }, + "keyVaultPrivateEndpointResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the key vault private endpoint." + } + }, + "dataProtection": { + "$ref": "#/definitions/dataProtectionType", + "nullable": true, + "metadata": { + "description": "Optional. DataProtection type volumes include an object containing details of the replication." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, + "zones": { + "type": "array", + "items": { + "type": "int" + }, + "nullable": true, + "metadata": { + "description": "Optional. Zone where the volume will be placed." + } + }, + "serviceLevel": { + "type": "string", + "allowedValues": [ + "Premium", + "Standard", + "StandardZRS", + "Ultra" + ], + "nullable": true, + "metadata": { + "description": "Optional. The pool service level. Must match the one of the parent capacity pool." + } + }, + "networkFeatures": { + "type": "string", + "allowedValues": [ + "Basic", + "Basic_Standard", + "Standard", + "Standard_Basic" + ], + "nullable": true, + "metadata": { + "description": "Optional. Network feature for the volume." + } + }, + "creationToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription." + } + }, + "usageThreshold": { + "type": "int", + "metadata": { + "description": "Required. Maximum storage quota allowed for a file system in bytes." + } + }, + "protocolTypes": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Set of protocol types." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." + } + }, + "exportPolicy": { + "$ref": "#/definitions/exportPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. Export policy rules." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "smbEncryption": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume." + } + }, + "smbContinuouslyAvailable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume." + } + }, + "smbNonBrowsable": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." + } + }, + "kerberosEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a volume in the capacity pool." + } + }, + "_1.backupType": { + "type": "object", + "properties": { + "backupPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the backup policy to link." + } + }, + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Backup Vault." + } + } + }, + "metadata": { + "description": "The type for the backup properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "_1.replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, + "metadata": { + "description": "The type for the replication properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "_1.snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, + "metadata": { + "description": "The type for the snapshot properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/_1.replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/_1.backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/_1.snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, + "metadata": { + "description": "The type for the data protection properties.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, + "metadata": { + "description": "The type for export policy rules.", + "__bicep_imported_from!": { + "sourceTemplate": "volume/main.bicep" + } + } + }, + "roleAssignmentType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } + } + } + }, + "parameters": { + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags for all resources." + } + }, + "serviceLevel": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Premium", + "Standard", + "StandardZRS", + "Ultra" + ], + "metadata": { + "description": "Optional. The pool service level." + } + }, + "size": { + "type": "int", + "metadata": { + "description": "Required. Provisioned size of the pool (in bytes). Allowed values are in 4TiB chunks (value must be multiply of 4398046511104)." + } + }, + "qosType": { + "type": "string", + "defaultValue": "Auto", + "allowedValues": [ + "Auto", + "Manual" + ], + "metadata": { + "description": "Optional. The qos type of the pool." + } + }, + "volumes": { + "type": "array", + "items": { + "$ref": "#/definitions/volumeType" + }, + "nullable": true, + "metadata": { + "description": "Optional. List of volumes to create in the capacity pool." + } + }, + "coolAccess": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "encryptionType": { + "type": "string", + "defaultValue": "Single", + "allowedValues": [ + "Double", + "Single" + ], + "metadata": { + "description": "Optional. Encryption type of the capacity pool, set encryption type for data at rest for this pool and all volumes in it. This value can only be set when creating new pool." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "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')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "capacityPool": { + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "serviceLevel": "[parameters('serviceLevel')]", + "size": "[parameters('size')]", + "qosType": "[parameters('qosType')]", + "coolAccess": "[parameters('coolAccess')]", + "encryptionType": "[parameters('encryptionType')]" + } + }, + "capacityPool_roleAssignments": { + "copy": { + "name": "capacityPool_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.NetApp/netAppAccounts/{0}/capacityPools/{1}', parameters('netAppAccountName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.NetApp/netAppAccounts/capacityPools', parameters('netAppAccountName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "capacityPool" + ] + }, + "capacityPool_volumes": { + "copy": { + "name": "capacityPool_volumes", + "count": "[length(coalesce(parameters('volumes'), createArray()))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Vol-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('netAppAccountName')]" + }, + "capacityPoolName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].name]" + }, + "location": { + "value": "[parameters('location')]" + }, + "serviceLevel": { + "value": "[parameters('serviceLevel')]" + }, + "creationToken": { + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'creationToken'), coalesce(parameters('volumes'), createArray())[copyIndex()].name)]" + }, + "usageThreshold": { + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].usageThreshold]" + }, + "protocolTypes": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'protocolTypes')]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('volumes'), createArray())[copyIndex()].subnetResourceId]" + }, + "exportPolicy": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'exportPolicy')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "networkFeatures": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'networkFeatures')]" + }, + "zones": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'zones')]" + }, + "coolAccess": { + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolAccess'), false())]" + }, + "coolAccessRetrievalPolicy": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolAccessRetrievalPolicy')]" + }, + "coolnessPeriod": { + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'coolnessPeriod'), 0)]" + }, + "encryptionKeySource": { + "value": "[coalesce(tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'encryptionKeySource'), 'Microsoft.NetApp')]" + }, + "keyVaultPrivateEndpointResourceId": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'keyVaultPrivateEndpointResourceId')]" + }, + "dataProtection": { + "value": "[tryGet(coalesce(parameters('volumes'), createArray())[copyIndex()], 'dataProtection')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "8045934107791458590" + }, + "name": "Azure NetApp Files Capacity Pool Volumes", + "description": "This module deploys an Azure NetApp Files Capacity Pool Volume." + }, + "definitions": { + "dataProtectionType": { + "type": "object", + "properties": { + "replication": { + "$ref": "#/definitions/replicationType", + "nullable": true, + "metadata": { + "description": "Optional. Replication properties." + } + }, + "backup": { + "$ref": "#/definitions/backupType", + "nullable": true, + "metadata": { + "description": "Optional. Backup properties." + } + }, + "snapshot": { + "$ref": "#/definitions/snapshotType", + "nullable": true, + "metadata": { + "description": "Optional. Snapshot properties." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for the data protection properties." + } + }, + "replicationType": { + "type": "object", + "properties": { + "endpointType": { + "type": "string", + "allowedValues": [ + "dst", + "src" + ], + "metadata": { + "description": "Required. Indicates whether the local volume is the source or destination for the Volume Replication." + } + }, + "remoteVolumeRegion": { + "type": "string", + "metadata": { + "description": "Required. The remote region for the other end of the Volume Replication." + } + }, + "remoteVolumeResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the remote volume." + } + }, + "replicationSchedule": { + "type": "string", + "allowedValues": [ + "_10minutely", + "daily", + "hourly" + ], + "metadata": { + "description": "Required. The replication schedule for the volume." + } + } + }, + "metadata": { + "description": "The type for the replication properties." + } + }, + "backupType": { + "type": "object", + "properties": { + "backupPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the backup policy to link." + } + }, + "policyEnforced": { + "type": "bool", + "metadata": { + "description": "Required. Enable to enforce the policy." + } + }, + "backupVaultName": { + "type": "string", + "metadata": { + "description": "Required. The name of the Backup Vault." + } + } + }, + "metadata": { + "description": "The type for the backup properties." + } + }, + "snapshotType": { + "type": "object", + "properties": { + "snapshotPolicyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the snapshot policy to link." + } + } + }, + "metadata": { + "description": "The type for the snapshot properties." + } + }, + "exportPolicyType": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ruleIndex": { + "type": "int", + "metadata": { + "description": "Required. Order index." + } + }, + "allowedClients": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Client ingress specification as comma separated string with IPv4 CIDRs, IPv4 host addresses and host names." + } + }, + "chownMode": { + "type": "string", + "allowedValues": [ + "Restricted", + "Unrestricted" + ], + "nullable": true, + "metadata": { + "description": "Optional. This parameter specifies who is authorized to change the ownership of a file. restricted - Only root user can change the ownership of the file. unrestricted - Non-root users can change ownership of files that they own." + } + }, + "cifs": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Allows CIFS protocol." + } + }, + "hasRootAccess": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Has root access to volume." + } + }, + "kerberos5ReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read only access." + } + }, + "kerberos5ReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5 Read and write access." + } + }, + "kerberos5iReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read only access." + } + }, + "kerberos5iReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5i Read and write access." + } + }, + "kerberos5pReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read only access." + } + }, + "kerberos5pReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Kerberos5p Read and write access." + } + }, + "nfsv3": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv3 protocol. Enable only for NFSv3 type volumes." + } + }, + "nfsv41": { + "type": "bool", + "metadata": { + "description": "Required. Allows NFSv4.1 protocol. Enable only for NFSv4.1 type volumes." + } + }, + "unixReadOnly": { + "type": "bool", + "metadata": { + "description": "Required. Read only access." + } + }, + "unixReadWrite": { + "type": "bool", + "metadata": { + "description": "Required. Read and write access." + } + } + } + }, + "metadata": { + "description": "Required. The Export policy rules." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for export policy rules." + } + }, + "roleAssignmentType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.4.0" + } + } + } + }, + "parameters": { + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent capacity pool. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the pool volume." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the pool volume." + } + }, + "coolAccess": { + "type": "bool", + "metadata": { + "description": "Required. If enabled (true) the pool can contain cool Access enabled volumes." + } + }, + "coolnessPeriod": { + "type": "int", + "metadata": { + "description": "Required. Specifies the number of days after which data that is not accessed by clients will be tiered." + } + }, + "coolAccessRetrievalPolicy": { + "type": "string", + "defaultValue": "Default", + "metadata": { + "description": "Optional. Determines the data retrieval behavior from the cool tier to standard storage based on the read pattern for cool access enabled volumes (Default/Never/Read)." + } + }, + "encryptionKeySource": { + "type": "string", + "metadata": { + "description": "Required. The source of the encryption key." + } + }, + "keyVaultPrivateEndpointResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the key vault private endpoint." + } + }, + "volumeType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The type of the volume. DataProtection volumes are used for replication." + } + }, + "zones": { + "type": "array", + "items": { + "type": "int" + }, + "defaultValue": [ + 1, + 2, + 3 + ], + "metadata": { + "description": "Optional. Zone where the volume will be placed." + } + }, + "serviceLevel": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Premium", + "Standard", "StandardZRS", "Ultra" ], "metadata": { - "description": "Optional. The pool service level. Must match the one of the parent capacity pool." - } + "description": "Optional. The pool service level. Must match the one of the parent capacity pool." + } + }, + "networkFeatures": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Basic", + "Basic_Standard", + "Standard", + "Standard_Basic" + ], + "metadata": { + "description": "Optional. Network feature for the volume." + } + }, + "creationToken": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription." + } + }, + "usageThreshold": { + "type": "int", + "metadata": { + "description": "Required. Maximum storage quota allowed for a file system in bytes." + } + }, + "protocolTypes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Set of protocol types." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." + } + }, + "exportPolicy": { + "$ref": "#/definitions/exportPolicyType", + "nullable": true, + "metadata": { + "description": "Optional. The export policy rules." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "dataProtection": { + "$ref": "#/definitions/dataProtectionType", + "nullable": true, + "metadata": { + "description": "Optional. DataProtection type volumes include an object containing details of the replication." + } + }, + "smbEncryption": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume." + } + }, + "smbContinuouslyAvailable": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume." + } + }, + "smbNonBrowsable": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." + } + }, + "kerberosEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Define if a volume is KerberosEnabled." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "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')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "netAppAccount::capacityPool": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('capacityPoolName'))]" + }, + "netAppAccount::backupVault": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))]" + }, + "netAppAccount::backupPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'backup')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName'))]" + }, + "netAppAccount::snapshotPolicy": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'snapshot')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))]" + }, + "remoteNetAppAccount::remoteCapacityPool::remoteVolume": { + "condition": "[and(and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication')))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}/{2}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/')))]" + }, + "remoteNetAppAccount::remoteCapacityPool": { + "condition": "[and(not(empty(tryGet(parameters('dataProtection'), 'replication'))), not(empty(tryGet(parameters('dataProtection'), 'replication'))))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10])]" + }, + "vnet::subnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[format('{0}/{1}', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/')))]" + }, + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "keyVaultPrivateEndpoint": { + "condition": "[not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp'))]", + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/'))]" + }, + "remoteNetAppAccount": { + "condition": "[not(empty(tryGet(parameters('dataProtection'), 'replication')))]", + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]]", + "name": "[split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8]]" + }, + "vnet": { + "existing": true, + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2024-03-01", + "subscriptionId": "[split(parameters('subnetResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('subnetResourceId'), '/')[4]]", + "name": "[split(parameters('subnetResourceId'), '/')[8]]" + }, + "volume": { + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '//'), '/')[2], split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), '////'), '/')[4]), 'Microsoft.Network/privateEndpoints', last(split(coalesce(parameters('keyVaultPrivateEndpointResourceId'), 'dummyVault'), '/')))), createObject()), if(not(empty(parameters('volumeType'))), createObject('volumeType', parameters('volumeType')), createObject()), createObject('dataProtection', if(not(empty(parameters('dataProtection'))), createObject('replication', if(not(empty(tryGet(parameters('dataProtection'), 'replication'))), createObject('endpointType', tryGet(parameters('dataProtection'), 'replication', 'endpointType'), 'remoteVolumeRegion', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[2], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '////'), '/')[4]), 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[8], split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), '//'), '/')[10], last(split(coalesce(tryGet(tryGet(parameters('dataProtection'), 'replication'), 'remoteVolumeResourceId'), 'dummyvolume'), '/'))), 'remoteVolumeResourceId', tryGet(parameters('dataProtection'), 'replication', 'remoteVolumeResourceId'), 'replicationSchedule', tryGet(parameters('dataProtection'), 'replication', 'replicationSchedule')), createObject()), 'backup', if(not(empty(tryGet(parameters('dataProtection'), 'backup'))), createObject('backupPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupPolicyName')), 'policyEnforced', coalesce(tryGet(parameters('dataProtection'), 'backup', 'policyEnforced'), false()), 'backupVaultId', resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'backup', 'backupVaultName'))), createObject()), 'snapshot', if(not(empty(tryGet(parameters('dataProtection'), 'snapshot'))), createObject('snapshotPolicyId', resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), tryGet(parameters('dataProtection'), 'snapshot', 'snapshotPolicyName'))), createObject())), null()), 'networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('subnetResourceId'), '/')[2], split(parameters('subnetResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks/subnets', split(parameters('subnetResourceId'), '/')[8], last(split(parameters('subnetResourceId'), '/'))), 'exportPolicy', parameters('exportPolicy'), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'), 'kerberosEnabled', parameters('kerberosEnabled'))))]", + "zones": "[map(parameters('zones'), lambda('zone', format('{0}', lambdaVariables('zone'))))]" + }, + "volume_roleAssignments": { + "copy": { + "name": "volume_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.NetApp/netAppAccounts/{0}/capacityPools/{1}/volumes/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "volume" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Volume." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the Volume." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Volume was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('volume', '2024-03-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "capacityPool" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Capacity Pool." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Capacity Pool." + }, + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools', parameters('netAppAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Capacity Pool was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('capacityPool', '2024-03-01', 'full').location]" + }, + "volumeResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The resource IDs of the volume created in the capacity pool." + }, + "copy": { + "count": "[length(coalesce(parameters('volumes'), createArray()))]", + "input": "[reference(format('capacityPool_volumes[{0}]', copyIndex())).outputs.resourceId.value]" + } + } + } + } + }, + "dependsOn": [ + "netAppAccount", + "netAppAccount_backupPolicies", + "netAppAccount_backupVault", + "netAppAccount_snapshotPolicies" + ] + }, + "netAppAccount_backupVaultBackups": { + "condition": "[not(empty(tryGet(parameters('backupVault'), 'backups')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANFAccount-BackupVault-Backups', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[tryGet(parameters('backupVault'), 'name')]" + }, + "backups": { + "value": "[tryGet(parameters('backupVault'), 'backups')]" + }, + "location": { + "value": "[coalesce(tryGet(parameters('backupVault'), 'location'), parameters('location'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "1432647773332765235" + }, + "name": "Azure NetApp Files Volume Backup Vault", + "description": "This module deploys a NetApp Files Backup Vault." + }, + "definitions": { + "backupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the backup." + } + }, + "label": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Label for backup." + } + }, + "snapshotName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the snapshot." + } + }, + "volumeName": { + "type": "string", + "metadata": { + "description": "Required. The name of the volume to backup." + } + }, + "capacityPoolName": { + "type": "string", + "metadata": { + "description": "Required. The name of the capacity pool containing the volume." + } + } + }, + "metadata": { + "__bicep_export!": true, + "description": "The type for a backup." + } + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "vault", + "metadata": { + "description": "Optional. The name of the backup vault." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location of the backup vault." + } + }, + "netAppAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." + } + }, + "backups": { + "type": "array", + "items": { + "$ref": "#/definitions/backupType" + }, + "nullable": true, + "metadata": { + "description": "Optional. The list of backups to create." + } + } + }, + "resources": { + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "backupVault": { + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": {} + }, + "backupVault_backups": { + "copy": { + "name": "backupVault_backups", + "count": "[length(coalesce(parameters('backups'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ANF-Backup-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "netAppAccountName": { + "value": "[parameters('netAppAccountName')]" + }, + "backupVaultName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'name')]" + }, + "label": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'label')]" + }, + "snapshotName": { + "value": "[tryGet(coalesce(parameters('backups'), createArray())[copyIndex()], 'snapshotName')]" + }, + "volumeName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].volumeName]" + }, + "capacityPoolName": { + "value": "[coalesce(parameters('backups'), createArray())[copyIndex()].capacityPoolName]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.13.18514", + "templateHash": "10519572323483923146" }, - "networkFeatures": { + "name": "Azure NetApp Files Volume Backup", + "description": "This module deploys a backup of a NetApp Files Volume." + }, + "parameters": { + "name": { "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Basic", - "Basic_Standard", - "Standard", - "Standard_Basic" - ], + "defaultValue": "backup", "metadata": { - "description": "Optional. Network feature for the volume." + "description": "Optional. The name of the backup." } }, - "creationToken": { + "backupVaultName": { "type": "string", - "defaultValue": "[parameters('name')]", "metadata": { - "description": "Optional. A unique file path for the volume. This is the name of the volume export. A volume is mounted using the export path. File path must start with an alphabetical character and be unique within the subscription." - } - }, - "usageThreshold": { - "type": "int", - "metadata": { - "description": "Required. Maximum storage quota allowed for a file system in bytes." - } - }, - "protocolTypes": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Set of protocol types." + "description": "Conditional. The name of the parent backup vault. Required if the template is used in a standalone deployment." } }, - "subnetResourceId": { + "netAppAccountName": { "type": "string", "metadata": { - "description": "Required. The Azure Resource URI for a delegated subnet. Must have the delegation Microsoft.NetApp/volumes." - } - }, - "exportPolicyRules": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Export policy rules." + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." } }, - "roleAssignments": { - "type": "array", - "items": { - "$ref": "#/definitions/roleAssignmentType" - }, + "label": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "Optional. Label for backup." } }, - "backupVaultResourceId": { + "snapshotName": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The Id of the Backup Vault." - } - }, - "replicationEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enables replication." - } - }, - "smbEncryption": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enables SMB encryption. Only applicable for SMB/DualProtocol volume." + "description": "Optional. The name of the snapshot." } }, - "smbContinuouslyAvailable": { - "type": "bool", - "defaultValue": false, + "volumeName": { + "type": "string", "metadata": { - "description": "Optional. Enables continuously available share property for SMB volume. Only applicable for SMB volume." + "description": "Required. The name of the volume to backup." } }, - "smbNonBrowsable": { + "capacityPoolName": { "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Enabled", - "Disabled" - ], "metadata": { - "description": "Optional. Enables non-browsable property for SMB Shares. Only applicable for SMB/DualProtocol volume." - } - } - }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + "description": "Required. The name of the capacity pool containing the volume." } - ], - "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')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" } }, "resources": { - "netAppAccount::capacityPool": { + "netAppAccount::remoteCapacityPool::volume": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", + "apiVersion": "2024-07-01", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" + }, + "netAppAccount::backupVault": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts/backupVaults", + "apiVersion": "2024-03-01", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]" + }, + "netAppAccount::remoteCapacityPool": { "existing": true, "type": "Microsoft.NetApp/netAppAccounts/capacityPools", "apiVersion": "2024-03-01", @@ -1482,463 +3941,14 @@ "apiVersion": "2024-03-01", "name": "[parameters('netAppAccountName')]" }, - "volume": { - "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": "[shallowMerge(createArray(createObject('coolAccess', parameters('coolAccess'), 'coolAccessRetrievalPolicy', parameters('coolAccessRetrievalPolicy'), 'coolnessPeriod', parameters('coolnessPeriod'), 'encryptionKeySource', parameters('encryptionKeySource')), if(not(equals(parameters('encryptionKeySource'), 'Microsoft.NetApp')), createObject('keyVaultPrivateEndpointResourceId', parameters('keyVaultPrivateEndpointResourceId')), createObject()), if(not(equals(parameters('volumeType'), '')), createObject('volumeType', parameters('volumeType'), 'dataProtection', createObject('replication', if(parameters('replicationEnabled'), createObject('endpointType', parameters('endpointType'), 'remoteVolumeRegion', parameters('remoteVolumeRegion'), 'remoteVolumeResourceId', parameters('remoteVolumeResourceId'), 'replicationSchedule', parameters('replicationSchedule')), createObject()), 'backup', if(parameters('backupEnabled'), createObject('backupPolicyId', reference('backupPolicies').outputs.resourceId.value, 'policyEnforced', parameters('policyEnforced'), 'backupVaultId', parameters('backupVaultResourceId')), createObject()), 'snapshot', if(parameters('snapEnabled'), createObject('snapshotPolicyId', reference('snapshotPolicies').outputs.resourceId.value), createObject()))), createObject()), createObject('networkFeatures', parameters('networkFeatures'), 'serviceLevel', parameters('serviceLevel'), 'creationToken', parameters('creationToken'), 'usageThreshold', parameters('usageThreshold'), 'protocolTypes', parameters('protocolTypes'), 'subnetId', parameters('subnetResourceId'), 'exportPolicy', if(not(empty(parameters('exportPolicyRules'))), createObject('rules', parameters('exportPolicyRules')), null()), 'smbContinuouslyAvailable', parameters('smbContinuouslyAvailable'), 'smbEncryption', parameters('smbEncryption'), 'smbNonBrowsable', parameters('smbNonBrowsable'))))]", - "zones": "[parameters('zones')]", - "dependsOn": [ - "backupPolicies", - "backupVaults", - "snapshotPolicies" - ] - }, - "backupVaults": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/backupVaults", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupVaultName'))]", - "location": "[parameters('backupVaultLocation')]", - "properties": {} - }, - "backups": { - "condition": "[parameters('backupEnabled')]", + "backup": { "type": "Microsoft.NetApp/netAppAccounts/backupVaults/backups", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('backupName'))]", - "properties": "[if(parameters('backupEnabled'), createObject('label', parameters('backupLabel'), 'snapshotName', parameters('snapshotName'), 'useExistingSnapshot', parameters('useExistingSnapshot'), 'volumeResourceId', parameters('volumeResourceId')), createObject())]", - "dependsOn": [ - "backupVaults", - "volume" - ] - }, - "volume_roleAssignments": { - "copy": { - "name": "volume_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.NetApp/netAppAccounts/{0}/capacityPools/{1}/volumes/{2}', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", - "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "volume" - ] - }, - "backupPolicies": { - "condition": "[parameters('backupEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[parameters('backupPolicyName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyBackupsToKeep": { - "value": "[parameters('dailyBackupsToKeep')]" - }, - "monthlyBackupsToKeep": { - "value": "[parameters('monthlyBackupsToKeep')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "weeklyBackupsToKeep": { - "value": "[parameters('weeklyBackupsToKeep')]" - }, - "backupEnabled": { - "value": "[parameters('backupEnabled')]" - }, - "backupPolicyLocation": { - "value": "[parameters('backupPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "2321320275404095362" - }, - "name": "Azure NetApp Files Backup Policy", - "description": "This module deploys a Backup Policy for Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "backupPolicy", - "metadata": { - "description": "Optional. The name of the backup policy." - } - }, - "backupPolicyLocation": { - "type": "string", - "metadata": { - "description": "Required. The location of the backup policy. Required if the template is used in a standalone deployment." - } - }, - "dailyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The daily backups to keep." - } - }, - "monthlyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The monthly backups to keep." - } - }, - "weeklyBackupsToKeep": { - "type": "int", - "metadata": { - "description": "Required. The weekly backups to keep." - } - }, - "backupEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether the backup policy is enabled." - } - } - }, - "resources": [ - { - "type": "Microsoft.NetApp/netAppAccounts/backupPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('backupPolicyName'))]", - "location": "[parameters('backupPolicyLocation')]", - "properties": { - "dailyBackupsToKeep": "[parameters('dailyBackupsToKeep')]", - "enabled": "[parameters('backupEnabled')]", - "monthlyBackupsToKeep": "[parameters('monthlyBackupsToKeep')]", - "weeklyBackupsToKeep": "[parameters('weeklyBackupsToKeep')]" - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the backup Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupPolicies', parameters('netAppAccountName'), parameters('backupPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('backupPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Backup Policy was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - } - }, - "snapshotPolicies": { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[uniqueString(parameters('snapshotPolicyName'))]", + "name": "[format('{0}/{1}/{2}', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "dailyHour": { - "value": "[parameters('dailyHour')]" - }, - "dailyMinute": { - "value": "[parameters('dailyMinute')]" - }, - "dailySnapshotsToKeep": { - "value": "[parameters('dailySnapshotsToKeep')]" - }, - "dailyUsedBytes": { - "value": "[parameters('dailyUsedBytes')]" - }, - "daysOfMonth": { - "value": "[parameters('daysOfMonth')]" - }, - "hourlyMinute": { - "value": "[parameters('hourlyMinute')]" - }, - "hourlySnapshotsToKeep": { - "value": "[parameters('hourlySnapshotsToKeep')]" - }, - "hourlyUsedBytes": { - "value": "[parameters('hourlyUsedBytes')]" - }, - "monthlyHour": { - "value": "[parameters('monthlyHour')]" - }, - "monthlyMinute": { - "value": "[parameters('monthlyMinute')]" - }, - "monthlySnapshotsToKeep": { - "value": "[parameters('monthlySnapshotsToKeep')]" - }, - "monthlyUsedBytes": { - "value": "[parameters('monthlyUsedBytes')]" - }, - "netAppAccountName": { - "value": "[parameters('netAppAccountName')]" - }, - "snapshotPolicyName": { - "value": "[parameters('snapshotPolicyName')]" - }, - "weeklyDay": { - "value": "[parameters('weeklyDay')]" - }, - "weeklyHour": { - "value": "[parameters('weeklyHour')]" - }, - "weeklyMinute": { - "value": "[parameters('weeklyMinute')]" - }, - "weeklySnapshotsToKeep": { - "value": "[parameters('weeklySnapshotsToKeep')]" - }, - "weeklyUsedBytes": { - "value": "[parameters('weeklyUsedBytes')]" - }, - "snapshotPolicyLocation": { - "value": "[parameters('snapshotPolicyLocation')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17538391796648994915" - }, - "name": "Azure NetApp Files Snapshot Policy", - "description": "This module deploys a Snapshot Policy for an Azure NetApp File." - }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the snapshot policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot used bytes." - } - }, - "hourlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The hourly snapshot minute." - } - }, - "hourlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot count to keep." - } - }, - "hourlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Hourly snapshot used bytes." - } - }, - "daysOfMonth": { - "type": "string", - "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." - } - }, - "monthlyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot used bytes." - } - }, - "weeklyDay": { - "type": "string", - "metadata": { - "description": "Required. The weekly snapshot day." - } - }, - "weeklyHour": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot hour." - } - }, - "weeklyMinute": { - "type": "int", - "metadata": { - "description": "Required. The weekly snapshot minute." - } - }, - "weeklySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot count to keep." - } - }, - "weeklyUsedBytes": { - "type": "int", - "metadata": { - "description": "Required. Weekly snapshot used bytes." - } - }, - "snapEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether the snapshot policy is enabled." - } - } - }, - "resources": [ - { - "condition": "[parameters('snapEnabled')]", - "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", - "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]", - "location": "[parameters('snapshotPolicyLocation')]", - "properties": { - "enabled": "[parameters('snapEnabled')]", - "dailySchedule": { - "hour": "[parameters('dailyHour')]", - "minute": "[parameters('dailyMinute')]", - "snapshotsToKeep": "[parameters('dailySnapshotsToKeep')]", - "usedBytes": "[parameters('dailyUsedBytes')]" - }, - "hourlySchedule": { - "minute": "[parameters('hourlyMinute')]", - "snapshotsToKeep": "[parameters('hourlySnapshotsToKeep')]", - "usedBytes": "[parameters('hourlyUsedBytes')]" - }, - "monthlySchedule": { - "daysOfMonth": "[parameters('daysOfMonth')]", - "hour": "[parameters('monthlyHour')]", - "minute": "[parameters('monthlyMinute')]", - "snapshotsToKeep": "[parameters('monthlySnapshotsToKeep')]", - "usedBytes": "[parameters('monthlyUsedBytes')]" - }, - "weeklySchedule": { - "day": "[parameters('weeklyDay')]", - "hour": "[parameters('weeklyHour')]", - "minute": "[parameters('weeklyMinute')]", - "snapshotsToKeep": "[parameters('weeklySnapshotsToKeep')]", - "usedBytes": "[parameters('weeklyUsedBytes')]" - } - } - } - ], - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the snapshot Policy created within volume." - }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Backup Policy." - }, - "value": "[parameters('snapshotPolicyName')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the Snapshot was created in." - }, - "value": "[resourceGroup().name]" - } - } - } + "label": "[parameters('label')]", + "snapshotName": "[parameters('snapshotName')]", + "volumeResourceId": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('volumeName'))]" } } }, @@ -1946,36 +3956,29 @@ "name": { "type": "string", "metadata": { - "description": "The name of the Volume." + "description": "The name of the backup." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The Resource ID of the Volume." + "description": "The Resource ID of the backup." }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools/volumes', parameters('netAppAccountName'), parameters('capacityPoolName'), parameters('name'))]" + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults/backups', parameters('netAppAccountName'), parameters('backupVaultName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the Resource Group the Volume was created in." + "description": "The name of the Resource Group the backup was created in." }, "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('volume', '2024-03-01', 'full').location]" } } } }, "dependsOn": [ - "capacityPool" + "backupVault" ] } }, @@ -1983,21 +3986,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the Capacity Pool." + "description": "The name of the backup vault." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the Capacity Pool." + "description": "The Resource ID of the backup vault." }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/capacityPools', parameters('netAppAccountName'), parameters('name'))]" + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/backupVaults', parameters('netAppAccountName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the Resource Group the Capacity Pool was created in." + "description": "The name of the Resource Group the backup vault was created in." }, "value": "[resourceGroup().name]" }, @@ -2006,20 +4009,14 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('capacityPool', '2024-03-01', 'full').location]" - }, - "volumeResourceId": { - "type": "string", - "metadata": { - "description": "The resource IDs of the volume created in the capacity pool." - }, - "value": "[if(not(equals(parameters('volumes'), createArray())), reference(format('capacityPool_volumes[{0}]', 0)).outputs.resourceId.value, '')]" + "value": "[reference('backupVault', '2024-03-01', 'full').location]" } } } }, "dependsOn": [ - "netAppAccount" + "netAppAccount", + "netAppAccount_capacityPools" ] } }, @@ -2052,12 +4049,32 @@ }, "value": "[reference('netAppAccount', '2024-03-01', 'full').location]" }, - "volumeResourceId": { - "type": "string", + "capacityPoolResourceIds": { + "type": "array", + "items": { + "type": "object", + "properties": { + "resourceId": { + "type": "string" + }, + "volumeResourceIds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "metadata": { - "description": "The resource IDs of the volume created in the capacity pool." + "description": "The resource IDs of the created capacity pools & their volumes." }, - "value": "[if(not(equals(parameters('capacityPools'), createArray())), reference(format('netAppAccount_capacityPools[{0}]', 0)).outputs.volumeResourceId.value, '')]" + "copy": { + "count": "[length(coalesce(parameters('capacityPools'), createArray()))]", + "input": { + "resourceId": "[reference(format('netAppAccount_capacityPools[{0}]', copyIndex())).outputs.resourceId.value]", + "volumeResourceIds": "[reference(format('netAppAccount_capacityPools[{0}]', copyIndex())).outputs.volumeResourceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/net-app/net-app-account/snapshot-policies/README.md b/avm/res/net-app/net-app-account/snapshot-policies/README.md index d059bf9769..51bcd093fd 100644 --- a/avm/res/net-app/net-app-account/snapshot-policies/README.md +++ b/avm/res/net-app/net-app-account/snapshot-policies/README.md @@ -16,190 +16,300 @@ This module deploys a Snapshot Policy for an Azure NetApp File. ## Parameters -**Required parameters** +**Conditional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`dailyHour`](#parameter-dailyhour) | int | The daily snapshot hour. | -| [`dailyMinute`](#parameter-dailyminute) | int | The daily snapshot minute. | -| [`dailySnapshotsToKeep`](#parameter-dailysnapshotstokeep) | int | Daily snapshot count to keep. | -| [`dailyUsedBytes`](#parameter-dailyusedbytes) | int | Daily snapshot used bytes. | -| [`daysOfMonth`](#parameter-daysofmonth) | string | The monthly snapshot day. | -| [`hourlyMinute`](#parameter-hourlyminute) | int | The hourly snapshot minute. | -| [`hourlySnapshotsToKeep`](#parameter-hourlysnapshotstokeep) | int | Hourly snapshot count to keep. | -| [`hourlyUsedBytes`](#parameter-hourlyusedbytes) | int | Hourly snapshot used bytes. | -| [`monthlyHour`](#parameter-monthlyhour) | int | The monthly snapshot hour. | -| [`monthlyMinute`](#parameter-monthlyminute) | int | The monthly snapshot minute. | -| [`monthlySnapshotsToKeep`](#parameter-monthlysnapshotstokeep) | int | Monthly snapshot count to keep. | -| [`monthlyUsedBytes`](#parameter-monthlyusedbytes) | int | Monthly snapshot used bytes. | -| [`snapshotPolicyName`](#parameter-snapshotpolicyname) | string | The name of the snapshot policy. | -| [`weeklyDay`](#parameter-weeklyday) | string | The weekly snapshot day. | -| [`weeklyHour`](#parameter-weeklyhour) | int | The weekly snapshot hour. | -| [`weeklyMinute`](#parameter-weeklyminute) | int | The weekly snapshot minute. | -| [`weeklySnapshotsToKeep`](#parameter-weeklysnapshotstokeep) | int | Weekly snapshot count to keep. | -| [`weeklyUsedBytes`](#parameter-weeklyusedbytes) | int | Weekly snapshot used bytes. | +| [`netAppAccountName`](#parameter-netappaccountname) | string | The name of the parent NetApp account. Required if the template is used in a standalone deployment. | -**Conditional parameters** +**Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`netAppAccountName`](#parameter-netappaccountname) | string | The name of the parent NetApp account. Required if the template is used in a standalone deployment. | +| [`dailySchedule`](#parameter-dailyschedule) | object | Schedule for daily snapshots. | +| [`hourlySchedule`](#parameter-hourlyschedule) | object | Schedule for hourly snapshots. | +| [`location`](#parameter-location) | string | The location of the snapshot policy. | +| [`monthlySchedule`](#parameter-monthlyschedule) | object | Schedule for monthly snapshots. | +| [`name`](#parameter-name) | string | The name of the snapshot policy. | +| [`snapEnabled`](#parameter-snapenabled) | bool | Indicates whether the snapshot policy is enabled. | +| [`weeklySchedule`](#parameter-weeklyschedule) | object | Schedule for weekly snapshots. | + +### Parameter: `netAppAccountName` + +The name of the parent NetApp account. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `dailySchedule` + +Schedule for daily snapshots. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`hour`](#parameter-dailyschedulehour) | int | The daily snapshot hour. | +| [`minute`](#parameter-dailyscheduleminute) | int | The daily snapshot minute. | +| [`snapshotsToKeep`](#parameter-dailyschedulesnapshotstokeep) | int | Daily snapshot count to keep. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`snapEnabled`](#parameter-snapenabled) | bool | Indicates whether the snapshot policy is enabled. | -| [`snapshotPolicyLocation`](#parameter-snapshotpolicylocation) | string | The location of the snapshot policy. | +| [`usedBytes`](#parameter-dailyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | -### Parameter: `dailyHour` +### Parameter: `dailySchedule.hour` The daily snapshot hour. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 23 -### Parameter: `dailyMinute` +### Parameter: `dailySchedule.minute` The daily snapshot minute. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 59 -### Parameter: `dailySnapshotsToKeep` +### Parameter: `dailySchedule.snapshotsToKeep` Daily snapshot count to keep. - Required: Yes - Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `dailyUsedBytes` +### Parameter: `dailySchedule.usedBytes` -Daily snapshot used bytes. +Resource size in bytes, current storage usage for the volume in bytes. -- Required: Yes +- Required: No - Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `daysOfMonth` +### Parameter: `hourlySchedule` -The monthly snapshot day. +Schedule for hourly snapshots. -- Required: Yes -- Type: string +- Required: No +- Type: object -### Parameter: `hourlyMinute` +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`minute`](#parameter-hourlyscheduleminute) | int | The hourly snapshot minute. | +| [`snapshotsToKeep`](#parameter-hourlyschedulesnapshotstokeep) | int | Hourly snapshot count to keep. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-hourlyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `hourlySchedule.minute` The hourly snapshot minute. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 59 -### Parameter: `hourlySnapshotsToKeep` +### Parameter: `hourlySchedule.snapshotsToKeep` Hourly snapshot count to keep. - Required: Yes - Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `hourlyUsedBytes` +### Parameter: `hourlySchedule.usedBytes` -Hourly snapshot used bytes. +Resource size in bytes, current storage usage for the volume in bytes. -- Required: Yes +- Required: No - Type: int +- MinValue: 1 +- MaxValue: 255 + +### Parameter: `location` + +The location of the snapshot policy. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `monthlySchedule` + +Schedule for monthly snapshots. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`daysOfMonth`](#parameter-monthlyscheduledaysofmonth) | string | Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'. | +| [`hour`](#parameter-monthlyschedulehour) | int | The monthly snapshot hour. | +| [`minute`](#parameter-monthlyscheduleminute) | int | The monthly snapshot minute. | +| [`snapshotsToKeep`](#parameter-monthlyschedulesnapshotstokeep) | int | Monthly snapshot count to keep. | -### Parameter: `monthlyHour` +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-monthlyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | + +### Parameter: `monthlySchedule.daysOfMonth` + +Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'. + +- Required: Yes +- Type: string + +### Parameter: `monthlySchedule.hour` The monthly snapshot hour. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 23 -### Parameter: `monthlyMinute` +### Parameter: `monthlySchedule.minute` The monthly snapshot minute. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 59 -### Parameter: `monthlySnapshotsToKeep` +### Parameter: `monthlySchedule.snapshotsToKeep` Monthly snapshot count to keep. - Required: Yes - Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `monthlyUsedBytes` +### Parameter: `monthlySchedule.usedBytes` -Monthly snapshot used bytes. +Resource size in bytes, current storage usage for the volume in bytes. -- Required: Yes +- Required: No - Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `snapshotPolicyName` +### Parameter: `name` The name of the snapshot policy. -- Required: Yes +- Required: No - Type: string +- Default: `'snapshotPolicy'` -### Parameter: `weeklyDay` +### Parameter: `snapEnabled` -The weekly snapshot day. +Indicates whether the snapshot policy is enabled. -- Required: Yes -- Type: string +- Required: No +- Type: bool +- Default: `False` -### Parameter: `weeklyHour` +### Parameter: `weeklySchedule` -The weekly snapshot hour. +Schedule for weekly snapshots. -- Required: Yes -- Type: int +- Required: No +- Type: object -### Parameter: `weeklyMinute` +**Required parameters** -The weekly snapshot minute. +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`day`](#parameter-weeklyscheduleday) | string | The weekly snapshot day. | +| [`hour`](#parameter-weeklyschedulehour) | int | The weekly snapshot hour. | +| [`minute`](#parameter-weeklyscheduleminute) | int | The weekly snapshot minute. | +| [`snapshotsToKeep`](#parameter-weeklyschedulesnapshotstokeep) | int | Weekly snapshot count to keep. | -- Required: Yes -- Type: int +**Optional parameters** -### Parameter: `weeklySnapshotsToKeep` +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`usedBytes`](#parameter-weeklyscheduleusedbytes) | int | Resource size in bytes, current storage usage for the volume in bytes. | -Weekly snapshot count to keep. +### Parameter: `weeklySchedule.day` -- Required: Yes -- Type: int +The weekly snapshot day. -### Parameter: `weeklyUsedBytes` +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Friday' + 'Monday' + 'Saturday' + 'Sunday' + 'Thursday' + 'Tuesday' + 'Wednesday' + ] + ``` + +### Parameter: `weeklySchedule.hour` -Weekly snapshot used bytes. +The weekly snapshot hour. - Required: Yes - Type: int +- MinValue: 0 +- MaxValue: 23 -### Parameter: `netAppAccountName` +### Parameter: `weeklySchedule.minute` -The name of the parent NetApp account. Required if the template is used in a standalone deployment. +The weekly snapshot minute. - Required: Yes -- Type: string +- Type: int +- MinValue: 0 +- MaxValue: 59 -### Parameter: `snapEnabled` +### Parameter: `weeklySchedule.snapshotsToKeep` -Indicates whether the snapshot policy is enabled. +Weekly snapshot count to keep. -- Required: No -- Type: bool -- Default: `True` +- Required: Yes +- Type: int +- MinValue: 1 +- MaxValue: 255 -### Parameter: `snapshotPolicyLocation` +### Parameter: `weeklySchedule.usedBytes` -The location of the snapshot policy. +Resource size in bytes, current storage usage for the volume in bytes. - Required: No -- Type: string -- Default: `[resourceGroup().location]` +- Type: int +- MinValue: 1 +- MaxValue: 255 ## Outputs diff --git a/avm/res/net-app/net-app-account/snapshot-policies/main.bicep b/avm/res/net-app/net-app-account/snapshot-policies/main.bicep index 13a5788c06..3bd4bee1ff 100644 --- a/avm/res/net-app/net-app-account/snapshot-policies/main.bicep +++ b/avm/res/net-app/net-app-account/snapshot-policies/main.bicep @@ -4,101 +4,41 @@ metadata description = 'This module deploys a Snapshot Policy for an Azure NetAp @description('Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment.') param netAppAccountName string -@description('Required. The name of the snapshot policy.') -param snapshotPolicyName string +@description('Optional. The name of the snapshot policy.') +param name string = 'snapshotPolicy' @description('Optional. The location of the snapshot policy.') -param snapshotPolicyLocation string = resourceGroup().location +param location string = resourceGroup().location -@description('Required. The daily snapshot hour.') -param dailyHour int +@description('Optional. Schedule for hourly snapshots.') +param hourlySchedule hourlyScheduleType? -@description('Required. The daily snapshot minute.') -param dailyMinute int +@description('Optional. Schedule for daily snapshots.') +param dailySchedule dailyScheduleType? -@description('Required. Daily snapshot count to keep.') -param dailySnapshotsToKeep int +@description('Optional. Schedule for monthly snapshots.') +param monthlySchedule monthlyScheduleType? -@description('Required. Daily snapshot used bytes.') -param dailyUsedBytes int - -@description('Required. The hourly snapshot minute.') -param hourlyMinute int - -@description('Required. Hourly snapshot count to keep.') -param hourlySnapshotsToKeep int - -@description('Required. Hourly snapshot used bytes.') -param hourlyUsedBytes int - -@description('Required. The monthly snapshot day.') -param daysOfMonth string - -@description('Required. The monthly snapshot hour.') -param monthlyHour int - -@description('Required. The monthly snapshot minute.') -param monthlyMinute int - -@description('Required. Monthly snapshot count to keep.') -param monthlySnapshotsToKeep int - -@description('Required. Monthly snapshot used bytes.') -param monthlyUsedBytes int - -@description('Required. The weekly snapshot day.') -param weeklyDay string - -@description('Required. The weekly snapshot hour.') -param weeklyHour int - -@description('Required. The weekly snapshot minute.') -param weeklyMinute int - -@description('Required. Weekly snapshot count to keep.') -param weeklySnapshotsToKeep int - -@description('Required. Weekly snapshot used bytes.') -param weeklyUsedBytes int +@description('Optional. Schedule for weekly snapshots.') +param weeklySchedule weeklyScheduleType? @description('Optional. Indicates whether the snapshot policy is enabled.') -param snapEnabled bool = true +param snapEnabled bool = false resource netAppAccount 'Microsoft.NetApp/netAppAccounts@2024-03-01' existing = { name: netAppAccountName } -resource snapshotPolicies 'Microsoft.NetApp/netAppAccounts/snapshotPolicies@2024-03-01' = if (snapEnabled) { - name: snapshotPolicyName +resource snapshotPolicies 'Microsoft.NetApp/netAppAccounts/snapshotPolicies@2024-03-01' = { + name: name parent: netAppAccount - location: snapshotPolicyLocation + location: location properties: { enabled: snapEnabled - dailySchedule: { - hour: dailyHour - minute: dailyMinute - snapshotsToKeep: dailySnapshotsToKeep - usedBytes: dailyUsedBytes - } - hourlySchedule: { - minute: hourlyMinute - snapshotsToKeep: hourlySnapshotsToKeep - usedBytes: hourlyUsedBytes - } - monthlySchedule: { - daysOfMonth: daysOfMonth - hour: monthlyHour - minute: monthlyMinute - snapshotsToKeep: monthlySnapshotsToKeep - usedBytes: monthlyUsedBytes - } - weeklySchedule: { - day: weeklyDay - hour: weeklyHour - minute: weeklyMinute - snapshotsToKeep: weeklySnapshotsToKeep - usedBytes: weeklyUsedBytes - } + dailySchedule: dailySchedule + hourlySchedule: hourlySchedule + monthlySchedule: monthlySchedule + weeklySchedule: weeklySchedule } } @@ -110,3 +50,96 @@ output name string = snapshotPolicies.name @description('The name of the Resource Group the Snapshot was created in.') output resourceGroupName string = resourceGroup().name + +// ================ // +// Definitions // +// ================ // + +@export() +@description('The type for a daily schedule for the snapshot policy.') +type dailyScheduleType = { + @description('Required. The daily snapshot hour.') + @minValue(0) + @maxValue(23) + hour: int + + @description('Required. The daily snapshot minute.') + @minValue(0) + @maxValue(59) + minute: int + + @description('Required. Daily snapshot count to keep.') + @minValue(1) + @maxValue(255) + snapshotsToKeep: int + + @description('Optional. Resource size in bytes, current storage usage for the volume in bytes.') + usedBytes: int? +} + +@export() +@description('The type for an hourly schedule for the snapshot policy.') +type hourlyScheduleType = { + @description('Required. The hourly snapshot minute.') + @minValue(0) + @maxValue(59) + minute: int + + @description('Required. Hourly snapshot count to keep.') + @minValue(1) + @maxValue(255) + snapshotsToKeep: int + + @description('Optional. Resource size in bytes, current storage usage for the volume in bytes.') + usedBytes: int? +} + +@export() +@description('The type for a weekly schedule for the snapshot policy.') +type weeklyScheduleType = { + @description('Required. The weekly snapshot day.') + day: ('Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday') + + @description('Required. The weekly snapshot hour.') + @minValue(0) + @maxValue(23) + hour: int + + @description('Required. The weekly snapshot minute.') + @minValue(0) + @maxValue(59) + minute: int + + @description('Required. Weekly snapshot count to keep.') + @minValue(1) + @maxValue(255) + snapshotsToKeep: int + + @description('Optional. Resource size in bytes, current storage usage for the volume in bytes.') + usedBytes: int? +} + +@export() +@description('The type for a monthly schedule for the snapshot policy.') +type monthlyScheduleType = { + @description('Required. Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., \'10,11,12\'.') + daysOfMonth: string + + @description('Required. The monthly snapshot hour.') + @minValue(0) + @maxValue(23) + hour: int + + @description('Required. The monthly snapshot minute.') + @minValue(0) + @maxValue(59) + minute: int + + @description('Required. Monthly snapshot count to keep.') + @minValue(1) + @maxValue(255) + snapshotsToKeep: int + + @description('Optional. Resource size in bytes, current storage usage for the volume in bytes.') + usedBytes: int? +} diff --git a/avm/res/net-app/net-app-account/snapshot-policies/main.json b/avm/res/net-app/net-app-account/snapshot-policies/main.json index b6edeedd54..66bb746202 100644 --- a/avm/res/net-app/net-app-account/snapshot-policies/main.json +++ b/avm/res/net-app/net-app-account/snapshot-policies/main.json @@ -1,196 +1,283 @@ { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17538391796648994915" + "version": "0.33.13.18514", + "templateHash": "14119927784920096194" }, "name": "Azure NetApp Files Snapshot Policy", "description": "This module deploys a Snapshot Policy for an Azure NetApp File." }, - "parameters": { - "netAppAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." - } - }, - "snapshotPolicyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the snapshot policy." - } - }, - "snapshotPolicyLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location of the snapshot policy." - } - }, - "dailyHour": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot hour." - } - }, - "dailyMinute": { - "type": "int", - "metadata": { - "description": "Required. The daily snapshot minute." - } - }, - "dailySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Daily snapshot count to keep." - } - }, - "dailyUsedBytes": { - "type": "int", + "definitions": { + "dailyScheduleType": { + "type": "object", + "properties": { + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The daily snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The daily snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Daily snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Required. Daily snapshot used bytes." + "__bicep_export!": true, + "description": "The type for a daily schedule for the snapshot policy." } }, - "hourlyMinute": { - "type": "int", + "hourlyScheduleType": { + "type": "object", + "properties": { + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The hourly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Hourly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Required. The hourly snapshot minute." + "__bicep_export!": true, + "description": "The type for an hourly schedule for the snapshot policy." } }, - "hourlySnapshotsToKeep": { - "type": "int", + "weeklyScheduleType": { + "type": "object", + "properties": { + "day": { + "type": "string", + "allowedValues": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "metadata": { + "description": "Required. The weekly snapshot day." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The weekly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The weekly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Weekly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Required. Hourly snapshot count to keep." + "__bicep_export!": true, + "description": "The type for a weekly schedule for the snapshot policy." } }, - "hourlyUsedBytes": { - "type": "int", + "monthlyScheduleType": { + "type": "object", + "properties": { + "daysOfMonth": { + "type": "string", + "metadata": { + "description": "Required. Indicates which days of the month snapshot should be taken. A comma delimited string. E.g., '10,11,12'." + } + }, + "hour": { + "type": "int", + "minValue": 0, + "maxValue": 23, + "metadata": { + "description": "Required. The monthly snapshot hour." + } + }, + "minute": { + "type": "int", + "minValue": 0, + "maxValue": 59, + "metadata": { + "description": "Required. The monthly snapshot minute." + } + }, + "snapshotsToKeep": { + "type": "int", + "minValue": 1, + "maxValue": 255, + "metadata": { + "description": "Required. Monthly snapshot count to keep." + } + }, + "usedBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Resource size in bytes, current storage usage for the volume in bytes." + } + } + }, "metadata": { - "description": "Required. Hourly snapshot used bytes." + "__bicep_export!": true, + "description": "The type for a monthly schedule for the snapshot policy." } - }, - "daysOfMonth": { + } + }, + "parameters": { + "netAppAccountName": { "type": "string", "metadata": { - "description": "Required. The monthly snapshot day." - } - }, - "monthlyHour": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot hour." - } - }, - "monthlyMinute": { - "type": "int", - "metadata": { - "description": "Required. The monthly snapshot minute." - } - }, - "monthlySnapshotsToKeep": { - "type": "int", - "metadata": { - "description": "Required. Monthly snapshot count to keep." + "description": "Conditional. The name of the parent NetApp account. Required if the template is used in a standalone deployment." } }, - "monthlyUsedBytes": { - "type": "int", + "name": { + "type": "string", + "defaultValue": "snapshotPolicy", "metadata": { - "description": "Required. Monthly snapshot used bytes." + "description": "Optional. The name of the snapshot policy." } }, - "weeklyDay": { + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Required. The weekly snapshot day." + "description": "Optional. The location of the snapshot policy." } }, - "weeklyHour": { - "type": "int", + "hourlySchedule": { + "$ref": "#/definitions/hourlyScheduleType", + "nullable": true, "metadata": { - "description": "Required. The weekly snapshot hour." + "description": "Optional. Schedule for hourly snapshots." } }, - "weeklyMinute": { - "type": "int", + "dailySchedule": { + "$ref": "#/definitions/dailyScheduleType", + "nullable": true, "metadata": { - "description": "Required. The weekly snapshot minute." + "description": "Optional. Schedule for daily snapshots." } }, - "weeklySnapshotsToKeep": { - "type": "int", + "monthlySchedule": { + "$ref": "#/definitions/monthlyScheduleType", + "nullable": true, "metadata": { - "description": "Required. Weekly snapshot count to keep." + "description": "Optional. Schedule for monthly snapshots." } }, - "weeklyUsedBytes": { - "type": "int", + "weeklySchedule": { + "$ref": "#/definitions/weeklyScheduleType", + "nullable": true, "metadata": { - "description": "Required. Weekly snapshot used bytes." + "description": "Optional. Schedule for weekly snapshots." } }, "snapEnabled": { "type": "bool", - "defaultValue": true, + "defaultValue": false, "metadata": { "description": "Optional. Indicates whether the snapshot policy is enabled." } } }, - "resources": [ - { - "condition": "[parameters('snapEnabled')]", + "resources": { + "netAppAccount": { + "existing": true, + "type": "Microsoft.NetApp/netAppAccounts", + "apiVersion": "2024-03-01", + "name": "[parameters('netAppAccountName')]" + }, + "snapshotPolicies": { "type": "Microsoft.NetApp/netAppAccounts/snapshotPolicies", "apiVersion": "2024-03-01", - "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]", - "location": "[parameters('snapshotPolicyLocation')]", + "name": "[format('{0}/{1}', parameters('netAppAccountName'), parameters('name'))]", + "location": "[parameters('location')]", "properties": { "enabled": "[parameters('snapEnabled')]", - "dailySchedule": { - "hour": "[parameters('dailyHour')]", - "minute": "[parameters('dailyMinute')]", - "snapshotsToKeep": "[parameters('dailySnapshotsToKeep')]", - "usedBytes": "[parameters('dailyUsedBytes')]" - }, - "hourlySchedule": { - "minute": "[parameters('hourlyMinute')]", - "snapshotsToKeep": "[parameters('hourlySnapshotsToKeep')]", - "usedBytes": "[parameters('hourlyUsedBytes')]" - }, - "monthlySchedule": { - "daysOfMonth": "[parameters('daysOfMonth')]", - "hour": "[parameters('monthlyHour')]", - "minute": "[parameters('monthlyMinute')]", - "snapshotsToKeep": "[parameters('monthlySnapshotsToKeep')]", - "usedBytes": "[parameters('monthlyUsedBytes')]" - }, - "weeklySchedule": { - "day": "[parameters('weeklyDay')]", - "hour": "[parameters('weeklyHour')]", - "minute": "[parameters('weeklyMinute')]", - "snapshotsToKeep": "[parameters('weeklySnapshotsToKeep')]", - "usedBytes": "[parameters('weeklyUsedBytes')]" - } + "dailySchedule": "[parameters('dailySchedule')]", + "hourlySchedule": "[parameters('hourlySchedule')]", + "monthlySchedule": "[parameters('monthlySchedule')]", + "weeklySchedule": "[parameters('weeklySchedule')]" } } - ], + }, "outputs": { "resourceId": { "type": "string", "metadata": { "description": "The resource IDs of the snapshot Policy created within volume." }, - "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('snapshotPolicyName'))]" + "value": "[resourceId('Microsoft.NetApp/netAppAccounts/snapshotPolicies', parameters('netAppAccountName'), parameters('name'))]" }, "name": { "type": "string", "metadata": { "description": "The name of the Backup Policy." }, - "value": "[parameters('snapshotPolicyName')]" + "value": "[parameters('name')]" }, "resourceGroupName": { "type": "string", diff --git a/avm/res/net-app/net-app-account/tests/e2e/max/main.test.bicep b/avm/res/net-app/net-app-account/tests/e2e/max/main.test.bicep index 052295f9f1..920d492c07 100644 --- a/avm/res/net-app/net-app-account/tests/e2e/max/main.test.bicep +++ b/avm/res/net-app/net-app-account/tests/e2e/max/main.test.bicep @@ -55,9 +55,24 @@ module testDeployment '../../../main.bicep' = { params: { name: '${namePrefix}${serviceShort}001' location: enforcedLocation + backupPolicies: [ + { + name: 'myBackupPolicy' + } + ] + snapshotPolicies: [ + { + name: 'mySnapshotPolicy' + dailySchedule: { + snapshotsToKeep: 1 + minute: 0 + hour: 0 + } + } + ] capacityPools: [ { - name: '${namePrefix}-${serviceShort}-cp-001' + name: 'cp-001' roleAssignments: [ { roleDefinitionIdOrName: 'Reader' @@ -69,18 +84,36 @@ module testDeployment '../../../main.bicep' = { size: 4398046511104 volumes: [ { - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true + name: 'vol-001' + dataProtection: { + backup: { + backupPolicyName: 'myBackupPolicy' + backupVaultName: 'myVault' + policyEnforced: false } - ] - name: '${namePrefix}-${serviceShort}-vol-001' - zones: ['1'] + snapshot: { + snapshotPolicyName: 'mySnapshotPolicy' + } + } + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + kerberos5iReadOnly: false + kerberos5pReadOnly: false + kerberos5ReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadWrite: false + kerberos5ReadWrite: false + } + ] + } + zones: [1] networkFeatures: 'Standard' encryptionKeySource: encryptionKeySource protocolTypes: [ @@ -97,18 +130,27 @@ module testDeployment '../../../main.bicep' = { usageThreshold: 107374182400 } { - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: false - nfsv41: true - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] - name: '${namePrefix}-${serviceShort}-vol-002' - zones: ['1'] + kerberosEnabled: false + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + nfsv3: false + nfsv41: true + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: false + kerberos5ReadOnly: false + kerberos5ReadWrite: false + kerberos5iReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadOnly: false + kerberos5pReadWrite: false + } + ] + } + name: 'vol-002' + zones: [1] networkFeatures: 'Standard' encryptionKeySource: encryptionKeySource protocolTypes: [ @@ -123,7 +165,7 @@ module testDeployment '../../../main.bicep' = { ] } { - name: '${namePrefix}-${serviceShort}-cp-002' + name: 'cp-002' roleAssignments: [ { roleDefinitionIdOrName: 'Reader' @@ -136,6 +178,17 @@ module testDeployment '../../../main.bicep' = { volumes: [] } ] + backupVault: { + name: 'myVault' + backups: [ + { + name: 'myBackup01' + capacityPoolName: 'cp-001' + volumeName: 'vol-001' + label: 'myLabel' + } + ] + } roleAssignments: [ { name: '18051111-2a33-4f8e-8b24-441aac1e6562' @@ -173,7 +226,4 @@ module testDeployment '../../../main.bicep' = { ] } } - dependsOn: [ - nestedDependencies - ] } diff --git a/avm/res/net-app/net-app-account/tests/e2e/nfs3/main.test.bicep b/avm/res/net-app/net-app-account/tests/e2e/nfs3/main.test.bicep index 2a49696c4e..8e366f3faf 100644 --- a/avm/res/net-app/net-app-account/tests/e2e/nfs3/main.test.bicep +++ b/avm/res/net-app/net-app-account/tests/e2e/nfs3/main.test.bicep @@ -69,18 +69,26 @@ module testDeployment '../../../main.bicep' = { size: 4398046511104 volumes: [ { - exportPolicyRules: [ - { - allowedClients: '0.0.0.0/0' - nfsv3: true - nfsv41: false - ruleIndex: 1 - unixReadOnly: false - unixReadWrite: true - } - ] + exportPolicy: { + rules: [ + { + allowedClients: '0.0.0.0/0' + nfsv3: true + nfsv41: false + ruleIndex: 1 + unixReadOnly: false + unixReadWrite: true + kerberos5iReadOnly: false + kerberos5pReadOnly: false + kerberos5ReadOnly: false + kerberos5iReadWrite: false + kerberos5pReadWrite: false + kerberos5ReadWrite: false + } + ] + } name: '${namePrefix}-${serviceShort}-vol-001' - zones: ['1'] + zones: [1] networkFeatures: 'Standard' encryptionKeySource: encryptionKeySource protocolTypes: [ @@ -98,7 +106,7 @@ module testDeployment '../../../main.bicep' = { } { name: '${namePrefix}-${serviceShort}-vol-002' - zones: ['1'] + zones: [1] networkFeatures: 'Standard' encryptionKeySource: encryptionKeySource protocolTypes: [ @@ -157,7 +165,4 @@ module testDeployment '../../../main.bicep' = { ServiceName: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - ] } diff --git a/avm/res/net-app/net-app-account/version.json b/avm/res/net-app/net-app-account/version.json index 04a0dd1a80..e42c3d9e5f 100644 --- a/avm/res/net-app/net-app-account/version.json +++ b/avm/res/net-app/net-app-account/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] -} +} \ No newline at end of file