Skip to content

Commit

Permalink
Merge pull request #34534 from hashicorp/td-aws_s3_bucket_public_acce…
Browse files Browse the repository at this point in the history
…ss_block-aws-sdk-go-v2

r/aws_s3_bucket_public_access_block: Migrate to AWS SDK for Go v2
  • Loading branch information
ewbankkit authored Nov 22, 2023
2 parents 672d000 + c6a4aab commit 811cc85
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 233 deletions.
165 changes: 74 additions & 91 deletions internal/service/s3/bucket_public_access_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ package s3
import (
"context"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/hashicorp/aws-sdk-go-base/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -26,35 +26,32 @@ func ResourceBucketPublicAccessBlock() *schema.Resource {
ReadWithoutTimeout: resourceBucketPublicAccessBlockRead,
UpdateWithoutTimeout: resourceBucketPublicAccessBlockUpdate,
DeleteWithoutTimeout: resourceBucketPublicAccessBlockDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"block_public_acls": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"block_public_policy": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"bucket": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"ignore_public_acls": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"restrict_public_buckets": {
Type: schema.TypeBool,
Optional: true,
Expand All @@ -66,122 +63,81 @@ func ResourceBucketPublicAccessBlock() *schema.Resource {

func resourceBucketPublicAccessBlockCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3Conn(ctx)
bucket := d.Get("bucket").(string)
conn := meta.(*conns.AWSClient).S3Client(ctx)

bucket := d.Get("bucket").(string)
input := &s3.PutPublicAccessBlockInput{
Bucket: aws.String(bucket),
PublicAccessBlockConfiguration: &s3.PublicAccessBlockConfiguration{
PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{
BlockPublicAcls: aws.Bool(d.Get("block_public_acls").(bool)),
BlockPublicPolicy: aws.Bool(d.Get("block_public_policy").(bool)),
IgnorePublicAcls: aws.Bool(d.Get("ignore_public_acls").(bool)),
RestrictPublicBuckets: aws.Bool(d.Get("restrict_public_buckets").(bool)),
},
}

log.Printf("[DEBUG] S3 bucket: %s, public access block: %v", bucket, input.PublicAccessBlockConfiguration)
err := retry.RetryContext(ctx, 1*time.Minute, func() *retry.RetryError {
_, err := conn.PutPublicAccessBlockWithContext(ctx, input)
_, err := tfresource.RetryWhenAWSErrCodeEquals(ctx, s3BucketPropagationTimeout, func() (interface{}, error) {
return conn.PutPublicAccessBlock(ctx, input)
}, errCodeNoSuchBucket)

if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) {
return retry.RetryableError(err)
}
if err != nil {
return sdkdiag.AppendErrorf(diags, "creating S3 Bucket (%s) Public Access Block: %s", bucket, err)
}

if err != nil {
return retry.NonRetryableError(err)
}
d.SetId(bucket)

return nil
_, err = tfresource.RetryWhenNotFound(ctx, s3BucketPropagationTimeout, func() (interface{}, error) {
return findPublicAccessBlockConfiguration(ctx, conn, d.Id())
})
if tfresource.TimedOut(err) {
_, err = conn.PutPublicAccessBlockWithContext(ctx, input)
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "creating public access block policy for S3 bucket (%s): %s", bucket, err)
return sdkdiag.AppendErrorf(diags, "waiting for S3 Bucket Public Access Block (%s) create: %s", d.Id(), err)
}

d.SetId(bucket)
return append(diags, resourceBucketPublicAccessBlockRead(ctx, d, meta)...)
}

func resourceBucketPublicAccessBlockRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3Conn(ctx)

input := &s3.GetPublicAccessBlockInput{
Bucket: aws.String(d.Id()),
}

// Retry for eventual consistency on creation
var output *s3.GetPublicAccessBlockOutput
err := retry.RetryContext(ctx, s3BucketPropagationTimeout, func() *retry.RetryError {
var err error
output, err = conn.GetPublicAccessBlockWithContext(ctx, input)

if d.IsNewResource() && tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) {
return retry.RetryableError(err)
}

if d.IsNewResource() && tfawserr.ErrCodeEquals(err, ErrCodeNoSuchPublicAccessBlockConfiguration) {
return retry.RetryableError(err)
}

if err != nil {
return retry.NonRetryableError(err)
}
conn := meta.(*conns.AWSClient).S3Client(ctx)

return nil
})

if tfresource.TimedOut(err) {
output, err = conn.GetPublicAccessBlockWithContext(ctx, input)
}
pabc, err := findPublicAccessBlockConfiguration(ctx, conn, d.Id())

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, ErrCodeNoSuchPublicAccessBlockConfiguration) {
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] S3 Bucket Public Access Block (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
}

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) {
log.Printf("[WARN] S3 Bucket (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "reading S3 bucket Public Access Block (%s): %s", d.Id(), err)
}

if output == nil || output.PublicAccessBlockConfiguration == nil {
return sdkdiag.AppendErrorf(diags, "reading S3 Bucket Public Access Block (%s): empty response", d.Id())
return sdkdiag.AppendErrorf(diags, "reading S3 Bucket Public Access Block (%s): %s", d.Id(), err)
}

d.Set("bucket", d.Id())
d.Set("block_public_acls", output.PublicAccessBlockConfiguration.BlockPublicAcls)
d.Set("block_public_policy", output.PublicAccessBlockConfiguration.BlockPublicPolicy)
d.Set("ignore_public_acls", output.PublicAccessBlockConfiguration.IgnorePublicAcls)
d.Set("restrict_public_buckets", output.PublicAccessBlockConfiguration.RestrictPublicBuckets)
d.Set("block_public_acls", pabc.BlockPublicAcls)
d.Set("block_public_policy", pabc.BlockPublicPolicy)
d.Set("ignore_public_acls", pabc.IgnorePublicAcls)
d.Set("restrict_public_buckets", pabc.RestrictPublicBuckets)

return diags
}

func resourceBucketPublicAccessBlockUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3Conn(ctx)
conn := meta.(*conns.AWSClient).S3Client(ctx)

input := &s3.PutPublicAccessBlockInput{
Bucket: aws.String(d.Id()),
PublicAccessBlockConfiguration: &s3.PublicAccessBlockConfiguration{
PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{
BlockPublicAcls: aws.Bool(d.Get("block_public_acls").(bool)),
BlockPublicPolicy: aws.Bool(d.Get("block_public_policy").(bool)),
IgnorePublicAcls: aws.Bool(d.Get("ignore_public_acls").(bool)),
RestrictPublicBuckets: aws.Bool(d.Get("restrict_public_buckets").(bool)),
},
}

log.Printf("[DEBUG] Updating S3 bucket Public Access Block: %s", input)
_, err := conn.PutPublicAccessBlockWithContext(ctx, input)
_, err := conn.PutPublicAccessBlock(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating S3 Bucket Public Access Block (%s): %s", d.Id(), err)
}
Expand All @@ -195,32 +151,59 @@ func resourceBucketPublicAccessBlockUpdate(ctx context.Context, d *schema.Resour
d.Set("ignore_public_acls", input.PublicAccessBlockConfiguration.IgnorePublicAcls)
d.Set("restrict_public_buckets", input.PublicAccessBlockConfiguration.RestrictPublicBuckets)

// Skip normal Read after Update due to eventual consistency issues
// Skip normal Read after Update due to eventual consistency issues.
return diags
}

func resourceBucketPublicAccessBlockDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3Conn(ctx)
conn := meta.(*conns.AWSClient).S3Client(ctx)

input := &s3.DeletePublicAccessBlockInput{
log.Printf("[DEBUG] Deleting S3 Bucket Ownership Controls: %s", d.Id())
_, err := conn.DeletePublicAccessBlock(ctx, &s3.DeletePublicAccessBlockInput{
Bucket: aws.String(d.Id()),
}

log.Printf("[DEBUG] S3 bucket: %s, delete public access block", d.Id())
_, err := conn.DeletePublicAccessBlockWithContext(ctx, input)
})

if tfawserr.ErrCodeEquals(err, ErrCodeNoSuchPublicAccessBlockConfiguration) {
if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket, errCodeNoSuchPublicAccessBlockConfiguration) {
return diags
}

if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) {
return diags
if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting S3 Bucket Public Access Block (%s): %s", d.Id(), err)
}

_, err = tfresource.RetryUntilNotFound(ctx, s3BucketPropagationTimeout, func() (interface{}, error) {
return findPublicAccessBlockConfiguration(ctx, conn, d.Id())
})

if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting S3 Bucket Public Access Block (%s): %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for S3 Bucket Public Access Block (%s) delete: %s", d.Id(), err)
}

return diags
}

func findPublicAccessBlockConfiguration(ctx context.Context, conn *s3.Client, bucket string) (*types.PublicAccessBlockConfiguration, error) {
input := &s3.GetPublicAccessBlockInput{
Bucket: aws.String(bucket),
}

output, err := conn.GetPublicAccessBlock(ctx, input)

if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket, errCodeNoSuchPublicAccessBlockConfiguration) {
return nil, &retry.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil || output.PublicAccessBlockConfiguration == nil {
return nil, tfresource.NewEmptyResultError(input)
}

return output.PublicAccessBlockConfiguration, nil
}
Loading

0 comments on commit 811cc85

Please sign in to comment.