github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/backend/remote-state/s3/backend_complete_test.go (about) 1 package s3 2 3 import ( 4 "fmt" 5 "os" 6 "regexp" 7 "testing" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/credentials" 11 "github.com/google/go-cmp/cmp" 12 awsbase "github.com/hashicorp/aws-sdk-go-base" 13 mockdata "github.com/hashicorp/aws-sdk-go-base" 14 servicemocks "github.com/hashicorp/aws-sdk-go-base" 15 "github.com/terramate-io/tf/configs/hcl2shim" 16 "github.com/terramate-io/tf/tfdiags" 17 ) 18 19 type DiagsValidator func(*testing.T, tfdiags.Diagnostics) 20 21 func ExpectNoDiags(t *testing.T, diags tfdiags.Diagnostics) { 22 expectDiagsCount(t, diags, 0) 23 } 24 25 func expectDiagsCount(t *testing.T, diags tfdiags.Diagnostics, c int) { 26 if l := len(diags); l != c { 27 t.Fatalf("Diagnostics: expected %d element, got %d\n%#v", c, l, diags) 28 } 29 } 30 31 func ExpectDiagsEqual(expected tfdiags.Diagnostics) DiagsValidator { 32 return func(t *testing.T, diags tfdiags.Diagnostics) { 33 if diff := cmp.Diff(diags, expected, cmp.Comparer(diagnosticComparer)); diff != "" { 34 t.Fatalf("unexpected diagnostics difference: %s", diff) 35 } 36 } 37 } 38 39 // ExpectDiagMatching returns a validator expeceting a single Diagnostic with fields matching the expectation 40 func ExpectDiagMatching(severity tfdiags.Severity, summary matcher, detail matcher) DiagsValidator { 41 return func(t *testing.T, diags tfdiags.Diagnostics) { 42 for _, d := range diags { 43 if !summary.Match(d.Description().Summary) || !detail.Match(d.Description().Detail) { 44 t.Fatalf("expected Diagnostic matching %#v, got %#v", 45 tfdiags.Sourceless( 46 severity, 47 summary.String(), 48 detail.String(), 49 ), 50 d, 51 ) 52 } 53 } 54 55 expectDiagsCount(t, diags, 1) 56 } 57 } 58 59 type matcher interface { 60 fmt.Stringer 61 Match(string) bool 62 } 63 64 type equalsMatcher string 65 66 func (m equalsMatcher) Match(s string) bool { 67 return string(m) == s 68 } 69 70 func (m equalsMatcher) String() string { 71 return string(m) 72 } 73 74 type regexpMatcher struct { 75 re *regexp.Regexp 76 } 77 78 func newRegexpMatcher(re string) regexpMatcher { 79 return regexpMatcher{ 80 re: regexp.MustCompile(re), 81 } 82 } 83 84 func (m regexpMatcher) Match(s string) bool { 85 return m.re.MatchString(s) 86 } 87 88 func (m regexpMatcher) String() string { 89 return m.re.String() 90 } 91 92 func TestBackendConfig_Authentication(t *testing.T) { 93 testCases := map[string]struct { 94 config map[string]any 95 EnableEc2MetadataServer bool 96 EnableEcsCredentialsServer bool 97 EnableWebIdentityEnvVars bool 98 // EnableWebIdentityConfig bool // Not supported 99 EnvironmentVariables map[string]string 100 ExpectedCredentialsValue credentials.Value 101 MockStsEndpoints []*servicemocks.MockEndpoint 102 SharedConfigurationFile string 103 SharedCredentialsFile string 104 ValidateDiags DiagsValidator 105 }{ 106 "empty config": { 107 config: map[string]any{}, 108 ValidateDiags: ExpectDiagMatching( 109 tfdiags.Error, 110 equalsMatcher("Failed to configure AWS client"), 111 newRegexpMatcher("no valid credential sources for S3 Backend found"), 112 ), 113 }, 114 115 "config AccessKey": { 116 config: map[string]any{ 117 "access_key": awsbase.MockStaticAccessKey, 118 "secret_key": servicemocks.MockStaticSecretKey, 119 }, 120 MockStsEndpoints: []*servicemocks.MockEndpoint{ 121 servicemocks.MockStsGetCallerIdentityValidEndpoint, 122 }, 123 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 124 ValidateDiags: ExpectNoDiags, 125 }, 126 127 "config AccessKey config AssumeRoleARN access key": { 128 config: map[string]any{ 129 "access_key": awsbase.MockStaticAccessKey, 130 "secret_key": servicemocks.MockStaticSecretKey, 131 "role_arn": servicemocks.MockStsAssumeRoleArn, 132 "session_name": servicemocks.MockStsAssumeRoleSessionName, 133 }, 134 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 135 MockStsEndpoints: []*servicemocks.MockEndpoint{ 136 servicemocks.MockStsAssumeRoleValidEndpoint, 137 servicemocks.MockStsGetCallerIdentityValidEndpoint, 138 }, 139 }, 140 141 "config AssumeRoleDuration": { 142 config: map[string]any{ 143 "access_key": awsbase.MockStaticAccessKey, 144 "secret_key": servicemocks.MockStaticSecretKey, 145 "role_arn": servicemocks.MockStsAssumeRoleArn, 146 "session_name": servicemocks.MockStsAssumeRoleSessionName, 147 "assume_role_duration_seconds": 3600, 148 }, 149 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 150 MockStsEndpoints: []*servicemocks.MockEndpoint{ 151 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"DurationSeconds": "3600"}), 152 servicemocks.MockStsGetCallerIdentityValidEndpoint, 153 }, 154 }, 155 156 "config AssumeRoleExternalID": { 157 config: map[string]any{ 158 "access_key": awsbase.MockStaticAccessKey, 159 "secret_key": servicemocks.MockStaticSecretKey, 160 "role_arn": servicemocks.MockStsAssumeRoleArn, 161 "session_name": servicemocks.MockStsAssumeRoleSessionName, 162 "external_id": servicemocks.MockStsAssumeRoleExternalId, 163 }, 164 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 165 MockStsEndpoints: []*servicemocks.MockEndpoint{ 166 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"ExternalId": servicemocks.MockStsAssumeRoleExternalId}), 167 servicemocks.MockStsGetCallerIdentityValidEndpoint, 168 }, 169 }, 170 171 "config AssumeRolePolicy": { 172 config: map[string]any{ 173 "access_key": awsbase.MockStaticAccessKey, 174 "secret_key": servicemocks.MockStaticSecretKey, 175 "role_arn": servicemocks.MockStsAssumeRoleArn, 176 "session_name": servicemocks.MockStsAssumeRoleSessionName, 177 "assume_role_policy": servicemocks.MockStsAssumeRolePolicy, 178 }, 179 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 180 MockStsEndpoints: []*servicemocks.MockEndpoint{ 181 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"Policy": servicemocks.MockStsAssumeRolePolicy}), 182 servicemocks.MockStsGetCallerIdentityValidEndpoint, 183 }, 184 }, 185 186 "config AssumeRolePolicyARNs": { 187 config: map[string]any{ 188 "access_key": awsbase.MockStaticAccessKey, 189 "secret_key": servicemocks.MockStaticSecretKey, 190 "role_arn": servicemocks.MockStsAssumeRoleArn, 191 "session_name": servicemocks.MockStsAssumeRoleSessionName, 192 "assume_role_policy_arns": []any{servicemocks.MockStsAssumeRolePolicyArn}, 193 }, 194 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 195 MockStsEndpoints: []*servicemocks.MockEndpoint{ 196 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"PolicyArns.member.1.arn": servicemocks.MockStsAssumeRolePolicyArn}), 197 servicemocks.MockStsGetCallerIdentityValidEndpoint, 198 }, 199 }, 200 201 "config AssumeRoleTags": { 202 config: map[string]any{ 203 "access_key": awsbase.MockStaticAccessKey, 204 "secret_key": servicemocks.MockStaticSecretKey, 205 "role_arn": servicemocks.MockStsAssumeRoleArn, 206 "session_name": servicemocks.MockStsAssumeRoleSessionName, 207 "assume_role_tags": map[string]any{ 208 servicemocks.MockStsAssumeRoleTagKey: servicemocks.MockStsAssumeRoleTagValue, 209 }, 210 }, 211 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 212 MockStsEndpoints: []*servicemocks.MockEndpoint{ 213 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"Tags.member.1.Key": servicemocks.MockStsAssumeRoleTagKey, "Tags.member.1.Value": servicemocks.MockStsAssumeRoleTagValue}), 214 servicemocks.MockStsGetCallerIdentityValidEndpoint, 215 }, 216 }, 217 218 "config AssumeRoleTransitiveTagKeys": { 219 config: map[string]any{ 220 "access_key": awsbase.MockStaticAccessKey, 221 "secret_key": servicemocks.MockStaticSecretKey, 222 "role_arn": servicemocks.MockStsAssumeRoleArn, 223 "session_name": servicemocks.MockStsAssumeRoleSessionName, 224 "assume_role_tags": map[string]any{ 225 servicemocks.MockStsAssumeRoleTagKey: servicemocks.MockStsAssumeRoleTagValue, 226 }, 227 "assume_role_transitive_tag_keys": []any{servicemocks.MockStsAssumeRoleTagKey}, 228 }, 229 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 230 MockStsEndpoints: []*servicemocks.MockEndpoint{ 231 servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"Tags.member.1.Key": servicemocks.MockStsAssumeRoleTagKey, "Tags.member.1.Value": servicemocks.MockStsAssumeRoleTagValue, "TransitiveTagKeys.member.1": servicemocks.MockStsAssumeRoleTagKey}), 232 servicemocks.MockStsGetCallerIdentityValidEndpoint, 233 }, 234 }, 235 236 // NOT SUPPORTED: AssumeRoleSourceIdentity 237 // "config AssumeRoleSourceIdentity": { 238 // config: map[string]any{ 239 // "access_key": awsbase.MockStaticAccessKey, 240 // "secret_key": servicemocks.MockStaticSecretKey, 241 // "role_arn": servicemocks.MockStsAssumeRoleArn, 242 // "session_name": servicemocks.MockStsAssumeRoleSessionName, 243 // "assume_role_source_identity": servicemocks.MockStsAssumeRoleSourceIdentity, 244 // }, 245 // ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 246 // MockStsEndpoints: []*servicemocks.MockEndpoint{ 247 // servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"SourceIdentity": servicemocks.MockStsAssumeRoleSourceIdentity}), 248 // servicemocks.MockStsGetCallerIdentityValidEndpoint, 249 // }, 250 // }, 251 252 "config Profile shared credentials profile aws_access_key_id": { 253 config: map[string]any{ 254 "profile": "SharedCredentialsProfile", 255 }, 256 ExpectedCredentialsValue: credentials.Value{ 257 AccessKeyID: "ProfileSharedCredentialsAccessKey", 258 SecretAccessKey: "ProfileSharedCredentialsSecretKey", 259 ProviderName: credentials.SharedCredsProviderName, 260 }, 261 MockStsEndpoints: []*servicemocks.MockEndpoint{ 262 servicemocks.MockStsGetCallerIdentityValidEndpoint, 263 }, 264 SharedCredentialsFile: ` 265 [default] 266 aws_access_key_id = DefaultSharedCredentialsAccessKey 267 aws_secret_access_key = DefaultSharedCredentialsSecretKey 268 269 [SharedCredentialsProfile] 270 aws_access_key_id = ProfileSharedCredentialsAccessKey 271 aws_secret_access_key = ProfileSharedCredentialsSecretKey 272 `, 273 ValidateDiags: ExpectNoDiags, 274 }, 275 276 "environment AWS_ACCESS_KEY_ID overrides config Profile": { // Legacy behavior 277 config: map[string]any{ 278 "profile": "SharedCredentialsProfile", 279 }, 280 EnvironmentVariables: map[string]string{ 281 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 282 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 283 }, 284 ExpectedCredentialsValue: servicemocks.MockEnvCredentials, 285 MockStsEndpoints: []*servicemocks.MockEndpoint{ 286 servicemocks.MockStsGetCallerIdentityValidEndpoint, 287 }, 288 SharedCredentialsFile: ` 289 [default] 290 aws_access_key_id = DefaultSharedCredentialsAccessKey 291 aws_secret_access_key = DefaultSharedCredentialsSecretKey 292 293 [SharedCredentialsProfile] 294 aws_access_key_id = ProfileSharedCredentialsAccessKey 295 aws_secret_access_key = ProfileSharedCredentialsSecretKey 296 `, 297 ValidateDiags: ExpectNoDiags, 298 }, 299 300 "config Profile shared configuration credential_source Ec2InstanceMetadata": { 301 config: map[string]any{ 302 "profile": "SharedConfigurationProfile", 303 }, 304 EnableEc2MetadataServer: true, 305 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 306 MockStsEndpoints: []*servicemocks.MockEndpoint{ 307 servicemocks.MockStsAssumeRoleValidEndpoint, 308 servicemocks.MockStsGetCallerIdentityValidEndpoint, 309 }, 310 SharedConfigurationFile: fmt.Sprintf(` 311 [profile SharedConfigurationProfile] 312 credential_source = Ec2InstanceMetadata 313 role_arn = %[1]s 314 role_session_name = %[2]s 315 `, servicemocks.MockStsAssumeRoleArn, servicemocks.MockStsAssumeRoleSessionName), 316 }, 317 318 "config Profile shared configuration source_profile": { 319 config: map[string]any{ 320 "profile": "SharedConfigurationProfile", 321 }, 322 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 323 MockStsEndpoints: []*servicemocks.MockEndpoint{ 324 servicemocks.MockStsAssumeRoleValidEndpoint, 325 servicemocks.MockStsGetCallerIdentityValidEndpoint, 326 }, 327 SharedConfigurationFile: fmt.Sprintf(` 328 [profile SharedConfigurationProfile] 329 role_arn = %[1]s 330 role_session_name = %[2]s 331 source_profile = SharedConfigurationSourceProfile 332 333 [profile SharedConfigurationSourceProfile] 334 aws_access_key_id = SharedConfigurationSourceAccessKey 335 aws_secret_access_key = SharedConfigurationSourceSecretKey 336 `, servicemocks.MockStsAssumeRoleArn, servicemocks.MockStsAssumeRoleSessionName), 337 }, 338 339 "environment AWS_ACCESS_KEY_ID": { 340 config: map[string]any{}, 341 EnvironmentVariables: map[string]string{ 342 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 343 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 344 }, 345 ExpectedCredentialsValue: mockdata.MockEnvCredentials, 346 MockStsEndpoints: []*servicemocks.MockEndpoint{ 347 servicemocks.MockStsGetCallerIdentityValidEndpoint, 348 }, 349 ValidateDiags: ExpectNoDiags, 350 }, 351 352 "environment AWS_ACCESS_KEY_ID config AssumeRoleARN access key": { 353 config: map[string]any{ 354 "role_arn": servicemocks.MockStsAssumeRoleArn, 355 "session_name": servicemocks.MockStsAssumeRoleSessionName, 356 }, 357 EnvironmentVariables: map[string]string{ 358 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 359 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 360 }, 361 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 362 MockStsEndpoints: []*servicemocks.MockEndpoint{ 363 servicemocks.MockStsAssumeRoleValidEndpoint, 364 servicemocks.MockStsGetCallerIdentityValidEndpoint, 365 }, 366 }, 367 368 "environment AWS_PROFILE shared credentials profile aws_access_key_id": { 369 config: map[string]any{}, 370 EnvironmentVariables: map[string]string{ 371 "AWS_PROFILE": "SharedCredentialsProfile", 372 }, 373 ExpectedCredentialsValue: credentials.Value{ 374 AccessKeyID: "ProfileSharedCredentialsAccessKey", 375 SecretAccessKey: "ProfileSharedCredentialsSecretKey", 376 ProviderName: credentials.SharedCredsProviderName, 377 }, 378 MockStsEndpoints: []*servicemocks.MockEndpoint{ 379 servicemocks.MockStsGetCallerIdentityValidEndpoint, 380 }, 381 SharedCredentialsFile: ` 382 [default] 383 aws_access_key_id = DefaultSharedCredentialsAccessKey 384 aws_secret_access_key = DefaultSharedCredentialsSecretKey 385 386 [SharedCredentialsProfile] 387 aws_access_key_id = ProfileSharedCredentialsAccessKey 388 aws_secret_access_key = ProfileSharedCredentialsSecretKey 389 `, 390 ValidateDiags: ExpectNoDiags, 391 }, 392 393 "environment AWS_PROFILE shared configuration credential_source Ec2InstanceMetadata": { 394 config: map[string]any{}, 395 EnableEc2MetadataServer: true, 396 EnvironmentVariables: map[string]string{ 397 "AWS_PROFILE": "SharedConfigurationProfile", 398 }, 399 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 400 MockStsEndpoints: []*servicemocks.MockEndpoint{ 401 servicemocks.MockStsAssumeRoleValidEndpoint, 402 servicemocks.MockStsGetCallerIdentityValidEndpoint, 403 }, 404 SharedConfigurationFile: fmt.Sprintf(` 405 [profile SharedConfigurationProfile] 406 credential_source = Ec2InstanceMetadata 407 role_arn = %[1]s 408 role_session_name = %[2]s 409 `, servicemocks.MockStsAssumeRoleArn, servicemocks.MockStsAssumeRoleSessionName), 410 }, 411 412 "environment AWS_PROFILE shared configuration source_profile": { 413 config: map[string]any{}, 414 EnvironmentVariables: map[string]string{ 415 "AWS_PROFILE": "SharedConfigurationProfile", 416 }, 417 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 418 MockStsEndpoints: []*servicemocks.MockEndpoint{ 419 servicemocks.MockStsAssumeRoleValidEndpoint, 420 servicemocks.MockStsGetCallerIdentityValidEndpoint, 421 }, 422 SharedConfigurationFile: fmt.Sprintf(` 423 [profile SharedConfigurationProfile] 424 role_arn = %[1]s 425 role_session_name = %[2]s 426 source_profile = SharedConfigurationSourceProfile 427 428 [profile SharedConfigurationSourceProfile] 429 aws_access_key_id = SharedConfigurationSourceAccessKey 430 aws_secret_access_key = SharedConfigurationSourceSecretKey 431 `, servicemocks.MockStsAssumeRoleArn, servicemocks.MockStsAssumeRoleSessionName), 432 }, 433 434 "environment AWS_SESSION_TOKEN": { 435 config: map[string]any{}, 436 EnvironmentVariables: map[string]string{ 437 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 438 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 439 "AWS_SESSION_TOKEN": servicemocks.MockEnvSessionToken, 440 }, 441 ExpectedCredentialsValue: mockdata.MockEnvCredentialsWithSessionToken, 442 MockStsEndpoints: []*servicemocks.MockEndpoint{ 443 servicemocks.MockStsGetCallerIdentityValidEndpoint, 444 }, 445 }, 446 447 "shared credentials default aws_access_key_id": { 448 config: map[string]any{}, 449 ExpectedCredentialsValue: credentials.Value{ 450 AccessKeyID: "DefaultSharedCredentialsAccessKey", 451 SecretAccessKey: "DefaultSharedCredentialsSecretKey", 452 ProviderName: credentials.SharedCredsProviderName, 453 }, 454 MockStsEndpoints: []*servicemocks.MockEndpoint{ 455 servicemocks.MockStsGetCallerIdentityValidEndpoint, 456 }, 457 SharedCredentialsFile: ` 458 [default] 459 aws_access_key_id = DefaultSharedCredentialsAccessKey 460 aws_secret_access_key = DefaultSharedCredentialsSecretKey 461 `, 462 }, 463 464 "shared credentials default aws_access_key_id config AssumeRoleARN access key": { 465 config: map[string]any{ 466 "role_arn": servicemocks.MockStsAssumeRoleArn, 467 "session_name": servicemocks.MockStsAssumeRoleSessionName, 468 }, 469 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 470 MockStsEndpoints: []*servicemocks.MockEndpoint{ 471 servicemocks.MockStsAssumeRoleValidEndpoint, 472 servicemocks.MockStsGetCallerIdentityValidEndpoint, 473 }, 474 SharedCredentialsFile: ` 475 [default] 476 aws_access_key_id = DefaultSharedCredentialsAccessKey 477 aws_secret_access_key = DefaultSharedCredentialsSecretKey 478 `, 479 }, 480 481 "web identity token access key": { 482 config: map[string]any{}, 483 EnableWebIdentityEnvVars: true, 484 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials, 485 MockStsEndpoints: []*servicemocks.MockEndpoint{ 486 servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint, 487 servicemocks.MockStsGetCallerIdentityValidEndpoint, 488 }, 489 }, 490 491 "EC2 metadata access key": { 492 config: map[string]any{}, 493 EnableEc2MetadataServer: true, 494 ExpectedCredentialsValue: mockdata.MockEc2MetadataCredentials, 495 MockStsEndpoints: []*servicemocks.MockEndpoint{ 496 servicemocks.MockStsGetCallerIdentityValidEndpoint, 497 }, 498 ValidateDiags: ExpectNoDiags, 499 }, 500 501 "EC2 metadata access key config AssumeRoleARN access key": { 502 config: map[string]any{ 503 "role_arn": servicemocks.MockStsAssumeRoleArn, 504 "session_name": servicemocks.MockStsAssumeRoleSessionName, 505 }, 506 EnableEc2MetadataServer: true, 507 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 508 MockStsEndpoints: []*servicemocks.MockEndpoint{ 509 servicemocks.MockStsAssumeRoleValidEndpoint, 510 servicemocks.MockStsGetCallerIdentityValidEndpoint, 511 }, 512 }, 513 514 "ECS credentials access key": { 515 config: map[string]any{}, 516 EnableEcsCredentialsServer: true, 517 ExpectedCredentialsValue: mockdata.MockEcsCredentialsCredentials, 518 MockStsEndpoints: []*servicemocks.MockEndpoint{ 519 servicemocks.MockStsGetCallerIdentityValidEndpoint, 520 }, 521 }, 522 523 "ECS credentials access key config AssumeRoleARN access key": { 524 config: map[string]any{ 525 "role_arn": servicemocks.MockStsAssumeRoleArn, 526 "session_name": servicemocks.MockStsAssumeRoleSessionName, 527 }, 528 EnableEcsCredentialsServer: true, 529 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 530 MockStsEndpoints: []*servicemocks.MockEndpoint{ 531 servicemocks.MockStsAssumeRoleValidEndpoint, 532 servicemocks.MockStsGetCallerIdentityValidEndpoint, 533 }, 534 }, 535 536 "AssumeWebIdentity envvar AssumeRoleARN access key": { 537 config: map[string]any{ 538 "role_arn": servicemocks.MockStsAssumeRoleArn, 539 "session_name": servicemocks.MockStsAssumeRoleSessionName, 540 }, 541 EnableWebIdentityEnvVars: true, 542 ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 543 MockStsEndpoints: []*servicemocks.MockEndpoint{ 544 servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint, 545 servicemocks.MockStsAssumeRoleValidEndpoint, 546 servicemocks.MockStsGetCallerIdentityValidEndpoint, 547 }, 548 }, 549 550 // NOT SUPPORTED: AssumeWebIdentity config 551 // "AssumeWebIdentity config AssumeRoleARN access key": { 552 // config: map[string]any{ 553 // "role_arn": servicemocks.MockStsAssumeRoleArn, 554 // "session_name": servicemocks.MockStsAssumeRoleSessionName, 555 // }, 556 // EnableWebIdentityConfig: true, 557 // ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, 558 // MockStsEndpoints: []*servicemocks.MockEndpoint{ 559 // servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint, 560 // servicemocks.MockStsAssumeRoleValidEndpoint, 561 // servicemocks.MockStsGetCallerIdentityValidEndpoint, 562 // }, 563 // }, 564 565 "config AccessKey over environment AWS_ACCESS_KEY_ID": { 566 config: map[string]any{ 567 "access_key": awsbase.MockStaticAccessKey, 568 "secret_key": servicemocks.MockStaticSecretKey, 569 }, 570 EnvironmentVariables: map[string]string{ 571 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 572 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 573 }, 574 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 575 MockStsEndpoints: []*servicemocks.MockEndpoint{ 576 servicemocks.MockStsGetCallerIdentityValidEndpoint, 577 }, 578 ValidateDiags: ExpectNoDiags, 579 }, 580 581 "config AccessKey over shared credentials default aws_access_key_id": { 582 config: map[string]any{ 583 "access_key": awsbase.MockStaticAccessKey, 584 "secret_key": servicemocks.MockStaticSecretKey, 585 }, 586 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 587 MockStsEndpoints: []*servicemocks.MockEndpoint{ 588 servicemocks.MockStsGetCallerIdentityValidEndpoint, 589 }, 590 SharedCredentialsFile: ` 591 [default] 592 aws_access_key_id = DefaultSharedCredentialsAccessKey 593 aws_secret_access_key = DefaultSharedCredentialsSecretKey 594 `, 595 ValidateDiags: ExpectNoDiags, 596 }, 597 598 "config AccessKey over EC2 metadata access key": { 599 config: map[string]any{ 600 "access_key": awsbase.MockStaticAccessKey, 601 "secret_key": servicemocks.MockStaticSecretKey, 602 }, 603 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 604 MockStsEndpoints: []*servicemocks.MockEndpoint{ 605 servicemocks.MockStsGetCallerIdentityValidEndpoint, 606 }, 607 }, 608 609 "config AccessKey over ECS credentials access key": { 610 config: map[string]any{ 611 "access_key": awsbase.MockStaticAccessKey, 612 "secret_key": servicemocks.MockStaticSecretKey, 613 }, 614 EnableEcsCredentialsServer: true, 615 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 616 MockStsEndpoints: []*servicemocks.MockEndpoint{ 617 servicemocks.MockStsGetCallerIdentityValidEndpoint, 618 }, 619 }, 620 621 "environment AWS_ACCESS_KEY_ID over shared credentials default aws_access_key_id": { 622 config: map[string]any{}, 623 EnvironmentVariables: map[string]string{ 624 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 625 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 626 }, 627 ExpectedCredentialsValue: mockdata.MockEnvCredentials, 628 MockStsEndpoints: []*servicemocks.MockEndpoint{ 629 servicemocks.MockStsGetCallerIdentityValidEndpoint, 630 }, 631 SharedCredentialsFile: ` 632 [default] 633 aws_access_key_id = DefaultSharedCredentialsAccessKey 634 aws_secret_access_key = DefaultSharedCredentialsSecretKey 635 `, 636 ValidateDiags: ExpectNoDiags, 637 }, 638 639 "environment AWS_ACCESS_KEY_ID over EC2 metadata access key": { 640 config: map[string]any{}, 641 EnvironmentVariables: map[string]string{ 642 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 643 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 644 }, 645 ExpectedCredentialsValue: mockdata.MockEnvCredentials, 646 MockStsEndpoints: []*servicemocks.MockEndpoint{ 647 servicemocks.MockStsGetCallerIdentityValidEndpoint, 648 }, 649 }, 650 651 "environment AWS_ACCESS_KEY_ID over ECS credentials access key": { 652 config: map[string]any{}, 653 EnvironmentVariables: map[string]string{ 654 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 655 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 656 }, 657 EnableEcsCredentialsServer: true, 658 ExpectedCredentialsValue: mockdata.MockEnvCredentials, 659 MockStsEndpoints: []*servicemocks.MockEndpoint{ 660 servicemocks.MockStsGetCallerIdentityValidEndpoint, 661 }, 662 }, 663 664 "shared credentials default aws_access_key_id over EC2 metadata access key": { 665 config: map[string]any{}, 666 ExpectedCredentialsValue: credentials.Value{ 667 AccessKeyID: "DefaultSharedCredentialsAccessKey", 668 SecretAccessKey: "DefaultSharedCredentialsSecretKey", 669 ProviderName: credentials.SharedCredsProviderName, 670 }, 671 MockStsEndpoints: []*servicemocks.MockEndpoint{ 672 servicemocks.MockStsGetCallerIdentityValidEndpoint, 673 }, 674 SharedCredentialsFile: ` 675 [default] 676 aws_access_key_id = DefaultSharedCredentialsAccessKey 677 aws_secret_access_key = DefaultSharedCredentialsSecretKey 678 `, 679 }, 680 681 "shared credentials default aws_access_key_id over ECS credentials access key": { 682 config: map[string]any{}, 683 EnableEcsCredentialsServer: true, 684 ExpectedCredentialsValue: credentials.Value{ 685 AccessKeyID: "DefaultSharedCredentialsAccessKey", 686 SecretAccessKey: "DefaultSharedCredentialsSecretKey", 687 ProviderName: credentials.SharedCredsProviderName, 688 }, 689 MockStsEndpoints: []*servicemocks.MockEndpoint{ 690 servicemocks.MockStsGetCallerIdentityValidEndpoint, 691 }, 692 SharedCredentialsFile: ` 693 [default] 694 aws_access_key_id = DefaultSharedCredentialsAccessKey 695 aws_secret_access_key = DefaultSharedCredentialsSecretKey 696 `, 697 }, 698 699 "ECS credentials access key over EC2 metadata access key": { 700 config: map[string]any{}, 701 EnableEcsCredentialsServer: true, 702 ExpectedCredentialsValue: mockdata.MockEcsCredentialsCredentials, 703 MockStsEndpoints: []*servicemocks.MockEndpoint{ 704 servicemocks.MockStsGetCallerIdentityValidEndpoint, 705 }, 706 }, 707 708 "retrieve region from shared configuration file": { 709 config: map[string]any{ 710 "access_key": awsbase.MockStaticAccessKey, 711 "secret_key": servicemocks.MockStaticSecretKey, 712 }, 713 ExpectedCredentialsValue: mockdata.MockStaticCredentials, 714 MockStsEndpoints: []*servicemocks.MockEndpoint{ 715 servicemocks.MockStsGetCallerIdentityValidEndpoint, 716 }, 717 SharedConfigurationFile: ` 718 [default] 719 region = us-east-1 720 `, 721 }, 722 723 "assume role error": { 724 config: map[string]any{ 725 "access_key": awsbase.MockStaticAccessKey, 726 "secret_key": servicemocks.MockStaticSecretKey, 727 "role_arn": servicemocks.MockStsAssumeRoleArn, 728 "session_name": servicemocks.MockStsAssumeRoleSessionName, 729 }, 730 MockStsEndpoints: []*servicemocks.MockEndpoint{ 731 servicemocks.MockStsAssumeRoleInvalidEndpointInvalidClientTokenId, 732 servicemocks.MockStsGetCallerIdentityValidEndpoint, 733 }, 734 ValidateDiags: ExpectDiagMatching( 735 tfdiags.Error, 736 equalsMatcher("Failed to configure AWS client"), 737 newRegexpMatcher(`IAM Role \(.+\) cannot be assumed.`), 738 ), 739 }, 740 741 "skip EC2 Metadata API check": { 742 config: map[string]any{ 743 "skip_metadata_api_check": true, 744 }, 745 // The IMDS server must be enabled so that auth will succeed if the IMDS is called 746 EnableEc2MetadataServer: true, 747 MockStsEndpoints: []*servicemocks.MockEndpoint{ 748 servicemocks.MockStsGetCallerIdentityValidEndpoint, 749 }, 750 ValidateDiags: ExpectDiagMatching( 751 tfdiags.Error, 752 equalsMatcher("Failed to configure AWS client"), 753 newRegexpMatcher("no valid credential sources for S3 Backend found"), 754 ), 755 }, 756 757 "invalid profile name from envvar": { 758 config: map[string]any{}, 759 EnvironmentVariables: map[string]string{ 760 "AWS_PROFILE": "no-such-profile", 761 }, 762 SharedCredentialsFile: ` 763 [some-profile] 764 aws_access_key_id = DefaultSharedCredentialsAccessKey 765 aws_secret_access_key = DefaultSharedCredentialsSecretKey 766 `, 767 ValidateDiags: ExpectDiagMatching( 768 tfdiags.Error, 769 equalsMatcher("Failed to configure AWS client"), 770 newRegexpMatcher("no valid credential sources for S3 Backend found"), 771 ), 772 }, 773 774 "invalid profile name from config": { 775 config: map[string]any{ 776 "profile": "no-such-profile", 777 }, 778 SharedCredentialsFile: ` 779 [some-profile] 780 aws_access_key_id = DefaultSharedCredentialsAccessKey 781 aws_secret_access_key = DefaultSharedCredentialsSecretKey 782 `, 783 ValidateDiags: ExpectDiagMatching( 784 tfdiags.Error, 785 equalsMatcher("Failed to configure AWS client"), 786 newRegexpMatcher("no valid credential sources for S3 Backend found"), 787 ), 788 }, 789 790 "AWS_ACCESS_KEY_ID overrides AWS_PROFILE": { 791 config: map[string]any{}, 792 EnvironmentVariables: map[string]string{ 793 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 794 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 795 "AWS_PROFILE": "SharedCredentialsProfile", 796 }, 797 SharedCredentialsFile: ` 798 [default] 799 aws_access_key_id = DefaultSharedCredentialsAccessKey 800 aws_secret_access_key = DefaultSharedCredentialsSecretKey 801 802 [SharedCredentialsProfile] 803 aws_access_key_id = ProfileSharedCredentialsAccessKey 804 aws_secret_access_key = ProfileSharedCredentialsSecretKey 805 `, 806 MockStsEndpoints: []*servicemocks.MockEndpoint{ 807 servicemocks.MockStsGetCallerIdentityValidEndpoint, 808 }, 809 ExpectedCredentialsValue: mockdata.MockEnvCredentials, 810 ValidateDiags: ExpectNoDiags, 811 }, 812 813 "AWS_ACCESS_KEY_ID does not override invalid profile name from envvar": { 814 config: map[string]any{}, 815 EnvironmentVariables: map[string]string{ 816 "AWS_ACCESS_KEY_ID": servicemocks.MockEnvAccessKey, 817 "AWS_SECRET_ACCESS_KEY": servicemocks.MockEnvSecretKey, 818 "AWS_PROFILE": "no-such-profile", 819 }, 820 SharedCredentialsFile: ` 821 [some-profile] 822 aws_access_key_id = DefaultSharedCredentialsAccessKey 823 aws_secret_access_key = DefaultSharedCredentialsSecretKey 824 `, 825 ValidateDiags: ExpectDiagMatching( 826 tfdiags.Error, 827 equalsMatcher("Failed to configure AWS client"), 828 newRegexpMatcher("error validating provider credentials:"), 829 ), 830 }, 831 } 832 833 for name, tc := range testCases { 834 tc := tc 835 836 t.Run(name, func(t *testing.T) { 837 oldEnv := initSessionTestEnv() 838 defer popEnv(oldEnv) 839 840 // Populate required fields 841 tc.config["region"] = "us-east-1" 842 tc.config["bucket"] = "bucket" 843 tc.config["key"] = "key" 844 845 if tc.ValidateDiags == nil { 846 tc.ValidateDiags = ExpectNoDiags 847 } 848 849 if tc.EnableEc2MetadataServer { 850 closeEc2Metadata := awsMetadataApiMock(append( 851 ec2metadata_securityCredentialsEndpoints, 852 ec2metadata_instanceIdEndpoint, 853 ec2metadata_iamInfoEndpoint, 854 )) 855 defer closeEc2Metadata() 856 } 857 858 if tc.EnableEcsCredentialsServer { 859 closeEcsCredentials := ecsCredentialsApiMock() 860 defer closeEcsCredentials() 861 } 862 863 if tc.EnableWebIdentityEnvVars /*|| tc.EnableWebIdentityConfig*/ { 864 file, err := os.CreateTemp("", "aws-sdk-go-base-web-identity-token-file") 865 if err != nil { 866 t.Fatalf("unexpected error creating temporary web identity token file: %s", err) 867 } 868 869 defer os.Remove(file.Name()) 870 871 err = os.WriteFile(file.Name(), []byte(servicemocks.MockWebIdentityToken), 0600) 872 873 if err != nil { 874 t.Fatalf("unexpected error writing web identity token file: %s", err) 875 } 876 877 if tc.EnableWebIdentityEnvVars { 878 os.Setenv("AWS_ROLE_ARN", servicemocks.MockStsAssumeRoleWithWebIdentityArn) 879 os.Setenv("AWS_ROLE_SESSION_NAME", servicemocks.MockStsAssumeRoleWithWebIdentitySessionName) 880 os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", file.Name()) 881 } /*else if tc.EnableWebIdentityConfig { 882 tc.Config.AssumeRoleWithWebIdentity = &AssumeRoleWithWebIdentity{ 883 RoleARN: servicemocks.MockStsAssumeRoleWithWebIdentityArn, 884 SessionName: servicemocks.MockStsAssumeRoleWithWebIdentitySessionName, 885 WebIdentityTokenFile: file.Name(), 886 } 887 }*/ 888 } 889 890 ts := servicemocks.MockAwsApiServer("STS", tc.MockStsEndpoints) 891 defer ts.Close() 892 893 tc.config["sts_endpoint"] = ts.URL 894 895 if tc.SharedConfigurationFile != "" { 896 file, err := os.CreateTemp("", "aws-sdk-go-base-shared-configuration-file") 897 898 if err != nil { 899 t.Fatalf("unexpected error creating temporary shared configuration file: %s", err) 900 } 901 902 defer os.Remove(file.Name()) 903 904 err = os.WriteFile(file.Name(), []byte(tc.SharedConfigurationFile), 0600) 905 906 if err != nil { 907 t.Fatalf("unexpected error writing shared configuration file: %s", err) 908 } 909 910 setSharedConfigFile(file.Name()) 911 } 912 913 if tc.SharedCredentialsFile != "" { 914 file, err := os.CreateTemp("", "aws-sdk-go-base-shared-credentials-file") 915 916 if err != nil { 917 t.Fatalf("unexpected error creating temporary shared credentials file: %s", err) 918 } 919 920 defer os.Remove(file.Name()) 921 922 err = os.WriteFile(file.Name(), []byte(tc.SharedCredentialsFile), 0600) 923 924 if err != nil { 925 t.Fatalf("unexpected error writing shared credentials file: %s", err) 926 } 927 928 tc.config["shared_credentials_file"] = file.Name() 929 } 930 931 for k, v := range tc.EnvironmentVariables { 932 os.Setenv(k, v) 933 } 934 935 b, diags := configureBackend(t, tc.config) 936 937 tc.ValidateDiags(t, diags) 938 939 if diags.HasErrors() { 940 return 941 } 942 943 credentials, err := b.s3Client.Config.Credentials.Get() 944 if err != nil { 945 t.Fatalf("Error when requesting credentials: %s", err) 946 } 947 948 if diff := cmp.Diff(credentials, tc.ExpectedCredentialsValue); diff != "" { 949 t.Fatalf("unexpected credentials: (- got, + expected)\n%s", diff) 950 } 951 }) 952 } 953 } 954 955 func TestBackendConfig_Region(t *testing.T) { 956 testCases := map[string]struct { 957 config map[string]any 958 EnvironmentVariables map[string]string 959 IMDSRegion string 960 SharedConfigurationFile string 961 ExpectedRegion string 962 }{ 963 // NOT SUPPORTED: region is required 964 // "no configuration": { 965 // config: map[string]any{ 966 // "access_key": awsbase.MockStaticAccessKey, 967 // "secret_key": servicemocks.MockStaticSecretKey, 968 // }, 969 // ExpectedRegion: "", 970 // }, 971 972 "config": { 973 config: map[string]any{ 974 "access_key": awsbase.MockStaticAccessKey, 975 "secret_key": servicemocks.MockStaticSecretKey, 976 "region": "us-east-1", 977 }, 978 ExpectedRegion: "us-east-1", 979 }, 980 981 "AWS_REGION": { 982 config: map[string]any{ 983 "access_key": awsbase.MockStaticAccessKey, 984 "secret_key": servicemocks.MockStaticSecretKey, 985 }, 986 EnvironmentVariables: map[string]string{ 987 "AWS_REGION": "us-east-1", 988 }, 989 ExpectedRegion: "us-east-1", 990 }, 991 "AWS_DEFAULT_REGION": { 992 config: map[string]any{ 993 "access_key": awsbase.MockStaticAccessKey, 994 "secret_key": servicemocks.MockStaticSecretKey, 995 }, 996 EnvironmentVariables: map[string]string{ 997 "AWS_DEFAULT_REGION": "us-east-1", 998 }, 999 ExpectedRegion: "us-east-1", 1000 }, 1001 "AWS_REGION overrides AWS_DEFAULT_REGION": { 1002 config: map[string]any{ 1003 "access_key": awsbase.MockStaticAccessKey, 1004 "secret_key": servicemocks.MockStaticSecretKey, 1005 }, 1006 EnvironmentVariables: map[string]string{ 1007 "AWS_REGION": "us-east-1", 1008 "AWS_DEFAULT_REGION": "us-west-2", 1009 }, 1010 ExpectedRegion: "us-east-1", 1011 }, 1012 1013 // NOT SUPPORTED: region from shared configuration file 1014 // "shared configuration file": { 1015 // config: map[string]any{ 1016 // "access_key": awsbase.MockStaticAccessKey, 1017 // "secret_key": servicemocks.MockStaticSecretKey, 1018 // }, 1019 // SharedConfigurationFile: ` 1020 // [default] 1021 // region = us-east-1 1022 // `, 1023 // ExpectedRegion: "us-east-1", 1024 // }, 1025 1026 // NOT SUPPORTED: region from IMDS 1027 // "IMDS": { 1028 // config: map[string]any{}, 1029 // IMDSRegion: "us-east-1", 1030 // ExpectedRegion: "us-east-1", 1031 // }, 1032 1033 "config overrides AWS_REGION": { 1034 config: map[string]any{ 1035 "access_key": awsbase.MockStaticAccessKey, 1036 "secret_key": servicemocks.MockStaticSecretKey, 1037 "region": "us-east-1", 1038 }, 1039 EnvironmentVariables: map[string]string{ 1040 "AWS_REGION": "us-west-2", 1041 }, 1042 ExpectedRegion: "us-east-1", 1043 }, 1044 "config overrides AWS_DEFAULT_REGION": { 1045 config: map[string]any{ 1046 "access_key": awsbase.MockStaticAccessKey, 1047 "secret_key": servicemocks.MockStaticSecretKey, 1048 "region": "us-east-1", 1049 }, 1050 EnvironmentVariables: map[string]string{ 1051 "AWS_DEFAULT_REGION": "us-west-2", 1052 }, 1053 ExpectedRegion: "us-east-1", 1054 }, 1055 1056 "config overrides IMDS": { 1057 config: map[string]any{ 1058 "access_key": awsbase.MockStaticAccessKey, 1059 "secret_key": servicemocks.MockStaticSecretKey, 1060 "region": "us-west-2", 1061 }, 1062 IMDSRegion: "us-east-1", 1063 ExpectedRegion: "us-west-2", 1064 }, 1065 1066 "AWS_REGION overrides shared configuration": { 1067 config: map[string]any{ 1068 "access_key": awsbase.MockStaticAccessKey, 1069 "secret_key": servicemocks.MockStaticSecretKey, 1070 }, 1071 EnvironmentVariables: map[string]string{ 1072 "AWS_REGION": "us-east-1", 1073 }, 1074 SharedConfigurationFile: ` 1075 [default] 1076 region = us-west-2 1077 `, 1078 ExpectedRegion: "us-east-1", 1079 }, 1080 "AWS_DEFAULT_REGION overrides shared configuration": { 1081 config: map[string]any{ 1082 "access_key": awsbase.MockStaticAccessKey, 1083 "secret_key": servicemocks.MockStaticSecretKey, 1084 }, 1085 EnvironmentVariables: map[string]string{ 1086 "AWS_DEFAULT_REGION": "us-east-1", 1087 }, 1088 SharedConfigurationFile: ` 1089 [default] 1090 region = us-west-2 1091 `, 1092 ExpectedRegion: "us-east-1", 1093 }, 1094 1095 "AWS_REGION overrides IMDS": { 1096 config: map[string]any{ 1097 "access_key": awsbase.MockStaticAccessKey, 1098 "secret_key": servicemocks.MockStaticSecretKey, 1099 }, 1100 EnvironmentVariables: map[string]string{ 1101 "AWS_REGION": "us-east-1", 1102 }, 1103 IMDSRegion: "us-west-2", 1104 ExpectedRegion: "us-east-1", 1105 }, 1106 } 1107 1108 for name, tc := range testCases { 1109 tc := tc 1110 1111 t.Run(name, func(t *testing.T) { 1112 oldEnv := initSessionTestEnv() 1113 defer popEnv(oldEnv) 1114 1115 // Populate required fields 1116 tc.config["bucket"] = "bucket" 1117 tc.config["key"] = "key" 1118 1119 for k, v := range tc.EnvironmentVariables { 1120 os.Setenv(k, v) 1121 } 1122 1123 if tc.IMDSRegion != "" { 1124 closeEc2Metadata := awsMetadataApiMock(append( 1125 ec2metadata_securityCredentialsEndpoints, 1126 ec2metadata_instanceIdEndpoint, 1127 ec2metadata_iamInfoEndpoint, 1128 ec2metadata_instanceIdentityEndpoint(tc.IMDSRegion), 1129 )) 1130 defer closeEc2Metadata() 1131 } 1132 1133 if tc.SharedConfigurationFile != "" { 1134 file, err := os.CreateTemp("", "aws-sdk-go-base-shared-configuration-file") 1135 1136 if err != nil { 1137 t.Fatalf("unexpected error creating temporary shared configuration file: %s", err) 1138 } 1139 1140 defer os.Remove(file.Name()) 1141 1142 err = os.WriteFile(file.Name(), []byte(tc.SharedConfigurationFile), 0600) 1143 1144 if err != nil { 1145 t.Fatalf("unexpected error writing shared configuration file: %s", err) 1146 } 1147 1148 setSharedConfigFile(file.Name()) 1149 } 1150 1151 tc.config["skip_credentials_validation"] = true 1152 1153 b, diags := configureBackend(t, tc.config) 1154 if diags.HasErrors() { 1155 t.Fatalf("configuring backend: %s", diagnosticsString(diags)) 1156 } 1157 1158 if a, e := aws.StringValue(b.s3Client.Config.Region), tc.ExpectedRegion; a != e { 1159 t.Errorf("expected Region %q, got: %q", e, a) 1160 } 1161 }) 1162 } 1163 } 1164 1165 func setSharedConfigFile(filename string) { 1166 os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 1167 os.Setenv("AWS_CONFIG_FILE", filename) 1168 } 1169 1170 func configureBackend(t *testing.T, config map[string]any) (*Backend, tfdiags.Diagnostics) { 1171 b := New().(*Backend) 1172 configSchema := populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(config)) 1173 1174 configSchema, diags := b.PrepareConfig(configSchema) 1175 1176 if diags.HasErrors() { 1177 return b, diags 1178 } 1179 1180 confDiags := b.Configure(configSchema) 1181 diags = diags.Append(confDiags) 1182 1183 return b, diags 1184 }