diff --git a/.changelog/34893.txt b/.changelog/34893.txt new file mode 100644 index 00000000000..107a64230ea --- /dev/null +++ b/.changelog/34893.txt @@ -0,0 +1,3 @@ +```release-note:bug +provider: Always use the S3 regional endpoint in `us-east-1` for S3 directory bucket operations. This fixes `no such host` errors +``` diff --git a/.ci/semgrep/migrate/context.yml b/.ci/semgrep/migrate/context.yml index e8674d7eaa8..bb28f7e8213 100644 --- a/.ci/semgrep/migrate/context.yml +++ b/.ci/semgrep/migrate/context.yml @@ -27,6 +27,7 @@ rules: - pattern-not: tfkafkaconnect.$API() - pattern-not: conn.Handlers.$X(...) - pattern-not: conn.Handlers.$X.$Y(...) + - pattern-not: conn.Options() severity: ERROR - id: context-todo languages: [go] diff --git a/internal/conns/awsclient.go b/internal/conns/awsclient.go index 05e58080b59..aa9e51412cf 100644 --- a/internal/conns/awsclient.go +++ b/internal/conns/awsclient.go @@ -11,13 +11,16 @@ import ( "sync" aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" + s3_sdkv2 "github.com/aws/aws-sdk-go-v2/service/s3" endpoints_sdkv1 "github.com/aws/aws-sdk-go/aws/endpoints" session_sdkv1 "github.com/aws/aws-sdk-go/aws/session" apigatewayv2_sdkv1 "github.com/aws/aws-sdk-go/service/apigatewayv2" mediaconvert_sdkv1 "github.com/aws/aws-sdk-go/service/mediaconvert" baselogging "github.com/hashicorp/aws-sdk-go-base/v2/logging" + "github.com/hashicorp/terraform-provider-aws/internal/errs" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/names" + "golang.org/x/exp/maps" ) type AWSClient struct { @@ -40,92 +43,115 @@ type AWSClient struct { httpClient *http.Client lock sync.Mutex logger baselogging.Logger + s3ExpressClient *s3_sdkv2.Client s3UsePathStyle bool // From provider configuration. s3UsEast1RegionalEndpoint endpoints_sdkv1.S3UsEast1RegionalEndpoint // From provider configuration. stsRegion string // From provider configuration. } // CredentialsProvider returns the AWS SDK for Go v2 credentials provider. -func (client *AWSClient) CredentialsProvider() aws_sdkv2.CredentialsProvider { - if client.awsConfig == nil { +func (c *AWSClient) CredentialsProvider() aws_sdkv2.CredentialsProvider { + if c.awsConfig == nil { return nil } - return client.awsConfig.Credentials + return c.awsConfig.Credentials } -func (client *AWSClient) AwsConfig() aws_sdkv2.Config { // nosemgrep:ci.aws-in-func-name - return client.awsConfig.Copy() +func (c *AWSClient) AwsConfig() aws_sdkv2.Config { // nosemgrep:ci.aws-in-func-name + return c.awsConfig.Copy() } // PartitionHostname returns a hostname with the provider domain suffix for the partition // e.g. PREFIX.amazonaws.com // The prefix should not contain a trailing period. -func (client *AWSClient) PartitionHostname(prefix string) string { - return fmt.Sprintf("%s.%s", prefix, client.DNSSuffix) +func (c *AWSClient) PartitionHostname(prefix string) string { + return fmt.Sprintf("%s.%s", prefix, c.DNSSuffix) } // RegionalHostname returns a hostname with the provider domain suffix for the region and partition // e.g. PREFIX.us-west-2.amazonaws.com // The prefix should not contain a trailing period. -func (client *AWSClient) RegionalHostname(prefix string) string { - return fmt.Sprintf("%s.%s.%s", prefix, client.Region, client.DNSSuffix) +func (c *AWSClient) RegionalHostname(prefix string) string { + return fmt.Sprintf("%s.%s.%s", prefix, c.Region, c.DNSSuffix) +} + +// S3ExpressClient returns an S3 API client suitable for use with S3 Express (directory buckets). +// This client differs from the standard S3 API client only in us-east-1 if the global S3 endpoint is used. +// In that case the returned client uses the regional S3 endpoint. +func (c *AWSClient) S3ExpressClient(ctx context.Context) *s3_sdkv2.Client { + s3Client := c.S3Client(ctx) + + c.lock.Lock() // OK since a non-default client is created. + defer c.lock.Unlock() + + if c.s3ExpressClient == nil { + if s3Client.Options().Region == names.GlobalRegionID { + c.s3ExpressClient = errs.Must(client[*s3_sdkv2.Client](ctx, c, names.S3, map[string]any{ + "s3_us_east_1_regional_endpoint": endpoints_sdkv1.RegionalS3UsEast1Endpoint, + })) + } else { + c.s3ExpressClient = s3Client + } + } + + return c.s3ExpressClient } // S3UsePathStyle returns the s3_force_path_style provider configuration value. -func (client *AWSClient) S3UsePathStyle() bool { - return client.s3UsePathStyle +func (c *AWSClient) S3UsePathStyle() bool { + return c.s3UsePathStyle } // SetHTTPClient sets the http.Client used for AWS API calls. // To have effect it must be called before the AWS SDK v1 Session is created. -func (client *AWSClient) SetHTTPClient(httpClient *http.Client) { - if client.Session == nil { - client.httpClient = httpClient +func (c *AWSClient) SetHTTPClient(httpClient *http.Client) { + if c.Session == nil { + c.httpClient = httpClient } } // HTTPClient returns the http.Client used for AWS API calls. -func (client *AWSClient) HTTPClient() *http.Client { - return client.httpClient +func (c *AWSClient) HTTPClient() *http.Client { + return c.httpClient } // RegisterLogger places the configured logger into Context so it can be used via `tflog`. -func (client *AWSClient) RegisterLogger(ctx context.Context) context.Context { - return baselogging.RegisterLogger(ctx, client.logger) +func (c *AWSClient) RegisterLogger(ctx context.Context) context.Context { + return baselogging.RegisterLogger(ctx, c.logger) } // APIGatewayInvokeURL returns the Amazon API Gateway (REST APIs) invoke URL for the configured AWS Region. // See https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html. -func (client *AWSClient) APIGatewayInvokeURL(restAPIID, stageName string) string { - return fmt.Sprintf("https://%s/%s", client.RegionalHostname(fmt.Sprintf("%s.execute-api", restAPIID)), stageName) +func (c *AWSClient) APIGatewayInvokeURL(restAPIID, stageName string) string { + return fmt.Sprintf("https://%s/%s", c.RegionalHostname(fmt.Sprintf("%s.execute-api", restAPIID)), stageName) } // APIGatewayV2InvokeURL returns the Amazon API Gateway v2 (WebSocket & HTTP APIs) invoke URL for the configured AWS Region. // See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-publish.html and // https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-set-up-websocket-deployment.html. -func (client *AWSClient) APIGatewayV2InvokeURL(protocolType, apiID, stageName string) string { +func (c *AWSClient) APIGatewayV2InvokeURL(protocolType, apiID, stageName string) string { if protocolType == apigatewayv2_sdkv1.ProtocolTypeWebsocket { - return fmt.Sprintf("wss://%s/%s", client.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID)), stageName) + return fmt.Sprintf("wss://%s/%s", c.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID)), stageName) } if stageName == "$default" { - return fmt.Sprintf("https://%s/", client.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID))) + return fmt.Sprintf("https://%s/", c.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID))) } - return fmt.Sprintf("https://%s/%s", client.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID)), stageName) + return fmt.Sprintf("https://%s/%s", c.RegionalHostname(fmt.Sprintf("%s.execute-api", apiID)), stageName) } // CloudFrontDistributionHostedZoneID returns the Route 53 hosted zone ID // for Amazon CloudFront distributions in the configured AWS partition. -func (client *AWSClient) CloudFrontDistributionHostedZoneID() string { - if client.Partition == endpoints_sdkv1.AwsCnPartitionID { +func (c *AWSClient) CloudFrontDistributionHostedZoneID() string { + if c.Partition == endpoints_sdkv1.AwsCnPartitionID { return "Z3RFFRIM2A3IF5" // See https://docs.amazonaws.cn/en_us/aws/latest/userguide/route53.html } return "Z2FDTNDATAQYW2" // See https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html#Route53-Type-AliasTarget-HostedZoneId } // DefaultKMSKeyPolicy returns the default policy for KMS keys in the configured AWS partition. -func (client *AWSClient) DefaultKMSKeyPolicy() string { +func (c *AWSClient) DefaultKMSKeyPolicy() string { return fmt.Sprintf(` { "Id": "default", @@ -142,52 +168,57 @@ func (client *AWSClient) DefaultKMSKeyPolicy() string { } ] } -`, client.Partition, client.AccountID) +`, c.Partition, c.AccountID) } // GlobalAcceleratorHostedZoneID returns the Route 53 hosted zone ID // for AWS Global Accelerator accelerators in the configured AWS partition. -func (client *AWSClient) GlobalAcceleratorHostedZoneID() string { +func (c *AWSClient) GlobalAcceleratorHostedZoneID() string { return "Z2BJ6XQ5FK7U4H" // See https://docs.aws.amazon.com/general/latest/gr/global_accelerator.html#global_accelerator_region } // apiClientConfig returns the AWS API client configuration parameters for the specified service. -func (client *AWSClient) apiClientConfig(servicePackageName string) map[string]any { +func (c *AWSClient) apiClientConfig(servicePackageName string) map[string]any { m := map[string]any{ - "aws_sdkv2_config": client.awsConfig, - "endpoint": client.endpoints[servicePackageName], - "partition": client.Partition, - "session": client.Session, + "aws_sdkv2_config": c.awsConfig, + "endpoint": c.endpoints[servicePackageName], + "partition": c.Partition, + "session": c.Session, } switch servicePackageName { case names.S3: - m["s3_use_path_style"] = client.s3UsePathStyle + m["s3_use_path_style"] = c.s3UsePathStyle // AWS SDK for Go v2 does not use the AWS_S3_US_EAST_1_REGIONAL_ENDPOINT environment variable during configuration. // For compatibility, read it now. - if client.s3UsEast1RegionalEndpoint == endpoints_sdkv1.UnsetS3UsEast1Endpoint { + if c.s3UsEast1RegionalEndpoint == endpoints_sdkv1.UnsetS3UsEast1Endpoint { if v, err := endpoints_sdkv1.GetS3UsEast1RegionalEndpoint(os.Getenv("AWS_S3_US_EAST_1_REGIONAL_ENDPOINT")); err == nil { - client.s3UsEast1RegionalEndpoint = v + c.s3UsEast1RegionalEndpoint = v } } - m["s3_us_east_1_regional_endpoint"] = client.s3UsEast1RegionalEndpoint + m["s3_us_east_1_regional_endpoint"] = c.s3UsEast1RegionalEndpoint case names.STS: - m["sts_region"] = client.stsRegion + m["sts_region"] = c.stsRegion } return m } // conn returns the AWS SDK for Go v1 API client for the specified service. -func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string) (T, error) { - c.lock.Lock() - defer c.lock.Unlock() - - if raw, ok := c.conns[servicePackageName]; ok { - if conn, ok := raw.(T); ok { - return conn, nil - } else { - var zero T - return zero, fmt.Errorf("AWS SDK v1 API client (%s): %T, want %T", servicePackageName, raw, zero) +// The default service client (`extra` is empty) is cached. In this case the AWSClient lock is held. +func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string, extra map[string]any) (T, error) { + isDefault := len(extra) == 0 + // Default service client is cached. + if isDefault { + c.lock.Lock() + defer c.lock.Unlock() // Runs at function exit, NOT block. + + if raw, ok := c.conns[servicePackageName]; ok { + if conn, ok := raw.(T); ok { + return conn, nil + } else { + var zero T + return zero, fmt.Errorf("AWS SDK v1 API client (%s): %T, want %T", servicePackageName, raw, zero) + } } } @@ -205,7 +236,9 @@ func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string) ( return zero, fmt.Errorf("no AWS SDK v1 API client factory: %s", servicePackageName) } - conn, err := v.NewConn(ctx, c.apiClientConfig(servicePackageName)) + config := c.apiClientConfig(servicePackageName) + maps.Copy(config, extra) // Extras overwrite per-service defaults. + conn, err := v.NewConn(ctx, config) if err != nil { var zero T return zero, err @@ -221,22 +254,30 @@ func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string) ( } } - c.conns[servicePackageName] = conn + // Default service client is cached. + if isDefault { + c.conns[servicePackageName] = conn + } return conn, nil } // client returns the AWS SDK for Go v2 API client for the specified service. -func client[T any](ctx context.Context, c *AWSClient, servicePackageName string) (T, error) { - c.lock.Lock() - defer c.lock.Unlock() - - if raw, ok := c.clients[servicePackageName]; ok { - if client, ok := raw.(T); ok { - return client, nil - } else { - var zero T - return zero, fmt.Errorf("AWS SDK v2 API client (%s): %T, want %T", servicePackageName, raw, zero) +// The default service client (`extra` is empty) is cached. In this case the AWSClient lock is held. +func client[T any](ctx context.Context, c *AWSClient, servicePackageName string, extra map[string]any) (T, error) { + isDefault := len(extra) == 0 + // Default service client is cached. + if isDefault { + c.lock.Lock() + defer c.lock.Unlock() // Runs at function exit, NOT block. + + if raw, ok := c.clients[servicePackageName]; ok { + if client, ok := raw.(T); ok { + return client, nil + } else { + var zero T + return zero, fmt.Errorf("AWS SDK v2 API client (%s): %T, want %T", servicePackageName, raw, zero) + } } } @@ -254,7 +295,9 @@ func client[T any](ctx context.Context, c *AWSClient, servicePackageName string) return zero, fmt.Errorf("no AWS SDK v2 API client factory: %s", servicePackageName) } - client, err := v.NewClient(ctx, c.apiClientConfig(servicePackageName)) + config := c.apiClientConfig(servicePackageName) + maps.Copy(config, extra) // Extras overwrite per-service defaults. + client, err := v.NewClient(ctx, config) if err != nil { var zero T return zero, err @@ -262,7 +305,9 @@ func client[T any](ctx context.Context, c *AWSClient, servicePackageName string) // All customization for AWS SDK for Go v2 API clients must be done during construction. - c.clients[servicePackageName] = client + if isDefault { + c.clients[servicePackageName] = client + } return client, nil } diff --git a/internal/conns/awsclient_gen.go b/internal/conns/awsclient_gen.go index a4fdea6ff88..265415a822b 100644 --- a/internal/conns/awsclient_gen.go +++ b/internal/conns/awsclient_gen.go @@ -233,897 +233,897 @@ import ( ) func (c *AWSClient) ACMClient(ctx context.Context) *acm_sdkv2.Client { - return errs.Must(client[*acm_sdkv2.Client](ctx, c, names.ACM)) + return errs.Must(client[*acm_sdkv2.Client](ctx, c, names.ACM, make(map[string]any))) } func (c *AWSClient) ACMPCAConn(ctx context.Context) *acmpca_sdkv1.ACMPCA { - return errs.Must(conn[*acmpca_sdkv1.ACMPCA](ctx, c, names.ACMPCA)) + return errs.Must(conn[*acmpca_sdkv1.ACMPCA](ctx, c, names.ACMPCA, make(map[string]any))) } func (c *AWSClient) AMPConn(ctx context.Context) *prometheusservice_sdkv1.PrometheusService { - return errs.Must(conn[*prometheusservice_sdkv1.PrometheusService](ctx, c, names.AMP)) + return errs.Must(conn[*prometheusservice_sdkv1.PrometheusService](ctx, c, names.AMP, make(map[string]any))) } func (c *AWSClient) APIGatewayConn(ctx context.Context) *apigateway_sdkv1.APIGateway { - return errs.Must(conn[*apigateway_sdkv1.APIGateway](ctx, c, names.APIGateway)) + return errs.Must(conn[*apigateway_sdkv1.APIGateway](ctx, c, names.APIGateway, make(map[string]any))) } func (c *AWSClient) APIGatewayV2Conn(ctx context.Context) *apigatewayv2_sdkv1.ApiGatewayV2 { - return errs.Must(conn[*apigatewayv2_sdkv1.ApiGatewayV2](ctx, c, names.APIGatewayV2)) + return errs.Must(conn[*apigatewayv2_sdkv1.ApiGatewayV2](ctx, c, names.APIGatewayV2, make(map[string]any))) } func (c *AWSClient) AccessAnalyzerClient(ctx context.Context) *accessanalyzer_sdkv2.Client { - return errs.Must(client[*accessanalyzer_sdkv2.Client](ctx, c, names.AccessAnalyzer)) + return errs.Must(client[*accessanalyzer_sdkv2.Client](ctx, c, names.AccessAnalyzer, make(map[string]any))) } func (c *AWSClient) AccountClient(ctx context.Context) *account_sdkv2.Client { - return errs.Must(client[*account_sdkv2.Client](ctx, c, names.Account)) + return errs.Must(client[*account_sdkv2.Client](ctx, c, names.Account, make(map[string]any))) } func (c *AWSClient) AmplifyConn(ctx context.Context) *amplify_sdkv1.Amplify { - return errs.Must(conn[*amplify_sdkv1.Amplify](ctx, c, names.Amplify)) + return errs.Must(conn[*amplify_sdkv1.Amplify](ctx, c, names.Amplify, make(map[string]any))) } func (c *AWSClient) AppAutoScalingConn(ctx context.Context) *applicationautoscaling_sdkv1.ApplicationAutoScaling { - return errs.Must(conn[*applicationautoscaling_sdkv1.ApplicationAutoScaling](ctx, c, names.AppAutoScaling)) + return errs.Must(conn[*applicationautoscaling_sdkv1.ApplicationAutoScaling](ctx, c, names.AppAutoScaling, make(map[string]any))) } func (c *AWSClient) AppConfigConn(ctx context.Context) *appconfig_sdkv1.AppConfig { - return errs.Must(conn[*appconfig_sdkv1.AppConfig](ctx, c, names.AppConfig)) + return errs.Must(conn[*appconfig_sdkv1.AppConfig](ctx, c, names.AppConfig, make(map[string]any))) } func (c *AWSClient) AppConfigClient(ctx context.Context) *appconfig_sdkv2.Client { - return errs.Must(client[*appconfig_sdkv2.Client](ctx, c, names.AppConfig)) + return errs.Must(client[*appconfig_sdkv2.Client](ctx, c, names.AppConfig, make(map[string]any))) } func (c *AWSClient) AppFabricClient(ctx context.Context) *appfabric_sdkv2.Client { - return errs.Must(client[*appfabric_sdkv2.Client](ctx, c, names.AppFabric)) + return errs.Must(client[*appfabric_sdkv2.Client](ctx, c, names.AppFabric, make(map[string]any))) } func (c *AWSClient) AppFlowClient(ctx context.Context) *appflow_sdkv2.Client { - return errs.Must(client[*appflow_sdkv2.Client](ctx, c, names.AppFlow)) + return errs.Must(client[*appflow_sdkv2.Client](ctx, c, names.AppFlow, make(map[string]any))) } func (c *AWSClient) AppIntegrationsConn(ctx context.Context) *appintegrationsservice_sdkv1.AppIntegrationsService { - return errs.Must(conn[*appintegrationsservice_sdkv1.AppIntegrationsService](ctx, c, names.AppIntegrations)) + return errs.Must(conn[*appintegrationsservice_sdkv1.AppIntegrationsService](ctx, c, names.AppIntegrations, make(map[string]any))) } func (c *AWSClient) AppMeshConn(ctx context.Context) *appmesh_sdkv1.AppMesh { - return errs.Must(conn[*appmesh_sdkv1.AppMesh](ctx, c, names.AppMesh)) + return errs.Must(conn[*appmesh_sdkv1.AppMesh](ctx, c, names.AppMesh, make(map[string]any))) } func (c *AWSClient) AppRunnerClient(ctx context.Context) *apprunner_sdkv2.Client { - return errs.Must(client[*apprunner_sdkv2.Client](ctx, c, names.AppRunner)) + return errs.Must(client[*apprunner_sdkv2.Client](ctx, c, names.AppRunner, make(map[string]any))) } func (c *AWSClient) AppStreamConn(ctx context.Context) *appstream_sdkv1.AppStream { - return errs.Must(conn[*appstream_sdkv1.AppStream](ctx, c, names.AppStream)) + return errs.Must(conn[*appstream_sdkv1.AppStream](ctx, c, names.AppStream, make(map[string]any))) } func (c *AWSClient) AppSyncConn(ctx context.Context) *appsync_sdkv1.AppSync { - return errs.Must(conn[*appsync_sdkv1.AppSync](ctx, c, names.AppSync)) + return errs.Must(conn[*appsync_sdkv1.AppSync](ctx, c, names.AppSync, make(map[string]any))) } func (c *AWSClient) ApplicationInsightsConn(ctx context.Context) *applicationinsights_sdkv1.ApplicationInsights { - return errs.Must(conn[*applicationinsights_sdkv1.ApplicationInsights](ctx, c, names.ApplicationInsights)) + return errs.Must(conn[*applicationinsights_sdkv1.ApplicationInsights](ctx, c, names.ApplicationInsights, make(map[string]any))) } func (c *AWSClient) AthenaClient(ctx context.Context) *athena_sdkv2.Client { - return errs.Must(client[*athena_sdkv2.Client](ctx, c, names.Athena)) + return errs.Must(client[*athena_sdkv2.Client](ctx, c, names.Athena, make(map[string]any))) } func (c *AWSClient) AuditManagerClient(ctx context.Context) *auditmanager_sdkv2.Client { - return errs.Must(client[*auditmanager_sdkv2.Client](ctx, c, names.AuditManager)) + return errs.Must(client[*auditmanager_sdkv2.Client](ctx, c, names.AuditManager, make(map[string]any))) } func (c *AWSClient) AutoScalingConn(ctx context.Context) *autoscaling_sdkv1.AutoScaling { - return errs.Must(conn[*autoscaling_sdkv1.AutoScaling](ctx, c, names.AutoScaling)) + return errs.Must(conn[*autoscaling_sdkv1.AutoScaling](ctx, c, names.AutoScaling, make(map[string]any))) } func (c *AWSClient) AutoScalingPlansConn(ctx context.Context) *autoscalingplans_sdkv1.AutoScalingPlans { - return errs.Must(conn[*autoscalingplans_sdkv1.AutoScalingPlans](ctx, c, names.AutoScalingPlans)) + return errs.Must(conn[*autoscalingplans_sdkv1.AutoScalingPlans](ctx, c, names.AutoScalingPlans, make(map[string]any))) } func (c *AWSClient) BackupConn(ctx context.Context) *backup_sdkv1.Backup { - return errs.Must(conn[*backup_sdkv1.Backup](ctx, c, names.Backup)) + return errs.Must(conn[*backup_sdkv1.Backup](ctx, c, names.Backup, make(map[string]any))) } func (c *AWSClient) BatchConn(ctx context.Context) *batch_sdkv1.Batch { - return errs.Must(conn[*batch_sdkv1.Batch](ctx, c, names.Batch)) + return errs.Must(conn[*batch_sdkv1.Batch](ctx, c, names.Batch, make(map[string]any))) } func (c *AWSClient) BedrockClient(ctx context.Context) *bedrock_sdkv2.Client { - return errs.Must(client[*bedrock_sdkv2.Client](ctx, c, names.Bedrock)) + return errs.Must(client[*bedrock_sdkv2.Client](ctx, c, names.Bedrock, make(map[string]any))) } func (c *AWSClient) BudgetsConn(ctx context.Context) *budgets_sdkv1.Budgets { - return errs.Must(conn[*budgets_sdkv1.Budgets](ctx, c, names.Budgets)) + return errs.Must(conn[*budgets_sdkv1.Budgets](ctx, c, names.Budgets, make(map[string]any))) } func (c *AWSClient) CEConn(ctx context.Context) *costexplorer_sdkv1.CostExplorer { - return errs.Must(conn[*costexplorer_sdkv1.CostExplorer](ctx, c, names.CE)) + return errs.Must(conn[*costexplorer_sdkv1.CostExplorer](ctx, c, names.CE, make(map[string]any))) } func (c *AWSClient) CURConn(ctx context.Context) *costandusagereportservice_sdkv1.CostandUsageReportService { - return errs.Must(conn[*costandusagereportservice_sdkv1.CostandUsageReportService](ctx, c, names.CUR)) + return errs.Must(conn[*costandusagereportservice_sdkv1.CostandUsageReportService](ctx, c, names.CUR, make(map[string]any))) } func (c *AWSClient) ChimeConn(ctx context.Context) *chime_sdkv1.Chime { - return errs.Must(conn[*chime_sdkv1.Chime](ctx, c, names.Chime)) + return errs.Must(conn[*chime_sdkv1.Chime](ctx, c, names.Chime, make(map[string]any))) } func (c *AWSClient) ChimeSDKMediaPipelinesClient(ctx context.Context) *chimesdkmediapipelines_sdkv2.Client { - return errs.Must(client[*chimesdkmediapipelines_sdkv2.Client](ctx, c, names.ChimeSDKMediaPipelines)) + return errs.Must(client[*chimesdkmediapipelines_sdkv2.Client](ctx, c, names.ChimeSDKMediaPipelines, make(map[string]any))) } func (c *AWSClient) ChimeSDKVoiceClient(ctx context.Context) *chimesdkvoice_sdkv2.Client { - return errs.Must(client[*chimesdkvoice_sdkv2.Client](ctx, c, names.ChimeSDKVoice)) + return errs.Must(client[*chimesdkvoice_sdkv2.Client](ctx, c, names.ChimeSDKVoice, make(map[string]any))) } func (c *AWSClient) CleanRoomsClient(ctx context.Context) *cleanrooms_sdkv2.Client { - return errs.Must(client[*cleanrooms_sdkv2.Client](ctx, c, names.CleanRooms)) + return errs.Must(client[*cleanrooms_sdkv2.Client](ctx, c, names.CleanRooms, make(map[string]any))) } func (c *AWSClient) Cloud9Conn(ctx context.Context) *cloud9_sdkv1.Cloud9 { - return errs.Must(conn[*cloud9_sdkv1.Cloud9](ctx, c, names.Cloud9)) + return errs.Must(conn[*cloud9_sdkv1.Cloud9](ctx, c, names.Cloud9, make(map[string]any))) } func (c *AWSClient) CloudControlClient(ctx context.Context) *cloudcontrol_sdkv2.Client { - return errs.Must(client[*cloudcontrol_sdkv2.Client](ctx, c, names.CloudControl)) + return errs.Must(client[*cloudcontrol_sdkv2.Client](ctx, c, names.CloudControl, make(map[string]any))) } func (c *AWSClient) CloudFormationConn(ctx context.Context) *cloudformation_sdkv1.CloudFormation { - return errs.Must(conn[*cloudformation_sdkv1.CloudFormation](ctx, c, names.CloudFormation)) + return errs.Must(conn[*cloudformation_sdkv1.CloudFormation](ctx, c, names.CloudFormation, make(map[string]any))) } func (c *AWSClient) CloudFrontConn(ctx context.Context) *cloudfront_sdkv1.CloudFront { - return errs.Must(conn[*cloudfront_sdkv1.CloudFront](ctx, c, names.CloudFront)) + return errs.Must(conn[*cloudfront_sdkv1.CloudFront](ctx, c, names.CloudFront, make(map[string]any))) } func (c *AWSClient) CloudHSMV2Conn(ctx context.Context) *cloudhsmv2_sdkv1.CloudHSMV2 { - return errs.Must(conn[*cloudhsmv2_sdkv1.CloudHSMV2](ctx, c, names.CloudHSMV2)) + return errs.Must(conn[*cloudhsmv2_sdkv1.CloudHSMV2](ctx, c, names.CloudHSMV2, make(map[string]any))) } func (c *AWSClient) CloudSearchConn(ctx context.Context) *cloudsearch_sdkv1.CloudSearch { - return errs.Must(conn[*cloudsearch_sdkv1.CloudSearch](ctx, c, names.CloudSearch)) + return errs.Must(conn[*cloudsearch_sdkv1.CloudSearch](ctx, c, names.CloudSearch, make(map[string]any))) } func (c *AWSClient) CloudTrailConn(ctx context.Context) *cloudtrail_sdkv1.CloudTrail { - return errs.Must(conn[*cloudtrail_sdkv1.CloudTrail](ctx, c, names.CloudTrail)) + return errs.Must(conn[*cloudtrail_sdkv1.CloudTrail](ctx, c, names.CloudTrail, make(map[string]any))) } func (c *AWSClient) CloudWatchConn(ctx context.Context) *cloudwatch_sdkv1.CloudWatch { - return errs.Must(conn[*cloudwatch_sdkv1.CloudWatch](ctx, c, names.CloudWatch)) + return errs.Must(conn[*cloudwatch_sdkv1.CloudWatch](ctx, c, names.CloudWatch, make(map[string]any))) } func (c *AWSClient) CodeArtifactConn(ctx context.Context) *codeartifact_sdkv1.CodeArtifact { - return errs.Must(conn[*codeartifact_sdkv1.CodeArtifact](ctx, c, names.CodeArtifact)) + return errs.Must(conn[*codeartifact_sdkv1.CodeArtifact](ctx, c, names.CodeArtifact, make(map[string]any))) } func (c *AWSClient) CodeBuildConn(ctx context.Context) *codebuild_sdkv1.CodeBuild { - return errs.Must(conn[*codebuild_sdkv1.CodeBuild](ctx, c, names.CodeBuild)) + return errs.Must(conn[*codebuild_sdkv1.CodeBuild](ctx, c, names.CodeBuild, make(map[string]any))) } func (c *AWSClient) CodeCatalystClient(ctx context.Context) *codecatalyst_sdkv2.Client { - return errs.Must(client[*codecatalyst_sdkv2.Client](ctx, c, names.CodeCatalyst)) + return errs.Must(client[*codecatalyst_sdkv2.Client](ctx, c, names.CodeCatalyst, make(map[string]any))) } func (c *AWSClient) CodeCommitConn(ctx context.Context) *codecommit_sdkv1.CodeCommit { - return errs.Must(conn[*codecommit_sdkv1.CodeCommit](ctx, c, names.CodeCommit)) + return errs.Must(conn[*codecommit_sdkv1.CodeCommit](ctx, c, names.CodeCommit, make(map[string]any))) } func (c *AWSClient) CodeGuruProfilerClient(ctx context.Context) *codeguruprofiler_sdkv2.Client { - return errs.Must(client[*codeguruprofiler_sdkv2.Client](ctx, c, names.CodeGuruProfiler)) + return errs.Must(client[*codeguruprofiler_sdkv2.Client](ctx, c, names.CodeGuruProfiler, make(map[string]any))) } func (c *AWSClient) CodeGuruReviewerConn(ctx context.Context) *codegurureviewer_sdkv1.CodeGuruReviewer { - return errs.Must(conn[*codegurureviewer_sdkv1.CodeGuruReviewer](ctx, c, names.CodeGuruReviewer)) + return errs.Must(conn[*codegurureviewer_sdkv1.CodeGuruReviewer](ctx, c, names.CodeGuruReviewer, make(map[string]any))) } func (c *AWSClient) CodePipelineConn(ctx context.Context) *codepipeline_sdkv1.CodePipeline { - return errs.Must(conn[*codepipeline_sdkv1.CodePipeline](ctx, c, names.CodePipeline)) + return errs.Must(conn[*codepipeline_sdkv1.CodePipeline](ctx, c, names.CodePipeline, make(map[string]any))) } func (c *AWSClient) CodeStarConnectionsClient(ctx context.Context) *codestarconnections_sdkv2.Client { - return errs.Must(client[*codestarconnections_sdkv2.Client](ctx, c, names.CodeStarConnections)) + return errs.Must(client[*codestarconnections_sdkv2.Client](ctx, c, names.CodeStarConnections, make(map[string]any))) } func (c *AWSClient) CodeStarNotificationsClient(ctx context.Context) *codestarnotifications_sdkv2.Client { - return errs.Must(client[*codestarnotifications_sdkv2.Client](ctx, c, names.CodeStarNotifications)) + return errs.Must(client[*codestarnotifications_sdkv2.Client](ctx, c, names.CodeStarNotifications, make(map[string]any))) } func (c *AWSClient) CognitoIDPConn(ctx context.Context) *cognitoidentityprovider_sdkv1.CognitoIdentityProvider { - return errs.Must(conn[*cognitoidentityprovider_sdkv1.CognitoIdentityProvider](ctx, c, names.CognitoIDP)) + return errs.Must(conn[*cognitoidentityprovider_sdkv1.CognitoIdentityProvider](ctx, c, names.CognitoIDP, make(map[string]any))) } func (c *AWSClient) CognitoIdentityConn(ctx context.Context) *cognitoidentity_sdkv1.CognitoIdentity { - return errs.Must(conn[*cognitoidentity_sdkv1.CognitoIdentity](ctx, c, names.CognitoIdentity)) + return errs.Must(conn[*cognitoidentity_sdkv1.CognitoIdentity](ctx, c, names.CognitoIdentity, make(map[string]any))) } func (c *AWSClient) ComprehendClient(ctx context.Context) *comprehend_sdkv2.Client { - return errs.Must(client[*comprehend_sdkv2.Client](ctx, c, names.Comprehend)) + return errs.Must(client[*comprehend_sdkv2.Client](ctx, c, names.Comprehend, make(map[string]any))) } func (c *AWSClient) ComputeOptimizerClient(ctx context.Context) *computeoptimizer_sdkv2.Client { - return errs.Must(client[*computeoptimizer_sdkv2.Client](ctx, c, names.ComputeOptimizer)) + return errs.Must(client[*computeoptimizer_sdkv2.Client](ctx, c, names.ComputeOptimizer, make(map[string]any))) } func (c *AWSClient) ConfigServiceConn(ctx context.Context) *configservice_sdkv1.ConfigService { - return errs.Must(conn[*configservice_sdkv1.ConfigService](ctx, c, names.ConfigService)) + return errs.Must(conn[*configservice_sdkv1.ConfigService](ctx, c, names.ConfigService, make(map[string]any))) } func (c *AWSClient) ConnectConn(ctx context.Context) *connect_sdkv1.Connect { - return errs.Must(conn[*connect_sdkv1.Connect](ctx, c, names.Connect)) + return errs.Must(conn[*connect_sdkv1.Connect](ctx, c, names.Connect, make(map[string]any))) } func (c *AWSClient) ConnectCasesClient(ctx context.Context) *connectcases_sdkv2.Client { - return errs.Must(client[*connectcases_sdkv2.Client](ctx, c, names.ConnectCases)) + return errs.Must(client[*connectcases_sdkv2.Client](ctx, c, names.ConnectCases, make(map[string]any))) } func (c *AWSClient) ControlTowerClient(ctx context.Context) *controltower_sdkv2.Client { - return errs.Must(client[*controltower_sdkv2.Client](ctx, c, names.ControlTower)) + return errs.Must(client[*controltower_sdkv2.Client](ctx, c, names.ControlTower, make(map[string]any))) } func (c *AWSClient) CustomerProfilesClient(ctx context.Context) *customerprofiles_sdkv2.Client { - return errs.Must(client[*customerprofiles_sdkv2.Client](ctx, c, names.CustomerProfiles)) + return errs.Must(client[*customerprofiles_sdkv2.Client](ctx, c, names.CustomerProfiles, make(map[string]any))) } func (c *AWSClient) DAXConn(ctx context.Context) *dax_sdkv1.DAX { - return errs.Must(conn[*dax_sdkv1.DAX](ctx, c, names.DAX)) + return errs.Must(conn[*dax_sdkv1.DAX](ctx, c, names.DAX, make(map[string]any))) } func (c *AWSClient) DLMConn(ctx context.Context) *dlm_sdkv1.DLM { - return errs.Must(conn[*dlm_sdkv1.DLM](ctx, c, names.DLM)) + return errs.Must(conn[*dlm_sdkv1.DLM](ctx, c, names.DLM, make(map[string]any))) } func (c *AWSClient) DMSConn(ctx context.Context) *databasemigrationservice_sdkv1.DatabaseMigrationService { - return errs.Must(conn[*databasemigrationservice_sdkv1.DatabaseMigrationService](ctx, c, names.DMS)) + return errs.Must(conn[*databasemigrationservice_sdkv1.DatabaseMigrationService](ctx, c, names.DMS, make(map[string]any))) } func (c *AWSClient) DSConn(ctx context.Context) *directoryservice_sdkv1.DirectoryService { - return errs.Must(conn[*directoryservice_sdkv1.DirectoryService](ctx, c, names.DS)) + return errs.Must(conn[*directoryservice_sdkv1.DirectoryService](ctx, c, names.DS, make(map[string]any))) } func (c *AWSClient) DSClient(ctx context.Context) *directoryservice_sdkv2.Client { - return errs.Must(client[*directoryservice_sdkv2.Client](ctx, c, names.DS)) + return errs.Must(client[*directoryservice_sdkv2.Client](ctx, c, names.DS, make(map[string]any))) } func (c *AWSClient) DataExchangeConn(ctx context.Context) *dataexchange_sdkv1.DataExchange { - return errs.Must(conn[*dataexchange_sdkv1.DataExchange](ctx, c, names.DataExchange)) + return errs.Must(conn[*dataexchange_sdkv1.DataExchange](ctx, c, names.DataExchange, make(map[string]any))) } func (c *AWSClient) DataPipelineConn(ctx context.Context) *datapipeline_sdkv1.DataPipeline { - return errs.Must(conn[*datapipeline_sdkv1.DataPipeline](ctx, c, names.DataPipeline)) + return errs.Must(conn[*datapipeline_sdkv1.DataPipeline](ctx, c, names.DataPipeline, make(map[string]any))) } func (c *AWSClient) DataSyncConn(ctx context.Context) *datasync_sdkv1.DataSync { - return errs.Must(conn[*datasync_sdkv1.DataSync](ctx, c, names.DataSync)) + return errs.Must(conn[*datasync_sdkv1.DataSync](ctx, c, names.DataSync, make(map[string]any))) } func (c *AWSClient) DeployClient(ctx context.Context) *codedeploy_sdkv2.Client { - return errs.Must(client[*codedeploy_sdkv2.Client](ctx, c, names.Deploy)) + return errs.Must(client[*codedeploy_sdkv2.Client](ctx, c, names.Deploy, make(map[string]any))) } func (c *AWSClient) DetectiveConn(ctx context.Context) *detective_sdkv1.Detective { - return errs.Must(conn[*detective_sdkv1.Detective](ctx, c, names.Detective)) + return errs.Must(conn[*detective_sdkv1.Detective](ctx, c, names.Detective, make(map[string]any))) } func (c *AWSClient) DeviceFarmConn(ctx context.Context) *devicefarm_sdkv1.DeviceFarm { - return errs.Must(conn[*devicefarm_sdkv1.DeviceFarm](ctx, c, names.DeviceFarm)) + return errs.Must(conn[*devicefarm_sdkv1.DeviceFarm](ctx, c, names.DeviceFarm, make(map[string]any))) } func (c *AWSClient) DirectConnectConn(ctx context.Context) *directconnect_sdkv1.DirectConnect { - return errs.Must(conn[*directconnect_sdkv1.DirectConnect](ctx, c, names.DirectConnect)) + return errs.Must(conn[*directconnect_sdkv1.DirectConnect](ctx, c, names.DirectConnect, make(map[string]any))) } func (c *AWSClient) DocDBConn(ctx context.Context) *docdb_sdkv1.DocDB { - return errs.Must(conn[*docdb_sdkv1.DocDB](ctx, c, names.DocDB)) + return errs.Must(conn[*docdb_sdkv1.DocDB](ctx, c, names.DocDB, make(map[string]any))) } func (c *AWSClient) DocDBElasticClient(ctx context.Context) *docdbelastic_sdkv2.Client { - return errs.Must(client[*docdbelastic_sdkv2.Client](ctx, c, names.DocDBElastic)) + return errs.Must(client[*docdbelastic_sdkv2.Client](ctx, c, names.DocDBElastic, make(map[string]any))) } func (c *AWSClient) DynamoDBConn(ctx context.Context) *dynamodb_sdkv1.DynamoDB { - return errs.Must(conn[*dynamodb_sdkv1.DynamoDB](ctx, c, names.DynamoDB)) + return errs.Must(conn[*dynamodb_sdkv1.DynamoDB](ctx, c, names.DynamoDB, make(map[string]any))) } func (c *AWSClient) EC2Conn(ctx context.Context) *ec2_sdkv1.EC2 { - return errs.Must(conn[*ec2_sdkv1.EC2](ctx, c, names.EC2)) + return errs.Must(conn[*ec2_sdkv1.EC2](ctx, c, names.EC2, make(map[string]any))) } func (c *AWSClient) EC2Client(ctx context.Context) *ec2_sdkv2.Client { - return errs.Must(client[*ec2_sdkv2.Client](ctx, c, names.EC2)) + return errs.Must(client[*ec2_sdkv2.Client](ctx, c, names.EC2, make(map[string]any))) } func (c *AWSClient) ECRConn(ctx context.Context) *ecr_sdkv1.ECR { - return errs.Must(conn[*ecr_sdkv1.ECR](ctx, c, names.ECR)) + return errs.Must(conn[*ecr_sdkv1.ECR](ctx, c, names.ECR, make(map[string]any))) } func (c *AWSClient) ECRClient(ctx context.Context) *ecr_sdkv2.Client { - return errs.Must(client[*ecr_sdkv2.Client](ctx, c, names.ECR)) + return errs.Must(client[*ecr_sdkv2.Client](ctx, c, names.ECR, make(map[string]any))) } func (c *AWSClient) ECRPublicConn(ctx context.Context) *ecrpublic_sdkv1.ECRPublic { - return errs.Must(conn[*ecrpublic_sdkv1.ECRPublic](ctx, c, names.ECRPublic)) + return errs.Must(conn[*ecrpublic_sdkv1.ECRPublic](ctx, c, names.ECRPublic, make(map[string]any))) } func (c *AWSClient) ECSConn(ctx context.Context) *ecs_sdkv1.ECS { - return errs.Must(conn[*ecs_sdkv1.ECS](ctx, c, names.ECS)) + return errs.Must(conn[*ecs_sdkv1.ECS](ctx, c, names.ECS, make(map[string]any))) } func (c *AWSClient) EFSConn(ctx context.Context) *efs_sdkv1.EFS { - return errs.Must(conn[*efs_sdkv1.EFS](ctx, c, names.EFS)) + return errs.Must(conn[*efs_sdkv1.EFS](ctx, c, names.EFS, make(map[string]any))) } func (c *AWSClient) EKSClient(ctx context.Context) *eks_sdkv2.Client { - return errs.Must(client[*eks_sdkv2.Client](ctx, c, names.EKS)) + return errs.Must(client[*eks_sdkv2.Client](ctx, c, names.EKS, make(map[string]any))) } func (c *AWSClient) ELBConn(ctx context.Context) *elb_sdkv1.ELB { - return errs.Must(conn[*elb_sdkv1.ELB](ctx, c, names.ELB)) + return errs.Must(conn[*elb_sdkv1.ELB](ctx, c, names.ELB, make(map[string]any))) } func (c *AWSClient) ELBV2Conn(ctx context.Context) *elbv2_sdkv1.ELBV2 { - return errs.Must(conn[*elbv2_sdkv1.ELBV2](ctx, c, names.ELBV2)) + return errs.Must(conn[*elbv2_sdkv1.ELBV2](ctx, c, names.ELBV2, make(map[string]any))) } func (c *AWSClient) EMRConn(ctx context.Context) *emr_sdkv1.EMR { - return errs.Must(conn[*emr_sdkv1.EMR](ctx, c, names.EMR)) + return errs.Must(conn[*emr_sdkv1.EMR](ctx, c, names.EMR, make(map[string]any))) } func (c *AWSClient) EMRClient(ctx context.Context) *emr_sdkv2.Client { - return errs.Must(client[*emr_sdkv2.Client](ctx, c, names.EMR)) + return errs.Must(client[*emr_sdkv2.Client](ctx, c, names.EMR, make(map[string]any))) } func (c *AWSClient) EMRContainersConn(ctx context.Context) *emrcontainers_sdkv1.EMRContainers { - return errs.Must(conn[*emrcontainers_sdkv1.EMRContainers](ctx, c, names.EMRContainers)) + return errs.Must(conn[*emrcontainers_sdkv1.EMRContainers](ctx, c, names.EMRContainers, make(map[string]any))) } func (c *AWSClient) EMRServerlessClient(ctx context.Context) *emrserverless_sdkv2.Client { - return errs.Must(client[*emrserverless_sdkv2.Client](ctx, c, names.EMRServerless)) + return errs.Must(client[*emrserverless_sdkv2.Client](ctx, c, names.EMRServerless, make(map[string]any))) } func (c *AWSClient) ElastiCacheConn(ctx context.Context) *elasticache_sdkv1.ElastiCache { - return errs.Must(conn[*elasticache_sdkv1.ElastiCache](ctx, c, names.ElastiCache)) + return errs.Must(conn[*elasticache_sdkv1.ElastiCache](ctx, c, names.ElastiCache, make(map[string]any))) } func (c *AWSClient) ElasticBeanstalkConn(ctx context.Context) *elasticbeanstalk_sdkv1.ElasticBeanstalk { - return errs.Must(conn[*elasticbeanstalk_sdkv1.ElasticBeanstalk](ctx, c, names.ElasticBeanstalk)) + return errs.Must(conn[*elasticbeanstalk_sdkv1.ElasticBeanstalk](ctx, c, names.ElasticBeanstalk, make(map[string]any))) } func (c *AWSClient) ElasticTranscoderConn(ctx context.Context) *elastictranscoder_sdkv1.ElasticTranscoder { - return errs.Must(conn[*elastictranscoder_sdkv1.ElasticTranscoder](ctx, c, names.ElasticTranscoder)) + return errs.Must(conn[*elastictranscoder_sdkv1.ElasticTranscoder](ctx, c, names.ElasticTranscoder, make(map[string]any))) } func (c *AWSClient) ElasticsearchConn(ctx context.Context) *elasticsearchservice_sdkv1.ElasticsearchService { - return errs.Must(conn[*elasticsearchservice_sdkv1.ElasticsearchService](ctx, c, names.Elasticsearch)) + return errs.Must(conn[*elasticsearchservice_sdkv1.ElasticsearchService](ctx, c, names.Elasticsearch, make(map[string]any))) } func (c *AWSClient) EventsConn(ctx context.Context) *eventbridge_sdkv1.EventBridge { - return errs.Must(conn[*eventbridge_sdkv1.EventBridge](ctx, c, names.Events)) + return errs.Must(conn[*eventbridge_sdkv1.EventBridge](ctx, c, names.Events, make(map[string]any))) } func (c *AWSClient) EvidentlyClient(ctx context.Context) *evidently_sdkv2.Client { - return errs.Must(client[*evidently_sdkv2.Client](ctx, c, names.Evidently)) + return errs.Must(client[*evidently_sdkv2.Client](ctx, c, names.Evidently, make(map[string]any))) } func (c *AWSClient) FISClient(ctx context.Context) *fis_sdkv2.Client { - return errs.Must(client[*fis_sdkv2.Client](ctx, c, names.FIS)) + return errs.Must(client[*fis_sdkv2.Client](ctx, c, names.FIS, make(map[string]any))) } func (c *AWSClient) FMSConn(ctx context.Context) *fms_sdkv1.FMS { - return errs.Must(conn[*fms_sdkv1.FMS](ctx, c, names.FMS)) + return errs.Must(conn[*fms_sdkv1.FMS](ctx, c, names.FMS, make(map[string]any))) } func (c *AWSClient) FSxConn(ctx context.Context) *fsx_sdkv1.FSx { - return errs.Must(conn[*fsx_sdkv1.FSx](ctx, c, names.FSx)) + return errs.Must(conn[*fsx_sdkv1.FSx](ctx, c, names.FSx, make(map[string]any))) } func (c *AWSClient) FinSpaceClient(ctx context.Context) *finspace_sdkv2.Client { - return errs.Must(client[*finspace_sdkv2.Client](ctx, c, names.FinSpace)) + return errs.Must(client[*finspace_sdkv2.Client](ctx, c, names.FinSpace, make(map[string]any))) } func (c *AWSClient) FirehoseConn(ctx context.Context) *firehose_sdkv1.Firehose { - return errs.Must(conn[*firehose_sdkv1.Firehose](ctx, c, names.Firehose)) + return errs.Must(conn[*firehose_sdkv1.Firehose](ctx, c, names.Firehose, make(map[string]any))) } func (c *AWSClient) GameLiftConn(ctx context.Context) *gamelift_sdkv1.GameLift { - return errs.Must(conn[*gamelift_sdkv1.GameLift](ctx, c, names.GameLift)) + return errs.Must(conn[*gamelift_sdkv1.GameLift](ctx, c, names.GameLift, make(map[string]any))) } func (c *AWSClient) GlacierClient(ctx context.Context) *glacier_sdkv2.Client { - return errs.Must(client[*glacier_sdkv2.Client](ctx, c, names.Glacier)) + return errs.Must(client[*glacier_sdkv2.Client](ctx, c, names.Glacier, make(map[string]any))) } func (c *AWSClient) GlobalAcceleratorConn(ctx context.Context) *globalaccelerator_sdkv1.GlobalAccelerator { - return errs.Must(conn[*globalaccelerator_sdkv1.GlobalAccelerator](ctx, c, names.GlobalAccelerator)) + return errs.Must(conn[*globalaccelerator_sdkv1.GlobalAccelerator](ctx, c, names.GlobalAccelerator, make(map[string]any))) } func (c *AWSClient) GlueConn(ctx context.Context) *glue_sdkv1.Glue { - return errs.Must(conn[*glue_sdkv1.Glue](ctx, c, names.Glue)) + return errs.Must(conn[*glue_sdkv1.Glue](ctx, c, names.Glue, make(map[string]any))) } func (c *AWSClient) GrafanaConn(ctx context.Context) *managedgrafana_sdkv1.ManagedGrafana { - return errs.Must(conn[*managedgrafana_sdkv1.ManagedGrafana](ctx, c, names.Grafana)) + return errs.Must(conn[*managedgrafana_sdkv1.ManagedGrafana](ctx, c, names.Grafana, make(map[string]any))) } func (c *AWSClient) GreengrassConn(ctx context.Context) *greengrass_sdkv1.Greengrass { - return errs.Must(conn[*greengrass_sdkv1.Greengrass](ctx, c, names.Greengrass)) + return errs.Must(conn[*greengrass_sdkv1.Greengrass](ctx, c, names.Greengrass, make(map[string]any))) } func (c *AWSClient) GuardDutyConn(ctx context.Context) *guardduty_sdkv1.GuardDuty { - return errs.Must(conn[*guardduty_sdkv1.GuardDuty](ctx, c, names.GuardDuty)) + return errs.Must(conn[*guardduty_sdkv1.GuardDuty](ctx, c, names.GuardDuty, make(map[string]any))) } func (c *AWSClient) HealthLakeClient(ctx context.Context) *healthlake_sdkv2.Client { - return errs.Must(client[*healthlake_sdkv2.Client](ctx, c, names.HealthLake)) + return errs.Must(client[*healthlake_sdkv2.Client](ctx, c, names.HealthLake, make(map[string]any))) } func (c *AWSClient) IAMConn(ctx context.Context) *iam_sdkv1.IAM { - return errs.Must(conn[*iam_sdkv1.IAM](ctx, c, names.IAM)) + return errs.Must(conn[*iam_sdkv1.IAM](ctx, c, names.IAM, make(map[string]any))) } func (c *AWSClient) IVSConn(ctx context.Context) *ivs_sdkv1.IVS { - return errs.Must(conn[*ivs_sdkv1.IVS](ctx, c, names.IVS)) + return errs.Must(conn[*ivs_sdkv1.IVS](ctx, c, names.IVS, make(map[string]any))) } func (c *AWSClient) IVSChatClient(ctx context.Context) *ivschat_sdkv2.Client { - return errs.Must(client[*ivschat_sdkv2.Client](ctx, c, names.IVSChat)) + return errs.Must(client[*ivschat_sdkv2.Client](ctx, c, names.IVSChat, make(map[string]any))) } func (c *AWSClient) IdentityStoreClient(ctx context.Context) *identitystore_sdkv2.Client { - return errs.Must(client[*identitystore_sdkv2.Client](ctx, c, names.IdentityStore)) + return errs.Must(client[*identitystore_sdkv2.Client](ctx, c, names.IdentityStore, make(map[string]any))) } func (c *AWSClient) ImageBuilderConn(ctx context.Context) *imagebuilder_sdkv1.Imagebuilder { - return errs.Must(conn[*imagebuilder_sdkv1.Imagebuilder](ctx, c, names.ImageBuilder)) + return errs.Must(conn[*imagebuilder_sdkv1.Imagebuilder](ctx, c, names.ImageBuilder, make(map[string]any))) } func (c *AWSClient) InspectorConn(ctx context.Context) *inspector_sdkv1.Inspector { - return errs.Must(conn[*inspector_sdkv1.Inspector](ctx, c, names.Inspector)) + return errs.Must(conn[*inspector_sdkv1.Inspector](ctx, c, names.Inspector, make(map[string]any))) } func (c *AWSClient) Inspector2Client(ctx context.Context) *inspector2_sdkv2.Client { - return errs.Must(client[*inspector2_sdkv2.Client](ctx, c, names.Inspector2)) + return errs.Must(client[*inspector2_sdkv2.Client](ctx, c, names.Inspector2, make(map[string]any))) } func (c *AWSClient) InternetMonitorClient(ctx context.Context) *internetmonitor_sdkv2.Client { - return errs.Must(client[*internetmonitor_sdkv2.Client](ctx, c, names.InternetMonitor)) + return errs.Must(client[*internetmonitor_sdkv2.Client](ctx, c, names.InternetMonitor, make(map[string]any))) } func (c *AWSClient) IoTConn(ctx context.Context) *iot_sdkv1.IoT { - return errs.Must(conn[*iot_sdkv1.IoT](ctx, c, names.IoT)) + return errs.Must(conn[*iot_sdkv1.IoT](ctx, c, names.IoT, make(map[string]any))) } func (c *AWSClient) IoTAnalyticsConn(ctx context.Context) *iotanalytics_sdkv1.IoTAnalytics { - return errs.Must(conn[*iotanalytics_sdkv1.IoTAnalytics](ctx, c, names.IoTAnalytics)) + return errs.Must(conn[*iotanalytics_sdkv1.IoTAnalytics](ctx, c, names.IoTAnalytics, make(map[string]any))) } func (c *AWSClient) IoTEventsConn(ctx context.Context) *iotevents_sdkv1.IoTEvents { - return errs.Must(conn[*iotevents_sdkv1.IoTEvents](ctx, c, names.IoTEvents)) + return errs.Must(conn[*iotevents_sdkv1.IoTEvents](ctx, c, names.IoTEvents, make(map[string]any))) } func (c *AWSClient) KMSConn(ctx context.Context) *kms_sdkv1.KMS { - return errs.Must(conn[*kms_sdkv1.KMS](ctx, c, names.KMS)) + return errs.Must(conn[*kms_sdkv1.KMS](ctx, c, names.KMS, make(map[string]any))) } func (c *AWSClient) KafkaConn(ctx context.Context) *kafka_sdkv1.Kafka { - return errs.Must(conn[*kafka_sdkv1.Kafka](ctx, c, names.Kafka)) + return errs.Must(conn[*kafka_sdkv1.Kafka](ctx, c, names.Kafka, make(map[string]any))) } func (c *AWSClient) KafkaClient(ctx context.Context) *kafka_sdkv2.Client { - return errs.Must(client[*kafka_sdkv2.Client](ctx, c, names.Kafka)) + return errs.Must(client[*kafka_sdkv2.Client](ctx, c, names.Kafka, make(map[string]any))) } func (c *AWSClient) KafkaConnectConn(ctx context.Context) *kafkaconnect_sdkv1.KafkaConnect { - return errs.Must(conn[*kafkaconnect_sdkv1.KafkaConnect](ctx, c, names.KafkaConnect)) + return errs.Must(conn[*kafkaconnect_sdkv1.KafkaConnect](ctx, c, names.KafkaConnect, make(map[string]any))) } func (c *AWSClient) KendraClient(ctx context.Context) *kendra_sdkv2.Client { - return errs.Must(client[*kendra_sdkv2.Client](ctx, c, names.Kendra)) + return errs.Must(client[*kendra_sdkv2.Client](ctx, c, names.Kendra, make(map[string]any))) } func (c *AWSClient) KeyspacesClient(ctx context.Context) *keyspaces_sdkv2.Client { - return errs.Must(client[*keyspaces_sdkv2.Client](ctx, c, names.Keyspaces)) + return errs.Must(client[*keyspaces_sdkv2.Client](ctx, c, names.Keyspaces, make(map[string]any))) } func (c *AWSClient) KinesisConn(ctx context.Context) *kinesis_sdkv1.Kinesis { - return errs.Must(conn[*kinesis_sdkv1.Kinesis](ctx, c, names.Kinesis)) + return errs.Must(conn[*kinesis_sdkv1.Kinesis](ctx, c, names.Kinesis, make(map[string]any))) } func (c *AWSClient) KinesisAnalyticsConn(ctx context.Context) *kinesisanalytics_sdkv1.KinesisAnalytics { - return errs.Must(conn[*kinesisanalytics_sdkv1.KinesisAnalytics](ctx, c, names.KinesisAnalytics)) + return errs.Must(conn[*kinesisanalytics_sdkv1.KinesisAnalytics](ctx, c, names.KinesisAnalytics, make(map[string]any))) } func (c *AWSClient) KinesisAnalyticsV2Conn(ctx context.Context) *kinesisanalyticsv2_sdkv1.KinesisAnalyticsV2 { - return errs.Must(conn[*kinesisanalyticsv2_sdkv1.KinesisAnalyticsV2](ctx, c, names.KinesisAnalyticsV2)) + return errs.Must(conn[*kinesisanalyticsv2_sdkv1.KinesisAnalyticsV2](ctx, c, names.KinesisAnalyticsV2, make(map[string]any))) } func (c *AWSClient) KinesisVideoConn(ctx context.Context) *kinesisvideo_sdkv1.KinesisVideo { - return errs.Must(conn[*kinesisvideo_sdkv1.KinesisVideo](ctx, c, names.KinesisVideo)) + return errs.Must(conn[*kinesisvideo_sdkv1.KinesisVideo](ctx, c, names.KinesisVideo, make(map[string]any))) } func (c *AWSClient) LakeFormationConn(ctx context.Context) *lakeformation_sdkv1.LakeFormation { - return errs.Must(conn[*lakeformation_sdkv1.LakeFormation](ctx, c, names.LakeFormation)) + return errs.Must(conn[*lakeformation_sdkv1.LakeFormation](ctx, c, names.LakeFormation, make(map[string]any))) } func (c *AWSClient) LambdaConn(ctx context.Context) *lambda_sdkv1.Lambda { - return errs.Must(conn[*lambda_sdkv1.Lambda](ctx, c, names.Lambda)) + return errs.Must(conn[*lambda_sdkv1.Lambda](ctx, c, names.Lambda, make(map[string]any))) } func (c *AWSClient) LambdaClient(ctx context.Context) *lambda_sdkv2.Client { - return errs.Must(client[*lambda_sdkv2.Client](ctx, c, names.Lambda)) + return errs.Must(client[*lambda_sdkv2.Client](ctx, c, names.Lambda, make(map[string]any))) } func (c *AWSClient) LexModelsConn(ctx context.Context) *lexmodelbuildingservice_sdkv1.LexModelBuildingService { - return errs.Must(conn[*lexmodelbuildingservice_sdkv1.LexModelBuildingService](ctx, c, names.LexModels)) + return errs.Must(conn[*lexmodelbuildingservice_sdkv1.LexModelBuildingService](ctx, c, names.LexModels, make(map[string]any))) } func (c *AWSClient) LexV2ModelsClient(ctx context.Context) *lexmodelsv2_sdkv2.Client { - return errs.Must(client[*lexmodelsv2_sdkv2.Client](ctx, c, names.LexV2Models)) + return errs.Must(client[*lexmodelsv2_sdkv2.Client](ctx, c, names.LexV2Models, make(map[string]any))) } func (c *AWSClient) LicenseManagerConn(ctx context.Context) *licensemanager_sdkv1.LicenseManager { - return errs.Must(conn[*licensemanager_sdkv1.LicenseManager](ctx, c, names.LicenseManager)) + return errs.Must(conn[*licensemanager_sdkv1.LicenseManager](ctx, c, names.LicenseManager, make(map[string]any))) } func (c *AWSClient) LightsailClient(ctx context.Context) *lightsail_sdkv2.Client { - return errs.Must(client[*lightsail_sdkv2.Client](ctx, c, names.Lightsail)) + return errs.Must(client[*lightsail_sdkv2.Client](ctx, c, names.Lightsail, make(map[string]any))) } func (c *AWSClient) LocationConn(ctx context.Context) *locationservice_sdkv1.LocationService { - return errs.Must(conn[*locationservice_sdkv1.LocationService](ctx, c, names.Location)) + return errs.Must(conn[*locationservice_sdkv1.LocationService](ctx, c, names.Location, make(map[string]any))) } func (c *AWSClient) LogsClient(ctx context.Context) *cloudwatchlogs_sdkv2.Client { - return errs.Must(client[*cloudwatchlogs_sdkv2.Client](ctx, c, names.Logs)) + return errs.Must(client[*cloudwatchlogs_sdkv2.Client](ctx, c, names.Logs, make(map[string]any))) } func (c *AWSClient) LookoutMetricsClient(ctx context.Context) *lookoutmetrics_sdkv2.Client { - return errs.Must(client[*lookoutmetrics_sdkv2.Client](ctx, c, names.LookoutMetrics)) + return errs.Must(client[*lookoutmetrics_sdkv2.Client](ctx, c, names.LookoutMetrics, make(map[string]any))) } func (c *AWSClient) MQConn(ctx context.Context) *mq_sdkv1.MQ { - return errs.Must(conn[*mq_sdkv1.MQ](ctx, c, names.MQ)) + return errs.Must(conn[*mq_sdkv1.MQ](ctx, c, names.MQ, make(map[string]any))) } func (c *AWSClient) MWAAConn(ctx context.Context) *mwaa_sdkv1.MWAA { - return errs.Must(conn[*mwaa_sdkv1.MWAA](ctx, c, names.MWAA)) + return errs.Must(conn[*mwaa_sdkv1.MWAA](ctx, c, names.MWAA, make(map[string]any))) } func (c *AWSClient) Macie2Conn(ctx context.Context) *macie2_sdkv1.Macie2 { - return errs.Must(conn[*macie2_sdkv1.Macie2](ctx, c, names.Macie2)) + return errs.Must(conn[*macie2_sdkv1.Macie2](ctx, c, names.Macie2, make(map[string]any))) } func (c *AWSClient) MediaConnectClient(ctx context.Context) *mediaconnect_sdkv2.Client { - return errs.Must(client[*mediaconnect_sdkv2.Client](ctx, c, names.MediaConnect)) + return errs.Must(client[*mediaconnect_sdkv2.Client](ctx, c, names.MediaConnect, make(map[string]any))) } func (c *AWSClient) MediaConvertConn(ctx context.Context) *mediaconvert_sdkv1.MediaConvert { - return errs.Must(conn[*mediaconvert_sdkv1.MediaConvert](ctx, c, names.MediaConvert)) + return errs.Must(conn[*mediaconvert_sdkv1.MediaConvert](ctx, c, names.MediaConvert, make(map[string]any))) } func (c *AWSClient) MediaLiveClient(ctx context.Context) *medialive_sdkv2.Client { - return errs.Must(client[*medialive_sdkv2.Client](ctx, c, names.MediaLive)) + return errs.Must(client[*medialive_sdkv2.Client](ctx, c, names.MediaLive, make(map[string]any))) } func (c *AWSClient) MediaPackageClient(ctx context.Context) *mediapackage_sdkv2.Client { - return errs.Must(client[*mediapackage_sdkv2.Client](ctx, c, names.MediaPackage)) + return errs.Must(client[*mediapackage_sdkv2.Client](ctx, c, names.MediaPackage, make(map[string]any))) } func (c *AWSClient) MediaPackageV2Client(ctx context.Context) *mediapackagev2_sdkv2.Client { - return errs.Must(client[*mediapackagev2_sdkv2.Client](ctx, c, names.MediaPackageV2)) + return errs.Must(client[*mediapackagev2_sdkv2.Client](ctx, c, names.MediaPackageV2, make(map[string]any))) } func (c *AWSClient) MediaStoreConn(ctx context.Context) *mediastore_sdkv1.MediaStore { - return errs.Must(conn[*mediastore_sdkv1.MediaStore](ctx, c, names.MediaStore)) + return errs.Must(conn[*mediastore_sdkv1.MediaStore](ctx, c, names.MediaStore, make(map[string]any))) } func (c *AWSClient) MemoryDBConn(ctx context.Context) *memorydb_sdkv1.MemoryDB { - return errs.Must(conn[*memorydb_sdkv1.MemoryDB](ctx, c, names.MemoryDB)) + return errs.Must(conn[*memorydb_sdkv1.MemoryDB](ctx, c, names.MemoryDB, make(map[string]any))) } func (c *AWSClient) NeptuneConn(ctx context.Context) *neptune_sdkv1.Neptune { - return errs.Must(conn[*neptune_sdkv1.Neptune](ctx, c, names.Neptune)) + return errs.Must(conn[*neptune_sdkv1.Neptune](ctx, c, names.Neptune, make(map[string]any))) } func (c *AWSClient) NetworkFirewallConn(ctx context.Context) *networkfirewall_sdkv1.NetworkFirewall { - return errs.Must(conn[*networkfirewall_sdkv1.NetworkFirewall](ctx, c, names.NetworkFirewall)) + return errs.Must(conn[*networkfirewall_sdkv1.NetworkFirewall](ctx, c, names.NetworkFirewall, make(map[string]any))) } func (c *AWSClient) NetworkManagerConn(ctx context.Context) *networkmanager_sdkv1.NetworkManager { - return errs.Must(conn[*networkmanager_sdkv1.NetworkManager](ctx, c, names.NetworkManager)) + return errs.Must(conn[*networkmanager_sdkv1.NetworkManager](ctx, c, names.NetworkManager, make(map[string]any))) } func (c *AWSClient) ObservabilityAccessManagerClient(ctx context.Context) *oam_sdkv2.Client { - return errs.Must(client[*oam_sdkv2.Client](ctx, c, names.ObservabilityAccessManager)) + return errs.Must(client[*oam_sdkv2.Client](ctx, c, names.ObservabilityAccessManager, make(map[string]any))) } func (c *AWSClient) OpenSearchConn(ctx context.Context) *opensearchservice_sdkv1.OpenSearchService { - return errs.Must(conn[*opensearchservice_sdkv1.OpenSearchService](ctx, c, names.OpenSearch)) + return errs.Must(conn[*opensearchservice_sdkv1.OpenSearchService](ctx, c, names.OpenSearch, make(map[string]any))) } func (c *AWSClient) OpenSearchIngestionClient(ctx context.Context) *osis_sdkv2.Client { - return errs.Must(client[*osis_sdkv2.Client](ctx, c, names.OpenSearchIngestion)) + return errs.Must(client[*osis_sdkv2.Client](ctx, c, names.OpenSearchIngestion, make(map[string]any))) } func (c *AWSClient) OpenSearchServerlessClient(ctx context.Context) *opensearchserverless_sdkv2.Client { - return errs.Must(client[*opensearchserverless_sdkv2.Client](ctx, c, names.OpenSearchServerless)) + return errs.Must(client[*opensearchserverless_sdkv2.Client](ctx, c, names.OpenSearchServerless, make(map[string]any))) } func (c *AWSClient) OpsWorksConn(ctx context.Context) *opsworks_sdkv1.OpsWorks { - return errs.Must(conn[*opsworks_sdkv1.OpsWorks](ctx, c, names.OpsWorks)) + return errs.Must(conn[*opsworks_sdkv1.OpsWorks](ctx, c, names.OpsWorks, make(map[string]any))) } func (c *AWSClient) OrganizationsConn(ctx context.Context) *organizations_sdkv1.Organizations { - return errs.Must(conn[*organizations_sdkv1.Organizations](ctx, c, names.Organizations)) + return errs.Must(conn[*organizations_sdkv1.Organizations](ctx, c, names.Organizations, make(map[string]any))) } func (c *AWSClient) OutpostsConn(ctx context.Context) *outposts_sdkv1.Outposts { - return errs.Must(conn[*outposts_sdkv1.Outposts](ctx, c, names.Outposts)) + return errs.Must(conn[*outposts_sdkv1.Outposts](ctx, c, names.Outposts, make(map[string]any))) } func (c *AWSClient) PinpointConn(ctx context.Context) *pinpoint_sdkv1.Pinpoint { - return errs.Must(conn[*pinpoint_sdkv1.Pinpoint](ctx, c, names.Pinpoint)) + return errs.Must(conn[*pinpoint_sdkv1.Pinpoint](ctx, c, names.Pinpoint, make(map[string]any))) } func (c *AWSClient) PipesClient(ctx context.Context) *pipes_sdkv2.Client { - return errs.Must(client[*pipes_sdkv2.Client](ctx, c, names.Pipes)) + return errs.Must(client[*pipes_sdkv2.Client](ctx, c, names.Pipes, make(map[string]any))) } func (c *AWSClient) PollyClient(ctx context.Context) *polly_sdkv2.Client { - return errs.Must(client[*polly_sdkv2.Client](ctx, c, names.Polly)) + return errs.Must(client[*polly_sdkv2.Client](ctx, c, names.Polly, make(map[string]any))) } func (c *AWSClient) PricingClient(ctx context.Context) *pricing_sdkv2.Client { - return errs.Must(client[*pricing_sdkv2.Client](ctx, c, names.Pricing)) + return errs.Must(client[*pricing_sdkv2.Client](ctx, c, names.Pricing, make(map[string]any))) } func (c *AWSClient) QLDBClient(ctx context.Context) *qldb_sdkv2.Client { - return errs.Must(client[*qldb_sdkv2.Client](ctx, c, names.QLDB)) + return errs.Must(client[*qldb_sdkv2.Client](ctx, c, names.QLDB, make(map[string]any))) } func (c *AWSClient) QuickSightConn(ctx context.Context) *quicksight_sdkv1.QuickSight { - return errs.Must(conn[*quicksight_sdkv1.QuickSight](ctx, c, names.QuickSight)) + return errs.Must(conn[*quicksight_sdkv1.QuickSight](ctx, c, names.QuickSight, make(map[string]any))) } func (c *AWSClient) RAMConn(ctx context.Context) *ram_sdkv1.RAM { - return errs.Must(conn[*ram_sdkv1.RAM](ctx, c, names.RAM)) + return errs.Must(conn[*ram_sdkv1.RAM](ctx, c, names.RAM, make(map[string]any))) } func (c *AWSClient) RBinClient(ctx context.Context) *rbin_sdkv2.Client { - return errs.Must(client[*rbin_sdkv2.Client](ctx, c, names.RBin)) + return errs.Must(client[*rbin_sdkv2.Client](ctx, c, names.RBin, make(map[string]any))) } func (c *AWSClient) RDSConn(ctx context.Context) *rds_sdkv1.RDS { - return errs.Must(conn[*rds_sdkv1.RDS](ctx, c, names.RDS)) + return errs.Must(conn[*rds_sdkv1.RDS](ctx, c, names.RDS, make(map[string]any))) } func (c *AWSClient) RDSClient(ctx context.Context) *rds_sdkv2.Client { - return errs.Must(client[*rds_sdkv2.Client](ctx, c, names.RDS)) + return errs.Must(client[*rds_sdkv2.Client](ctx, c, names.RDS, make(map[string]any))) } func (c *AWSClient) RUMConn(ctx context.Context) *cloudwatchrum_sdkv1.CloudWatchRUM { - return errs.Must(conn[*cloudwatchrum_sdkv1.CloudWatchRUM](ctx, c, names.RUM)) + return errs.Must(conn[*cloudwatchrum_sdkv1.CloudWatchRUM](ctx, c, names.RUM, make(map[string]any))) } func (c *AWSClient) RedshiftConn(ctx context.Context) *redshift_sdkv1.Redshift { - return errs.Must(conn[*redshift_sdkv1.Redshift](ctx, c, names.Redshift)) + return errs.Must(conn[*redshift_sdkv1.Redshift](ctx, c, names.Redshift, make(map[string]any))) } func (c *AWSClient) RedshiftDataClient(ctx context.Context) *redshiftdata_sdkv2.Client { - return errs.Must(client[*redshiftdata_sdkv2.Client](ctx, c, names.RedshiftData)) + return errs.Must(client[*redshiftdata_sdkv2.Client](ctx, c, names.RedshiftData, make(map[string]any))) } func (c *AWSClient) RedshiftServerlessConn(ctx context.Context) *redshiftserverless_sdkv1.RedshiftServerless { - return errs.Must(conn[*redshiftserverless_sdkv1.RedshiftServerless](ctx, c, names.RedshiftServerless)) + return errs.Must(conn[*redshiftserverless_sdkv1.RedshiftServerless](ctx, c, names.RedshiftServerless, make(map[string]any))) } func (c *AWSClient) ResourceExplorer2Client(ctx context.Context) *resourceexplorer2_sdkv2.Client { - return errs.Must(client[*resourceexplorer2_sdkv2.Client](ctx, c, names.ResourceExplorer2)) + return errs.Must(client[*resourceexplorer2_sdkv2.Client](ctx, c, names.ResourceExplorer2, make(map[string]any))) } func (c *AWSClient) ResourceGroupsClient(ctx context.Context) *resourcegroups_sdkv2.Client { - return errs.Must(client[*resourcegroups_sdkv2.Client](ctx, c, names.ResourceGroups)) + return errs.Must(client[*resourcegroups_sdkv2.Client](ctx, c, names.ResourceGroups, make(map[string]any))) } func (c *AWSClient) ResourceGroupsTaggingAPIClient(ctx context.Context) *resourcegroupstaggingapi_sdkv2.Client { - return errs.Must(client[*resourcegroupstaggingapi_sdkv2.Client](ctx, c, names.ResourceGroupsTaggingAPI)) + return errs.Must(client[*resourcegroupstaggingapi_sdkv2.Client](ctx, c, names.ResourceGroupsTaggingAPI, make(map[string]any))) } func (c *AWSClient) RolesAnywhereClient(ctx context.Context) *rolesanywhere_sdkv2.Client { - return errs.Must(client[*rolesanywhere_sdkv2.Client](ctx, c, names.RolesAnywhere)) + return errs.Must(client[*rolesanywhere_sdkv2.Client](ctx, c, names.RolesAnywhere, make(map[string]any))) } func (c *AWSClient) Route53Conn(ctx context.Context) *route53_sdkv1.Route53 { - return errs.Must(conn[*route53_sdkv1.Route53](ctx, c, names.Route53)) + return errs.Must(conn[*route53_sdkv1.Route53](ctx, c, names.Route53, make(map[string]any))) } func (c *AWSClient) Route53DomainsClient(ctx context.Context) *route53domains_sdkv2.Client { - return errs.Must(client[*route53domains_sdkv2.Client](ctx, c, names.Route53Domains)) + return errs.Must(client[*route53domains_sdkv2.Client](ctx, c, names.Route53Domains, make(map[string]any))) } func (c *AWSClient) Route53RecoveryControlConfigConn(ctx context.Context) *route53recoverycontrolconfig_sdkv1.Route53RecoveryControlConfig { - return errs.Must(conn[*route53recoverycontrolconfig_sdkv1.Route53RecoveryControlConfig](ctx, c, names.Route53RecoveryControlConfig)) + return errs.Must(conn[*route53recoverycontrolconfig_sdkv1.Route53RecoveryControlConfig](ctx, c, names.Route53RecoveryControlConfig, make(map[string]any))) } func (c *AWSClient) Route53RecoveryReadinessConn(ctx context.Context) *route53recoveryreadiness_sdkv1.Route53RecoveryReadiness { - return errs.Must(conn[*route53recoveryreadiness_sdkv1.Route53RecoveryReadiness](ctx, c, names.Route53RecoveryReadiness)) + return errs.Must(conn[*route53recoveryreadiness_sdkv1.Route53RecoveryReadiness](ctx, c, names.Route53RecoveryReadiness, make(map[string]any))) } func (c *AWSClient) Route53ResolverConn(ctx context.Context) *route53resolver_sdkv1.Route53Resolver { - return errs.Must(conn[*route53resolver_sdkv1.Route53Resolver](ctx, c, names.Route53Resolver)) + return errs.Must(conn[*route53resolver_sdkv1.Route53Resolver](ctx, c, names.Route53Resolver, make(map[string]any))) } func (c *AWSClient) S3Conn(ctx context.Context) *s3_sdkv1.S3 { - return errs.Must(conn[*s3_sdkv1.S3](ctx, c, names.S3)) + return errs.Must(conn[*s3_sdkv1.S3](ctx, c, names.S3, make(map[string]any))) } func (c *AWSClient) S3Client(ctx context.Context) *s3_sdkv2.Client { - return errs.Must(client[*s3_sdkv2.Client](ctx, c, names.S3)) + return errs.Must(client[*s3_sdkv2.Client](ctx, c, names.S3, make(map[string]any))) } func (c *AWSClient) S3ControlClient(ctx context.Context) *s3control_sdkv2.Client { - return errs.Must(client[*s3control_sdkv2.Client](ctx, c, names.S3Control)) + return errs.Must(client[*s3control_sdkv2.Client](ctx, c, names.S3Control, make(map[string]any))) } func (c *AWSClient) S3OutpostsConn(ctx context.Context) *s3outposts_sdkv1.S3Outposts { - return errs.Must(conn[*s3outposts_sdkv1.S3Outposts](ctx, c, names.S3Outposts)) + return errs.Must(conn[*s3outposts_sdkv1.S3Outposts](ctx, c, names.S3Outposts, make(map[string]any))) } func (c *AWSClient) SESConn(ctx context.Context) *ses_sdkv1.SES { - return errs.Must(conn[*ses_sdkv1.SES](ctx, c, names.SES)) + return errs.Must(conn[*ses_sdkv1.SES](ctx, c, names.SES, make(map[string]any))) } func (c *AWSClient) SESV2Client(ctx context.Context) *sesv2_sdkv2.Client { - return errs.Must(client[*sesv2_sdkv2.Client](ctx, c, names.SESV2)) + return errs.Must(client[*sesv2_sdkv2.Client](ctx, c, names.SESV2, make(map[string]any))) } func (c *AWSClient) SFNConn(ctx context.Context) *sfn_sdkv1.SFN { - return errs.Must(conn[*sfn_sdkv1.SFN](ctx, c, names.SFN)) + return errs.Must(conn[*sfn_sdkv1.SFN](ctx, c, names.SFN, make(map[string]any))) } func (c *AWSClient) SNSClient(ctx context.Context) *sns_sdkv2.Client { - return errs.Must(client[*sns_sdkv2.Client](ctx, c, names.SNS)) + return errs.Must(client[*sns_sdkv2.Client](ctx, c, names.SNS, make(map[string]any))) } func (c *AWSClient) SQSClient(ctx context.Context) *sqs_sdkv2.Client { - return errs.Must(client[*sqs_sdkv2.Client](ctx, c, names.SQS)) + return errs.Must(client[*sqs_sdkv2.Client](ctx, c, names.SQS, make(map[string]any))) } func (c *AWSClient) SSMConn(ctx context.Context) *ssm_sdkv1.SSM { - return errs.Must(conn[*ssm_sdkv1.SSM](ctx, c, names.SSM)) + return errs.Must(conn[*ssm_sdkv1.SSM](ctx, c, names.SSM, make(map[string]any))) } func (c *AWSClient) SSMClient(ctx context.Context) *ssm_sdkv2.Client { - return errs.Must(client[*ssm_sdkv2.Client](ctx, c, names.SSM)) + return errs.Must(client[*ssm_sdkv2.Client](ctx, c, names.SSM, make(map[string]any))) } func (c *AWSClient) SSMContactsClient(ctx context.Context) *ssmcontacts_sdkv2.Client { - return errs.Must(client[*ssmcontacts_sdkv2.Client](ctx, c, names.SSMContacts)) + return errs.Must(client[*ssmcontacts_sdkv2.Client](ctx, c, names.SSMContacts, make(map[string]any))) } func (c *AWSClient) SSMIncidentsClient(ctx context.Context) *ssmincidents_sdkv2.Client { - return errs.Must(client[*ssmincidents_sdkv2.Client](ctx, c, names.SSMIncidents)) + return errs.Must(client[*ssmincidents_sdkv2.Client](ctx, c, names.SSMIncidents, make(map[string]any))) } func (c *AWSClient) SSOAdminClient(ctx context.Context) *ssoadmin_sdkv2.Client { - return errs.Must(client[*ssoadmin_sdkv2.Client](ctx, c, names.SSOAdmin)) + return errs.Must(client[*ssoadmin_sdkv2.Client](ctx, c, names.SSOAdmin, make(map[string]any))) } func (c *AWSClient) STSConn(ctx context.Context) *sts_sdkv1.STS { - return errs.Must(conn[*sts_sdkv1.STS](ctx, c, names.STS)) + return errs.Must(conn[*sts_sdkv1.STS](ctx, c, names.STS, make(map[string]any))) } func (c *AWSClient) STSClient(ctx context.Context) *sts_sdkv2.Client { - return errs.Must(client[*sts_sdkv2.Client](ctx, c, names.STS)) + return errs.Must(client[*sts_sdkv2.Client](ctx, c, names.STS, make(map[string]any))) } func (c *AWSClient) SWFClient(ctx context.Context) *swf_sdkv2.Client { - return errs.Must(client[*swf_sdkv2.Client](ctx, c, names.SWF)) + return errs.Must(client[*swf_sdkv2.Client](ctx, c, names.SWF, make(map[string]any))) } func (c *AWSClient) SageMakerConn(ctx context.Context) *sagemaker_sdkv1.SageMaker { - return errs.Must(conn[*sagemaker_sdkv1.SageMaker](ctx, c, names.SageMaker)) + return errs.Must(conn[*sagemaker_sdkv1.SageMaker](ctx, c, names.SageMaker, make(map[string]any))) } func (c *AWSClient) SchedulerClient(ctx context.Context) *scheduler_sdkv2.Client { - return errs.Must(client[*scheduler_sdkv2.Client](ctx, c, names.Scheduler)) + return errs.Must(client[*scheduler_sdkv2.Client](ctx, c, names.Scheduler, make(map[string]any))) } func (c *AWSClient) SchemasConn(ctx context.Context) *schemas_sdkv1.Schemas { - return errs.Must(conn[*schemas_sdkv1.Schemas](ctx, c, names.Schemas)) + return errs.Must(conn[*schemas_sdkv1.Schemas](ctx, c, names.Schemas, make(map[string]any))) } func (c *AWSClient) SecretsManagerConn(ctx context.Context) *secretsmanager_sdkv1.SecretsManager { - return errs.Must(conn[*secretsmanager_sdkv1.SecretsManager](ctx, c, names.SecretsManager)) + return errs.Must(conn[*secretsmanager_sdkv1.SecretsManager](ctx, c, names.SecretsManager, make(map[string]any))) } func (c *AWSClient) SecurityHubClient(ctx context.Context) *securityhub_sdkv2.Client { - return errs.Must(client[*securityhub_sdkv2.Client](ctx, c, names.SecurityHub)) + return errs.Must(client[*securityhub_sdkv2.Client](ctx, c, names.SecurityHub, make(map[string]any))) } func (c *AWSClient) SecurityLakeClient(ctx context.Context) *securitylake_sdkv2.Client { - return errs.Must(client[*securitylake_sdkv2.Client](ctx, c, names.SecurityLake)) + return errs.Must(client[*securitylake_sdkv2.Client](ctx, c, names.SecurityLake, make(map[string]any))) } func (c *AWSClient) ServerlessRepoConn(ctx context.Context) *serverlessapplicationrepository_sdkv1.ServerlessApplicationRepository { - return errs.Must(conn[*serverlessapplicationrepository_sdkv1.ServerlessApplicationRepository](ctx, c, names.ServerlessRepo)) + return errs.Must(conn[*serverlessapplicationrepository_sdkv1.ServerlessApplicationRepository](ctx, c, names.ServerlessRepo, make(map[string]any))) } func (c *AWSClient) ServiceCatalogConn(ctx context.Context) *servicecatalog_sdkv1.ServiceCatalog { - return errs.Must(conn[*servicecatalog_sdkv1.ServiceCatalog](ctx, c, names.ServiceCatalog)) + return errs.Must(conn[*servicecatalog_sdkv1.ServiceCatalog](ctx, c, names.ServiceCatalog, make(map[string]any))) } func (c *AWSClient) ServiceDiscoveryConn(ctx context.Context) *servicediscovery_sdkv1.ServiceDiscovery { - return errs.Must(conn[*servicediscovery_sdkv1.ServiceDiscovery](ctx, c, names.ServiceDiscovery)) + return errs.Must(conn[*servicediscovery_sdkv1.ServiceDiscovery](ctx, c, names.ServiceDiscovery, make(map[string]any))) } func (c *AWSClient) ServiceQuotasClient(ctx context.Context) *servicequotas_sdkv2.Client { - return errs.Must(client[*servicequotas_sdkv2.Client](ctx, c, names.ServiceQuotas)) + return errs.Must(client[*servicequotas_sdkv2.Client](ctx, c, names.ServiceQuotas, make(map[string]any))) } func (c *AWSClient) ShieldConn(ctx context.Context) *shield_sdkv1.Shield { - return errs.Must(conn[*shield_sdkv1.Shield](ctx, c, names.Shield)) + return errs.Must(conn[*shield_sdkv1.Shield](ctx, c, names.Shield, make(map[string]any))) } func (c *AWSClient) SignerClient(ctx context.Context) *signer_sdkv2.Client { - return errs.Must(client[*signer_sdkv2.Client](ctx, c, names.Signer)) + return errs.Must(client[*signer_sdkv2.Client](ctx, c, names.Signer, make(map[string]any))) } func (c *AWSClient) SimpleDBConn(ctx context.Context) *simpledb_sdkv1.SimpleDB { - return errs.Must(conn[*simpledb_sdkv1.SimpleDB](ctx, c, names.SimpleDB)) + return errs.Must(conn[*simpledb_sdkv1.SimpleDB](ctx, c, names.SimpleDB, make(map[string]any))) } func (c *AWSClient) StorageGatewayConn(ctx context.Context) *storagegateway_sdkv1.StorageGateway { - return errs.Must(conn[*storagegateway_sdkv1.StorageGateway](ctx, c, names.StorageGateway)) + return errs.Must(conn[*storagegateway_sdkv1.StorageGateway](ctx, c, names.StorageGateway, make(map[string]any))) } func (c *AWSClient) SyntheticsConn(ctx context.Context) *synthetics_sdkv1.Synthetics { - return errs.Must(conn[*synthetics_sdkv1.Synthetics](ctx, c, names.Synthetics)) + return errs.Must(conn[*synthetics_sdkv1.Synthetics](ctx, c, names.Synthetics, make(map[string]any))) } func (c *AWSClient) TimestreamWriteClient(ctx context.Context) *timestreamwrite_sdkv2.Client { - return errs.Must(client[*timestreamwrite_sdkv2.Client](ctx, c, names.TimestreamWrite)) + return errs.Must(client[*timestreamwrite_sdkv2.Client](ctx, c, names.TimestreamWrite, make(map[string]any))) } func (c *AWSClient) TranscribeClient(ctx context.Context) *transcribe_sdkv2.Client { - return errs.Must(client[*transcribe_sdkv2.Client](ctx, c, names.Transcribe)) + return errs.Must(client[*transcribe_sdkv2.Client](ctx, c, names.Transcribe, make(map[string]any))) } func (c *AWSClient) TransferConn(ctx context.Context) *transfer_sdkv1.Transfer { - return errs.Must(conn[*transfer_sdkv1.Transfer](ctx, c, names.Transfer)) + return errs.Must(conn[*transfer_sdkv1.Transfer](ctx, c, names.Transfer, make(map[string]any))) } func (c *AWSClient) VPCLatticeClient(ctx context.Context) *vpclattice_sdkv2.Client { - return errs.Must(client[*vpclattice_sdkv2.Client](ctx, c, names.VPCLattice)) + return errs.Must(client[*vpclattice_sdkv2.Client](ctx, c, names.VPCLattice, make(map[string]any))) } func (c *AWSClient) VerifiedPermissionsClient(ctx context.Context) *verifiedpermissions_sdkv2.Client { - return errs.Must(client[*verifiedpermissions_sdkv2.Client](ctx, c, names.VerifiedPermissions)) + return errs.Must(client[*verifiedpermissions_sdkv2.Client](ctx, c, names.VerifiedPermissions, make(map[string]any))) } func (c *AWSClient) WAFConn(ctx context.Context) *waf_sdkv1.WAF { - return errs.Must(conn[*waf_sdkv1.WAF](ctx, c, names.WAF)) + return errs.Must(conn[*waf_sdkv1.WAF](ctx, c, names.WAF, make(map[string]any))) } func (c *AWSClient) WAFRegionalConn(ctx context.Context) *wafregional_sdkv1.WAFRegional { - return errs.Must(conn[*wafregional_sdkv1.WAFRegional](ctx, c, names.WAFRegional)) + return errs.Must(conn[*wafregional_sdkv1.WAFRegional](ctx, c, names.WAFRegional, make(map[string]any))) } func (c *AWSClient) WAFV2Conn(ctx context.Context) *wafv2_sdkv1.WAFV2 { - return errs.Must(conn[*wafv2_sdkv1.WAFV2](ctx, c, names.WAFV2)) + return errs.Must(conn[*wafv2_sdkv1.WAFV2](ctx, c, names.WAFV2, make(map[string]any))) } func (c *AWSClient) WorkLinkConn(ctx context.Context) *worklink_sdkv1.WorkLink { - return errs.Must(conn[*worklink_sdkv1.WorkLink](ctx, c, names.WorkLink)) + return errs.Must(conn[*worklink_sdkv1.WorkLink](ctx, c, names.WorkLink, make(map[string]any))) } func (c *AWSClient) WorkSpacesClient(ctx context.Context) *workspaces_sdkv2.Client { - return errs.Must(client[*workspaces_sdkv2.Client](ctx, c, names.WorkSpaces)) + return errs.Must(client[*workspaces_sdkv2.Client](ctx, c, names.WorkSpaces, make(map[string]any))) } func (c *AWSClient) XRayClient(ctx context.Context) *xray_sdkv2.Client { - return errs.Must(client[*xray_sdkv2.Client](ctx, c, names.XRay)) + return errs.Must(client[*xray_sdkv2.Client](ctx, c, names.XRay, make(map[string]any))) } diff --git a/internal/generate/awsclient/file.tmpl b/internal/generate/awsclient/file.tmpl index b93c0f591b5..359233aeb7c 100644 --- a/internal/generate/awsclient/file.tmpl +++ b/internal/generate/awsclient/file.tmpl @@ -19,13 +19,13 @@ import ( {{ range .Services }} {{if eq .SDKVersion "1" "1,2" }} func (c *AWSClient) {{ .ProviderNameUpper }}Conn(ctx context.Context) *{{ .GoV1Package }}_sdkv1.{{ .GoV1ClientTypeName }} { - return errs.Must(conn[*{{ .GoV1Package }}_sdkv1.{{ .GoV1ClientTypeName }}](ctx, c, names.{{ .ProviderNameUpper }})) + return errs.Must(conn[*{{ .GoV1Package }}_sdkv1.{{ .GoV1ClientTypeName }}](ctx, c, names.{{ .ProviderNameUpper }}, make(map[string]any))) } {{- end }} {{if eq .SDKVersion "2" "1,2" }} func (c *AWSClient) {{ .ProviderNameUpper }}Client(ctx context.Context) *{{ .GoV2Package }}_sdkv2.Client { - return errs.Must(client[*{{ .GoV2Package }}_sdkv2.Client](ctx, c, names.{{ .ProviderNameUpper }})) + return errs.Must(client[*{{ .GoV2Package }}_sdkv2.Client](ctx, c, names.{{ .ProviderNameUpper }}, make(map[string]any))) } {{- end }} {{ end }} diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index 37d4a0c4244..e26e7024b3b 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -1441,6 +1441,8 @@ func findBucket(ctx context.Context, conn *s3_sdkv2.Client, bucket string, optFn _, err := conn.HeadBucket(ctx, input, optFns...) + // For directory buckets that no longer exist it's the CreateSession call invoked by HeadBucket that returns "NoSuchBucket", + // and that error code is flattend into HeadBucket's error message -- hence the 'errs.Contains' call. if tfawserr_sdkv2.ErrHTTPStatusCodeEquals(err, http.StatusNotFound) || tfawserr_sdkv2.ErrCodeEquals(err, errCodeNoSuchBucket) || errs.Contains(err, errCodeNoSuchBucket) { return &retry.NotFoundError{ LastError: err, diff --git a/internal/service/s3/bucket_policy.go b/internal/service/s3/bucket_policy.go index 32c26742832..ab0d4516985 100644 --- a/internal/service/s3/bucket_policy.go +++ b/internal/service/s3/bucket_policy.go @@ -64,6 +64,9 @@ func resourceBucketPolicyPut(ctx context.Context, d *schema.ResourceData, meta i } bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } input := &s3.PutBucketPolicyInput{ Bucket: aws.String(bucket), Policy: aws.String(policy), @@ -95,6 +98,9 @@ func resourceBucketPolicyPut(ctx context.Context, d *schema.ResourceData, meta i func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + if isDirectoryBucket(d.Id()) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } policy, err := findBucketPolicy(ctx, conn, d.Id()) @@ -122,6 +128,9 @@ func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta func resourceBucketPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + if isDirectoryBucket(d.Id()) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } log.Printf("[DEBUG] Deleting S3 Bucket Policy: %s", d.Id()) _, err := conn.DeleteBucketPolicy(ctx, &s3.DeleteBucketPolicyInput{ diff --git a/internal/service/s3/bucket_policy_test.go b/internal/service/s3/bucket_policy_test.go index d60f13b1a6e..f31211381cf 100644 --- a/internal/service/s3/bucket_policy_test.go +++ b/internal/service/s3/bucket_policy_test.go @@ -453,13 +453,16 @@ func TestAccS3BucketPolicy_directoryBucket(t *testing.T) { func testAccCheckBucketPolicyDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) - for _, rs := range s.RootModule().Resources { if rs.Type != "aws_s3_bucket_policy" { continue } + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.ID) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + _, err := tfs3.FindBucketPolicy(ctx, conn, rs.Primary.ID) if tfresource.NotFound(err) { @@ -485,6 +488,9 @@ func testAccCheckBucketHasPolicy(ctx context.Context, n string, expectedPolicyTe } conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.ID) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } policy, err := tfs3.FindBucketPolicy(ctx, conn, rs.Primary.ID) diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index 0404361ae56..bddb085ee2c 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -2628,7 +2628,11 @@ func testAccCheckBucketExistsWithProvider(ctx context.Context, n string, provide func testAccCheckBucketAddObjects(ctx context.Context, n string, keys ...string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.ID) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } for _, key := range keys { _, err := conn.PutObject(ctx, &s3_sdkv2.PutObjectInput{ @@ -2648,6 +2652,7 @@ func testAccCheckBucketAddObjects(ctx context.Context, n string, keys ...string) func testAccCheckBucketAddObjectsWithLegalHold(ctx context.Context, n string, keys ...string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn(ctx) for _, key := range keys { diff --git a/internal/service/s3/delete.go b/internal/service/s3/delete.go index 8df4f6b8bce..30fd747f134 100644 --- a/internal/service/s3/delete.go +++ b/internal/service/s3/delete.go @@ -314,7 +314,7 @@ func newDeleteObjectVersionError(err types.Error) error { // Set `force` to `true` to override any S3 object lock protections on object lock enabled buckets. // Returns the number of objects deleted. // Use `emptyBucket` to delete all versions of all objects in a bucket. -func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key string, force, ignoreObjectErrors bool) (int64, error) { +func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key string, force, ignoreObjectErrors bool, optFns ...func(*s3.Options)) (int64, error) { if key == "" { return 0, errors.New("use `emptyBucket` to delete all versions of all objects in an S3 general purpose bucket") } @@ -328,7 +328,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s pages := s3.NewListObjectVersionsPaginator(conn, input) for pages.HasMorePages() { - page, err := pages.NextPage(ctx) + page, err := pages.NextPage(ctx, optFns...) if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket) { break @@ -346,7 +346,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s continue } - err := deleteObjectVersion(ctx, conn, bucket, objectKey, objectVersionID, force) + err := deleteObjectVersion(ctx, conn, bucket, objectKey, objectVersionID, force, optFns...) if err == nil { nObjects++ @@ -360,7 +360,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s VersionId: aws.String(objectVersionID), } - output, err := conn.HeadObject(ctx, input) + output, err := conn.HeadObject(ctx, input, optFns...) if err != nil { log.Printf("[ERROR] Getting S3 Bucket (%s) Object (%s) Version (%s) metadata: %s", bucket, objectKey, objectVersionID, err) @@ -378,7 +378,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s VersionId: aws.String(objectVersionID), } - _, err := conn.PutObjectLegalHold(ctx, input) + _, err := conn.PutObjectLegalHold(ctx, input, optFns...) if err != nil { log.Printf("[ERROR] Putting S3 Bucket (%s) Object (%s) Version(%s) legal hold: %s", bucket, objectKey, objectVersionID, err) @@ -387,7 +387,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s } // Attempt to delete again. - err = deleteObjectVersion(ctx, conn, bucket, objectKey, objectVersionID, force) + err = deleteObjectVersion(ctx, conn, bucket, objectKey, objectVersionID, force, optFns...) if err != nil { lastErr = err @@ -419,7 +419,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s pages = s3.NewListObjectVersionsPaginator(conn, input) for pages.HasMorePages() { - page, err := pages.NextPage(ctx) + page, err := pages.NextPage(ctx, optFns...) if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket) { break @@ -438,7 +438,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s } // Delete markers have no object lock protections. - err := deleteObjectVersion(ctx, conn, bucket, deleteMarkerKey, deleteMarkerVersionID, false) + err := deleteObjectVersion(ctx, conn, bucket, deleteMarkerKey, deleteMarkerVersionID, false, optFns...) if err != nil { lastErr = err @@ -459,7 +459,7 @@ func deleteAllObjectVersions(ctx context.Context, conn *s3.Client, bucket, key s // deleteObjectVersion deletes a specific object version. // Set `force` to `true` to override any S3 object lock protections. -func deleteObjectVersion(ctx context.Context, conn *s3.Client, b, k, v string, force bool) error { +func deleteObjectVersion(ctx context.Context, conn *s3.Client, b, k, v string, force bool, optFns ...func(*s3.Options)) error { input := &s3.DeleteObjectInput{ Bucket: aws.String(b), Key: aws.String(k), @@ -473,7 +473,7 @@ func deleteObjectVersion(ctx context.Context, conn *s3.Client, b, k, v string, f } log.Printf("[INFO] Deleting S3 Bucket (%s) Object (%s) Version (%s)", b, k, v) - _, err := conn.DeleteObject(ctx, input) + _, err := conn.DeleteObject(ctx, input, optFns...) if err != nil { log.Printf("[WARN] Deleting S3 Bucket (%s) Object (%s) Version (%s): %s", b, k, v, err) diff --git a/internal/service/s3/directory_bucket.go b/internal/service/s3/directory_bucket.go index a1485758423..1b37ed97ab3 100644 --- a/internal/service/s3/directory_bucket.go +++ b/internal/service/s3/directory_bucket.go @@ -33,6 +33,10 @@ var ( directoryBucketNameRegex = regexache.MustCompile(`^([0-9a-z.-]+)--([a-z]+\d+-az\d+)--x-s3$`) ) +func isDirectoryBucket(bucket string) bool { + return directoryBucketNameRegex.MatchString(bucket) +} + // @FrameworkResource(name="Directory Bucket") func newDirectoryBucketResource(context.Context) (resource.ResourceWithConfigure, error) { r := &directoryBucketResource{} @@ -139,7 +143,7 @@ func (r *directoryBucketResource) Create(ctx context.Context, request resource.C return } - conn := r.Meta().S3Client(ctx) + conn := r.Meta().S3ExpressClient(ctx) input := &s3.CreateBucketInput{ Bucket: flex.StringFromFramework(ctx, data.Bucket), @@ -155,7 +159,7 @@ func (r *directoryBucketResource) Create(ctx context.Context, request resource.C }, } - _, err := conn.CreateBucket(ctx, input, useRegionalEndpointInUSEast1) + _, err := conn.CreateBucket(ctx, input) if err != nil { response.Diagnostics.AddError(fmt.Sprintf("creating S3 Directory Bucket (%s)", data.Bucket.ValueString()), err.Error()) @@ -185,9 +189,9 @@ func (r *directoryBucketResource) Read(ctx context.Context, request resource.Rea return } - conn := r.Meta().S3Client(ctx) + conn := r.Meta().S3ExpressClient(ctx) - err := findBucket(ctx, conn, data.Bucket.ValueString(), useRegionalEndpointInUSEast1) + err := findBucket(ctx, conn, data.Bucket.ValueString()) if tfresource.NotFound(err) { response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) @@ -245,11 +249,11 @@ func (r *directoryBucketResource) Delete(ctx context.Context, request resource.D return } - conn := r.Meta().S3Client(ctx) + conn := r.Meta().S3ExpressClient(ctx) _, err := conn.DeleteBucket(ctx, &s3.DeleteBucketInput{ Bucket: flex.StringFromFramework(ctx, data.ID), - }, useRegionalEndpointInUSEast1) + }) if tfawserr.ErrCodeEquals(err, errCodeBucketNotEmpty) { if data.ForceDestroy.ValueBool() { diff --git a/internal/service/s3/directory_bucket_test.go b/internal/service/s3/directory_bucket_test.go index a8a3cc53cb0..3f6085dddc9 100644 --- a/internal/service/s3/directory_bucket_test.go +++ b/internal/service/s3/directory_bucket_test.go @@ -99,7 +99,7 @@ func TestAccS3DirectoryBucket_forceDestroy(t *testing.T) { func testAccCheckDirectoryBucketDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_s3_directory_bucket" { @@ -130,7 +130,7 @@ func testAccCheckDirectoryBucketExists(ctx context.Context, n string) resource.T return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) return tfs3.FindBucket(ctx, conn, rs.Primary.ID) } diff --git a/internal/service/s3/directory_buckets_data_source.go b/internal/service/s3/directory_buckets_data_source.go index 67d408d919d..fbb819a6538 100644 --- a/internal/service/s3/directory_buckets_data_source.go +++ b/internal/service/s3/directory_buckets_data_source.go @@ -58,7 +58,7 @@ func (d *directoryBucketsDataSource) Read(ctx context.Context, request datasourc return } - conn := d.Meta().S3Client(ctx) + conn := d.Meta().S3ExpressClient(ctx) input := &s3.ListDirectoryBucketsInput{} var buckets []string diff --git a/internal/service/s3/exports_test.go b/internal/service/s3/exports_test.go index a8073d65d0d..952663c63fb 100644 --- a/internal/service/s3/exports_test.go +++ b/internal/service/s3/exports_test.go @@ -30,6 +30,7 @@ var ( FindPublicAccessBlockConfiguration = findPublicAccessBlockConfiguration FindReplicationConfiguration = findReplicationConfiguration FindServerSideEncryptionConfiguration = findServerSideEncryptionConfiguration + IsDirectoryBucket = isDirectoryBucket SDKv1CompatibleCleanKey = sdkv1CompatibleCleanKey ErrCodeNoSuchCORSConfiguration = errCodeNoSuchCORSConfiguration diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index b1a88a4f998..c3723f0e8ca 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -17,6 +17,7 @@ import ( "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" @@ -252,10 +253,18 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, meta inte func resourceObjectRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) - output, err := findObjectByBucketAndKey(ctx, conn, bucket, key, "", d.Get("checksum_algorithm").(string)) + output, err := findObjectByBucketAndKey(ctx, conn, bucket, key, "", d.Get("checksum_algorithm").(string), optFns...) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] S3 Object (%s) not found, removing from state", d.Id()) @@ -293,11 +302,11 @@ func resourceObjectRead(ctx context.Context, d *schema.ResourceData, meta interf d.Set("version_id", output.VersionId) d.Set("website_redirect", output.WebsiteRedirectLocation) - if err := resourceObjectSetKMS(ctx, d, meta, output.SSEKMSKeyId); err != nil { + if err := resourceObjectSetKMS(ctx, meta, d, aws.ToString(output.SSEKMSKeyId)); err != nil { return sdkdiag.AppendFromErr(diags, err) } - if tags, err := ObjectListTags(ctx, conn, bucket, key); err == nil { + if tags, err := ObjectListTags(ctx, conn, bucket, key, optFns...); err == nil { setTagsOut(ctx, Tags(tags)) } else if !tfawserr.ErrHTTPStatusCodeEquals(err, http.StatusNotImplemented) { // Directory buckets return HTTP status code 501, NotImplemented. return sdkdiag.AppendErrorf(diags, "listing tags for S3 Bucket (%s) Object (%s): %s", bucket, key, err) @@ -313,8 +322,16 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte } conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) if d.HasChange("acl") { @@ -324,7 +341,7 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte Key: aws.String(key), } - _, err := conn.PutObjectAcl(ctx, input) + _, err := conn.PutObjectAcl(ctx, input, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "putting S3 Object (%s) ACL: %s", d.Id(), err) @@ -340,7 +357,7 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte }, } - _, err := conn.PutObjectLegalHold(ctx, input) + _, err := conn.PutObjectLegalHold(ctx, input, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "putting S3 Object (%s) legal hold: %s", d.Id(), err) @@ -367,7 +384,7 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte } } - _, err := conn.PutObjectRetention(ctx, input) + _, err := conn.PutObjectRetention(ctx, input, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "putting S3 Object (%s) retention: %s", d.Id(), err) @@ -377,7 +394,7 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte if d.HasChange("tags_all") { o, n := d.GetChange("tags_all") - if err := ObjectUpdateTags(ctx, conn, bucket, key, o, n); err != nil { + if err := ObjectUpdateTags(ctx, conn, bucket, key, o, n, optFns...); err != nil { return sdkdiag.AppendErrorf(diags, "updating tags: %s", err) } } @@ -388,15 +405,23 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, meta inte func resourceObjectDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) var err error if _, ok := d.GetOk("version_id"); ok { - _, err = deleteAllObjectVersions(ctx, conn, bucket, key, d.Get("force_destroy").(bool), false) + _, err = deleteAllObjectVersions(ctx, conn, bucket, key, d.Get("force_destroy").(bool), false, optFns...) } else { - err = deleteObjectVersion(ctx, conn, bucket, key, "", false) + err = deleteObjectVersion(ctx, conn, bucket, key, "", false, optFns...) } if err != nil { @@ -428,10 +453,19 @@ func resourceObjectImport(ctx context.Context, d *schema.ResourceData, meta inte func resourceObjectUpload(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) - uploader := manager.NewUploader(conn) + var optFns []func(*s3.Options) defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig - tags := tftags.New(ctx, d.Get("tags").(map[string]interface{})) + bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } + + tags := tftags.New(ctx, d.Get("tags").(map[string]interface{})) if ignoreProviderDefaultTags(ctx, d) { tags = tags.RemoveDefaultConfig(defaultTagsConfig) } else { @@ -476,7 +510,7 @@ func resourceObjectUpload(ctx context.Context, d *schema.ResourceData, meta inte input := &s3.PutObjectInput{ Body: body, - Bucket: aws.String(d.Get("bucket").(string)), + Bucket: aws.String(bucket), Key: aws.String(sdkv1CompatibleCleanKey(d.Get("key").(string))), } @@ -556,6 +590,8 @@ func resourceObjectUpload(ctx context.Context, d *schema.ResourceData, meta inte input.ChecksumAlgorithm = types.ChecksumAlgorithmCrc32 } + uploader := manager.NewUploader(conn, manager.WithUploaderRequestOptions(optFns...)) + if _, err := uploader.Upload(ctx, input); err != nil { return sdkdiag.AppendErrorf(diags, "uploading S3 Object (%s) to Bucket (%s): %s", aws.ToString(input.Key), aws.ToString(input.Bucket), err) } @@ -567,19 +603,19 @@ func resourceObjectUpload(ctx context.Context, d *schema.ResourceData, meta inte return append(diags, resourceObjectRead(ctx, d, meta)...) } -func resourceObjectSetKMS(ctx context.Context, d *schema.ResourceData, meta interface{}, sseKMSKeyId *string) error { - // Only set non-default KMS key ID (one that doesn't match default) - if sseKMSKeyId != nil { - // retrieve S3 KMS Default Master Key - conn := meta.(*conns.AWSClient).KMSConn(ctx) - keyMetadata, err := kms.FindKeyByID(ctx, conn, DefaultKMSKeyAlias) +func resourceObjectSetKMS(ctx context.Context, meta interface{}, d *schema.ResourceData, sseKMSKeyID string) error { + // Only set non-default KMS key ID (one that doesn't match default). + if sseKMSKeyID != "" { + // Read S3 KMS default master key. + keyMetadata, err := kms.FindKeyByID(ctx, meta.(*conns.AWSClient).KMSConn(ctx), DefaultKMSKeyAlias) + if err != nil { - return fmt.Errorf("Failed to describe default S3 KMS key (%s): %s", DefaultKMSKeyAlias, err) + return fmt.Errorf("reading default S3 KMS key (%s): %s", DefaultKMSKeyAlias, err) } - if kmsKeyID := aws.ToString(sseKMSKeyId); kmsKeyID != aws.ToString(keyMetadata.Arn) { - log.Printf("[DEBUG] S3 object is encrypted using a non-default KMS Key ID: %s", kmsKeyID) - d.Set("kms_key_id", sseKMSKeyId) + if sseKMSKeyID != aws.ToString(keyMetadata.Arn) { + log.Printf("[DEBUG] S3 object is encrypted using a non-default KMS key: %s", sseKMSKeyID) + d.Set("kms_key_id", sseKMSKeyID) } } @@ -638,7 +674,7 @@ func hasObjectContentChanges(d verify.ResourceDiffer) bool { return false } -func findObjectByBucketAndKey(ctx context.Context, conn *s3.Client, bucket, key, etag, checksumAlgorithm string) (*s3.HeadObjectOutput, error) { +func findObjectByBucketAndKey(ctx context.Context, conn *s3.Client, bucket, key, etag, checksumAlgorithm string, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error) { input := &s3.HeadObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), @@ -650,11 +686,11 @@ func findObjectByBucketAndKey(ctx context.Context, conn *s3.Client, bucket, key, input.IfMatch = aws.String(etag) } - return findObject(ctx, conn, input) + return findObject(ctx, conn, input, optFns...) } -func findObject(ctx context.Context, conn *s3.Client, input *s3.HeadObjectInput) (*s3.HeadObjectOutput, error) { - output, err := conn.HeadObject(ctx, input) +func findObject(ctx context.Context, conn *s3.Client, input *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error) { + output, err := conn.HeadObject(ctx, input, optFns...) if tfawserr.ErrHTTPStatusCodeEquals(err, http.StatusNotFound) { return nil, &retry.NotFoundError{ diff --git a/internal/service/s3/object_copy.go b/internal/service/s3/object_copy.go index 4e5e2f99b0b..d9f6efc2739 100644 --- a/internal/service/s3/object_copy.go +++ b/internal/service/s3/object_copy.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "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" @@ -332,10 +333,18 @@ func resourceObjectCopyCreate(ctx context.Context, d *schema.ResourceData, meta func resourceObjectCopyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) - output, err := findObjectByBucketAndKey(ctx, conn, bucket, key, "", d.Get("checksum_algorithm").(string)) + output, err := findObjectByBucketAndKey(ctx, conn, bucket, key, "", d.Get("checksum_algorithm").(string), optFns...) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] S3 Object (%s) not found, removing from state", d.Id()) @@ -378,11 +387,11 @@ func resourceObjectCopyRead(ctx context.Context, d *schema.ResourceData, meta in d.Set("version_id", output.VersionId) d.Set("website_redirect", output.WebsiteRedirectLocation) - if err := resourceObjectSetKMS(ctx, d, meta, output.SSEKMSKeyId); err != nil { + if err := resourceObjectSetKMS(ctx, meta, d, aws.ToString(output.SSEKMSKeyId)); err != nil { return sdkdiag.AppendFromErr(diags, err) } - if tags, err := ObjectListTags(ctx, conn, bucket, key); err == nil { + if tags, err := ObjectListTags(ctx, conn, bucket, key, optFns...); err == nil { setTagsOut(ctx, Tags(tags)) } else if !tfawserr.ErrHTTPStatusCodeEquals(err, http.StatusNotImplemented) { // Directory buckets return HTTP status code 501, NotImplemented. return sdkdiag.AppendErrorf(diags, "listing tags for S3 Bucket (%s) Object (%s): %s", bucket, key, err) @@ -453,15 +462,23 @@ func resourceObjectCopyUpdate(ctx context.Context, d *schema.ResourceData, meta func resourceObjectCopyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) var err error if _, ok := d.GetOk("version_id"); ok { - _, err = deleteAllObjectVersions(ctx, conn, bucket, key, d.Get("force_destroy").(bool), false) + _, err = deleteAllObjectVersions(ctx, conn, bucket, key, d.Get("force_destroy").(bool), false, optFns...) } else { - err = deleteObjectVersion(ctx, conn, bucket, key, "", false) + err = deleteObjectVersion(ctx, conn, bucket, key, "", false, optFns...) } if err != nil { @@ -473,11 +490,21 @@ func resourceObjectCopyDelete(ctx context.Context, d *schema.ResourceData, meta func resourceObjectCopyDoCopy(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + + bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } tags := defaultTagsConfig.MergeTags(tftags.New(ctx, d.Get("tags").(map[string]interface{}))) input := &s3.CopyObjectInput{ - Bucket: aws.String(d.Get("bucket").(string)), + Bucket: aws.String(bucket), CopySource: aws.String(url.QueryEscape(d.Get("source").(string))), Key: aws.String(sdkv1CompatibleCleanKey(d.Get("key").(string))), } @@ -629,7 +656,7 @@ func resourceObjectCopyDoCopy(ctx context.Context, d *schema.ResourceData, meta input.WebsiteRedirectLocation = aws.String(v.(string)) } - output, err := conn.CopyObject(ctx, input) + output, err := conn.CopyObject(ctx, input, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "copying %s to S3 Bucket (%s) Object (%s): %s", aws.ToString(input.CopySource), aws.ToString(input.Bucket), aws.ToString(input.Key), err) diff --git a/internal/service/s3/object_copy_test.go b/internal/service/s3/object_copy_test.go index c5f6a225fe2..4c466dfe788 100644 --- a/internal/service/s3/object_copy_test.go +++ b/internal/service/s3/object_copy_test.go @@ -8,6 +8,8 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/service/s3" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -447,9 +449,7 @@ func TestAccS3ObjectCopy_directoryBucket(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - // FIXME "Error running post-test destroy, there may be dangling resources: operation error S3: HeadObject, https response error StatusCode: 403, RequestID: 0033eada6b00018c1826f0b80509eee5684ca4b6, HostID: T7lA2Yxglq, api error Forbidden: Forbidden" - // CheckDestroy: testAccCheckObjectCopyDestroy(ctx), - CheckDestroy: acctest.CheckDestroyNoop, + CheckDestroy: testAccCheckObjectCopyDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccObjectCopyConfig_directoryBucket(rName1, sourceKey, rName2, targetKey), @@ -509,16 +509,98 @@ func TestAccS3ObjectCopy_directoryBucket(t *testing.T) { }) } +func TestAccS3ObjectCopy_basicViaAccessPoint(t *testing.T) { + ctx := acctest.Context(t) + rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_object_copy.test" + sourceName := "aws_s3_object.source" + sourceKey := "source" + targetKey := "target" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckObjectCopyDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccObjectCopyConfig_basicViaAccessPoint(rName1, sourceKey, rName2, targetKey), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckObjectCopyExists(ctx, resourceName), + resource.TestCheckNoResourceAttr(resourceName, "acl"), + resource.TestCheckResourceAttrSet(resourceName, "bucket"), + resource.TestCheckResourceAttr(resourceName, "bucket_key_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "cache_control", ""), + resource.TestCheckNoResourceAttr(resourceName, "checksum_algorithm"), + resource.TestCheckResourceAttr(resourceName, "checksum_crc32", ""), + resource.TestCheckResourceAttr(resourceName, "checksum_crc32c", ""), + resource.TestCheckResourceAttr(resourceName, "checksum_sha1", ""), + resource.TestCheckResourceAttr(resourceName, "checksum_sha256", ""), + resource.TestCheckResourceAttr(resourceName, "content_disposition", ""), + resource.TestCheckResourceAttr(resourceName, "content_encoding", ""), + resource.TestCheckResourceAttr(resourceName, "content_language", ""), + resource.TestCheckResourceAttr(resourceName, "content_type", "application/octet-stream"), + resource.TestCheckNoResourceAttr(resourceName, "copy_if_match"), + resource.TestCheckNoResourceAttr(resourceName, "copy_if_modified_since"), + resource.TestCheckNoResourceAttr(resourceName, "copy_if_none_match"), + resource.TestCheckNoResourceAttr(resourceName, "copy_if_unmodified_since"), + resource.TestCheckResourceAttr(resourceName, "customer_algorithm", ""), + resource.TestCheckNoResourceAttr(resourceName, "customer_key"), + resource.TestCheckResourceAttr(resourceName, "customer_key_md5", ""), + resource.TestCheckResourceAttrPair(resourceName, "etag", sourceName, "etag"), + resource.TestCheckNoResourceAttr(resourceName, "expected_bucket_owner"), + resource.TestCheckNoResourceAttr(resourceName, "expected_source_bucket_owner"), + resource.TestCheckResourceAttr(resourceName, "expiration", ""), + resource.TestCheckNoResourceAttr(resourceName, "expires"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), + resource.TestCheckResourceAttr(resourceName, "grant.#", "0"), + resource.TestCheckResourceAttr(resourceName, "key", targetKey), + resource.TestCheckResourceAttr(resourceName, "kms_encryption_context", ""), + resource.TestCheckResourceAttr(resourceName, "kms_key_id", ""), + resource.TestCheckResourceAttrSet(resourceName, "last_modified"), + resource.TestCheckResourceAttr(resourceName, "metadata.%", "0"), + resource.TestCheckNoResourceAttr(resourceName, "metadata_directive"), + resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), + resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), + resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), + resource.TestCheckResourceAttr(resourceName, "request_charged", "false"), + resource.TestCheckNoResourceAttr(resourceName, "request_payer"), + resource.TestCheckResourceAttr(resourceName, "server_side_encryption", "AES256"), + resource.TestCheckResourceAttrSet(resourceName, "source"), + resource.TestCheckNoResourceAttr(resourceName, "source_customer_algorithm"), + resource.TestCheckNoResourceAttr(resourceName, "source_customer_key"), + resource.TestCheckNoResourceAttr(resourceName, "source_customer_key_md5"), + resource.TestCheckResourceAttrSet(resourceName, "source_version_id"), + resource.TestCheckResourceAttr(resourceName, "storage_class", "STANDARD"), + resource.TestCheckNoResourceAttr(resourceName, "tagging_directive"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "version_id"), + resource.TestCheckResourceAttr(resourceName, "website_redirect", ""), + ), + }, + }, + }) +} + func testAccCheckObjectCopyDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) - for _, rs := range s.RootModule().Resources { if rs.Type != "aws_s3_object_copy" { continue } - _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], "") + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } + + _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], "", optFns...) if tfresource.NotFound(err) { continue @@ -543,8 +625,16 @@ func testAccCheckObjectCopyExists(ctx context.Context, n string) resource.TestCh } conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } - _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], "") + _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], "", optFns...) return err } @@ -816,3 +906,55 @@ resource "aws_s3_object_copy" "test" { } `, sourceBucket, sourceKey, targetBucket, targetKey)) } + +func testAccObjectCopyConfig_basicViaAccessPoint(sourceBucket, sourceKey, targetBucket, targetKey string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "source" { + bucket = %[1]q + + force_destroy = true +} + +resource "aws_s3_bucket_versioning" "source" { + bucket = aws_s3_bucket.source.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_access_point" "source" { + # Must have bucket versioning enabled first + bucket = aws_s3_bucket_versioning.source.bucket + name = %[1]q +} + +resource "aws_s3_bucket" "target" { + bucket = %[3]q +} + +resource "aws_s3_bucket_versioning" "target" { + bucket = aws_s3_bucket.target.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_access_point" "target" { + # Must have bucket versioning enabled first + bucket = aws_s3_bucket_versioning.target.bucket + name = %[3]q +} + +resource "aws_s3_object" "source" { + bucket = aws_s3_bucket.source.bucket + key = %[2]q + content = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +} + +resource "aws_s3_object_copy" "test" { + bucket = aws_s3_access_point.target.arn + key = %[4]q + source = "${aws_s3_access_point.source.arn}/object/${aws_s3_object.source.key}" +} +`, sourceBucket, sourceKey, targetBucket, targetKey) +} diff --git a/internal/service/s3/object_data_source.go b/internal/service/s3/object_data_source.go index 7d1830a703d..0b227821466 100644 --- a/internal/service/s3/object_data_source.go +++ b/internal/service/s3/object_data_source.go @@ -12,6 +12,7 @@ import ( "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" @@ -22,6 +23,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/names" ) // @SDKDataSource("aws_s3_object") @@ -157,9 +159,17 @@ func DataSourceObject() *schema.Resource { func dataSourceObjectRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } key := sdkv1CompatibleCleanKey(d.Get("key").(string)) input := &s3.HeadObjectInput{ Bucket: aws.String(bucket), @@ -175,7 +185,7 @@ func dataSourceObjectRead(ctx context.Context, d *schema.ResourceData, meta inte input.VersionId = aws.String(v.(string)) } - output, err := findObject(ctx, conn, input) + output, err := findObject(ctx, conn, input, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "reading S3 Bucket (%s) Object (%s): %s", bucket, key, err) @@ -231,7 +241,7 @@ func dataSourceObjectRead(ctx context.Context, d *schema.ResourceData, meta inte d.Set("website_redirect_location", output.WebsiteRedirectLocation) if isContentTypeAllowed(output.ContentType) { - downloader := manager.NewDownloader(conn) + downloader := manager.NewDownloader(conn, manager.WithDownloaderClientOptions(optFns...)) buf := manager.NewWriteAtBuffer(make([]byte, 0)) input := &s3.GetObjectInput{ Bucket: aws.String(bucket), @@ -251,7 +261,7 @@ func dataSourceObjectRead(ctx context.Context, d *schema.ResourceData, meta inte d.Set("body", string(buf.Bytes())) } - if tags, err := ObjectListTags(ctx, conn, bucket, key); err == nil { + if tags, err := ObjectListTags(ctx, conn, bucket, key, optFns...); err == nil { if err := d.Set("tags", tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return sdkdiag.AppendErrorf(diags, "setting tags: %s", err) } diff --git a/internal/service/s3/object_test.go b/internal/service/s3/object_test.go index f1b8c0bebb0..96a0f905192 100644 --- a/internal/service/s3/object_test.go +++ b/internal/service/s3/object_test.go @@ -15,6 +15,7 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/google/go-cmp/cmp" @@ -1709,9 +1710,7 @@ func TestAccS3Object_directoryBucket(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - // FIXME "Error running post-test destroy, there may be dangling resources: operation error S3: HeadObject, https response error StatusCode: 403, RequestID: 0033eada6b00018c1804fda905093646dd76f12a, HostID: SfKUL8OB, api error Forbidden: Forbidden" - // CheckDestroy: testAccCheckObjectDestroy(ctx), - CheckDestroy: acctest.CheckDestroyNoop, + CheckDestroy: testAccCheckObjectDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccObjectConfig_directoryBucket(rName), @@ -1782,9 +1781,7 @@ func TestAccS3Object_DirectoryBucket_disappears(t *testing.T) { // nosemgrep:ci. PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - // FIXME "Error running post-test destroy, there may be dangling resources: operation error S3: HeadObject, https response error StatusCode: 403, RequestID: 0033eada6b00018c1804fda905093646dd76f12a, HostID: SfKUL8OB, api error Forbidden: Forbidden" - // CheckDestroy: testAccCheckObjectDestroy(ctx), - CheckDestroy: acctest.CheckDestroyNoop, + CheckDestroy: testAccCheckObjectDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccObjectConfig_directoryBucket(rName), @@ -1845,14 +1842,22 @@ func testAccCheckObjectVersionIDEquals(first, second *s3.GetObjectOutput) resour func testAccCheckObjectDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) - for _, rs := range s.RootModule().Resources { if rs.Type != "aws_s3_object" { continue } - _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], rs.Primary.Attributes["checksum_algorithm"]) + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } + + _, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), rs.Primary.Attributes["etag"], rs.Primary.Attributes["checksum_algorithm"], optFns...) if tfresource.NotFound(err) { continue @@ -1877,6 +1882,14 @@ func testAccCheckObjectExists(ctx context.Context, n string, v *s3.GetObjectOutp } conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } input := &s3.GetObjectInput{ Bucket: aws.String(rs.Primary.Attributes["bucket"]), @@ -1884,7 +1897,7 @@ func testAccCheckObjectExists(ctx context.Context, n string, v *s3.GetObjectOutp IfMatch: aws.String(rs.Primary.Attributes["etag"]), } - output, err := conn.GetObject(ctx, input) + output, err := conn.GetObject(ctx, input, optFns...) if err != nil { return err @@ -1915,12 +1928,23 @@ func testAccCheckObjectBody(obj *s3.GetObjectOutput, want string) resource.TestC func testAccCheckObjectACL(ctx context.Context, n string, want []string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } - output, err := conn.GetObjectAcl(ctx, &s3.GetObjectAclInput{ + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } + + input := &s3.GetObjectAclInput{ Bucket: aws.String(rs.Primary.Attributes["bucket"]), Key: aws.String(tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"])), - }) + } + + output, err := conn.GetObjectAcl(ctx, input, optFns...) if err != nil { return err @@ -1943,9 +1967,18 @@ func testAccCheckObjectACL(ctx context.Context, n string, want []string) resourc func testAccCheckObjectStorageClass(ctx context.Context, n, want string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } - output, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), "", "") + output, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), "", "", optFns...) if err != nil { return err @@ -1969,9 +2002,18 @@ func testAccCheckObjectStorageClass(ctx context.Context, n, want string) resourc func testAccCheckObjectSSE(ctx context.Context, n, want string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } - output, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), "", "") + output, err := tfs3.FindObjectByBucketAndKey(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), "", "", optFns...) if err != nil { return err @@ -2004,18 +2046,36 @@ func testAccObjectCreateTempFile(t *testing.T, data string) string { func testAccCheckObjectUpdateTags(ctx context.Context, n string, oldTags, newTags map[string]string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } - return tfs3.ObjectUpdateTags(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), oldTags, newTags) + return tfs3.ObjectUpdateTags(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), oldTags, newTags, optFns...) } } func testAccCheckObjectCheckTags(ctx context.Context, n string, expectedTags map[string]string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Client(ctx) + if tfs3.IsDirectoryBucket(rs.Primary.Attributes["bucket"]) { + conn = acctest.Provider.Meta().(*conns.AWSClient).S3ExpressClient(ctx) + } + + var optFns []func(*s3.Options) + if arn.IsARN(rs.Primary.Attributes["bucket"]) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } - got, err := tfs3.ObjectListTags(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"])) + got, err := tfs3.ObjectListTags(ctx, conn, rs.Primary.Attributes["bucket"], tfs3.SDKv1CompatibleCleanKey(rs.Primary.Attributes["key"]), optFns...) if err != nil { return err } diff --git a/internal/service/s3/objects_data_source.go b/internal/service/s3/objects_data_source.go index 785bad66955..357cb9c9856 100644 --- a/internal/service/s3/objects_data_source.go +++ b/internal/service/s3/objects_data_source.go @@ -7,6 +7,7 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -14,6 +15,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/names" ) const keyRequestPageSize = 1000 @@ -85,8 +87,16 @@ func DataSourceObjects() *schema.Resource { func dataSourceObjectsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).S3Client(ctx) + var optFns []func(*s3.Options) bucket := d.Get("bucket").(string) + if isDirectoryBucket(bucket) { + conn = meta.(*conns.AWSClient).S3ExpressClient(ctx) + } + // Via S3 access point: "Invalid configuration: region from ARN `us-east-1` does not match client region `aws-global` and UseArnRegion is `false`". + if arn.IsARN(bucket) && conn.Options().Region == names.GlobalRegionID { + optFns = append(optFns, func(o *s3.Options) { o.UseARNRegion = true }) + } input := &s3.ListObjectsV2Input{ Bucket: aws.String(bucket), } @@ -130,7 +140,7 @@ func dataSourceObjectsRead(ctx context.Context, d *schema.ResourceData, meta int pages := s3.NewListObjectsV2Paginator(conn, input) pageLoop: for pages.HasMorePages() { - page, err := pages.NextPage(ctx) + page, err := pages.NextPage(ctx, optFns...) if err != nil { return sdkdiag.AppendErrorf(diags, "listing S3 Bucket (%s) Objects: %s", bucket, err) diff --git a/internal/service/s3/service_package.go b/internal/service/s3/service_package.go index 690936383f2..dc1ec5a6408 100644 --- a/internal/service/s3/service_package.go +++ b/internal/service/s3/service_package.go @@ -68,10 +68,3 @@ func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) ( })) }), nil } - -// Functional options to force the regional endpoint in us-east-1 if the client is configured to use the global endpoint. -func useRegionalEndpointInUSEast1(o *s3_sdkv2.Options) { - if o.Region == names.GlobalRegionID { - o.Region = names.USEast1RegionID - } -} diff --git a/internal/service/s3/sweep.go b/internal/service/s3/sweep.go index 2f88461742c..aacbaa0cacd 100644 --- a/internal/service/s3/sweep.go +++ b/internal/service/s3/sweep.go @@ -96,7 +96,8 @@ func sweepObjects(region string) error { } // Directory buckets. - pages := s3.NewListDirectoryBucketsPaginator(conn, &s3.ListDirectoryBucketsInput{}) + s3ExpressConn := client.S3ExpressClient(ctx) + pages := s3.NewListDirectoryBucketsPaginator(s3ExpressConn, &s3.ListDirectoryBucketsInput{}) for pages.HasMorePages() { page, err := pages.NextPage(ctx) @@ -115,7 +116,7 @@ func sweepObjects(region string) error { } sweepables = append(sweepables, directoryBucketObjectSweeper{ - conn: conn, + conn: s3ExpressConn, bucket: aws.ToString(v.Name), }) } @@ -281,7 +282,7 @@ func sweepDirectoryBuckets(region string) error { if err != nil { return fmt.Errorf("getting client: %s", err) } - conn := client.S3Client(ctx) + conn := client.S3ExpressClient(ctx) input := &s3.ListDirectoryBucketsInput{} sweepResources := make([]sweep.Sweepable, 0) diff --git a/internal/service/s3/tags.go b/internal/service/s3/tags.go index 690521b27fd..8707d4a3ecf 100644 --- a/internal/service/s3/tags.go +++ b/internal/service/s3/tags.go @@ -90,13 +90,13 @@ func BucketUpdateTags(ctx context.Context, conn s3iface_sdkv1.S3API, identifier } // ObjectListTags lists S3 object tags. -func ObjectListTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key string) (tftags.KeyValueTags, error) { +func ObjectListTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key string, optFns ...func(*s3_sdkv2.Options)) (tftags.KeyValueTags, error) { input := &s3_sdkv2.GetObjectTaggingInput{ Bucket: aws_sdkv2.String(bucket), Key: aws_sdkv2.String(key), } - output, err := conn.GetObjectTagging(ctx, input) + output, err := conn.GetObjectTagging(ctx, input, optFns...) if tfawserr_sdkv2.ErrCodeEquals(err, errCodeNoSuchTagSet, errCodeNoSuchTagSetError) { return tftags.New(ctx, nil), nil @@ -110,12 +110,12 @@ func ObjectListTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key stri } // ObjectUpdateTags updates S3 object tags. -func ObjectUpdateTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key string, oldTagsMap, newTagsMap any) error { +func ObjectUpdateTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key string, oldTagsMap, newTagsMap any, optFns ...func(*s3_sdkv2.Options)) error { oldTags := tftags.New(ctx, oldTagsMap) newTags := tftags.New(ctx, newTagsMap) // We need to also consider any existing ignored tags. - allTags, err := ObjectListTags(ctx, conn, bucket, key) + allTags, err := ObjectListTags(ctx, conn, bucket, key, optFns...) if err != nil { return fmt.Errorf("listing resource tags (%s/%s): %w", bucket, key, err) @@ -132,7 +132,7 @@ func ObjectUpdateTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key st }, } - _, err := conn.PutObjectTagging(ctx, input) + _, err := conn.PutObjectTagging(ctx, input, optFns...) if err != nil { return fmt.Errorf("setting resource tags (%s/%s): %w", bucket, key, err) @@ -143,7 +143,7 @@ func ObjectUpdateTags(ctx context.Context, conn *s3_sdkv2.Client, bucket, key st Key: aws_sdkv2.String(key), } - _, err := conn.DeleteObjectTagging(ctx, input) + _, err := conn.DeleteObjectTagging(ctx, input, optFns...) if err != nil { return fmt.Errorf("deleting resource tags (%s/%s): %w", bucket, key, err) diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index b2cab4d50eb..9dc29cb448a 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -68,7 +68,7 @@ which are applied in the following order: 1. Shared credentials files 1. Shared configuration files 1. Container credentials -1. Instance profile credentials and region +1. Instance profile credentials and Region This order matches the precedence used by the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence) @@ -110,7 +110,7 @@ Other settings related to authorization can be configured, such as: ### Environment Variables Credentials can be provided by using the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_SESSION_TOKEN` environment variables. -The region can be set using the `AWS_REGION` or `AWS_DEFAULT_REGION` environment variables. +The Region can be set using the `AWS_REGION` or `AWS_DEFAULT_REGION` environment variables. For example: @@ -160,7 +160,7 @@ If you're running Terraform on CodeBuild or ECS and have configured an [IAM Task If you're running Terraform on EKS and have configured [IAM Roles for Service Accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html), Terraform can use the pod's role. This support is based on the underlying `AWS_ROLE_ARN` and `AWS_WEB_IDENTITY_TOKEN_FILE` environment variables being automatically set by Kubernetes or manually for advanced usage. -### Instance profile credentials and region +### Instance profile credentials and Region When the AWS Provider is running on an EC2 instance with an IAM Instance Profile set, the provider can source credentials from the [EC2 Instance Metadata Service](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials). @@ -336,18 +336,19 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf Can also be set using the `NO_PROXY` or `no_proxy` environment variables. * `profile` - (Optional) AWS profile name as set in the shared configuration and credentials files. Can also be set using either the environment variables `AWS_PROFILE` or `AWS_DEFAULT_PROFILE`. -* `region` - (Optional) AWS region where the provider will operate. The region must be set. +* `region` - (Optional) AWS Region where the provider will operate. The Region must be set. Can also be set with either the `AWS_REGION` or `AWS_DEFAULT_REGION` environment variables, or via a shared config file parameter `region` if `profile` is used. - If credentials are retrieved from the EC2 Instance Metadata Service, the region can also be retrieved from the metadata. + If credentials are retrieved from the EC2 Instance Metadata Service, the Region can also be retrieved from the metadata. * `retry_mode` - (Optional) Specifies how retries are attempted. Valid values are `standard` and `adaptive`. Can also be configured using the `AWS_RETRY_MODE` environment variable or the shared config file parameter `retry_mode`. * `s3_use_path_style` - (Optional) Whether to enable the request to use path-style addressing, i.e., `https://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will use virtual hosted bucket addressing, `https://BUCKET.s3.amazonaws.com/KEY`, when possible. Specific to the Amazon S3 service. -* `s3_us_east_1_regional_endpoint` - (Optional) Specifies whether S3 API calls in the `us-east-1` region use the legacy global endpoint or a regional endpoint. +* `s3_us_east_1_regional_endpoint` - (Optional) Specifies whether S3 API calls in the `us-east-1` Region use the legacy global endpoint or a regional endpoint. Valid values are `legacy` or `regional`. + If omitted, the default behavior in the `us-east-1` Region is to use the global endpoint for general purpose buckets and the regional endpoint for directory buckets. Can also be configured using the `AWS_S3_US_EAST_1_REGIONAL_ENDPOINT` environment variable or the `s3_us_east_1_regional_endpoint` shared config file parameter. Specific to the Amazon S3 service. * `secret_key` - (Optional) AWS secret key. Can also be set with the `AWS_SECRET_ACCESS_KEY` environment variable, or via a shared configuration and credentials files if `profile` is used. See also `access_key`. @@ -355,7 +356,7 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf * `shared_credentials_files` - (Optional) List of paths to the shared credentials file. If not set and a profile is used, the default value is `[~/.aws/credentials]`. A single value can also be set with the `AWS_SHARED_CREDENTIALS_FILE` environment variable. * `skip_credentials_validation` - (Optional) Whether to skip credentials validation via the STS API. This can be useful for testing and for AWS API implementations that do not have STS available. * `skip_metadata_api_check` - (Optional) Whether to skip the AWS Metadata API check. Useful for AWS API implementations that do not have a metadata API endpoint. Setting to `true` prevents Terraform from authenticating via the Metadata API. You may need to use other authentication methods like static credentials, configuration variables, or environment variables. -* `skip_region_validation` - (Optional) Whether to skip validating the region. Useful for AWS-like implementations that use their own region names or to bypass the validation for regions that aren't publicly available yet. +* `skip_region_validation` - (Optional) Whether to skip validating the Region. Useful for AWS-like implementations that use their own Region names or to bypass the validation for Regions that aren't publicly available yet. * `skip_requesting_account_id` - (Optional) Whether to skip requesting the account ID. Useful for AWS API implementations that do not have the IAM, STS API, or metadata API. When set to `true` and not determined previously, returns an empty account ID when manually constructing ARN attributes with the following: - [`aws_api_gateway_deployment` resource](/docs/providers/aws/r/api_gateway_deployment.html) - [`aws_api_gateway_rest_api` resource](/docs/providers/aws/r/api_gateway_rest_api.html) @@ -472,7 +473,7 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf - [`aws_waf_size_constraint_set` resource](/docs/providers/aws/r/waf_size_constraint_set.html) - [`aws_waf_web_acl` resource](/docs/providers/aws/r/waf_web_acl.html) - [`aws_waf_xss_match_set` resource](/docs/providers/aws/r/waf_xss_match_set.html) -* `sts_region` - (Optional) AWS region for STS. If unset, AWS will use the same region for STS as other non-STS operations. +* `sts_region` - (Optional) AWS Region for STS. If unset, AWS will use the same Region for STS as other non-STS operations. * `token` - (Optional) Session token for validating temporary credentials. Typically provided after successful identity federation or Multi-Factor Authentication (MFA) login. With MFA login, this is the session token provided afterward, not the 6 digit MFA code used to get temporary credentials. Can also be set with the `AWS_SESSION_TOKEN` environment variable. * `use_dualstack_endpoint` - (Optional) Force the provider to resolve endpoints with DualStack capability. Can also be set with the `AWS_USE_DUALSTACK_ENDPOINT` environment variable or in a shared config file (`use_dualstack_endpoint`). * `use_fips_endpoint` - (Optional) Force the provider to resolve endpoints with FIPS capability. Can also be set with the `AWS_USE_FIPS_ENDPOINT` environment variable or in a shared config file (`use_fips_endpoint`).