diff --git a/.changelog/40763.txt b/.changelog/40763.txt new file mode 100644 index 00000000000..2e326447376 --- /dev/null +++ b/.changelog/40763.txt @@ -0,0 +1,3 @@ +```release-note:new-ephemeral +aws_cognito_identity_openid_token_for_developer_identity +``` diff --git a/.ci/.golangci3.yml b/.ci/.golangci3.yml index bc8457d804c..7d0b3728fc8 100644 --- a/.ci/.golangci3.yml +++ b/.ci/.golangci3.yml @@ -54,6 +54,7 @@ linters-settings: - int32validator.* - int64validator.* - listvalidator.* + - mapvalidator.* - setvalidator.* - stringvalidator.* - SetDefaultCreateTimeout diff --git a/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral.go b/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral.go new file mode 100644 index 00000000000..0dec5de7714 --- /dev/null +++ b/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cognitoidentity + +import ( + "context" + + "github.com/YakDriver/regexache" + "github.com/aws/aws-sdk-go-v2/service/cognitoidentity" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/ephemeral" + "github.com/hashicorp/terraform-plugin-framework/ephemeral/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" +) + +// @EphemeralResource("aws_cognito_identity_openid_token_for_developer_identity", name="Open ID Connect Token For Developer Identity") +func newOpenIDTokenForDeveloperIdentityEphemeralResource(context.Context) (ephemeral.EphemeralResourceWithConfigure, error) { + return &openIDTokenForDeveloperIdentityEphemeralResource{}, nil +} + +type openIDTokenForDeveloperIdentityEphemeralResource struct { + framework.EphemeralResourceWithConfigure +} + +func (*openIDTokenForDeveloperIdentityEphemeralResource) Metadata(_ context.Context, request ephemeral.MetadataRequest, response *ephemeral.MetadataResponse) { + response.TypeName = "aws_cognito_identity_openid_token_for_developer_identity" +} + +func (e *openIDTokenForDeveloperIdentityEphemeralResource) Schema(ctx context.Context, request ephemeral.SchemaRequest, response *ephemeral.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "identity_id": schema.StringAttribute{ + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`[\w-]+:[0-9a-f-]+`), "A unique identifier in the format REGION:GUID."), + stringvalidator.LengthBetween(1, 55), + }, + }, + "identity_pool_id": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`[\w-]+:[0-9a-f-]+`), "A unique identifier in the format REGION:GUID."), + stringvalidator.LengthBetween(1, 55), + }, + }, + "logins": schema.MapAttribute{ + CustomType: fwtypes.MapOfStringType, + Required: true, + Validators: []validator.Map{ + mapvalidator.KeysAre( + stringvalidator.LengthBetween(1, 128), + ), + mapvalidator.ValueStringsAre( + stringvalidator.LengthBetween(1, 50000), + ), + mapvalidator.SizeAtMost(10), + }, + }, + "principal_tags": schema.MapAttribute{ + CustomType: fwtypes.MapOfStringType, + Optional: true, + Validators: []validator.Map{ + mapvalidator.KeysAre( + stringvalidator.LengthBetween(1, 128), + ), + mapvalidator.ValueStringsAre( + stringvalidator.LengthBetween(1, 256), + ), + mapvalidator.SizeAtMost(50), + }, + }, + "token_duration": schema.Int64Attribute{ + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 86400), + }, + }, + "token": schema.StringAttribute{ + Computed: true, + Sensitive: true, + }, + }, + } +} + +func (e *openIDTokenForDeveloperIdentityEphemeralResource) Open(ctx context.Context, request ephemeral.OpenRequest, response *ephemeral.OpenResponse) { + var data openIDTokenForDeveloperIdentityEphemeralResourceModel + response.Diagnostics.Append(request.Config.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := e.Meta().CognitoIdentityClient(ctx) + + var input cognitoidentity.GetOpenIdTokenForDeveloperIdentityInput + response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) + if response.Diagnostics.HasError() { + return + } + + output, err := conn.GetOpenIdTokenForDeveloperIdentity(ctx, &input) + + if err != nil { + response.Diagnostics.AddError("creating Cognito Identity Open ID Connect Token For Developer Identity", err.Error()) + + return + } + + data.IdentityID = fwflex.StringToFramework(ctx, output.IdentityId) + data.Token = fwflex.StringToFramework(ctx, output.Token) + + response.Diagnostics.Append(response.Result.Set(ctx, &data)...) +} + +type openIDTokenForDeveloperIdentityEphemeralResourceModel struct { + IdentityID types.String `tfsdk:"identity_id"` + IdentityPoolID types.String `tfsdk:"identity_pool_id"` + Logins fwtypes.MapOfString `tfsdk:"logins"` + PrincipalTags fwtypes.MapOfString `tfsdk:"principal_tags"` + Token types.String `tfsdk:"token"` + TokenDuration types.Int64 `tfsdk:"token_duration"` +} diff --git a/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral_test.go b/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral_test.go new file mode 100644 index 00000000000..9182a7d3669 --- /dev/null +++ b/internal/service/cognitoidentity/openid_token_for_developer_identity_ephemeral_test.go @@ -0,0 +1,72 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cognitoidentity_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/go-uuid" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccCognitoIdentityOpenIDTokenForDeveloperIdentityEphemeral_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + uuid, err := uuid.GenerateUUID() + developerProviderName := sdkacctest.RandString(10) + echoResourceName := "echo.test" + dataPath := tfjsonpath.New("data") + if err != nil { + t.Logf("error generating uuid: %s", err.Error()) + t.Fail() + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.CognitoIdentityEndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.CognitoIdentityServiceID), + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_10_0), + }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories(ctx, acctest.ProviderNameEcho), + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccOpenIDTokenForDeveloperIdentityEphemeralConfig_basic(rName, developerProviderName, uuid), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(echoResourceName, dataPath.AtMapKey("token"), knownvalue.NotNull()), + }, + }, + }, + }) +} + +func testAccOpenIDTokenForDeveloperIdentityEphemeralConfig_basic(rName, developerProviderName, uuid string) string { + return acctest.ConfigCompose( + acctest.ConfigWithEchoProvider("ephemeral.aws_cognito_identity_openid_token_for_developer_identity.test"), + testAccPoolConfig_developerProviderName(rName, developerProviderName), + fmt.Sprintf(` +data "aws_region" "current" {} + +ephemeral "aws_cognito_identity_openid_token_for_developer_identity" "test" { + identity_pool_id = aws_cognito_identity_pool.test.id + + logins = { + %[2]q = "user123" + } +} +`, rName, developerProviderName, uuid)) +} diff --git a/internal/service/cognitoidentity/service_package_gen.go b/internal/service/cognitoidentity/service_package_gen.go index 48c7e372e0a..82f6d7fde4c 100644 --- a/internal/service/cognitoidentity/service_package_gen.go +++ b/internal/service/cognitoidentity/service_package_gen.go @@ -14,6 +14,15 @@ import ( type servicePackage struct{} +func (p *servicePackage) EphemeralResources(ctx context.Context) []*types.ServicePackageEphemeralResource { + return []*types.ServicePackageEphemeralResource{ + { + Factory: newOpenIDTokenForDeveloperIdentityEphemeralResource, + Name: "Open ID Connect Token For Developer Identity", + }, + } +} + func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { return []*types.ServicePackageFrameworkDataSource{} } diff --git a/website/docs/ephemeral-resources/cognito_identity_openid_token_for_developer_identity.markdown b/website/docs/ephemeral-resources/cognito_identity_openid_token_for_developer_identity.markdown new file mode 100644 index 00000000000..b5dcd1c181f --- /dev/null +++ b/website/docs/ephemeral-resources/cognito_identity_openid_token_for_developer_identity.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "Cognito Identity" +layout: "aws" +page_title: "AWS: aws_cognito_identity_openid_token_for_developer_identity" +description: |- + Terraform ephemeral resource for managing an AWS Cognito Identity Open ID Token for Developer Identity. +--- + + +# Ephemeral: aws_cognito_identity_openid_token_for_developer_identity + +Terraform ephemeral resource for managing an AWS Cognito Identity Open ID Token for Developer Identity. + +~> Ephemeral resources are a new feature and may evolve as we continue to explore their most effective uses. [Learn more](https://developer.hashicorp.com/terraform/language/v1.10.x/resources/ephemeral). + +## Example Usage + +### Basic Usage + +```terraform +data "aws_cognito_identity_pool" "example" { + identity_pool_name = "test pool" +} + +ephemeral "aws_cognito_identity_openid_token_for_developer_identity" "example" { + identity_pool_id = data.aws_cognito_identity_pool.example.id + logins = { + "login.mycompany.myapp" : "USER_IDENTIFIER" + } +} +``` + +## Argument Reference + +The following arguments are required: + +* `identity_pool_id` - (Required) An identity pool ID in the format REGION:GUID. + +The following arguments are optional: + +* `identity_id` - (Optional) A unique identifier in the format REGION:GUID. + +* `logins` - (Optional) A set of optional name-value pairs that map provider names to provider tokens. Each name-value pair represents a user from a public provider or developer provider. If the user is from a developer provider, the name-value pair will follow the syntax `"developer_provider_name": "developer_user_identifier"`. The developer provider is the "domain" by which Cognito will refer to your users; you provided this domain while creating/updating the identity pool. The developer user identifier is an identifier from your backend that uniquely identifies a user. When you create an identity pool, you can specify the supported logins. + +* `principal_tags` - (Optional) Use this operation to configure attribute mappings for custom providers. + +* `token_duration` - (Optional) The expiration time of the token, in seconds. You can specify a custom expiration time for the token so that you can cache it. If you don't provide an expiration time, the token is valid for 15 minutes. You can exchange the token with Amazon STS for temporary AWS credentials, which are valid for a maximum of one hour. The maximum token duration you can set is 24 hours. You should take care in setting the expiration time for a token, as there are significant security implications: an attacker could use a leaked token to access your AWS resources for the token's duration. + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `token` - An OpenID token.