diff --git a/internal/backend/remote-state/s3/backend.go b/internal/backend/remote-state/s3/backend.go index 88f7365345..860511eacc 100644 --- a/internal/backend/remote-state/s3/backend.go +++ b/internal/backend/remote-state/s3/backend.go @@ -407,25 +407,20 @@ var assumeRoleSchema = singleNestedAttribute{ Description: "The session name to use when assuming the role.", }, validateString{ - Validators: []stringValidator{ - validateStringLenBetween(2, 64), - validateStringMatches( - regexp.MustCompile(`^[\w+=,.@\-]*$`), - `Value can only contain letters, numbers, or the following characters: =,.@-`, - ), - }, + Validators: assumeRoleNameValidator, }, }, - // NOT SUPPORTED by `aws-sdk-go-base/v1` - // "source_identity": stringAttribute{ - // configschema.Attribute{ - // Type: cty.String, - // Optional: true, - // Description: "Source identity specified by the principal assuming the role.", - // ValidateFunc: validAssumeRoleSourceIdentity, - // }, - // }, + "source_identity": stringAttribute{ + configschema.Attribute{ + Type: cty.String, + Optional: true, + Description: "Source identity specified by the principal assuming the role.", + }, + validateString{ + Validators: assumeRoleNameValidator, + }, + }, "tags": mapAttribute{ configschema.Attribute{ @@ -517,13 +512,7 @@ var assumeRoleWithWebIdentitySchema = singleNestedAttribute{ Description: "The session name to use when assuming the role.", }, validateString{ - Validators: []stringValidator{ - validateStringLenBetween(2, 64), - validateStringMatches( - regexp.MustCompile(`^[\w+=,.@\-]*$`), - `Value can only contain letters, numbers, or the following characters: =,.@-`, - ), - }, + Validators: assumeRoleNameValidator, }, }, @@ -1077,6 +1066,9 @@ func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics { if val, ok := stringAttrOk(assumeRole, "session_name"); ok { ar.SessionName = val } + if val, ok := stringAttrOk(assumeRole, "source_identity"); ok { + ar.SourceIdentity = val + } if val, ok := stringMapAttrOk(assumeRole, "tags"); ok { ar.Tags = val } diff --git a/internal/backend/remote-state/s3/backend_complete_test.go b/internal/backend/remote-state/s3/backend_complete_test.go index a8d1ec342c..ce513a1b87 100644 --- a/internal/backend/remote-state/s3/backend_complete_test.go +++ b/internal/backend/remote-state/s3/backend_complete_test.go @@ -1081,23 +1081,6 @@ aws_secret_access_key = DefaultSharedCredentialsSecretKey ), }, - // NOT SUPPORTED: AssumeRoleSourceIdentity - // WAS: "config AssumeRoleSourceIdentity" - // "with source identity": { - // config: map[string]any{ - // "access_key": servicemocks.MockStaticAccessKey, - // "secret_key": servicemocks.MockStaticSecretKey, - // "role_arn": servicemocks.MockStsAssumeRoleArn, - // "session_name": servicemocks.MockStsAssumeRoleSessionName, - // "assume_role_source_identity": servicemocks.MockStsAssumeRoleSourceIdentity, - // }, - // ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, - // MockStsEndpoints: []*servicemocks.MockEndpoint{ - // servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"SourceIdentity": servicemocks.MockStsAssumeRoleSourceIdentity}), - // servicemocks.MockStsGetCallerIdentityValidEndpoint, - // }, - // }, - // WAS: "assume role error" "error": { config: map[string]any{ @@ -1524,24 +1507,23 @@ aws_secret_access_key = DefaultSharedCredentialsSecretKey }, }, - // NOT SUPPORTED: AssumeRoleSourceIdentity // WAS: "config AssumeRoleSourceIdentity" - // "with source identity": { - // config: map[string]any{ - // "access_key": servicemocks.MockStaticAccessKey, - // "secret_key": servicemocks.MockStaticSecretKey, - // "assume_role": map[string]any{ - // "role_arn": servicemocks.MockStsAssumeRoleArn, - // "session_name": servicemocks.MockStsAssumeRoleSessionName, - // "source_identity": servicemocks.MockStsAssumeRoleSourceIdentity, - // }, - // }, - // ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, - // MockStsEndpoints: []*servicemocks.MockEndpoint{ - // servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"SourceIdentity": servicemocks.MockStsAssumeRoleSourceIdentity}), - // servicemocks.MockStsGetCallerIdentityValidEndpoint, - // }, - // }, + "with source identity": { + config: map[string]any{ + "access_key": servicemocks.MockStaticAccessKey, + "secret_key": servicemocks.MockStaticSecretKey, + "assume_role": map[string]any{ + "role_arn": servicemocks.MockStsAssumeRoleArn, + "session_name": servicemocks.MockStsAssumeRoleSessionName, + "source_identity": servicemocks.MockStsAssumeRoleSourceIdentity, + }, + }, + ExpectedCredentialsValue: mockdata.MockStsAssumeRoleCredentials, + MockStsEndpoints: []*servicemocks.MockEndpoint{ + servicemocks.MockStsAssumeRoleValidEndpointWithOptions(map[string]string{"SourceIdentity": servicemocks.MockStsAssumeRoleSourceIdentity}), + servicemocks.MockStsGetCallerIdentityValidEndpoint, + }, + }, // WAS: "assume role error" "error": { diff --git a/internal/backend/remote-state/s3/backend_test.go b/internal/backend/remote-state/s3/backend_test.go index 5d7d6e4ab5..e36e1a7b28 100644 --- a/internal/backend/remote-state/s3/backend_test.go +++ b/internal/backend/remote-state/s3/backend_test.go @@ -2001,8 +2001,12 @@ func TestAssumeRole_PrepareConfigValidation(t *testing.T) { }, }, - // NOT SUPPORTED by `aws-sdk-go-base/v1` - // "source_identity" + "source_identity": { + config: map[string]cty.Value{ + "role_arn": cty.StringVal("arn:aws:iam::123456789012:role/testrole"), + "source_identity": cty.StringVal("source-identity"), + }, + }, "with tags": { config: map[string]cty.Value{ diff --git a/internal/backend/remote-state/s3/validate.go b/internal/backend/remote-state/s3/validate.go index c094f1fc7c..4fdda0ce51 100644 --- a/internal/backend/remote-state/s3/validate.go +++ b/internal/backend/remote-state/s3/validate.go @@ -476,3 +476,11 @@ func wholeBodyErrDiag(summary, detail string) tfdiags.Diagnostic { func wholeBodyWarningDiag(summary, detail string) tfdiags.Diagnostic { return tfdiags.WholeContainingBody(tfdiags.Warning, summary, detail) } + +var assumeRoleNameValidator = []stringValidator{ + validateStringLenBetween(2, 64), + validateStringMatches( + regexp.MustCompile(`^[\w+=,.@\-]*$`), + `Value can only contain letters, numbers, or the following characters: =,.@-`, + ), +} diff --git a/website/docs/language/settings/backends/s3.mdx b/website/docs/language/settings/backends/s3.mdx index e56f4cd1ab..2761bb3304 100644 --- a/website/docs/language/settings/backends/s3.mdx +++ b/website/docs/language/settings/backends/s3.mdx @@ -213,6 +213,7 @@ The argument `assume_role` contains the following arguments: * `policy` - (Optional) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed. * `policy_arns` - (Optional) Set of Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed. * `session_name` - (Optional) Session name to use when assuming the role. +* `source_identity` - (Optional) Source identity specified by the principal assuming the role. * `tags` - (Optional) Map of assume role session tags. * `transitive_tag_keys` - (Optional) Set of assume role session tag keys to pass to any subsequent sessions.