Skip to content

Commit

Permalink
Merge pull request #7207 from slapula/resource-aws-backup-vault
Browse files Browse the repository at this point in the history
r/aws_backup_vault: Adding resource to manage AWS Backup vaults
  • Loading branch information
bflad authored Feb 6, 2019
2 parents 24de47d + 91776ee commit 03dd9bf
Show file tree
Hide file tree
Showing 5 changed files with 320 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 @@ -337,6 +337,7 @@ func Provider() terraform.ResourceProvider {
"aws_autoscaling_notification": resourceAwsAutoscalingNotification(),
"aws_autoscaling_policy": resourceAwsAutoscalingPolicy(),
"aws_autoscaling_schedule": resourceAwsAutoscalingSchedule(),
"aws_backup_vault": resourceAwsBackupVault(),
"aws_budgets_budget": resourceAwsBudgetsBudget(),
"aws_cloud9_environment_ec2": resourceAwsCloud9EnvironmentEc2(),
"aws_cloudformation_stack": resourceAwsCloudFormationStack(),
Expand Down
121 changes: 121 additions & 0 deletions aws/resource_aws_backup_vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package aws

import (
"fmt"
"regexp"

"github.com/hashicorp/terraform/helper/validation"

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

func resourceAwsBackupVault() *schema.Resource {
return &schema.Resource{
Create: resourceAwsBackupVaultCreate,
Read: resourceAwsBackupVaultRead,
Delete: resourceAwsBackupVaultDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9\-\_\.]{1,50}$`), "must consist of lowercase letters, numbers, and hyphens."),
},
"tags": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"kms_key_arn": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validateArn,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"recovery_points": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}

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

input := &backup.CreateBackupVaultInput{
BackupVaultName: aws.String(d.Get("name").(string)),
}

if v, ok := d.GetOk("tags"); ok {
input.BackupVaultTags = tagsFromMapGeneric(v.(map[string]interface{}))
}

if v, ok := d.GetOk("kms_key_arn"); ok {
input.EncryptionKeyArn = aws.String(v.(string))
}

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

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

return resourceAwsBackupVaultRead(d, meta)
}

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

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

resp, err := conn.DescribeBackupVault(input)
if err != nil {
return fmt.Errorf("error reading Backup Vault (%s): %s", d.Id(), err)
}

d.Set("kms_key_arn", resp.EncryptionKeyArn)
d.Set("arn", resp.BackupVaultArn)
d.Set("recovery_points", resp.NumberOfRecoveryPoints)

tresp, err := conn.ListTags(&backup.ListTagsInput{
ResourceArn: aws.String(*resp.BackupVaultArn),
})

if err != nil {
return fmt.Errorf("error retrieving Backup Vault (%s) tags: %s", aws.StringValue(resp.BackupVaultArn), err)
}

if err := d.Set("tags", tagsToMapGeneric(tresp.Tags)); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

return nil
}

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

input := &backup.DeleteBackupVaultInput{
BackupVaultName: aws.String(d.Get("name").(string)),
}

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

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

import (
"fmt"
"testing"

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

func TestAccAwsBackupVault_basic(t *testing.T) {
var vault backup.DescribeBackupVaultOutput

rInt := acctest.RandInt()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupVaultDestroy,
Steps: []resource.TestStep{
{
Config: testAccBackupVaultConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
),
},
},
})
}

func TestAccAwsBackupVault_withKmsKey(t *testing.T) {
var vault backup.DescribeBackupVaultOutput

rInt := acctest.RandInt()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupVaultDestroy,
Steps: []resource.TestStep{
{
Config: testAccBackupVaultWithKmsKey(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
resource.TestCheckResourceAttrPair("aws_backup_vault.test", "kms_key_arn", "aws_kms_key.test", "arn"),
),
},
},
})
}

func TestAccAwsBackupVault_withTags(t *testing.T) {
var vault backup.DescribeBackupVaultOutput

rInt := acctest.RandInt()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsBackupVaultDestroy,
Steps: []resource.TestStep{
{
Config: testAccBackupVaultWithTags(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.%", "2"),
resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.up", "down"),
resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.left", "right"),
),
},
},
})
}

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

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

resp, err := conn.DescribeBackupVault(input)

if err == nil {
if *resp.BackupVaultName == rs.Primary.ID {
return fmt.Errorf("Vault '%s' was not deleted properly", rs.Primary.ID)
}
}
}

return nil
}

func testAccCheckAwsBackupVaultExists(name string, vault *backup.DescribeBackupVaultOutput) 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.DescribeBackupVaultInput{
BackupVaultName: aws.String(rs.Primary.ID),
}
resp, err := conn.DescribeBackupVault(params)
if err != nil {
return err
}

*vault = *resp

return nil
}
}

func testAccBackupVaultConfig(randInt int) string {
return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
name = "tf_acc_test_backup_vault_%d"
}
`, randInt)
}

func testAccBackupVaultWithKmsKey(randInt int) string {
return fmt.Sprintf(`
resource "aws_kms_key" "test" {
description = "Test KMS Key for AWS Backup Vault"
deletion_window_in_days = 10
}
resource "aws_backup_vault" "test" {
name = "tf_acc_test_backup_vault_%d"
kms_key_arn = "${aws_kms_key.test.arn}"
}
`, randInt)
}

func testAccBackupVaultWithTags(randInt int) string {
return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
name = "tf_acc_test_backup_vault_%d"
tags = {
up = "down"
left = "right"
}
}
`, randInt)
}
9 changes: 9 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,15 @@
</ul>
</li>

<li<%= sidebar_current("docs-aws-resource-backup") %>>
<a href="#">Backup Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-aws-resource-backup-vault") %>>
<a href="/docs/providers/aws/r/backup_vault.html">aws_backup_vault</a>
</li>
</ul>
</li>

<li<%= sidebar_current("docs-aws-resource-batch") %>>
<a href="#">Batch Resources</a>
<ul class="nav nav-visible">
Expand Down
36 changes: 36 additions & 0 deletions website/docs/r/backup_vault.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: "aws"
page_title: "AWS: aws_backup_vault"
sidebar_current: "docs-aws-resource-backup-vault"
description: |-
Provides an AWS Backup vault resource.
---

# aws_backup_vault

Provides an AWS Backup vault resource.

## Example Usage

```hcl
resource "aws_backup_vault" "example" {
name = "example_backup_vault"
kms_key_arn = "${aws_kms_key.example.arn}"
}
```

## Argument Reference

The following arguments are supported:

* `name` - (Required) Name of the backup vault to create.
* `tags` - (Optional) Metadata that you can assign to help organize the resources that you create.
* `kms_key_arn` - (Optional) The server-side encryption key that is used to protect your backups.

## Attributes Reference

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

* `id` - The name of the vault.
* `arn` - The ARN of the vault.
* `recovery_points` - The number of recovery points that are stored in a backup vault.

0 comments on commit 03dd9bf

Please sign in to comment.