Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/aws_backup_plan: Add support for AdvancedBackupSettings #15341

Merged
merged 1 commit into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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