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/backup_vault_policy - new resource #16112

Merged
merged 5 commits into from
Nov 13, 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
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