Skip to content

Commit 190d01e

Browse files
authored
Merge pull request #34233 from danielgmyers-figma/allow-endpoints-to-override-fips-flag
Allow custom endpoints to override the use_fips_endpoint flag for individual services.
2 parents 8fe34cf + 5a08e46 commit 190d01e

File tree

471 files changed

+13305
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

471 files changed

+13305
-96
lines changed

.changelog/34233.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
provider: The `use_fips_endpoint` flag is now ignored for any service with a custom endpoint configured in `endpoints`.
3+
```

internal/conns/awsclient.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
opsworks_sdkv1 "github.com/aws/aws-sdk-go/service/opsworks"
2424
rds_sdkv1 "github.com/aws/aws-sdk-go/service/rds"
2525
baselogging "github.com/hashicorp/aws-sdk-go-base/v2/logging"
26+
"github.com/hashicorp/terraform-plugin-log/tflog"
2627
"github.com/hashicorp/terraform-provider-aws/internal/errs"
2728
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
2829
"github.com/hashicorp/terraform-provider-aws/names"
@@ -344,6 +345,8 @@ func resolveServiceBaseEndpoint(ctx context.Context, sdkID string, configs []any
344345
// The default service client (`extra` is empty) is cached. In this case the AWSClient lock is held.
345346
// This function is not a method on `AWSClient` as methods can't be parameterized (https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods).
346347
func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string, extra map[string]any) (T, error) {
348+
ctx = tflog.SetField(ctx, "tf_aws.service_package", servicePackageName)
349+
347350
isDefault := len(extra) == 0
348351
// Default service client is cached.
349352
if isDefault {
@@ -404,6 +407,8 @@ func conn[T any](ctx context.Context, c *AWSClient, servicePackageName string, e
404407
// The default service client (`extra` is empty) is cached. In this case the AWSClient lock is held.
405408
// This function is not a method on `AWSClient` as methods can't be parameterized (https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods).
406409
func client[T any](ctx context.Context, c *AWSClient, servicePackageName string, extra map[string]any) (T, error) {
410+
ctx = tflog.SetField(ctx, "tf_aws.service_package", servicePackageName)
411+
407412
isDefault := len(extra) == 0
408413
// Default service client is cached.
409414
if isDefault {

internal/generate/serviceendpointtests/file.tmpl renamed to internal/generate/serviceendpointtests/file.gtpl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,23 @@ func TestEndpointConfiguration(t *testing.T) { //nolint:paralleltest // uses t.S
449449
},
450450
expected: expectBaseConfigFileEndpoint(),
451451
},
452+
453+
// Use FIPS endpoint on Config
454+
455+
"use fips config": {
456+
with: []setupFunc{
457+
withUseFIPSInConfig,
458+
},
459+
expected: expectDefaultFIPSEndpoint(region),
460+
},
461+
462+
"use fips config with package name endpoint config": {
463+
with: []setupFunc{
464+
withUseFIPSInConfig,
465+
withPackageNameEndpointInConfig,
466+
},
467+
expected: expectPackageNameConfigEndpoint(),
468+
},
452469
}
453470

454471
{{ if and (ne .GoV1Package "") (ne .GoV2Package "") }}
@@ -521,6 +538,44 @@ func defaultEndpoint(region string) string {
521538
{{ end -}}
522539
}
523540

541+
func defaultFIPSEndpoint(region string) string {
542+
{{- if ne .GoV2Package "" }}
543+
r := {{ .GoV2Package }}_sdkv2.NewDefaultEndpointResolverV2()
544+
545+
ep, err := r.ResolveEndpoint(context.Background(), {{ .GoV2Package }}_sdkv2.EndpointParameters{
546+
Region: aws_sdkv2.String(region),
547+
UseFIPS: aws_sdkv2.Bool(true),
548+
})
549+
if err != nil {
550+
return err.Error()
551+
}
552+
553+
if ep.URI.Path == "" {
554+
ep.URI.Path = "/"
555+
}
556+
557+
return ep.URI.String()
558+
{{ else }}
559+
r := endpoints.DefaultResolver()
560+
561+
ep, err := r.EndpointFor({{ .GoV1Package }}_sdkv1.EndpointsID, region, func(opt *endpoints.Options) {
562+
{{- if .V1NameResolverNeedsUnknownService }}opt.ResolveUnknownService = true{{ end }}
563+
opt.UseFIPSEndpoint = endpoints.FIPSEndpointStateEnabled
564+
})
565+
if err != nil {
566+
return err.Error()
567+
}
568+
569+
url, _ := url.Parse(ep.URL)
570+
571+
if url.Path == "" {
572+
url.Path = "/"
573+
}
574+
575+
return url.String()
576+
{{ end -}}
577+
}
578+
524579
{{ if ne .GoV2Package "" }}
525580
func callService{{ if ne .GoV1Package "" }}V2{{ end }}(ctx context.Context, t *testing.T, meta *conns.AWSClient) string {
526581
t.Helper()
@@ -637,12 +692,22 @@ func withBaseEndpointInConfigFile(setup *caseSetup) {
637692
setup.configFile.baseUrl = baseConfigFileEndpoint
638693
}
639694

695+
func withUseFIPSInConfig(setup *caseSetup) {
696+
setup.config["use_fips_endpoint"] = true
697+
}
698+
640699
func expectDefaultEndpoint(region string) caseExpectations {
641700
return caseExpectations{
642701
endpoint: defaultEndpoint(region),
643702
}
644703
}
645704

705+
func expectDefaultFIPSEndpoint(region string) caseExpectations {
706+
return caseExpectations{
707+
endpoint: defaultFIPSEndpoint(region),
708+
}
709+
}
710+
646711
func expectPackageNameConfigEndpoint() caseExpectations {
647712
return caseExpectations{
648713
endpoint: packageNameConfigEndpoint,

internal/generate/serviceendpointtests/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,5 @@ type TemplateData struct {
133133
ImportAwsTypes bool
134134
}
135135

136-
//go:embed file.tmpl
136+
//go:embed file.gtpl
137137
var tmpl string

internal/generate/servicepackage/file.tmpl

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ import (
88
{{if not .SkipClientGenerate }}
99
{{- if eq .SDKVersion "1" "1,2" }}
1010
aws_sdkv1 "github.com/aws/aws-sdk-go/aws"
11+
endpoints_sdkv1 "github.com/aws/aws-sdk-go/aws/endpoints"
1112
session_sdkv1 "github.com/aws/aws-sdk-go/aws/session"
1213
{{ .GoV1Package }}_sdkv1 "github.com/aws/aws-sdk-go/service/{{ .GoV1Package }}"
1314
{{- end }}
1415
{{- if eq .SDKVersion "2" "1,2" }}
1516
aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws"
1617
{{ .GoV2Package }}_sdkv2 "github.com/aws/aws-sdk-go-v2/service/{{ .GoV2Package }}"
1718
{{- end }}
19+
{{- if .SDKVersion }}
20+
"github.com/hashicorp/terraform-plugin-log/tflog"
21+
{{- end }}
1822
{{- end }}
1923
"github.com/hashicorp/terraform-provider-aws/internal/conns"
2024
"github.com/hashicorp/terraform-provider-aws/internal/types"
@@ -133,7 +137,21 @@ func (p *servicePackage) ServicePackageName() string {
133137
func (p *servicePackage) NewConn(ctx context.Context, config map[string]any) (*{{ .GoV1Package }}_sdkv1.{{ .GoV1ClientTypeName }}, error) {
134138
sess := config[names.AttrSession].(*session_sdkv1.Session)
135139

136-
return {{ .GoV1Package }}_sdkv1.New(sess.Copy(&aws_sdkv1.Config{Endpoint: aws_sdkv1.String(config[names.AttrEndpoint].(string))})), nil
140+
cfg := aws_sdkv1.Config{}
141+
142+
if endpoint := config[names.AttrEndpoint].(string); endpoint != "" {
143+
tflog.Debug(ctx, "setting endpoint", map[string]any{
144+
"tf_aws.endpoint": endpoint,
145+
})
146+
cfg.Endpoint = aws_sdkv1.String(endpoint)
147+
148+
if sess.Config.UseFIPSEndpoint == endpoints_sdkv1.FIPSEndpointStateEnabled {
149+
tflog.Debug(ctx, "endpoint set, ignoring UseFIPSEndpoint setting")
150+
cfg.UseFIPSEndpoint = endpoints_sdkv1.FIPSEndpointStateDisabled
151+
}
152+
}
153+
154+
return {{ .GoV1Package }}_sdkv1.New(sess.Copy(&cfg)), nil
137155
}
138156
{{- end }}
139157

@@ -144,7 +162,15 @@ func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (
144162

145163
return {{ .GoV2Package }}_sdkv2.NewFromConfig(cfg, func(o *{{ .GoV2Package }}_sdkv2.Options) {
146164
if endpoint := config[names.AttrEndpoint].(string); endpoint != "" {
165+
tflog.Debug(ctx, "setting endpoint", map[string]any{
166+
"tf_aws.endpoint": endpoint,
167+
})
147168
o.BaseEndpoint = aws_sdkv2.String(endpoint)
169+
170+
if (o.EndpointOptions.UseFIPSEndpoint == aws_sdkv2.FIPSEndpointStateEnabled) {
171+
tflog.Debug(ctx, "endpoint set, ignoring UseFIPSEndpoint setting")
172+
o.EndpointOptions.UseFIPSEndpoint = aws_sdkv2.FIPSEndpointStateDisabled
173+
}
148174
}
149175
}), nil
150176
}

internal/provider/provider_acc_test.go

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func TestAccProvider_endpoints(t *testing.T) {
158158
})
159159
}
160160

161-
func TestAccProvider_fipsEndpoint(t *testing.T) {
161+
func TestAccProvider_customEndpoint(t *testing.T) {
162162
ctx := acctest.Context(t)
163163
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
164164
resourceName := "aws_s3_bucket.test"
@@ -170,7 +170,8 @@ func TestAccProvider_fipsEndpoint(t *testing.T) {
170170
CheckDestroy: nil,
171171
Steps: []resource.TestStep{
172172
{
173-
Config: testAccProviderConfig_fipsEndpoint(fmt.Sprintf("https://s3-fips.%s.%s", acctest.Region(), acctest.PartitionDNSSuffix()), rName),
173+
// The fips endpoint is used here just because it's a valid endpoint that isn't the normal endpoint.
174+
Config: testAccProviderConfig_customS3Endpoint(fmt.Sprintf("https://s3-fips.%s.%s", acctest.Region(), acctest.PartitionDNSSuffix()), rName),
174175
Check: resource.ComposeTestCheckFunc(
175176
resource.TestCheckResourceAttr(resourceName, "bucket", rName),
176177
),
@@ -210,6 +211,48 @@ func TestAccProvider_unusualEndpoints(t *testing.T) {
210211
})
211212
}
212213

214+
func TestAccProvider_useFipsEndpointFlag(t *testing.T) {
215+
ctx := acctest.Context(t)
216+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
217+
resourceName := "aws_s3_bucket.test"
218+
219+
resource.ParallelTest(t, resource.TestCase{
220+
PreCheck: func() { acctest.PreCheck(ctx, t) },
221+
ErrorCheck: acctest.ErrorCheck(t),
222+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
223+
CheckDestroy: nil,
224+
Steps: []resource.TestStep{
225+
{
226+
Config: testAccProviderConfig_useFipsEndpointFlag(rName),
227+
Check: resource.ComposeTestCheckFunc(
228+
resource.TestCheckResourceAttr(resourceName, "bucket", rName),
229+
),
230+
},
231+
},
232+
})
233+
}
234+
235+
func TestAccProvider_overrideUseFipsEndpointFlagForOneService(t *testing.T) {
236+
ctx := acctest.Context(t)
237+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
238+
resourceName := "aws_appconfig_application.test"
239+
240+
resource.ParallelTest(t, resource.TestCase{
241+
PreCheck: func() { acctest.PreCheck(ctx, t) },
242+
ErrorCheck: acctest.ErrorCheck(t),
243+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
244+
CheckDestroy: nil,
245+
Steps: []resource.TestStep{
246+
{
247+
Config: testAccProviderConfig_overridesUseFipsEndpointFlagForAppConfig(rName),
248+
Check: resource.ComposeTestCheckFunc(
249+
resource.TestCheckResourceAttr(resourceName, "name", rName),
250+
),
251+
},
252+
},
253+
})
254+
}
255+
213256
func TestAccProvider_IgnoreTags_emptyBlock(t *testing.T) {
214257
ctx := acctest.Context(t)
215258
var provider *schema.Provider
@@ -970,7 +1013,7 @@ provider "aws" {
9701013
`, endpoints))
9711014
}
9721015

973-
func testAccProviderConfig_fipsEndpoint(endpoint, rName string) string {
1016+
func testAccProviderConfig_customS3Endpoint(endpoint, rName string) string {
9741017
//lintignore:AT004
9751018
return acctest.ConfigCompose(testAccProviderConfig_base, fmt.Sprintf(`
9761019
provider "aws" {
@@ -1003,6 +1046,37 @@ provider "aws" {
10031046
`, unusual1.fieldName, unusual1.url, unusual2.fieldName, unusual2.url, unusual3.fieldName, unusual3.url))
10041047
}
10051048

1049+
func testAccProviderConfig_useFipsEndpointFlag(rName string) string {
1050+
//lintignore:AT004
1051+
return acctest.ConfigCompose(testAccProviderConfig_base, fmt.Sprintf(`
1052+
provider "aws" {
1053+
use_fips_endpoint = true
1054+
}
1055+
1056+
resource "aws_s3_bucket" "test" {
1057+
bucket = %[1]q
1058+
force_destroy = true
1059+
}
1060+
`, rName))
1061+
}
1062+
1063+
func testAccProviderConfig_overridesUseFipsEndpointFlagForAppConfig(rName string) string {
1064+
appconfig_endpoint := fmt.Sprintf("https://appconfig.%s.%s", acctest.Region(), acctest.PartitionDNSSuffix())
1065+
//lintignore:AT004
1066+
return acctest.ConfigCompose(testAccProviderConfig_base, fmt.Sprintf(`
1067+
provider "aws" {
1068+
use_fips_endpoint = true
1069+
endpoints {
1070+
appconfig = %[1]q
1071+
}
1072+
}
1073+
1074+
resource "aws_appconfig_application" "test" {
1075+
name = %[2]q
1076+
}
1077+
`, appconfig_endpoint, rName))
1078+
}
1079+
10061080
func testAccProviderConfig_ignoreTagsKeys0() string {
10071081
//lintignore:AT004
10081082
return acctest.ConfigCompose(testAccProviderConfig_base, `

internal/service/accessanalyzer/service_endpoints_gen_test.go

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/service/accessanalyzer/service_package_gen.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)