Skip to content

Commit

Permalink
feat: add aws_db_instance_automated_backups_replication
Browse files Browse the repository at this point in the history
Signed-off-by: marcin.janas <[email protected]>
  • Loading branch information
marcin-janas committed Aug 5, 2021
1 parent 407a85c commit 955b974
Show file tree
Hide file tree
Showing 7 changed files with 448 additions and 0 deletions.
28 changes: 28 additions & 0 deletions aws/internal/service/rds/finder/finder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package finder

import (
"context"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
Expand Down Expand Up @@ -120,3 +122,29 @@ func DBClusterByID(conn *rds.RDS, id string) (*rds.DBCluster, error) {

return dbCluster, nil
}

// DBInstanceAutomatedBackup returns matching DBInstanceAutomatedBackup
func DBInstanceAutomatedBackup(ctx context.Context, conn *rds.RDS, dbInstanceAutomatedBackupsArn string) (*rds.DBInstanceAutomatedBackup, error) {
input := &rds.DescribeDBInstanceAutomatedBackupsInput{
DBInstanceAutomatedBackupsArn: aws.String(dbInstanceAutomatedBackupsArn),
}

var dbInstanceAutomatedBackup *rds.DBInstanceAutomatedBackup

err := conn.DescribeDBInstanceAutomatedBackupsPagesWithContext(ctx, input, func(page *rds.DescribeDBInstanceAutomatedBackupsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, backup := range page.DBInstanceAutomatedBackups {
if aws.StringValue(backup.DBInstanceAutomatedBackupsArn) == dbInstanceAutomatedBackupsArn {
dbInstanceAutomatedBackup = backup
return false
}
}

return !lastPage
})

return dbInstanceAutomatedBackup, err
}
19 changes: 19 additions & 0 deletions aws/internal/service/rds/waiter/status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package waiter

import (
"context"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand Down Expand Up @@ -75,3 +77,20 @@ func DBClusterRoleStatus(conn *rds.RDS, dbClusterID, roleARN string) resource.St
return output, aws.StringValue(output.Status), nil
}
}

// DBInstanceAutomatedBackupsReplicationStatus fetches the DBInstanceAutomatedBackup and its Status
func DBInstanceAutomatedBackupsReplicationStatus(ctx context.Context, conn *rds.RDS, dbInstanceAutomatedBackupsArn string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := finder.DBInstanceAutomatedBackup(ctx, conn, dbInstanceAutomatedBackupsArn)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, aws.StringValue(output.Status), nil
}
}
46 changes: 46 additions & 0 deletions aws/internal/service/rds/waiter/waiter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package waiter

import (
"context"
"time"

"github.com/aws/aws-sdk-go/service/rds"
Expand All @@ -15,6 +16,15 @@ const (

DBClusterRoleAssociationCreatedTimeout = 5 * time.Minute
DBClusterRoleAssociationDeletedTimeout = 5 * time.Minute

// DB Instance Automated Backups Replication timeouts
DBInstanceAutomatedBackupsReplicationStartedTimeout = 30 * time.Minute
DBInstanceAutomatedBackupsReplicationDeletedTimeout = 5 * time.Minute

// DB Instance Automated Backups Replication states
DBInstanceAutomatedBackupsPending = "pending"
DBInstanceAutomatedBackupsReplicating = "replicating"
DBInstanceAutomatedBackupsDeleting = "deleting"
)

// EventSubscriptionDeleted waits for a EventSubscription to return Deleted
Expand Down Expand Up @@ -107,3 +117,39 @@ func DBClusterRoleAssociationDeleted(conn *rds.RDS, dbClusterID, roleARN string)

return nil, err
}

// DBInstanceAutomatedBackupsReplicationStarted waits for a DBInstanceAutomatedBackup to return replicating
func DBInstanceAutomatedBackupsReplicationStarted(ctx context.Context, conn *rds.RDS, dbInstanceAutomatedBackupsArn string) (*rds.DBInstanceAutomatedBackup, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{DBInstanceAutomatedBackupsPending},
Target: []string{DBInstanceAutomatedBackupsReplicating},
Refresh: DBInstanceAutomatedBackupsReplicationStatus(ctx, conn, dbInstanceAutomatedBackupsArn),
Timeout: DBInstanceAutomatedBackupsReplicationStartedTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*rds.DBInstanceAutomatedBackup); ok {
return output, err
}

return nil, err
}

// DBInstanceAutomatedBackupsReplicationDeleted waits for a DBInstanceAutomatedBackup to return deleting
func DBInstanceAutomatedBackupsReplicationDeleted(ctx context.Context, conn *rds.RDS, dbInstanceAutomatedBackupsArn string) (*rds.DBInstanceAutomatedBackup, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{DBInstanceAutomatedBackupsReplicating},
Target: []string{DBInstanceAutomatedBackupsDeleting},
Refresh: DBInstanceAutomatedBackupsReplicationStatus(ctx, conn, dbInstanceAutomatedBackupsArn),
Timeout: DBInstanceAutomatedBackupsReplicationDeletedTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*rds.DBInstanceAutomatedBackup); ok {
return output, err
}

return nil, err
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ func Provider() *schema.Provider {
"aws_db_cluster_snapshot": resourceAwsDbClusterSnapshot(),
"aws_db_event_subscription": resourceAwsDbEventSubscription(),
"aws_db_instance": resourceAwsDbInstance(),
"aws_db_instance_automated_backups_replication": resourceAwsDbInstanceAutomatedBackupsReplication(),
"aws_db_instance_role_association": resourceAwsDbInstanceRoleAssociation(),
"aws_db_option_group": resourceAwsDbOptionGroup(),
"aws_db_parameter_group": resourceAwsDbParameterGroup(),
Expand Down
150 changes: 150 additions & 0 deletions aws/resource_aws_db_instance_automated_backups_replication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package aws

import (
"context"
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/rds/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/rds/waiter"
)

func resourceAwsDbInstanceAutomatedBackupsReplication() *schema.Resource {
return &schema.Resource{
CreateContext: resourceAwsDbInstanceAutomatedBackupsReplicationCreate,
ReadContext: resourceAwsDbInstanceAutomatedBackupsReplicationRead,
DeleteContext: resourceAwsDbInstanceAutomatedBackupsReplicationDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"backup_retention_period": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 1,
},
"kms_key_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"pre_signed_url": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"source_db_instance_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateArn,
},
},
}
}

func resourceAwsDbInstanceAutomatedBackupsReplicationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).rdsconn

input := &rds.StartDBInstanceAutomatedBackupsReplicationInput{
SourceDBInstanceArn: aws.String(d.Get("source_db_instance_arn").(string)),
}

if attr, ok := d.GetOk("backup_retention_period"); ok {
input.BackupRetentionPeriod = aws.Int64(int64(attr.(int)))
}

if attr, ok := d.GetOk("kms_key_id"); ok {
input.KmsKeyId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("pre_signed_url"); ok {
input.PreSignedUrl = aws.String(attr.(string))
}

log.Printf("[DEBUG] RDS DB Instance Start Automated Backups Replication: (%s)", input)
output, err := conn.StartDBInstanceAutomatedBackupsReplicationWithContext(ctx, input)
if err != nil {
return diag.FromErr(fmt.Errorf("unable to Start Automated Backup Replication: %s", err))
}

if output == nil || output.DBInstanceAutomatedBackup == nil {
return diag.FromErr(fmt.Errorf("error starting RDS DB Instance Start Automated Backups Replication: empty output"))
}

dbInstanceAutomatedBackupsArn := aws.StringValue(output.DBInstanceAutomatedBackup.DBInstanceAutomatedBackupsArn)
d.SetId(dbInstanceAutomatedBackupsArn)

if _, err := waiter.DBInstanceAutomatedBackupsReplicationStarted(ctx, conn, dbInstanceAutomatedBackupsArn); err != nil {
return diag.FromErr(fmt.Errorf("error waiting to RDS DB Instance Start Automated Backups Replication: %s", err))
}

return resourceAwsDbInstanceAutomatedBackupsReplicationRead(ctx, d, meta)
}

func resourceAwsDbInstanceAutomatedBackupsReplicationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).rdsconn

dbInstanceAutomatedBackup, err := finder.DBInstanceAutomatedBackup(ctx, conn, d.Id())
if isAWSErr(err, rds.ErrCodeDBInstanceAutomatedBackupNotFoundFault, "") {
log.Printf("[WARN] RDS DB Instance Automated Backups Replication not found (%s), removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return diag.FromErr(fmt.Errorf("error describe RDS DB Instance Automated Backups Replication: %s", err))
}

if err := d.Set("backup_retention_period", dbInstanceAutomatedBackup.BackupRetentionPeriod); err != nil {
return diag.FromErr(fmt.Errorf("error setting backup retention period for RDS DB Instance: %s", err))
}
if err := d.Set("kms_key_id", dbInstanceAutomatedBackup.KmsKeyId); err != nil {
return diag.FromErr(fmt.Errorf("error setting kms key id for RDS DB Instance: %s", err))
}
if err := d.Set("source_db_instance_arn", dbInstanceAutomatedBackup.DBInstanceArn); err != nil {
return diag.FromErr(fmt.Errorf("error setting source db instance arn for RDS DB Instance: (%s)", err))
}

return nil
}

func resourceAwsDbInstanceAutomatedBackupsReplicationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).rdsconn

input := &rds.DeleteDBInstanceAutomatedBackupInput{
DBInstanceAutomatedBackupsArn: aws.String(d.Id()),
}

log.Printf("[DEBUG] Delete RDS DB Instance Automated Backups Replication: %s", d.Id())
_, err := conn.DeleteDBInstanceAutomatedBackupWithContext(ctx, input)

if isAWSErr(err, rds.ErrCodeDBInstanceAutomatedBackupNotFoundFault, "") {
return nil
}

if isAWSErr(err, rds.ErrCodeInvalidDBInstanceAutomatedBackupStateFault, "") {
return nil
}

if isAWSErr(err, rds.ErrCodeInvalidDBInstanceStateFault, "") {
return nil
}

if err != nil {
return diag.FromErr(fmt.Errorf("error delete RDS DB Instance Automated Backups Replication: %s", err))
}

if _, err = waiter.DBInstanceAutomatedBackupsReplicationDeleted(ctx, conn, d.Id()); err != nil {
return diag.FromErr(fmt.Errorf("error waiting to delete RDS DB Instance Automated Backups Replication: %s", err))
}

return nil
}
Loading

0 comments on commit 955b974

Please sign in to comment.