Skip to content
Open
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
19 changes: 19 additions & 0 deletions .changelog/44471.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```release-note:bug
resource/aws_s3_access_point: Fix support for S3 Express One Zone Directory Bucket Access Points by ensuring proper AWS SDK endpoint routing
```

```release-note:bug
resource/aws_s3control_access_point_policy: Fix support for S3 Express One Zone Directory Bucket Access Points by ensuring proper AWS SDK endpoint routing
```

```release-note:bug
resource/aws_s3control_bucket_policy: Fix support for S3 Express One Zone Directory Bucket resources by ensuring proper AWS SDK endpoint routing
```

```release-note:bug
resource/aws_s3control_bucket_lifecycle_configuration: Fix support for S3 Express One Zone Directory Bucket resources by ensuring proper AWS SDK endpoint routing
```

```release-note:bug
resource/aws_s3control_directory_bucket_access_point_scope: Fix operations by ensuring proper AWS SDK endpoint routing for Directory Buckets
```
11 changes: 10 additions & 1 deletion internal/conns/awsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/aws/aws-sdk-go-v2/aws/arn"
apigatewayv2_types "github.com/aws/aws-sdk-go-v2/service/apigatewayv2/types"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3control"
"github.com/hashicorp/aws-sdk-go-base/v2/endpoints"
baselogging "github.com/hashicorp/aws-sdk-go-base/v2/logging"
"github.com/hashicorp/terraform-plugin-log/tflog"
Expand Down Expand Up @@ -191,6 +192,14 @@ func (c *AWSClient) S3ExpressClient(ctx context.Context) *s3.Client {
return c.s3ExpressClient
}

// S3ExpressControlClient returns an AWS SDK for Go v2 S3 Control API client suitable for use with S3 Express (directory buckets).
// For Directory Buckets, control plane operations like ListTagsForResource must use the s3express-control.region.amazonaws.com endpoint.
func (c *AWSClient) S3ExpressControlClient(ctx context.Context) *s3control.Client {
return errs.Must(client[*s3control.Client](ctx, c, names.S3Control, map[string]any{
"endpoint": fmt.Sprintf("https://s3express-control.%s.%s", c.Region(ctx), c.DNSSuffix(ctx)),
}))
}

// S3UsePathStyle returns the s3_force_path_style provider configuration value.
func (c *AWSClient) S3UsePathStyle(context.Context) bool {
return c.s3UsePathStyle
Expand Down Expand Up @@ -258,7 +267,7 @@ func (c *AWSClient) DefaultKMSKeyPolicy(ctx context.Context) string {
"Resource": "*"
}
]
}
}
`, c.Partition(ctx), c.AccountID(ctx))
}

Expand Down
28 changes: 22 additions & 6 deletions internal/service/s3control/access_point.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/hashicorp/terraform-provider-aws/names"
)

// @SDKResource("aws_s3_access_point, name="Access Point")
// @SDKResource("aws_s3_access_point", name="Access Point")
// @Tags(identifierAttribute="arn")
func resourceAccessPoint() *schema.Resource {
return &schema.Resource{
Expand Down Expand Up @@ -155,16 +155,21 @@ func resourceAccessPoint() *schema.Resource {
func resourceAccessPointCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
c := meta.(*conns.AWSClient)
conn := c.S3ControlClient(ctx)

accountID := c.AccountID(ctx)
if v, ok := d.GetOk(names.AttrAccountID); ok {
accountID = v.(string)
}
name := d.Get(names.AttrName).(string)
bucketName := d.Get(names.AttrBucket).(string)

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

input := s3control.CreateAccessPointInput{
AccountId: aws.String(accountID),
Bucket: aws.String(d.Get(names.AttrBucket).(string)),
Bucket: aws.String(bucketName),
Name: aws.String(name),
Tags: getTagsIn(ctx),
}
Expand Down Expand Up @@ -224,13 +229,16 @@ func resourceAccessPointCreate(ctx context.Context, d *schema.ResourceData, meta
func resourceAccessPointRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
c := meta.(*conns.AWSClient)
conn := c.S3ControlClient(ctx)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

output, err := findAccessPointByTwoPartKey(ctx, conn, accountID, name)

if !d.IsNewResource() && tfresource.NotFound(err) {
Expand Down Expand Up @@ -335,13 +343,17 @@ func resourceAccessPointRead(ctx context.Context, d *schema.ResourceData, meta a

func resourceAccessPointUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

if d.HasChange(names.AttrPolicy) {
if v, ok := d.GetOk(names.AttrPolicy); ok && v.(string) != "" && v.(string) != "{}" {
policy, err := structure.NormalizeJsonString(v.(string))
Expand Down Expand Up @@ -379,13 +391,17 @@ func resourceAccessPointUpdate(ctx context.Context, d *schema.ResourceData, meta

func resourceAccessPointDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

log.Printf("[DEBUG] Deleting S3 Access Point: %s", d.Id())
input := s3control.DeleteAccessPointInput{
AccountId: aws.String(accountID),
Expand Down
27 changes: 22 additions & 5 deletions internal/service/s3control/access_point_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ func resourceAccessPointPolicy() *schema.Resource {

func resourceAccessPointPolicyCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

resourceID, err := accessPointCreateResourceID(d.Get("access_point_arn").(string))
accessPointARN := d.Get("access_point_arn").(string)
resourceID, err := accessPointCreateResourceID(accessPointARN)
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}
Expand All @@ -65,6 +66,10 @@ func resourceAccessPointPolicyCreate(ctx context.Context, d *schema.ResourceData
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

policy, err := structure.NormalizeJsonString(d.Get(names.AttrPolicy).(string))
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
Expand All @@ -89,13 +94,17 @@ func resourceAccessPointPolicyCreate(ctx context.Context, d *schema.ResourceData

func resourceAccessPointPolicyRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

policy, status, err := findAccessPointPolicyAndStatusByTwoPartKey(ctx, conn, accountID, name)

if !d.IsNewResource() && tfresource.NotFound(err) {
Expand Down Expand Up @@ -125,13 +134,17 @@ func resourceAccessPointPolicyRead(ctx context.Context, d *schema.ResourceData,

func resourceAccessPointPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

policy, err := structure.NormalizeJsonString(d.Get(names.AttrPolicy).(string))
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
Expand All @@ -154,13 +167,17 @@ func resourceAccessPointPolicyUpdate(ctx context.Context, d *schema.ResourceData

func resourceAccessPointPolicyDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

accountID, name, err := accessPointParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

log.Printf("[DEBUG] Deleting S3 Access Point Policy: %s", d.Id())
input := s3control.DeleteAccessPointPolicyInput{
AccountId: aws.String(accountID),
Expand Down
26 changes: 21 additions & 5 deletions internal/service/s3control/bucket_lifecycle_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func resourceBucketLifecycleConfiguration() *schema.Resource {

func resourceBucketLifecycleConfigurationCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

bucket := d.Get(names.AttrBucket).(string)
parsedArn, err := arn.Parse(bucket)
Expand All @@ -140,9 +140,13 @@ func resourceBucketLifecycleConfigurationCreate(ctx context.Context, d *schema.R
}

if parsedArn.AccountID == "" {
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", bucket)
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

input := &s3control.PutBucketLifecycleConfigurationInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(bucket),
Expand All @@ -164,7 +168,7 @@ func resourceBucketLifecycleConfigurationCreate(ctx context.Context, d *schema.R

func resourceBucketLifecycleConfigurationRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

parsedArn, err := arn.Parse(d.Id())

Expand All @@ -176,6 +180,10 @@ func resourceBucketLifecycleConfigurationRead(ctx context.Context, d *schema.Res
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

output, err := findBucketLifecycleConfigurationByTwoPartKey(ctx, conn, parsedArn.AccountID, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
Expand All @@ -199,7 +207,7 @@ func resourceBucketLifecycleConfigurationRead(ctx context.Context, d *schema.Res

func resourceBucketLifecycleConfigurationUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

parsedArn, err := arn.Parse(d.Id())

Expand All @@ -211,6 +219,10 @@ func resourceBucketLifecycleConfigurationUpdate(ctx context.Context, d *schema.R
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

input := &s3control.PutBucketLifecycleConfigurationInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(d.Id()),
Expand All @@ -230,7 +242,7 @@ func resourceBucketLifecycleConfigurationUpdate(ctx context.Context, d *schema.R

func resourceBucketLifecycleConfigurationDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

parsedArn, err := arn.Parse(d.Id())

Expand All @@ -242,6 +254,10 @@ func resourceBucketLifecycleConfigurationDelete(ctx context.Context, d *schema.R
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

log.Printf("[DEBUG] Deleting S3 Control Bucket Lifecycle Configuration: %s", d.Id())
_, err = conn.DeleteBucketLifecycleConfiguration(ctx, &s3control.DeleteBucketLifecycleConfigurationInput{
AccountId: aws.String(parsedArn.AccountID),
Expand Down
24 changes: 20 additions & 4 deletions internal/service/s3control/bucket_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ func resourceBucketPolicy() *schema.Resource {

func resourceBucketPolicyCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

bucket := d.Get(names.AttrBucket).(string)

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

policy, err := structure.NormalizeJsonString(d.Get(names.AttrPolicy).(string))
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
Expand All @@ -86,7 +90,7 @@ func resourceBucketPolicyCreate(ctx context.Context, d *schema.ResourceData, met

func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

parsedArn, err := arn.Parse(d.Id())
if err != nil {
Expand All @@ -97,6 +101,10 @@ func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta
return sdkdiag.AppendErrorf(diags, "parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

output, err := findBucketPolicyByTwoPartKey(ctx, conn, parsedArn.AccountID, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
Expand Down Expand Up @@ -127,7 +135,11 @@ func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta

func resourceBucketPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

policy, err := structure.NormalizeJsonString(d.Get(names.AttrPolicy).(string))
if err != nil {
Expand All @@ -150,7 +162,11 @@ func resourceBucketPolicyUpdate(ctx context.Context, d *schema.ResourceData, met

func resourceBucketPolicyDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).S3ControlClient(ctx)
c := meta.(*conns.AWSClient)

// Directory Buckets are supported by the standard S3 Control client
// The AWS SDK automatically routes to the correct endpoint based on the resource ARN
conn := c.S3ControlClient(ctx)

parsedArn, err := arn.Parse(d.Id())

Expand Down
Loading
Loading