Skip to content

Commit

Permalink
r/aws_fsx_ontap_volume: Add 'bypass_snaplock_enterprise_retention' ar…
Browse files Browse the repository at this point in the history
…gument.
  • Loading branch information
ewbankkit committed Sep 25, 2023
1 parent ad58585 commit 0ed7cef
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .changelog/32530.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resource/aws_fsx_ontap_volume: Add `copy_tags_to_backups` and `snapshot_policy`
```

```release-note:enhancement
resource/aws_fsx_ontap_volume: Add `snaplock_configuration` configuration block to support [SnapLock](https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/snaplock.html)
resource/aws_fsx_ontap_volume: Add `bypass_snaplock_enterprise_retention` argument and `snaplock_configuration` configuration block to support [SnapLock](https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/snaplock.html)
```

```release-note:enhancement
Expand Down
9 changes: 8 additions & 1 deletion internal/service/fsx/ontap_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func ResourceONTAPVolume() *schema.Resource {

Importer: &schema.ResourceImporter{
StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.Set("bypass_snaplock_enterprise_retention", false)
d.Set("skip_final_backup", false)

return []*schema.ResourceData{d}, nil
Expand All @@ -55,6 +56,11 @@ func ResourceONTAPVolume() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"bypass_snaplock_enterprise_retention": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"copy_tags_to_backups": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -473,7 +479,8 @@ func resourceONTAPVolumeDelete(ctx context.Context, d *schema.ResourceData, meta
log.Printf("[DEBUG] Deleting FSx for NetApp ONTAP Volume: %s", d.Id())
_, err := conn.DeleteVolumeWithContext(ctx, &fsx.DeleteVolumeInput{
OntapConfiguration: &fsx.DeleteVolumeOntapConfiguration{
SkipFinalBackup: aws.Bool(d.Get("skip_final_backup").(bool)),
BypassSnaplockEnterpriseRetention: aws.Bool(d.Get("bypass_snaplock_enterprise_retention").(bool)),
SkipFinalBackup: aws.Bool(d.Get("skip_final_backup").(bool)),
},
VolumeId: aws.String(d.Id()),
})
Expand Down
99 changes: 56 additions & 43 deletions internal/service/fsx/ontap_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestAccFSxONTAPVolume_basic(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckONTAPVolumeExists(ctx, resourceName, &volume),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "fsx", regexache.MustCompile(`volume/fs-.+/fsvol-.+`)),
resource.TestCheckResourceAttr(resourceName, "bypass_snaplock_enterprise_retention", "false"),
resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", "false"),
resource.TestCheckResourceAttrSet(resourceName, "file_system_id"),
resource.TestCheckResourceAttr(resourceName, "junction_path", fmt.Sprintf("/%[1]s", rName)),
Expand All @@ -50,16 +51,15 @@ func TestAccFSxONTAPVolume_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "storage_efficiency_enabled", "true"),
resource.TestCheckResourceAttrSet(resourceName, "storage_virtual_machine_id"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
resource.TestCheckResourceAttr(resourceName, "tiering_policy.#", "0"),
resource.TestCheckResourceAttr(resourceName, "tiering_policy.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "uuid"),
resource.TestCheckResourceAttr(resourceName, "volume_type", "ONTAP"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestAccFSxONTAPVolume_copyTagsToBackups(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_copyTagsToBackups(rName, false),
Expand Down Expand Up @@ -152,7 +152,7 @@ func TestAccFSxONTAPVolume_junctionPath(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_junctionPath(rName, jPath2),
Expand Down Expand Up @@ -191,7 +191,7 @@ func TestAccFSxONTAPVolume_name(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_basic(rName2),
Expand Down Expand Up @@ -228,7 +228,7 @@ func TestAccFSxONTAPVolume_ontapVolumeType(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
},
})
Expand Down Expand Up @@ -258,7 +258,7 @@ func TestAccFSxONTAPVolume_securityStyle(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_securityStyle(rName, "NTFS"),
Expand Down Expand Up @@ -308,7 +308,7 @@ func TestAccFSxONTAPVolume_size(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_size(rName, size2),
Expand All @@ -325,7 +325,7 @@ func TestAccFSxONTAPVolume_size(t *testing.T) {

func TestAccFSxONTAPVolume_snaplock(t *testing.T) {
ctx := acctest.Context(t)
var volume1, volume2 fsx.Volume
var volume1 /*, volume2*/ fsx.Volume
resourceName := "aws_fsx_ontap_volume.test"
rName := fmt.Sprintf("tf_acc_test_%d", sdkacctest.RandInt())

Expand All @@ -339,6 +339,7 @@ func TestAccFSxONTAPVolume_snaplock(t *testing.T) {
Config: testAccONTAPVolumeConfig_snaplockCreate(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckONTAPVolumeExists(ctx, resourceName, &volume1),
resource.TestCheckResourceAttr(resourceName, "bypass_snaplock_enterprise_retention", "true"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.audit_log_volume", "false"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.#", "1"),
Expand All @@ -363,33 +364,39 @@ func TestAccFSxONTAPVolume_snaplock(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_snaplockUpdate(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckONTAPVolumeExists(ctx, resourceName, &volume2),
testAccCheckONTAPVolumeNotRecreated(&volume1, &volume2),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.audit_log_volume", "true"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.0.type", "DAYS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.0.value", "14"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.privileged_delete", "PERMANENTLY_DISABLED"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.0.type", "DAYS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.0.value", "30"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.0.type", "MONTHS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.0.value", "9"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.0.type", "HOURS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.0.value", "24"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.snaplock_type", "ENTERPRISE"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.volume_append_mode_enabled", "true"),
),
},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
/*
See https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/how-snaplock-works.html#snaplock-audit-log-volume.
> The minimum retention period for a SnapLock audit log volume is six months. Until this retention period expires, the SnapLock audit log volume and the SVM and file system that are associated with it can't be deleted even if the volume was created in SnapLock Enterprise mode.
{
Config: testAccONTAPVolumeConfig_snaplockUpdate(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckONTAPVolumeExists(ctx, resourceName, &volume2),
testAccCheckONTAPVolumeNotRecreated(&volume1, &volume2),
resource.TestCheckResourceAttr(resourceName, "bypass_snaplock_enterprise_retention", "true"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.audit_log_volume", "true"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.0.type", "DAYS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.autocommit_period.0.value", "14"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.privileged_delete", "PERMANENTLY_DISABLED"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.0.type", "DAYS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.default_retention.0.value", "30"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.0.type", "MONTHS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.maximum_retention.0.value", "9"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.#", "1"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.0.type", "HOURS"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.retention_period.0.minimum_retention.0.value", "24"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.snaplock_type", "ENTERPRISE"),
resource.TestCheckResourceAttr(resourceName, "snaplock_configuration.0.volume_append_mode_enabled", "true"),
),
},
*/
},
})
}
Expand Down Expand Up @@ -420,7 +427,7 @@ func TestAccFSxONTAPVolume_snapshotPolicy(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_snapshotPolicy(rName, policy2),
Expand Down Expand Up @@ -459,7 +466,7 @@ func TestAccFSxONTAPVolume_storageEfficiency(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_storageEfficiency(rName, false),
Expand Down Expand Up @@ -498,7 +505,7 @@ func TestAccFSxONTAPVolume_tags(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_tags2(rName, "key1", "value1updated", "key2", "value2"),
Expand Down Expand Up @@ -547,7 +554,7 @@ func TestAccFSxONTAPVolume_tieringPolicy(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"skip_final_backup"},
ImportStateVerifyIgnore: []string{"bypass_snaplock_enterprise_retention", "skip_final_backup"},
},
{
Config: testAccONTAPVolumeConfig_tieringPolicy(rName, "SNAPSHOT_ONLY", 10),
Expand Down Expand Up @@ -755,10 +762,13 @@ resource "aws_fsx_ontap_volume" "test" {
snaplock_configuration {
snaplock_type = "ENTERPRISE"
}
bypass_snaplock_enterprise_retention = true
}
`, rName))
}

/*
func testAccONTAPVolumeConfig_snaplockUpdate(rName string) string {
return acctest.ConfigCompose(testAccONTAPVolumeConfig_base(rName), fmt.Sprintf(`
resource "aws_fsx_ontap_volume" "test" {
Expand Down Expand Up @@ -796,9 +806,12 @@ resource "aws_fsx_ontap_volume" "test" {
}
}
}
bypass_snaplock_enterprise_retention = true
}
`, rName))
}
*/

func testAccONTAPVolumeConfig_snapshotPolicy(rName, snapshotPolicy string) string {
return acctest.ConfigCompose(testAccONTAPVolumeConfig_base(rName), fmt.Sprintf(`
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/fsx_ontap_volume.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ resource "aws_fsx_ontap_volume" "test" {
This resource supports the following arguments:

* `name` - (Required) The name of the Volume. You can use a maximum of 203 alphanumeric characters, plus the underscore (_) special character.
* `bypass_snaplock_enterprise_retention` - (Optional) Setting this to `true` allows a SnapLock administrator to delete an FSx for ONTAP SnapLock Enterprise volume with unexpired write once, read many (WORM) files. This configuration must be applied separately before attempting to delete the resource to have the desired behavior. Defaults to `false`.
* `copy_tags_to_backups` - (Optional) A boolean flag indicating whether tags for the volume should be copied to backups. This value defaults to `false`.
* `junction_path` - (Optional) Specifies the location in the storage virtual machine's namespace where the volume is mounted. The junction_path must have a leading forward slash, such as `/vol3`
* `ontap_volume_type` - (Optional) Specifies the type of volume, valid values are `RW`, `DP`. Default value is `RW`. These can be set by the ONTAP CLI or API. This setting is used as part of migration and replication [Migrating to Amazon FSx for NetApp ONTAP](https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/migrating-fsx-ontap.html)
Expand Down

0 comments on commit 0ed7cef

Please sign in to comment.