Skip to content

Commit

Permalink
Merge pull request #35029 from yaronya/f/efs-fs-protection
Browse files Browse the repository at this point in the history
Add `protection` attribute to `aws_efs_file_system` resource & data resource
  • Loading branch information
ewbankkit authored Jan 3, 2024
2 parents 8ed7b87 + 2ca2b50 commit 61fd851
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changelog/35029.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_efs_file_system: Add `protection` configuration block
```

```release-note:enhancement
data-source/aws_efs_file_system: Add `protection` attribute
```
80 changes: 78 additions & 2 deletions internal/service/efs/file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ func ResourceFileSystem() *schema.Resource {
ForceNew: true,
ValidateFunc: validation.StringInSlice(efs.PerformanceMode_Values(), false),
},
"protection": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"replication_overwrite": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
efs.ReplicationOverwriteProtectionEnabled,
efs.ReplicationOverwriteProtectionDisabled,
}, false),
},
},
},
},
"provisioned_throughput_in_mibps": {
Type: schema.TypeFloat,
Optional: true,
Expand Down Expand Up @@ -219,16 +238,28 @@ func resourceFileSystemCreate(ctx context.Context, d *schema.ResourceData, meta
}

if v, ok := d.GetOk("lifecycle_policy"); ok {
_, err := conn.PutLifecycleConfigurationWithContext(ctx, &efs.PutLifecycleConfigurationInput{
input := &efs.PutLifecycleConfigurationInput{
FileSystemId: aws.String(d.Id()),
LifecyclePolicies: expandFileSystemLifecyclePolicies(v.([]interface{})),
})
}

_, err := conn.PutLifecycleConfigurationWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "putting EFS file system (%s) lifecycle configuration: %s", d.Id(), err)
}
}

if v, ok := d.GetOk("protection"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input := expandUpdateFileSystemProtectionInput(d.Id(), v.([]interface{})[0].(map[string]interface{}))

_, err := conn.UpdateFileSystemProtectionWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating EFS file system (%s) protection: %s", d.Id(), err)
}
}

return append(diags, resourceFileSystemRead(ctx, d, meta)...)
}

Expand Down Expand Up @@ -260,6 +291,9 @@ func resourceFileSystemRead(ctx context.Context, d *schema.ResourceData, meta in
d.Set("number_of_mount_targets", fs.NumberOfMountTargets)
d.Set("owner_id", fs.OwnerId)
d.Set("performance_mode", fs.PerformanceMode)
if err := d.Set("protection", flattenFileSystemProtection(fs.FileSystemProtection)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting protection: %s", err)
}
d.Set("provisioned_throughput_in_mibps", fs.ProvisionedThroughputInMibps)
if err := d.Set("size_in_bytes", flattenFileSystemSizeInBytes(fs.SizeInBytes)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting size_in_bytes: %s", err)
Expand Down Expand Up @@ -330,6 +364,18 @@ func resourceFileSystemUpdate(ctx context.Context, d *schema.ResourceData, meta
}
}

if d.HasChanges("protection") {
if v, ok := d.GetOk("protection"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input := expandUpdateFileSystemProtectionInput(d.Id(), v.([]interface{})[0].(map[string]interface{}))

_, err := conn.UpdateFileSystemProtectionWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating EFS file system (%s) protection: %s", d.Id(), err)
}
}
}

return append(diags, resourceFileSystemRead(ctx, d, meta)...)
}

Expand Down Expand Up @@ -547,3 +593,33 @@ func flattenFileSystemSizeInBytes(sizeInBytes *efs.FileSystemSize) []interface{}

return []interface{}{m}
}

func expandUpdateFileSystemProtectionInput(id string, tfMap map[string]interface{}) *efs.UpdateFileSystemProtectionInput {
if tfMap == nil {
return nil
}

apiObject := &efs.UpdateFileSystemProtectionInput{
FileSystemId: aws.String(id),
}

if v, ok := tfMap["replication_overwrite"].(string); ok && v != "" {
apiObject.ReplicationOverwriteProtection = aws.String(v)
}

return apiObject
}

func flattenFileSystemProtection(protection *efs.FileSystemProtectionDescription) []interface{} {
if protection == nil {
return []interface{}{}
}

tfMap := map[string]interface{}{}

if protection.ReplicationOverwriteProtection != nil {
tfMap["replication_overwrite"] = aws.StringValue(protection.ReplicationOverwriteProtection)
}

return []interface{}{tfMap}
}
15 changes: 15 additions & 0 deletions internal/service/efs/file_system_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ func DataSourceFileSystem() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"protection": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"replication_overwrite": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"provisioned_throughput_in_mibps": {
Type: schema.TypeFloat,
Computed: true,
Expand Down Expand Up @@ -145,6 +157,9 @@ func dataSourceFileSystemRead(ctx context.Context, d *schema.ResourceData, meta
d.Set("kms_key_id", fs.KmsKeyId)
d.Set("name", fs.Name)
d.Set("performance_mode", fs.PerformanceMode)
if err := d.Set("protection", flattenFileSystemProtection(fs.FileSystemProtection)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting protection: %s", err)
}
d.Set("provisioned_throughput_in_mibps", fs.ProvisionedThroughputInMibps)
if fs.SizeInBytes != nil {
d.Set("size_in_bytes", fs.SizeInBytes.Value)
Expand Down
3 changes: 3 additions & 0 deletions internal/service/efs/file_system_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestAccEFSFileSystemDataSource_id(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"),
resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"),
resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexache.MustCompile(`^\d+$`)),
resource.TestCheckResourceAttrPair(dataSourceName, "protection", resourceName, "protection"),
),
},
},
Expand Down Expand Up @@ -70,6 +71,7 @@ func TestAccEFSFileSystemDataSource_tags(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"),
resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"),
resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexache.MustCompile(`^\d+$`)),
resource.TestCheckResourceAttrPair(dataSourceName, "protection", resourceName, "protection"),
),
},
},
Expand Down Expand Up @@ -100,6 +102,7 @@ func TestAccEFSFileSystemDataSource_name(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"),
resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"),
resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexache.MustCompile(`^\d+$`)),
resource.TestCheckResourceAttrPair(dataSourceName, "protection", resourceName, "protection"),
),
},
},
Expand Down
47 changes: 47 additions & 0 deletions internal/service/efs/file_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func TestAccEFSFileSystem_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "number_of_mount_targets", "0"),
acctest.MatchResourceAttrAccountID(resourceName, "owner_id"),
resource.TestCheckResourceAttr(resourceName, "performance_mode", "generalPurpose"),
resource.TestCheckResourceAttr(resourceName, "protection.#", "1"),
resource.TestCheckResourceAttr(resourceName, "protection.0.replication_overwrite", "ENABLED"),
resource.TestCheckResourceAttr(resourceName, "size_in_bytes.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "size_in_bytes.0.value"),
resource.TestCheckResourceAttrSet(resourceName, "size_in_bytes.0.value_in_ia"),
Expand Down Expand Up @@ -110,6 +112,41 @@ func TestAccEFSFileSystem_performanceMode(t *testing.T) {
})
}

func TestAccEFSFileSystem_protection(t *testing.T) {
ctx := acctest.Context(t)
var desc efs.FileSystemDescription
resourceName := "aws_efs_file_system.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckFileSystemDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccFileSystemConfig_protection("DISABLED"),
Check: resource.ComposeTestCheckFunc(
testAccCheckFileSystem(ctx, resourceName, &desc),
resource.TestCheckResourceAttr(resourceName, "protection.#", "1"),
resource.TestCheckResourceAttr(resourceName, "protection.0.replication_overwrite", "DISABLED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccFileSystemConfig_protection("ENABLED"),
Check: resource.ComposeTestCheckFunc(
testAccCheckFileSystem(ctx, resourceName, &desc),
resource.TestCheckResourceAttr(resourceName, "protection.0.replication_overwrite", "ENABLED"),
),
},
},
})
}

func TestAccEFSFileSystem_availabilityZoneName(t *testing.T) {
ctx := acctest.Context(t)
var desc efs.FileSystemDescription
Expand Down Expand Up @@ -477,6 +514,16 @@ resource "aws_efs_file_system" "test" {
}
`

func testAccFileSystemConfig_protection(replicationOverwwrite string) string {
return fmt.Sprintf(`
resource "aws_efs_file_system" "test" {
protection {
replication_overwrite = %[1]q
}
}
`, replicationOverwwrite)
}

func testAccFileSystemConfig_availabilityZoneName(rName string) string {
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(`
resource "aws_efs_file_system" "test" {
Expand Down
7 changes: 7 additions & 0 deletions website/docs/r/efs_file_system.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ user guide for more information.
* `encrypted` - (Optional) If true, the disk will be encrypted.
* `kms_key_id` - (Optional) The ARN for the KMS encryption key. When specifying kms_key_id, encrypted needs to be set to true.
* `lifecycle_policy` - (Optional) A file system [lifecycle policy](https://docs.aws.amazon.com/efs/latest/ug/API_LifecyclePolicy.html) object (documented below).
* `protection` - (Optional) A file system [protection](https://docs.aws.amazon.com/efs/latest/ug/API_FileSystemProtectionDescription.html) object (documented below).
* `performance_mode` - (Optional) The file system performance mode. Can be either `"generalPurpose"` or `"maxIO"` (Default: `"generalPurpose"`).
* `provisioned_throughput_in_mibps` - (Optional) The throughput, measured in MiB/s, that you want to provision for the file system. Only applicable with `throughput_mode` set to `provisioned`.
* `tags` - (Optional) A map of tags to assign to the file system. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
Expand All @@ -61,6 +62,12 @@ user guide for more information.
* `transition_to_primary_storage_class` - (Optional) Describes the policy used to transition a file from infequent access storage to primary storage. Valid values: `AFTER_1_ACCESS`.
* `transition_to_archive` - (Optional) Indicates how long it takes to transition files to the archive storage class. Requires transition_to_ia, Elastic Throughput and General Purpose performance mode. Valid values: `AFTER_1_DAY`, `AFTER_7_DAYS`, `AFTER_14_DAYS`, `AFTER_30_DAYS`, `AFTER_60_DAYS`, or `AFTER_90_DAYS`.

### Protection Arguments

`protection` supports the following arguments:

* `replication_overwrite` - (Optional) Indicates whether replication overwrite protection is enabled. Valid values: `ENABLED` or `DISABLED`.

## Attribute Reference

This resource exports the following attributes in addition to the arguments above:
Expand Down

0 comments on commit 61fd851

Please sign in to comment.