Skip to content

Commit

Permalink
resource/aws_backup_plan: Add support for AdvancedBackupSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
gazoakley committed Oct 2, 2020
1 parent 0e4645a commit 726b550
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 5 deletions.
71 changes: 66 additions & 5 deletions aws/resource_aws_backup_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ func resourceAwsBackupPlan() *schema.Resource {
},
Set: backupBackupPlanHash,
},
"advanced_backup_setting": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"backup_options": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"resource_type": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
"arn": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -125,8 +142,9 @@ func resourceAwsBackupPlanCreate(d *schema.ResourceData, meta interface{}) error

input := &backup.CreateBackupPlanInput{
BackupPlan: &backup.PlanInput{
BackupPlanName: aws.String(d.Get("name").(string)),
Rules: expandBackupPlanRules(d.Get("rule").(*schema.Set)),
BackupPlanName: aws.String(d.Get("name").(string)),
Rules: expandBackupPlanRules(d.Get("rule").(*schema.Set)),
AdvancedBackupSettings: expandBackupPlanAdvancedBackupSettings(d.Get("advanced_backup_setting").(*schema.Set)),
},
BackupPlanTags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().BackupTags(),
}
Expand Down Expand Up @@ -166,6 +184,12 @@ func resourceAwsBackupPlanRead(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("error setting rule: %s", err)
}

// AdvancedBackupSettings being read direct from resp and not from under
// resp.BackupPlan is deliberate - the latter always contains null
if err := d.Set("advanced_backup_setting", flattenBackupPlanAdvancedBackupSettings(resp.AdvancedBackupSettings)); err != nil {
return fmt.Errorf("error setting advanced_backup_setting: %s", err)
}

tags, err := keyvaluetags.BackupListTags(conn, d.Get("arn").(string))
if err != nil {
return fmt.Errorf("error listing tags for Backup Plan (%s): %s", d.Id(), err)
Expand All @@ -180,12 +204,13 @@ func resourceAwsBackupPlanRead(d *schema.ResourceData, meta interface{}) error {
func resourceAwsBackupPlanUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).backupconn

if d.HasChange("rule") {
if d.HasChanges("rule", "advanced_backup_setting") {
input := &backup.UpdateBackupPlanInput{
BackupPlanId: aws.String(d.Id()),
BackupPlan: &backup.PlanInput{
BackupPlanName: aws.String(d.Get("name").(string)),
Rules: expandBackupPlanRules(d.Get("rule").(*schema.Set)),
BackupPlanName: aws.String(d.Get("name").(string)),
Rules: expandBackupPlanRules(d.Get("rule").(*schema.Set)),
AdvancedBackupSettings: expandBackupPlanAdvancedBackupSettings(d.Get("advanced_backup_setting").(*schema.Set)),
},
}

Expand Down Expand Up @@ -279,6 +304,27 @@ func expandBackupPlanRules(vRules *schema.Set) []*backup.RuleInput {
return rules
}

func expandBackupPlanAdvancedBackupSettings(vAdvancedBackupSettings *schema.Set) []*backup.AdvancedBackupSetting {
advancedBackupSettings := []*backup.AdvancedBackupSetting{}

for _, vAdvancedBackupSetting := range vAdvancedBackupSettings.List() {
advancedBackupSetting := &backup.AdvancedBackupSetting{}

mAdvancedBackupSetting := vAdvancedBackupSetting.(map[string]interface{})

if v, ok := mAdvancedBackupSetting["backup_options"].(map[string]interface{}); ok && v != nil {
advancedBackupSetting.BackupOptions = stringMapToPointers(v)
}
if v, ok := mAdvancedBackupSetting["resource_type"].(string); ok && v != "" {
advancedBackupSetting.ResourceType = aws.String(v)
}

advancedBackupSettings = append(advancedBackupSettings, advancedBackupSetting)
}

return advancedBackupSettings
}

func expandBackupPlanCopyActions(actionList []interface{}) []*backup.CopyAction {
actions := []*backup.CopyAction{}

Expand Down Expand Up @@ -341,6 +387,21 @@ func flattenBackupPlanRules(rules []*backup.Rule) *schema.Set {
return schema.NewSet(backupBackupPlanHash, vRules)
}

func flattenBackupPlanAdvancedBackupSettings(advancedBackupSettings []*backup.AdvancedBackupSetting) *schema.Set {
vAdvancedBackupSettings := []interface{}{}

for _, advancedBackupSetting := range advancedBackupSettings {
mAdvancedBackupSetting := map[string]interface{}{
"backup_options": aws.StringValueMap(advancedBackupSetting.BackupOptions),
"resource_type": aws.StringValue(advancedBackupSetting.ResourceType),
}

vAdvancedBackupSettings = append(vAdvancedBackupSettings, mAdvancedBackupSetting)
}

return schema.NewSet(backupBackupPlanHash, vAdvancedBackupSettings)
}

func flattenBackupPlanCopyActions(copyActions []*backup.CopyAction) []interface{} {
if len(copyActions) == 0 {
return nil
Expand Down
62 changes: 62 additions & 0 deletions aws/resource_aws_backup_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,38 @@ func TestAccAwsBackupPlan_Rule_CopyAction_CrossRegion(t *testing.T) {
})
}

func TestAccAwsBackupPlan_AdvancedBackupSetting(t *testing.T) {
var plan backup.GetBackupPlanOutput
resourceName := "aws_backup_plan.test"
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupPlanDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsBackupPlanConfigAdvancedBackupSetting(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupPlanExists(resourceName, &plan),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "advanced_backup_setting.#", "1"),
tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "advanced_backup_setting.*", map[string]string{
"backup_options.%": "1",
"backup_options.WindowsVSS": "enabled",
"resource_type": "EC2",
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAwsBackupPlan_disappears(t *testing.T) {
var plan backup.GetBackupPlanOutput
resourceName := "aws_backup_plan.test"
Expand Down Expand Up @@ -890,3 +922,33 @@ resource "aws_backup_plan" "test" {
}
`, rName)
}

func testAccAwsBackupPlanConfigAdvancedBackupSetting(rName string) string {
return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
name = "%[1]s-1"
}
resource "aws_backup_plan" "test" {
name = %[1]q
rule {
rule_name = %[1]q
target_vault_name = aws_backup_vault.test.name
schedule = "cron(0 12 * * ? *)"
lifecycle {
cold_storage_after = 30
delete_after = 180
}
}
advanced_backup_setting {
backup_options = {
WindowsVSS = "enabled"
}
resource_type = "EC2"
}
}
`, rName)
}
14 changes: 14 additions & 0 deletions website/docs/r/backup_plan.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ resource "aws_backup_plan" "example" {
target_vault_name = aws_backup_vault.test.name
schedule = "cron(0 12 * * ? *)"
}
advanced_backup_setting {
backup_options = {
WindowsVSS = "enabled"
}
resource_type = "EC2"
}
}
```

Expand All @@ -30,6 +37,7 @@ The following arguments are supported:

* `name` - (Required) The display name of a backup plan.
* `rule` - (Required) A rule object that specifies a scheduled task that is used to back up a selection of resources.
* `advanced_backup_setting` - (Optional) An object that specifies backup options for each resource type.
* `tags` - (Optional) Metadata that you can assign to help organize the plans you create.

### Rule Arguments
Expand All @@ -56,6 +64,12 @@ For **copy_action** the following attributes are supported:
* `lifecycle` - (Optional) The lifecycle defines when a protected resource is copied over to a backup vault and when it expires. Fields documented above.
* `destination_vault_arn` - (Required) An Amazon Resource Name (ARN) that uniquely identifies the destination backup vault for the copied backup.

### Advanced Backup Setting Arguments
For `advanced_backup_setting` the following attibutes are supported:

* `backup_options` - (Optional) Specifies the backup option for a selected resource. This option is only available for Windows VSS backup jobs. Set to `{ WindowsVSS = "enabled" }` to enable Windows VSS backup option and create a VSS Windows backup.
* `resource_type` - (Optional) The type of AWS resource to be backed up. For VSS Windows backups, the only supported resource type is Amazon EC2. Valid values: `EC2`.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand Down

0 comments on commit 726b550

Please sign in to comment.