Skip to content

Commit

Permalink
Merge pull request #16112 from DrFaust92/r/backup_vault_policy
Browse files Browse the repository at this point in the history
r/backup_vault_policy - new resource
  • Loading branch information
breathingdust authored Nov 13, 2020
2 parents 32fcf01 + 2e3b71b commit 280cad8
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 0 deletions.
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ func Provider() *schema.Provider {
"aws_backup_selection": resourceAwsBackupSelection(),
"aws_backup_vault": resourceAwsBackupVault(),
"aws_backup_vault_notifications": resourceAwsBackupVaultNotifications(),
"aws_backup_vault_policy": resourceAwsBackupVaultPolicy(),
"aws_budgets_budget": resourceAwsBudgetsBudget(),
"aws_cloud9_environment_ec2": resourceAwsCloud9EnvironmentEc2(),
"aws_cloudformation_stack": resourceAwsCloudFormationStack(),
Expand Down
101 changes: 101 additions & 0 deletions aws/resource_aws_backup_vault_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/backup"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceAwsBackupVaultPolicy() *schema.Resource {
return &schema.Resource{
Create: resourceAwsBackupVaultPolicyPut,
Update: resourceAwsBackupVaultPolicyPut,
Read: resourceAwsBackupVaultPolicyRead,
Delete: resourceAwsBackupVaultPolicyDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"backup_vault_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"policy": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsJSON,
DiffSuppressFunc: suppressEquivalentAwsPolicyDiffs,
},
"backup_vault_arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsBackupVaultPolicyPut(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).backupconn

input := &backup.PutBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(d.Get("backup_vault_name").(string)),
Policy: aws.String(d.Get("policy").(string)),
}

_, err := conn.PutBackupVaultAccessPolicy(input)
if err != nil {
return fmt.Errorf("error creating Backup Vault Policy (%s): %w", d.Id(), err)
}

d.SetId(d.Get("backup_vault_name").(string))

return resourceAwsBackupVaultPolicyRead(d, meta)
}

func resourceAwsBackupVaultPolicyRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).backupconn

input := &backup.GetBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(d.Id()),
}

resp, err := conn.GetBackupVaultAccessPolicy(input)
if isAWSErr(err, backup.ErrCodeResourceNotFoundException, "") {
log.Printf("[WARN] Backup Vault Policy %s not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading Backup Vault Policy (%s): %w", d.Id(), err)
}
d.Set("backup_vault_name", resp.BackupVaultName)
d.Set("policy", resp.Policy)
d.Set("backup_vault_arn", resp.BackupVaultArn)

return nil
}

func resourceAwsBackupVaultPolicyDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).backupconn

input := &backup.DeleteBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(d.Id()),
}

_, err := conn.DeleteBackupVaultAccessPolicy(input)
if err != nil {
if isAWSErr(err, backup.ErrCodeResourceNotFoundException, "") {
return nil
}
return fmt.Errorf("error deleting Backup Vault Policy (%s): %w", d.Id(), err)
}

return nil
}
251 changes: 251 additions & 0 deletions aws/resource_aws_backup_vault_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package aws

import (
"fmt"
"log"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/backup"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func init() {
resource.AddTestSweepers("aws_backup_vault_policy", &resource.Sweeper{
Name: "aws_backup_vault_policy",
F: testSweepBackupVaultPolicies,
})
}

func testSweepBackupVaultPolicies(region string) error {
client, err := sharedClientForRegion(region)
if err != nil {
return fmt.Errorf("Error getting client: %w", err)
}
conn := client.(*AWSClient).backupconn
var sweeperErrs *multierror.Error

input := &backup.ListBackupVaultsInput{}

for {
output, err := conn.ListBackupVaults(input)
if err != nil {
if testSweepSkipSweepError(err) {
log.Printf("[WARN] Skipping Backup Vault Policies sweep for %s: %s", region, err)
return nil
}
sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Backup Vault Policies: %w", err))
return sweeperErrs.ErrorOrNil()
}

if len(output.BackupVaultList) == 0 {
log.Print("[DEBUG] No Backup Vault Policies to sweep")
return nil
}

for _, rule := range output.BackupVaultList {
name := aws.StringValue(rule.BackupVaultName)

log.Printf("[INFO] Deleting Backup Vault Policies %s", name)
_, err := conn.DeleteBackupVaultAccessPolicy(&backup.DeleteBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(name),
})
if err != nil {
sweeperErr := fmt.Errorf("error deleting Backup Vault Policies %s: %w", name, err)
log.Printf("[ERROR] %s", sweeperErr)
sweeperErrs = multierror.Append(sweeperErrs, sweeperErr)
continue
}
}

if output.NextToken == nil {
break
}
input.NextToken = output.NextToken
}

return sweeperErrs.ErrorOrNil()
}

func TestAccAwsBackupVaultPolicy_basic(t *testing.T) {
var vault backup.GetBackupVaultAccessPolicyOutput

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_backup_vault_policy.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupVaultPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccBackupVaultPolicyConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultPolicyExists(resourceName, &vault),
resource.TestMatchResourceAttr(resourceName, "policy", regexp.MustCompile("^{\"Version\":\"2012-10-17\".+"))),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccBackupVaultPolicyConfigUpdated(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultPolicyExists(resourceName, &vault),
resource.TestMatchResourceAttr(resourceName, "policy", regexp.MustCompile("^{\"Version\":\"2012-10-17\".+")),
resource.TestMatchResourceAttr(resourceName, "policy", regexp.MustCompile("backup:ListRecoveryPointsByBackupVault")),
),
},
},
})
}

func TestAccAwsBackupVaultPolicy_disappears(t *testing.T) {
var vault backup.GetBackupVaultAccessPolicyOutput

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_backup_vault_policy.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupVaultPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccBackupVaultPolicyConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultPolicyExists(resourceName, &vault),
testAccCheckResourceDisappears(testAccProvider, resourceAwsBackupVaultPolicy(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAwsBackupVaultPolicyDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).backupconn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_backup_vault_policy" {
continue
}

input := &backup.GetBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(rs.Primary.ID),
}

resp, err := conn.GetBackupVaultAccessPolicy(input)

if err == nil {
if aws.StringValue(resp.BackupVaultName) == rs.Primary.ID {
return fmt.Errorf("Backup Plan Policies '%s' was not deleted properly", rs.Primary.ID)
}
}
}

return nil
}

func testAccCheckAwsBackupVaultPolicyExists(name string, vault *backup.GetBackupVaultAccessPolicyOutput) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}

conn := testAccProvider.Meta().(*AWSClient).backupconn
params := &backup.GetBackupVaultAccessPolicyInput{
BackupVaultName: aws.String(rs.Primary.ID),
}
resp, err := conn.GetBackupVaultAccessPolicy(params)
if err != nil {
return err
}

*vault = *resp

return nil
}
}

func testAccBackupVaultPolicyConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
name = %[1]q
}
resource "aws_backup_vault_policy" "test" {
backup_vault_name = aws_backup_vault.test.name
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "default",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"backup:DescribeBackupVault",
"backup:DeleteBackupVault",
"backup:PutBackupVaultAccessPolicy",
"backup:DeleteBackupVaultAccessPolicy",
"backup:GetBackupVaultAccessPolicy",
"backup:StartBackupJob",
"backup:GetBackupVaultNotifications",
"backup:PutBackupVaultNotifications"
],
"Resource": "${aws_backup_vault.test.arn}"
}
]
}
POLICY
}
`, rName)
}

func testAccBackupVaultPolicyConfigUpdated(rName string) string {
return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
name = %[1]q
}
resource "aws_backup_vault_policy" "test" {
backup_vault_name = aws_backup_vault.test.name
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "default",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"backup:DescribeBackupVault",
"backup:DeleteBackupVault",
"backup:PutBackupVaultAccessPolicy",
"backup:DeleteBackupVaultAccessPolicy",
"backup:GetBackupVaultAccessPolicy",
"backup:StartBackupJob",
"backup:GetBackupVaultNotifications",
"backup:PutBackupVaultNotifications",
"backup:ListRecoveryPointsByBackupVault"
],
"Resource": "${aws_backup_vault.test.arn}"
}
]
}
POLICY
}
`, rName)
}
Loading

0 comments on commit 280cad8

Please sign in to comment.