From acc922cb9dd780ee6523d1b6697b26ef7dd56405 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Wed, 10 Jan 2024 21:26:02 -0500 Subject: [PATCH 01/23] feat: add pre_token_generation_config in Cognito User Pool --- .changelog/35234.txt | 3 + examples/cognito-user-pool/main.tf | 6 +- internal/service/cognitoidp/user_pool.go | 52 +++++++++ internal/service/cognitoidp/user_pool_test.go | 105 ++++++++++++++++++ .../python/r/cognito_user_pool.html.markdown | 8 +- .../r/cognito_user_pool.html.markdown | 8 +- .../typescript/r/cognito_user_pool.markdown | 8 +- .../docs/r/cognito_user_pool.html.markdown | 8 +- 8 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 .changelog/35234.txt diff --git a/.changelog/35234.txt b/.changelog/35234.txt new file mode 100644 index 000000000000..ec763cb85c2e --- /dev/null +++ b/.changelog/35234.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_cognito_user_pool: Add `pre_token_generation_config` attribute +``` \ No newline at end of file diff --git a/examples/cognito-user-pool/main.tf b/examples/cognito-user-pool/main.tf index c3d6b2bff66f..3cb729998708 100644 --- a/examples/cognito-user-pool/main.tf +++ b/examples/cognito-user-pool/main.tf @@ -117,7 +117,11 @@ resource "aws_cognito_user_pool" "pool" { post_confirmation = aws_lambda_function.main.arn pre_authentication = aws_lambda_function.main.arn pre_sign_up = aws_lambda_function.main.arn - pre_token_generation = aws_lambda_function.main.arn + pre_token_generation = aws_lambda_function.main.arn # Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `pre_token_generation_config` + pre_token_generation_config { + lambda_arn = aws_lambda_function.main.arn # Should be a identical to the pre_token_generation lambda ARN if used + lambda_version = "V2_0" + } user_migration = aws_lambda_function.main.arn verify_auth_challenge_response = aws_lambda_function.main.arn } diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index ab7debf79968..2c4e3c66de62 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -320,6 +320,25 @@ func ResourceUserPool() *schema.Resource { Optional: true, ValidateFunc: verify.ValidARN, }, + "pre_token_generation_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lambda_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: verify.ValidARN, + }, + "lambda_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(cognitoidentityprovider.PreTokenGenerationLambdaVersionType_Values(), false), + }, + }, + }, + }, "user_migration": { Type: schema.TypeString, Optional: true, @@ -1540,6 +1559,13 @@ func expandUserPoolLambdaConfig(config map[string]interface{}) *cognitoidentityp configs.PreTokenGeneration = aws.String(v.(string)) } + if v, ok := config["pre_token_generation_config"].([]interface{}); ok && len(v) > 0 { + s, sok := v[0].(map[string]interface{}) + if sok && s != nil { + configs.PreTokenGenerationConfig = expandedUserPoolPreGenerationConfig(s) + } + } + if v, ok := config["user_migration"]; ok && v.(string) != "" { configs.UserMigration = aws.String(v.(string)) } @@ -1608,6 +1634,10 @@ func flattenUserPoolLambdaConfig(s *cognitoidentityprovider.LambdaConfigType) [] m["pre_token_generation"] = aws.StringValue(s.PreTokenGeneration) } + if s.PreTokenGenerationConfig != nil { + m["pre_token_generation_config"] = flattenUserPoolPreTokenGenerationConfig(s.PreTokenGenerationConfig) + } + if s.UserMigration != nil { m["user_migration"] = aws.StringValue(s.UserMigration) } @@ -2205,6 +2235,28 @@ func UserPoolSchemaAttributeMatchesStandardAttribute(input *cognitoidentityprovi return false } +func expandedUserPoolPreGenerationConfig(config map[string]interface{}) *cognitoidentityprovider.PreTokenGenerationVersionConfigType { + preTokenGenerationConfig := &cognitoidentityprovider.PreTokenGenerationVersionConfigType{ + LambdaArn: aws.String(config["lambda_arn"].(string)), + LambdaVersion: aws.String(config["lambda_version"].(string)), + } + + return preTokenGenerationConfig +} + +func flattenUserPoolPreTokenGenerationConfig(u *cognitoidentityprovider.PreTokenGenerationVersionConfigType) []map[string]interface{} { + m := map[string]interface{}{} + + if u == nil { + return nil + } + + m["lambda_arn"] = aws.StringValue(u.LambdaArn) + m["lambda_version"] = aws.StringValue(u.LambdaVersion) + + return []map[string]interface{}{m} +} + func expandUserPoolCustomSMSSender(config map[string]interface{}) *cognitoidentityprovider.CustomSMSLambdaVersionConfigType { usernameConfigurationType := &cognitoidentityprovider.CustomSMSLambdaVersionConfigType{ LambdaArn: aws.String(config["lambda_arn"].(string)), diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index 77bc41f5caba..81a18a67b731 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1254,6 +1254,60 @@ func TestAccCognitoIDPUserPool_WithLambda_sms(t *testing.T) { }) } +func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cognito_user_pool.test" + lambdaResourceName := "aws_lambda_function.test" + lambdaUpdatedResourceName := "aws_lambda_function.second" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckUserPoolDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccUserPoolConfig_lambdaSMSSender(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, nil), + resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_version", "V2_0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccUserPoolConfig_lambdaSMSSenderUpdated(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaUpdatedResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_version", "V2_0"), + ), + }, + { + Config: testAccUserPoolConfig_lambdaSMSSenderUpdatedRemove(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "0"), + ), + }, + }, + }) +} + func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) { ctx := acctest.Context(t) var pool1, pool2 cognitoidentityprovider.DescribeUserPoolOutput @@ -2418,6 +2472,57 @@ resource "aws_cognito_user_pool" "test" { `, name)) } +func testAccUserPoolConfig_lambdaPreTokenGenerationConfig(name string) string { + return acctest.ConfigCompose(testAccUserPoolLambdaConfig_base(name), fmt.Sprintf(` +resource "aws_cognito_user_pool" "test" { + name = %[1]q + + lambda_config { + + pre_token_generation_config { + lambda_arn = aws_lambda_function.test.arn + lambda_version = "V2_0" + } + } +} +`, name)) +} + +func testAccUserPoolConfig_lambdaPreTokenGenerationConfigUpdated(name string) string { + return acctest.ConfigCompose(testAccUserPoolLambdaConfig_base(name), fmt.Sprintf(` +resource "aws_lambda_function" "second" { + filename = "test-fixtures/lambdatest.zip" + function_name = "%[1]s_second" + role = aws_iam_role.test.arn + handler = "exports.example" + runtime = "nodejs16.x" +} + +resource "aws_cognito_user_pool" "test" { + name = %[1]q + + lambda_config { + + pre_token_generation_config { + lambda_arn = aws_lambda_function.second.arn + lambda_version = "V2_0" + } + } +} +`, name)) +} + +func testAccUserPoolConfig_lambdaPreTokenGenerationConfigRemove(name string) string { + return acctest.ConfigCompose(testAccUserPoolLambdaConfig_base(name), fmt.Sprintf(` +resource "aws_cognito_user_pool" "test" { + name = %[1]q + + lambda_config { + } +} +`, name)) +} + func testAccUserPoolConfig_schemaAttributes(name string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { diff --git a/website/docs/cdktf/python/r/cognito_user_pool.html.markdown b/website/docs/cdktf/python/r/cognito_user_pool.html.markdown index c8e487a56243..fe96d50b7003 100644 --- a/website/docs/cdktf/python/r/cognito_user_pool.html.markdown +++ b/website/docs/cdktf/python/r/cognito_user_pool.html.markdown @@ -162,7 +162,8 @@ The following arguments are optional: * `post_confirmation` - (Optional) Post-confirmation AWS Lambda trigger. * `pre_authentication` - (Optional) Pre-authentication AWS Lambda trigger. * `pre_sign_up` - (Optional) Pre-registration AWS Lambda trigger. -* `pre_token_generation` - (Optional) Allow to customize identity token claims before token generation. +* `pre_token_generation` - (Optional) Allow to customize identity token claims before token generation. Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `pre_token_generation_config`. +* `pre_token_generation_config` - (Optional) Allow to customize access tokens. See [pre_token_configuration_type](#pre_token_configuration_type) * `user_migration` - (Optional) User migration Lambda config type. * `verify_auth_challenge_response` - (Optional) Verifies the authentication challenge response. * `kms_key_id` - (Optional) The Amazon Resource Name of Key Management Service Customer master keys. Amazon Cognito uses the key to encrypt codes and temporary passwords sent to CustomEmailSender and CustomSMSSender. @@ -179,6 +180,11 @@ The following arguments are optional: * `lambda_arn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to send SMS notifications to users. * `lambda_version` - (Required) The Lambda version represents the signature of the "request" attribute in the "event" information Amazon Cognito passes to your custom SMS Lambda function. The only supported value is `V1_0`. +#### pre_token_configuration + +* `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to customize access tokens. If you also set an ARN in `PreTokenGeneration`, its value must be identical to this one. +* `lambdaVersion` - (Required) The Lambda version represents the signature of the "version" attribute in the "event" information Amazon Cognito passes to your pre Token Generation Lambda function. The supported values are `V1_0`, `V2_0`. + ### password_policy * `minimum_length` - (Optional) Minimum length of the password policy that you have set. diff --git a/website/docs/cdktf/typescript/r/cognito_user_pool.html.markdown b/website/docs/cdktf/typescript/r/cognito_user_pool.html.markdown index d00a72723271..2704543350fb 100644 --- a/website/docs/cdktf/typescript/r/cognito_user_pool.html.markdown +++ b/website/docs/cdktf/typescript/r/cognito_user_pool.html.markdown @@ -176,7 +176,8 @@ The following arguments are optional: * `postConfirmation` - (Optional) Post-confirmation AWS Lambda trigger. * `preAuthentication` - (Optional) Pre-authentication AWS Lambda trigger. * `preSignUp` - (Optional) Pre-registration AWS Lambda trigger. -* `preTokenGeneration` - (Optional) Allow to customize identity token claims before token generation. +* `preTokenGeneration` - (Optional) Allow to customize identity token claims before token generation. Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `PreTokenGenerationConfig`. +* `preTokenGenerationConfig` - (Optional) Allow to customize access tokens. See [pre_token_configuration_type](#pre_token_configuration_type) * `userMigration` - (Optional) User migration Lambda config type. * `verifyAuthChallengeResponse` - (Optional) Verifies the authentication challenge response. * `kmsKeyId` - (Optional) The Amazon Resource Name of Key Management Service Customer master keys. Amazon Cognito uses the key to encrypt codes and temporary passwords sent to CustomEmailSender and CustomSMSSender. @@ -193,6 +194,11 @@ The following arguments are optional: * `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to send SMS notifications to users. * `lambdaVersion` - (Required) The Lambda version represents the signature of the "request" attribute in the "event" information Amazon Cognito passes to your custom SMS Lambda function. The only supported value is `V1_0`. +#### pre_token_configuration + +* `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to customize access tokens. If you also set an ARN in `PreTokenGeneration`, its value must be identical to this one. +* `lambdaVersion` - (Required) The Lambda version represents the signature of the "version" attribute in the "event" information Amazon Cognito passes to your pre Token Generation Lambda function. The supported values are `V1_0`, `V2_0`. + ### password_policy * `minimumLength` - (Optional) Minimum length of the password policy that you have set. diff --git a/website/docs/cdktf/typescript/r/cognito_user_pool.markdown b/website/docs/cdktf/typescript/r/cognito_user_pool.markdown index b003aeb64823..c4b6b0d27fac 100644 --- a/website/docs/cdktf/typescript/r/cognito_user_pool.markdown +++ b/website/docs/cdktf/typescript/r/cognito_user_pool.markdown @@ -176,7 +176,8 @@ The following arguments are optional: * `postConfirmation` - (Optional) Post-confirmation AWS Lambda trigger. * `preAuthentication` - (Optional) Pre-authentication AWS Lambda trigger. * `preSignUp` - (Optional) Pre-registration AWS Lambda trigger. -* `preTokenGeneration` - (Optional) Allow to customize identity token claims before token generation. +* `preTokenGeneration` - (Optional) Allow to customize identity token claims before token generation. Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `PreTokenGenerationConfig`. +* `preTokenGenerationConfig` - (Optional) Allow to customize access tokens. See [pre_token_configuration_type](#pre_token_configuration_type) * `userMigration` - (Optional) User migration Lambda config type. * `verifyAuthChallengeResponse` - (Optional) Verifies the authentication challenge response. * `kmsKeyId` - (Optional) The Amazon Resource Name of Key Management Service Customer master keys. Amazon Cognito uses the key to encrypt codes and temporary passwords sent to CustomEmailSender and CustomSMSSender. @@ -193,6 +194,11 @@ The following arguments are optional: * `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to send SMS notifications to users. * `lambdaVersion` - (Required) The Lambda version represents the signature of the "request" attribute in the "event" information Amazon Cognito passes to your custom SMS Lambda function. The only supported value is `v10`. +#### pre_token_configuration_type + +* `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to customize access tokens. If you also set an ARN in `PreTokenGeneration`, its value must be identical to this one. +* `lambdaVersion` - (Required) The Lambda version represents the signature of the "version" attribute in the "event" information Amazon Cognito passes to your pre Token Generation Lambda function. The supported values are `v10`, `v20`. + ### password_policy * `minimumLength` - (Optional) Minimum length of the password policy that you have set. diff --git a/website/docs/r/cognito_user_pool.html.markdown b/website/docs/r/cognito_user_pool.html.markdown index 09e49aeb038d..3a87f1282065 100644 --- a/website/docs/r/cognito_user_pool.html.markdown +++ b/website/docs/r/cognito_user_pool.html.markdown @@ -132,7 +132,8 @@ The following arguments are optional: * `post_confirmation` - (Optional) Post-confirmation AWS Lambda trigger. * `pre_authentication` - (Optional) Pre-authentication AWS Lambda trigger. * `pre_sign_up` - (Optional) Pre-registration AWS Lambda trigger. -* `pre_token_generation` - (Optional) Allow to customize identity token claims before token generation. +* `pre_token_generation` - (Optional) Allow to customize identity token claims before token generation. Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `pre_token_generation_config`. +* `pre_token_generation_config` - (Optional) Allow to customize access tokens. See [pre_token_configuration_type](#pre_token_configuration_type) * `user_migration` - (Optional) User migration Lambda config type. * `verify_auth_challenge_response` - (Optional) Verifies the authentication challenge response. * `kms_key_id` - (Optional) The Amazon Resource Name of Key Management Service Customer master keys. Amazon Cognito uses the key to encrypt codes and temporary passwords sent to CustomEmailSender and CustomSMSSender. @@ -149,6 +150,11 @@ The following arguments are optional: * `lambda_arn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to send SMS notifications to users. * `lambda_version` - (Required) The Lambda version represents the signature of the "request" attribute in the "event" information Amazon Cognito passes to your custom SMS Lambda function. The only supported value is `V1_0`. +#### pre_token_configuration_type + +* `lambdaArn` - (Required) The Lambda Amazon Resource Name of the Lambda function that Amazon Cognito triggers to customize access tokens. If you also set an ARN in `PreTokenGeneration`, its value must be identical to this one. +* `lambdaVersion` - (Required) The Lambda version represents the signature of the "version" attribute in the "event" information Amazon Cognito passes to your pre Token Generation Lambda function. The supported values are `V1_0`, `V2_0`. + ### password_policy * `minimum_length` - (Optional) Minimum length of the password policy that you have set. From 6738848c72cd607d19edfb0879e3f747ed23c4f4 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Wed, 10 Jan 2024 21:36:47 -0500 Subject: [PATCH 02/23] fix: updating changelog PR number --- .changelog/{35234.txt => 35236.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{35234.txt => 35236.txt} (100%) diff --git a/.changelog/35234.txt b/.changelog/35236.txt similarity index 100% rename from .changelog/35234.txt rename to .changelog/35236.txt From b011e80e5928d77ba1b855fb15ab80286e4d3382 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Wed, 10 Jan 2024 21:48:33 -0500 Subject: [PATCH 03/23] fix: Add advanced security mode to user pool add-ons when pre_token_generation_config is presented --- internal/service/cognitoidp/user_pool_test.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index 81a18a67b731..aecd9caeff5d 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1274,6 +1274,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaResourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_version", "V2_0"), @@ -1290,6 +1291,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaUpdatedResourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_version", "V2_0"), @@ -1301,6 +1303,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), + resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "0"), ), }, @@ -2477,8 +2480,11 @@ func testAccUserPoolConfig_lambdaPreTokenGenerationConfig(name string) string { resource "aws_cognito_user_pool" "test" { name = %[1]q - lambda_config { + user_pool_add_ons { + advanced_security_mode = "ENFORCED" + } + lambda_config { pre_token_generation_config { lambda_arn = aws_lambda_function.test.arn lambda_version = "V2_0" @@ -2501,8 +2507,11 @@ resource "aws_lambda_function" "second" { resource "aws_cognito_user_pool" "test" { name = %[1]q - lambda_config { + user_pool_add_ons { + advanced_security_mode = "ENFORCED" + } + lambda_config { pre_token_generation_config { lambda_arn = aws_lambda_function.second.arn lambda_version = "V2_0" @@ -2517,6 +2526,10 @@ func testAccUserPoolConfig_lambdaPreTokenGenerationConfigRemove(name string) str resource "aws_cognito_user_pool" "test" { name = %[1]q + user_pool_add_ons { + advanced_security_mode = "ENFORCED" + } + lambda_config { } } From d07c802469be6fe77f72fc43443466527181bc03 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Wed, 10 Jan 2024 22:41:38 -0500 Subject: [PATCH 04/23] fix: fix config function names --- internal/service/cognitoidp/user_pool_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index aecd9caeff5d..0a6540069428 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1268,7 +1268,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) CheckDestroy: testAccCheckUserPoolDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccUserPoolConfig_lambdaSMSSender(rName), + Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckUserPoolExists(ctx, resourceName, nil), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), @@ -1286,7 +1286,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) ImportStateVerify: true, }, { - Config: testAccUserPoolConfig_lambdaSMSSenderUpdated(rName), + Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfigUpdated(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), @@ -1298,7 +1298,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) ), }, { - Config: testAccUserPoolConfig_lambdaSMSSenderUpdatedRemove(rName), + Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfigRemove(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), From 30d57aa920e3a1b527bc1f82b573157abc50d8e6 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Thu, 11 Jan 2024 00:23:23 -0500 Subject: [PATCH 05/23] fix: Only one configuration pre_token_generation or pre_token_generation_config --- internal/service/cognitoidp/user_pool.go | 14 ++++---------- internal/service/cognitoidp/user_pool_test.go | 4 +--- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index 2c4e3c66de62..3d383b849e62 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -1121,7 +1121,6 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in if v, ok := d.GetOk("lambda_config"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) - if ok && config != nil { input.LambdaConfig = expandUserPoolLambdaConfig(config) } @@ -1555,15 +1554,13 @@ func expandUserPoolLambdaConfig(config map[string]interface{}) *cognitoidentityp configs.PreSignUp = aws.String(v.(string)) } - if v, ok := config["pre_token_generation"]; ok && v.(string) != "" { - configs.PreTokenGeneration = aws.String(v.(string)) - } - if v, ok := config["pre_token_generation_config"].([]interface{}); ok && len(v) > 0 { s, sok := v[0].(map[string]interface{}) if sok && s != nil { configs.PreTokenGenerationConfig = expandedUserPoolPreGenerationConfig(s) } + } else if v, ok := config["pre_token_generation"]; ok && v.(string) != "" { + configs.PreTokenGeneration = aws.String(v.(string)) } if v, ok := config["user_migration"]; ok && v.(string) != "" { @@ -1597,7 +1594,6 @@ func expandUserPoolLambdaConfig(config map[string]interface{}) *cognitoidentityp func flattenUserPoolLambdaConfig(s *cognitoidentityprovider.LambdaConfigType) []map[string]interface{} { m := map[string]interface{}{} - if s == nil { return nil } @@ -1630,12 +1626,10 @@ func flattenUserPoolLambdaConfig(s *cognitoidentityprovider.LambdaConfigType) [] m["pre_sign_up"] = aws.StringValue(s.PreSignUp) } - if s.PreTokenGeneration != nil { - m["pre_token_generation"] = aws.StringValue(s.PreTokenGeneration) - } - if s.PreTokenGenerationConfig != nil { m["pre_token_generation_config"] = flattenUserPoolPreTokenGenerationConfig(s.PreTokenGenerationConfig) + } else if s.PreTokenGeneration != nil { + m["pre_token_generation"] = aws.StringValue(s.PreTokenGeneration) } if s.UserMigration != nil { diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index 0a6540069428..1f66fa2dd80f 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1300,7 +1300,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) { Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfigRemove(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), @@ -2530,8 +2530,6 @@ resource "aws_cognito_user_pool" "test" { advanced_security_mode = "ENFORCED" } - lambda_config { - } } `, name)) } From d36347000c344a78879698cfb9a990b8b35f8c85 Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Thu, 11 Jan 2024 20:34:51 -0500 Subject: [PATCH 06/23] fix: Making pre_token_generation and pre_token_generation_config fields live together. --- internal/service/cognitoidp/user_pool.go | 45 ++++++++++++++++--- internal/service/cognitoidp/user_pool_test.go | 6 --- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index 3d383b849e62..65540dd951ad 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -16,6 +16,7 @@ import ( "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -318,11 +319,13 @@ func ResourceUserPool() *schema.Resource { "pre_token_generation": { Type: schema.TypeString, Optional: true, + Computed: true, ValidateFunc: verify.ValidARN, }, "pre_token_generation_config": { Type: schema.TypeList, Optional: true, + Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -633,7 +636,27 @@ func ResourceUserPool() *schema.Resource { }, }, - CustomizeDiff: verify.SetTagsDiff, + CustomizeDiff: customdiff.Sequence( + // func(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error { + + // // check if pre_token_generation exists + // // if it does, then we need to check if the pre_token_generation has changes + // // if it does, we need to set the pre_token_generation_config lambda_arn to be the same as the pre_token_generation lambda_arn + + // if diff.HasChange("lambda_config") { + // if diff.HasChange("lambda_config.0.pre_token_generation") { + // diff.SetNewComputed("lambda_config.0.pre_token_generation_config.0.lambda_arn") + // } + + // if diff.HasChange("lambda_config.0.pre_token_generation_config") { + // diff.SetNewComputed("lambda_config.0.pre_token_generation") + // } + // } + + // return nil + // }, + verify.SetTagsDiff, + ), } } @@ -1122,6 +1145,14 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) if ok && config != nil { + if d.HasChange("lambda_config.0.pre_token_generation") { + config["pre_token_generation_config"].([]interface{})[0].(map[string]interface{})["lambda_arn"] = d.Get("lambda_config.0.pre_token_generation") + } + + if d.HasChange("lambda_config.0.pre_token_generation_config.0.lambda_arn") { + config["pre_token_generation"] = d.Get("lambda_config.0.pre_token_generation_config.0.lambda_arn") + } + input.LambdaConfig = expandUserPoolLambdaConfig(config) } } @@ -1554,13 +1585,15 @@ func expandUserPoolLambdaConfig(config map[string]interface{}) *cognitoidentityp configs.PreSignUp = aws.String(v.(string)) } + if v, ok := config["pre_token_generation"]; ok && v.(string) != "" { + configs.PreTokenGeneration = aws.String(v.(string)) + } + if v, ok := config["pre_token_generation_config"].([]interface{}); ok && len(v) > 0 { s, sok := v[0].(map[string]interface{}) if sok && s != nil { configs.PreTokenGenerationConfig = expandedUserPoolPreGenerationConfig(s) } - } else if v, ok := config["pre_token_generation"]; ok && v.(string) != "" { - configs.PreTokenGeneration = aws.String(v.(string)) } if v, ok := config["user_migration"]; ok && v.(string) != "" { @@ -1626,10 +1659,12 @@ func flattenUserPoolLambdaConfig(s *cognitoidentityprovider.LambdaConfigType) [] m["pre_sign_up"] = aws.StringValue(s.PreSignUp) } + if s.PreTokenGeneration != nil { + m["pre_token_generation"] = aws.StringValue(s.PreTokenGeneration) + } + if s.PreTokenGenerationConfig != nil { m["pre_token_generation_config"] = flattenUserPoolPreTokenGenerationConfig(s.PreTokenGenerationConfig) - } else if s.PreTokenGeneration != nil { - m["pre_token_generation"] = aws.StringValue(s.PreTokenGeneration) } if s.UserMigration != nil { diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index 1f66fa2dd80f..0facdb01da35 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1272,8 +1272,6 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) Check: resource.ComposeAggregateTestCheckFunc( testAccCheckUserPoolExists(ctx, resourceName, nil), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaResourceName, "arn"), @@ -1289,8 +1287,6 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfigUpdated(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.pre_token_generation_config.0.lambda_arn", lambdaUpdatedResourceName, "arn"), @@ -1301,8 +1297,6 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfigRemove(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "0"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), - resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "0"), ), From 1fc804f06726579abc001ecec53fac845d6e456f Mon Sep 17 00:00:00 2001 From: Andres Morelos Date: Thu, 11 Jan 2024 22:31:27 -0500 Subject: [PATCH 07/23] fix: Removing big comment and customdiff helper --- internal/service/cognitoidp/user_pool.go | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index 65540dd951ad..e229dd3cced5 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -16,7 +16,6 @@ import ( "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -636,27 +635,7 @@ func ResourceUserPool() *schema.Resource { }, }, - CustomizeDiff: customdiff.Sequence( - // func(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error { - - // // check if pre_token_generation exists - // // if it does, then we need to check if the pre_token_generation has changes - // // if it does, we need to set the pre_token_generation_config lambda_arn to be the same as the pre_token_generation lambda_arn - - // if diff.HasChange("lambda_config") { - // if diff.HasChange("lambda_config.0.pre_token_generation") { - // diff.SetNewComputed("lambda_config.0.pre_token_generation_config.0.lambda_arn") - // } - - // if diff.HasChange("lambda_config.0.pre_token_generation_config") { - // diff.SetNewComputed("lambda_config.0.pre_token_generation") - // } - // } - - // return nil - // }, - verify.SetTagsDiff, - ), + CustomizeDiff: verify.SetTagsDiff, } } From e9abb2d0a6fb4ec9b85bfa92a1cea7a8c39f97a3 Mon Sep 17 00:00:00 2001 From: Jacob Doetsch Date: Mon, 11 Mar 2024 17:02:42 -0700 Subject: [PATCH 08/23] Prevent read-only ActiveEncryptionCertificate property from being used in ProviderDetails for UpdateIdentityProvider call --- internal/service/cognitoidp/identity_provider.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/service/cognitoidp/identity_provider.go b/internal/service/cognitoidp/identity_provider.go index 2c055c76ab86..76e87cdc8b40 100644 --- a/internal/service/cognitoidp/identity_provider.go +++ b/internal/service/cognitoidp/identity_provider.go @@ -201,7 +201,9 @@ func resourceIdentityProviderUpdate(ctx context.Context, d *schema.ResourceData, } if d.HasChange("provider_details") { - params.ProviderDetails = flex.ExpandStringMap(d.Get("provider_details").(map[string]interface{})) + providerDetailsForUpdate := flex.ExpandStringMap(d.Get("provider_details").(map[string]interface{})) + delete(providerDetailsForUpdate, "ActiveEncryptionCertificate") + params.ProviderDetails = providerDetailsForUpdate } if d.HasChange("idp_identifiers") { From 85c09da5b3787ddd817a8e01ea02fc0ab83a2203 Mon Sep 17 00:00:00 2001 From: Jacob Doetsch Date: Tue, 12 Mar 2024 09:53:51 -0700 Subject: [PATCH 09/23] Add changelog file --- .changelog/36311.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/36311.txt diff --git a/.changelog/36311.txt b/.changelog/36311.txt new file mode 100644 index 000000000000..bd8f59571b1e --- /dev/null +++ b/.changelog/36311.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_cognito_identity_provider: Ensure read-only property ActiveEncryptionCertificate is not used in UpdateIdentityProvider request +``` \ No newline at end of file From aa0dbffafa2f15cf52e3c8f8a3942b5e368cc6e1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 12 Mar 2024 15:48:13 -0400 Subject: [PATCH 10/23] Tweak CHANGELOG entries. --- .changelog/35236.txt | 2 +- .changelog/36311.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changelog/35236.txt b/.changelog/35236.txt index ec763cb85c2e..19cbdb5512b0 100644 --- a/.changelog/35236.txt +++ b/.changelog/35236.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_cognito_user_pool: Add `pre_token_generation_config` attribute +resource/aws_cognito_user_pool: Add `pre_token_generation_config` configuration block ``` \ No newline at end of file diff --git a/.changelog/36311.txt b/.changelog/36311.txt index bd8f59571b1e..991eeb2dfddc 100644 --- a/.changelog/36311.txt +++ b/.changelog/36311.txt @@ -1,3 +1,3 @@ ```release-note:bug -resource/aws_cognito_identity_provider: Ensure read-only property ActiveEncryptionCertificate is not used in UpdateIdentityProvider request +resource/aws_cognito_identity_provider: Fix `InvalidParameterException: ActiveEncryptionCertificate is not a valid key for SAML identity provider details` errors on resource Update ``` \ No newline at end of file From b81c93077fe5283c91c913dff8b4c038b95774e1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 12 Mar 2024 16:31:55 -0400 Subject: [PATCH 11/23] r/aws_cognito_identity_provider: Reduce visibility. --- internal/service/cognitoidp/consts.go | 1 - internal/service/cognitoidp/exports_test.go | 6 +- .../service/cognitoidp/identity_provider.go | 165 +++++++++--------- .../cognitoidp/identity_provider_test.go | 44 ++--- .../service/cognitoidp/service_package_gen.go | 3 +- 5 files changed, 105 insertions(+), 114 deletions(-) diff --git a/internal/service/cognitoidp/consts.go b/internal/service/cognitoidp/consts.go index 009281f3c711..b2e0c3f732ed 100644 --- a/internal/service/cognitoidp/consts.go +++ b/internal/service/cognitoidp/consts.go @@ -8,7 +8,6 @@ import ( ) const ( - ResNameIdentityProvider = "Identity Provider" ResNameResourceServer = "Resource Server" ResNameRiskConfiguration = "Risk Configuration" ResNameUserPoolClient = "User Pool Client" diff --git a/internal/service/cognitoidp/exports_test.go b/internal/service/cognitoidp/exports_test.go index 9cbdaee84841..31d4b3d7fb55 100644 --- a/internal/service/cognitoidp/exports_test.go +++ b/internal/service/cognitoidp/exports_test.go @@ -5,9 +5,11 @@ package cognitoidp // Exports for use in tests only. var ( + ResourceIdentityProvider = resourceIdentityProvider + ResourceManagedUserPoolClient = newResourceManagedUserPoolClient ResourceUserGroup = resourceUserGroup ResourceUserPoolClient = newResourceUserPoolClient - ResourceManagedUserPoolClient = newResourceManagedUserPoolClient - FindGroupByTwoPartKey = findGroupByTwoPartKey + FindGroupByTwoPartKey = findGroupByTwoPartKey + FindIdentityProviderByTwoPartKey = findIdentityProviderByTwoPartKey ) diff --git a/internal/service/cognitoidp/identity_provider.go b/internal/service/cognitoidp/identity_provider.go index 76e87cdc8b40..7233cfa9c038 100644 --- a/internal/service/cognitoidp/identity_provider.go +++ b/internal/service/cognitoidp/identity_provider.go @@ -5,7 +5,6 @@ package cognitoidp import ( "context" - "errors" "fmt" "log" "strings" @@ -15,17 +14,17 @@ import ( "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/flex" - "github.com/hashicorp/terraform-provider-aws/names" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_cognito_identity_provider") -func ResourceIdentityProvider() *schema.Resource { +// @SDKResource("aws_cognito_identity_provider", name="Identity Provider") +func resourceIdentityProvider() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceIdentityProviderCreate, ReadWithoutTimeout: resourceIdentityProviderRead, @@ -45,7 +44,6 @@ func ResourceIdentityProvider() *schema.Resource { Type: schema.TypeString, }, }, - "idp_identifiers": { Type: schema.TypeList, Optional: true, @@ -58,13 +56,11 @@ func ResourceIdentityProvider() *schema.Resource { ), }, }, - "provider_details": { Type: schema.TypeMap, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "provider_name": { Type: schema.TypeString, Required: true, @@ -74,14 +70,12 @@ func ResourceIdentityProvider() *schema.Resource { validation.StringMatch(regexache.MustCompile(`^[^_][\p{L}\p{M}\p{S}\p{N}\p{P}][^_]+$`), "see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#API_CreateIdentityProvider_RequestSyntax"), ), }, - "provider_type": { Type: schema.TypeString, Required: true, ForceNew: true, ValidateFunc: validation.StringInSlice(cognitoidentityprovider.IdentityProviderTypeType_Values(), false), }, - "user_pool_id": { Type: schema.TypeString, Required: true, @@ -94,34 +88,35 @@ func ResourceIdentityProvider() *schema.Resource { func resourceIdentityProviderCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - log.Print("[DEBUG] Creating Cognito Identity Provider") providerName := d.Get("provider_name").(string) userPoolID := d.Get("user_pool_id").(string) - params := &cognitoidentityprovider.CreateIdentityProviderInput{ + id := identityProviderCreateResourceID(userPoolID, providerName) + input := &cognitoidentityprovider.CreateIdentityProviderInput{ ProviderName: aws.String(providerName), ProviderType: aws.String(d.Get("provider_type").(string)), UserPoolId: aws.String(userPoolID), } - if v, ok := d.GetOk("attribute_mapping"); ok { - params.AttributeMapping = flex.ExpandStringMap(v.(map[string]interface{})) + if v, ok := d.GetOk("attribute_mapping"); ok && len(v.(map[string]interface{})) > 0 { + input.AttributeMapping = flex.ExpandStringMap(v.(map[string]interface{})) } - if v, ok := d.GetOk("provider_details"); ok { - params.ProviderDetails = flex.ExpandStringMap(v.(map[string]interface{})) + if v, ok := d.GetOk("idp_identifiers"); ok && len(v.([]interface{})) > 0 { + input.IdpIdentifiers = flex.ExpandStringList(v.([]interface{})) } - if v, ok := d.GetOk("idp_identifiers"); ok { - params.IdpIdentifiers = flex.ExpandStringList(v.([]interface{})) + if v, ok := d.GetOk("provider_details"); ok && len(v.(map[string]interface{})) > 0 { + input.ProviderDetails = flex.ExpandStringMap(v.(map[string]interface{})) } - _, err := conn.CreateIdentityProviderWithContext(ctx, params) + _, err := conn.CreateIdentityProviderWithContext(ctx, input) + if err != nil { - return sdkdiag.AppendErrorf(diags, "creating Cognito Identity Provider: %s", err) + return sdkdiag.AppendErrorf(diags, "creating Cognito Identity Provider (%s): %s", id, err) } - d.SetId(fmt.Sprintf("%s:%s", userPoolID, providerName)) + d.SetId(id) return append(diags, resourceIdentityProviderRead(ctx, d, meta)...) } @@ -129,54 +124,30 @@ func resourceIdentityProviderCreate(ctx context.Context, d *schema.ResourceData, func resourceIdentityProviderRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - log.Printf("[DEBUG] Reading Cognito Identity Provider: %s", d.Id()) - userPoolID, providerName, err := DecodeIdentityProviderID(d.Id()) + userPoolID, providerName, err := identityProviderParseResourceID(d.Id()) if err != nil { - return create.AppendDiagError(diags, names.CognitoIDP, create.ErrActionReading, ResNameIdentityProvider, d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - ret, err := conn.DescribeIdentityProviderWithContext(ctx, &cognitoidentityprovider.DescribeIdentityProviderInput{ - ProviderName: aws.String(providerName), - UserPoolId: aws.String(userPoolID), - }) + idp, err := findIdentityProviderByTwoPartKey(ctx, conn, userPoolID, providerName) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - create.LogNotFoundRemoveState(names.CognitoIDP, create.ErrActionReading, ResNameIdentityProvider, d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Cognito Identity Provider %s not found, removing from state", d.Id()) d.SetId("") return diags } if err != nil { - return create.AppendDiagError(diags, names.CognitoIDP, create.ErrActionReading, ResNameIdentityProvider, d.Id(), err) - } - - if !d.IsNewResource() && (ret == nil || ret.IdentityProvider == nil) { - create.LogNotFoundRemoveState(names.CognitoIDP, create.ErrActionReading, ResNameIdentityProvider, d.Id()) - d.SetId("") - return diags - } - - if d.IsNewResource() && (ret == nil || ret.IdentityProvider == nil) { - return create.AppendDiagError(diags, names.CognitoIDP, create.ErrActionReading, ResNameIdentityProvider, d.Id(), errors.New("not found after creation")) - } - - ip := ret.IdentityProvider - d.Set("provider_name", ip.ProviderName) - d.Set("provider_type", ip.ProviderType) - d.Set("user_pool_id", ip.UserPoolId) - - if err := d.Set("attribute_mapping", aws.StringValueMap(ip.AttributeMapping)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting attribute_mapping error: %s", err) + return sdkdiag.AppendErrorf(diags, "reading Cognito Identity Provider (%s): %s", d.Id(), err) } - if err := d.Set("provider_details", aws.StringValueMap(ip.ProviderDetails)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting provider_details error: %s", err) - } - - if err := d.Set("idp_identifiers", flex.FlattenStringList(ip.IdpIdentifiers)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting idp_identifiers error: %s", err) - } + d.Set("attribute_mapping", aws.StringValueMap(idp.AttributeMapping)) + d.Set("idp_identifiers", aws.StringValueSlice(idp.IdpIdentifiers)) + d.Set("provider_details", aws.StringValueMap(idp.ProviderDetails)) + d.Set("provider_name", idp.ProviderName) + d.Set("provider_type", idp.ProviderType) + d.Set("user_pool_id", idp.UserPoolId) return diags } @@ -184,33 +155,33 @@ func resourceIdentityProviderRead(ctx context.Context, d *schema.ResourceData, m func resourceIdentityProviderUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - log.Print("[DEBUG] Updating Cognito Identity Provider") - userPoolID, providerName, err := DecodeIdentityProviderID(d.Id()) + userPoolID, providerName, err := identityProviderParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "updating Cognito Identity Provider (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - params := &cognitoidentityprovider.UpdateIdentityProviderInput{ + input := &cognitoidentityprovider.UpdateIdentityProviderInput{ ProviderName: aws.String(providerName), UserPoolId: aws.String(userPoolID), } if d.HasChange("attribute_mapping") { - params.AttributeMapping = flex.ExpandStringMap(d.Get("attribute_mapping").(map[string]interface{})) + input.AttributeMapping = flex.ExpandStringMap(d.Get("attribute_mapping").(map[string]interface{})) + } + + if d.HasChange("idp_identifiers") { + input.IdpIdentifiers = flex.ExpandStringList(d.Get("idp_identifiers").([]interface{})) } if d.HasChange("provider_details") { providerDetailsForUpdate := flex.ExpandStringMap(d.Get("provider_details").(map[string]interface{})) delete(providerDetailsForUpdate, "ActiveEncryptionCertificate") - params.ProviderDetails = providerDetailsForUpdate + input.ProviderDetails = providerDetailsForUpdate } - if d.HasChange("idp_identifiers") { - params.IdpIdentifiers = flex.ExpandStringList(d.Get("idp_identifiers").([]interface{})) - } + _, err = conn.UpdateIdentityProviderWithContext(ctx, input) - _, err = conn.UpdateIdentityProviderWithContext(ctx, params) if err != nil { return sdkdiag.AppendErrorf(diags, "updating Cognito Identity Provider (%s): %s", d.Id(), err) } @@ -221,32 +192,70 @@ func resourceIdentityProviderUpdate(ctx context.Context, d *schema.ResourceData, func resourceIdentityProviderDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - log.Printf("[DEBUG] Deleting Cognito Identity Provider: %s", d.Id()) - userPoolID, providerName, err := DecodeIdentityProviderID(d.Id()) + userPoolID, providerName, err := identityProviderParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting Cognito Identity Provider (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } + log.Printf("[DEBUG] Deleting Cognito Identity Provider: %s", d.Id()) _, err = conn.DeleteIdentityProviderWithContext(ctx, &cognitoidentityprovider.DeleteIdentityProviderInput{ ProviderName: aws.String(providerName), UserPoolId: aws.String(userPoolID), }) + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return diags + } + if err != nil { - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - return diags - } return sdkdiag.AppendErrorf(diags, "deleting Cognito Identity Provider (%s): %s", d.Id(), err) } return diags } -func DecodeIdentityProviderID(id string) (string, string, error) { - idParts := strings.Split(id, ":") - if len(idParts) != 2 { - return "", "", fmt.Errorf("expected ID in format UserPoolID:ProviderName, received: %s", id) +const identityProviderResourceIDSeparator = ":" + +func identityProviderCreateResourceID(userPoolID, providerName string) string { + parts := []string{userPoolID, providerName} + id := strings.Join(parts, identityProviderResourceIDSeparator) + + return id +} + +func identityProviderParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, identityProviderResourceIDSeparator) + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil } - return idParts[0], idParts[1], nil + + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected UserPoolID%[2]sProviderName", id, identityProviderResourceIDSeparator) +} + +func findIdentityProviderByTwoPartKey(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolID, providerName string) (*cognitoidentityprovider.IdentityProviderType, error) { + input := &cognitoidentityprovider.DescribeIdentityProviderInput{ + ProviderName: aws.String(providerName), + UserPoolId: aws.String(userPoolID), + } + + output, err := conn.DescribeIdentityProviderWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil || output.IdentityProvider == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output.IdentityProvider, nil } diff --git a/internal/service/cognitoidp/identity_provider_test.go b/internal/service/cognitoidp/identity_provider_test.go index 786e014429de..46d64eab1faf 100644 --- a/internal/service/cognitoidp/identity_provider_test.go +++ b/internal/service/cognitoidp/identity_provider_test.go @@ -8,15 +8,14 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfcognitoidp "github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -176,58 +175,39 @@ func testAccCheckIdentityProviderDestroy(ctx context.Context) resource.TestCheck continue } - userPoolID, providerName, err := tfcognitoidp.DecodeIdentityProviderID(rs.Primary.ID) - if err != nil { - return err - } + _, err := tfcognitoidp.FindIdentityProviderByTwoPartKey(ctx, conn, rs.Primary.Attributes["user_pool_id"], rs.Primary.Attributes["provider_name"]) - _, err = conn.DescribeIdentityProviderWithContext(ctx, &cognitoidentityprovider.DescribeIdentityProviderInput{ - ProviderName: aws.String(providerName), - UserPoolId: aws.String(userPoolID), - }) + if tfresource.NotFound(err) { + continue + } if err != nil { - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - return nil - } return err } + + return fmt.Errorf("Cognito Identity Provider %s still exists", rs.Primary.ID) } return nil } } -func testAccCheckIdentityProviderExists(ctx context.Context, resourceName string, identityProvider *cognitoidentityprovider.IdentityProviderType) resource.TestCheckFunc { +func testAccCheckIdentityProviderExists(ctx context.Context, n string, v *cognitoidentityprovider.IdentityProviderType) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } - - userPoolID, providerName, err := tfcognitoidp.DecodeIdentityProviderID(rs.Primary.ID) - if err != nil { - return err + return fmt.Errorf("Not found: %s", n) } conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn(ctx) - input := &cognitoidentityprovider.DescribeIdentityProviderInput{ - ProviderName: aws.String(providerName), - UserPoolId: aws.String(userPoolID), - } - - output, err := conn.DescribeIdentityProviderWithContext(ctx, input) + output, err := tfcognitoidp.FindIdentityProviderByTwoPartKey(ctx, conn, rs.Primary.Attributes["user_pool_id"], rs.Primary.Attributes["provider_name"]) if err != nil { return err } - if output == nil || output.IdentityProvider == nil { - return fmt.Errorf("Cognito Identity Provider %q does not exist", rs.Primary.ID) - } - - *identityProvider = *output.IdentityProvider + *v = *output return nil } diff --git a/internal/service/cognitoidp/service_package_gen.go b/internal/service/cognitoidp/service_package_gen.go index f9730b166a36..4f2b9b622397 100644 --- a/internal/service/cognitoidp/service_package_gen.go +++ b/internal/service/cognitoidp/service_package_gen.go @@ -63,8 +63,9 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePackageSDKResource { return []*types.ServicePackageSDKResource{ { - Factory: ResourceIdentityProvider, + Factory: resourceIdentityProvider, TypeName: "aws_cognito_identity_provider", + Name: "Identity Provider", }, { Factory: ResourceResourceServer, From ee58d1f2a3dc9fb90f172cb791595601006dec25 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 12 Mar 2024 17:17:58 -0400 Subject: [PATCH 12/23] Add 'TestAccCognitoIDPIdentityProvider_saml'. --- .../service/cognitoidp/identity_provider.go | 6 +- .../cognitoidp/identity_provider_test.go | 82 +++++++++++++++++++ 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/internal/service/cognitoidp/identity_provider.go b/internal/service/cognitoidp/identity_provider.go index 7233cfa9c038..19ddaed8aa92 100644 --- a/internal/service/cognitoidp/identity_provider.go +++ b/internal/service/cognitoidp/identity_provider.go @@ -175,9 +175,9 @@ func resourceIdentityProviderUpdate(ctx context.Context, d *schema.ResourceData, } if d.HasChange("provider_details") { - providerDetailsForUpdate := flex.ExpandStringMap(d.Get("provider_details").(map[string]interface{})) - delete(providerDetailsForUpdate, "ActiveEncryptionCertificate") - input.ProviderDetails = providerDetailsForUpdate + v := flex.ExpandStringMap(d.Get("provider_details").(map[string]interface{})) + delete(v, "ActiveEncryptionCertificate") + input.ProviderDetails = v } _, err = conn.UpdateIdentityProviderWithContext(ctx, input) diff --git a/internal/service/cognitoidp/identity_provider_test.go b/internal/service/cognitoidp/identity_provider_test.go index 46d64eab1faf..bfc1c140cc6e 100644 --- a/internal/service/cognitoidp/identity_provider_test.go +++ b/internal/service/cognitoidp/identity_provider_test.go @@ -118,6 +118,59 @@ func TestAccCognitoIDPIdentityProvider_idpIdentifiers(t *testing.T) { }) } +func TestAccCognitoIDPIdentityProvider_saml(t *testing.T) { + ctx := acctest.Context(t) + var identityProvider cognitoidentityprovider.IdentityProviderType + resourceName := "aws_cognito_identity_provider.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CognitoIDPServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckIdentityProviderDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccIdentityProviderConfig_saml(rName, "false"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), + resource.TestCheckResourceAttr(resourceName, "attribute_mapping.%", "1"), + resource.TestCheckResourceAttr(resourceName, "attribute_mapping.email", "email"), + resource.TestCheckNoResourceAttr(resourceName, "idp_identifiers.#"), + resource.TestCheckResourceAttr(resourceName, "provider_details.%", "4"), + resource.TestCheckResourceAttrSet(resourceName, "provider_details.ActiveEncryptionCertificate"), + resource.TestCheckResourceAttr(resourceName, "provider_details.EncryptedResponses", "false"), + resource.TestCheckResourceAttrSet(resourceName, "provider_details.MetadataFile"), + resource.TestCheckResourceAttr(resourceName, "provider_details.SSORedirectBindingURI", "https://terraform-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect"), + resource.TestCheckResourceAttr(resourceName, "provider_name", rName), + resource.TestCheckResourceAttr(resourceName, "provider_type", "SAML"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccIdentityProviderConfig_saml(rName, "true"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), + resource.TestCheckResourceAttr(resourceName, "attribute_mapping.%", "1"), + resource.TestCheckResourceAttr(resourceName, "attribute_mapping.email", "email"), + resource.TestCheckNoResourceAttr(resourceName, "idp_identifiers.#"), + resource.TestCheckResourceAttr(resourceName, "provider_details.%", "4"), + resource.TestCheckResourceAttrSet(resourceName, "provider_details.ActiveEncryptionCertificate"), + resource.TestCheckResourceAttr(resourceName, "provider_details.EncryptedResponses", "true"), + resource.TestCheckResourceAttrSet(resourceName, "provider_details.MetadataFile"), + resource.TestCheckResourceAttr(resourceName, "provider_details.SSORedirectBindingURI", "https://terraform-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect"), + resource.TestCheckResourceAttr(resourceName, "provider_name", rName), + resource.TestCheckResourceAttr(resourceName, "provider_type", "SAML"), + ), + }, + }, + }) +} + func TestAccCognitoIDPIdentityProvider_disappears(t *testing.T) { ctx := acctest.Context(t) var identityProvider cognitoidentityprovider.IdentityProviderType @@ -300,3 +353,32 @@ resource "aws_cognito_identity_provider" "test" { } `, userPoolName, attribute) } + +func testAccIdentityProviderConfig_saml(rName, encryptedResponses string) string { + return fmt.Sprintf(` +resource "aws_cognito_user_pool" "test" { + name = %[1]q + auto_verified_attributes = ["email"] +} + +resource "aws_cognito_identity_provider" "test" { + user_pool_id = aws_cognito_user_pool.test.id + provider_name = %[1]q + provider_type = "SAML" + + provider_details = { + EncryptedResponses = %[2]q + MetadataFile = file("./test-fixtures/saml-metadata.xml") + SSORedirectBindingURI = "https://terraform-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect" + } + + attribute_mapping = { + email = "email" + } + + lifecycle { + ignore_changes = [provider_details["ActiveEncryptionCertificate"]] + } +} +`, rName, encryptedResponses) +} From 750d13b08044348f9785e3fcaf1a905fb213601e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 12 Mar 2024 17:20:35 -0400 Subject: [PATCH 13/23] r/aws_cognito_identity_provider: Tidy up acceptance tests. --- .../cognitoidp/identity_provider_test.go | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/internal/service/cognitoidp/identity_provider_test.go b/internal/service/cognitoidp/identity_provider_test.go index bfc1c140cc6e..58014d5f6540 100644 --- a/internal/service/cognitoidp/identity_provider_test.go +++ b/internal/service/cognitoidp/identity_provider_test.go @@ -23,7 +23,7 @@ func TestAccCognitoIDPIdentityProvider_basic(t *testing.T) { ctx := acctest.Context(t) var identityProvider cognitoidentityprovider.IdentityProviderType resourceName := "aws_cognito_identity_provider.test" - userPoolName := fmt.Sprintf("tf-acc-cognito-user-pool-%s", sdkacctest.RandString(7)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, @@ -32,7 +32,7 @@ func TestAccCognitoIDPIdentityProvider_basic(t *testing.T) { CheckDestroy: testAccCheckIdentityProviderDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccIdentityProviderConfig_basic(userPoolName), + Config: testAccIdentityProviderConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), resource.TestCheckResourceAttr(resourceName, "attribute_mapping.%", "1"), @@ -52,7 +52,7 @@ func TestAccCognitoIDPIdentityProvider_basic(t *testing.T) { ), }, { - Config: testAccIdentityProviderConfig_basicUpdated(userPoolName), + Config: testAccIdentityProviderConfig_basicUpdated(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), resource.TestCheckResourceAttr(resourceName, "attribute_mapping.%", "2"), @@ -85,7 +85,7 @@ func TestAccCognitoIDPIdentityProvider_idpIdentifiers(t *testing.T) { ctx := acctest.Context(t) var identityProvider cognitoidentityprovider.IdentityProviderType resourceName := "aws_cognito_identity_provider.test" - userPoolName := fmt.Sprintf("tf-acc-cognito-user-pool-%s", sdkacctest.RandString(7)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, @@ -94,7 +94,7 @@ func TestAccCognitoIDPIdentityProvider_idpIdentifiers(t *testing.T) { CheckDestroy: testAccCheckIdentityProviderDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccIdentityProviderConfig_identifier(userPoolName, "test"), + Config: testAccIdentityProviderConfig_identifier(rName, "test"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), resource.TestCheckResourceAttr(resourceName, "idp_identifiers.#", "1"), @@ -107,7 +107,7 @@ func TestAccCognitoIDPIdentityProvider_idpIdentifiers(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccIdentityProviderConfig_identifier(userPoolName, "test2"), + Config: testAccIdentityProviderConfig_identifier(rName, "test2"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), resource.TestCheckResourceAttr(resourceName, "idp_identifiers.#", "1"), @@ -175,7 +175,7 @@ func TestAccCognitoIDPIdentityProvider_disappears(t *testing.T) { ctx := acctest.Context(t) var identityProvider cognitoidentityprovider.IdentityProviderType resourceName := "aws_cognito_identity_provider.test" - userPoolName := fmt.Sprintf("tf-acc-cognito-user-pool-%s", sdkacctest.RandString(7)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, @@ -184,7 +184,7 @@ func TestAccCognitoIDPIdentityProvider_disappears(t *testing.T) { CheckDestroy: testAccCheckIdentityProviderDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccIdentityProviderConfig_basic(userPoolName), + Config: testAccIdentityProviderConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), acctest.CheckResourceDisappears(ctx, acctest.Provider, tfcognitoidp.ResourceIdentityProvider(), resourceName), @@ -199,7 +199,7 @@ func TestAccCognitoIDPIdentityProvider_Disappears_userPool(t *testing.T) { ctx := acctest.Context(t) var identityProvider cognitoidentityprovider.IdentityProviderType resourceName := "aws_cognito_identity_provider.test" - userPoolName := fmt.Sprintf("tf-acc-cognito-user-pool-%s", sdkacctest.RandString(7)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, @@ -208,7 +208,7 @@ func TestAccCognitoIDPIdentityProvider_Disappears_userPool(t *testing.T) { CheckDestroy: testAccCheckIdentityProviderDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccIdentityProviderConfig_basic(userPoolName), + Config: testAccIdentityProviderConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIdentityProviderExists(ctx, resourceName, &identityProvider), acctest.CheckResourceDisappears(ctx, acctest.Provider, tfcognitoidp.ResourceUserPool(), "aws_cognito_user_pool.test"), @@ -266,10 +266,10 @@ func testAccCheckIdentityProviderExists(ctx context.Context, n string, v *cognit } } -func testAccIdentityProviderConfig_basic(userPoolName string) string { +func testAccIdentityProviderConfig_basic(rName string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { - name = "%s" + name = %[1]q auto_verified_attributes = ["email"] } @@ -290,13 +290,13 @@ resource "aws_cognito_identity_provider" "test" { token_url = "https://www.googleapis.com/oauth2/v4/token" } } -`, userPoolName) +`, rName) } -func testAccIdentityProviderConfig_basicUpdated(userPoolName string) string { +func testAccIdentityProviderConfig_basicUpdated(rName string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { - name = "%s" + name = %[1]q auto_verified_attributes = ["email"] } @@ -322,10 +322,10 @@ resource "aws_cognito_identity_provider" "test" { username = "sub" } } -`, userPoolName) +`, rName) } -func testAccIdentityProviderConfig_identifier(userPoolName, attribute string) string { +func testAccIdentityProviderConfig_identifier(rName, attribute string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "test" { name = %[1]q @@ -351,7 +351,7 @@ resource "aws_cognito_identity_provider" "test" { token_url = "https://www.googleapis.com/oauth2/v4/token" } } -`, userPoolName, attribute) +`, rName, attribute) } func testAccIdentityProviderConfig_saml(rName, encryptedResponses string) string { From d77f3e183cea3f0aacbe7087ae212e99170ae927 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 08:07:52 -0400 Subject: [PATCH 14/23] cognitoidentity: Reduce visibility. --- internal/service/cognitoidentity/exports_test.go | 11 +++++++++++ internal/service/cognitoidentity/pool.go | 2 +- internal/service/cognitoidentity/pool_data_source.go | 2 +- .../cognitoidentity/pool_provider_principal_tag.go | 4 ++-- .../service/cognitoidentity/pool_roles_attachment.go | 4 ++-- .../service/cognitoidentity/service_package_gen.go | 10 ++++++---- 6 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 internal/service/cognitoidentity/exports_test.go diff --git a/internal/service/cognitoidentity/exports_test.go b/internal/service/cognitoidentity/exports_test.go new file mode 100644 index 000000000000..cbb7a986c4f7 --- /dev/null +++ b/internal/service/cognitoidentity/exports_test.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cognitoidentity + +// Exports for use in tests only. +var ( + ResourcePool = resourcePool + ResourcePoolProviderPrincipalTag = resourcePoolProviderPrincipalTag + ResourcePoolRolesAttachment = resourcePoolRolesAttachment +) diff --git a/internal/service/cognitoidentity/pool.go b/internal/service/cognitoidentity/pool.go index a46fff4d7268..3bebb96257bd 100644 --- a/internal/service/cognitoidentity/pool.go +++ b/internal/service/cognitoidentity/pool.go @@ -26,7 +26,7 @@ import ( // @SDKResource("aws_cognito_identity_pool", name="Pool") // @Tags(identifierAttribute="arn") -func ResourcePool() *schema.Resource { +func resourcePool() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourcePoolCreate, ReadWithoutTimeout: resourcePoolRead, diff --git a/internal/service/cognitoidentity/pool_data_source.go b/internal/service/cognitoidentity/pool_data_source.go index 15e0dae6c5f3..8b6f3b188f82 100644 --- a/internal/service/cognitoidentity/pool_data_source.go +++ b/internal/service/cognitoidentity/pool_data_source.go @@ -21,7 +21,7 @@ import ( // @SDKDataSource("aws_cognito_identity_pool", name="Pool") // @Tags(identifierAttribute="arn") -func DataSourcePool() *schema.Resource { +func dataSourcePool() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourcePoolRead, diff --git a/internal/service/cognitoidentity/pool_provider_principal_tag.go b/internal/service/cognitoidentity/pool_provider_principal_tag.go index 1259529049f2..fbf95c75e9cd 100644 --- a/internal/service/cognitoidentity/pool_provider_principal_tag.go +++ b/internal/service/cognitoidentity/pool_provider_principal_tag.go @@ -24,8 +24,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_identity_pool_provider_principal_tag") -func ResourcePoolProviderPrincipalTag() *schema.Resource { +// @SDKResource("aws_cognito_identity_pool_provider_principal_tag", name="Provider Principal Tags") +func resourcePoolProviderPrincipalTag() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourcePoolProviderPrincipalTagCreate, ReadWithoutTimeout: resourcePoolProviderPrincipalTagRead, diff --git a/internal/service/cognitoidentity/pool_roles_attachment.go b/internal/service/cognitoidentity/pool_roles_attachment.go index 9727830edd77..45b0faba8d46 100644 --- a/internal/service/cognitoidentity/pool_roles_attachment.go +++ b/internal/service/cognitoidentity/pool_roles_attachment.go @@ -23,8 +23,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_identity_pool_roles_attachment") -func ResourcePoolRolesAttachment() *schema.Resource { +// @SDKResource("aws_cognito_identity_pool_roles_attachment", name="Pool Roles Association") +func resourcePoolRolesAttachment() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourcePoolRolesAttachmentCreate, ReadWithoutTimeout: resourcePoolRolesAttachmentRead, diff --git a/internal/service/cognitoidentity/service_package_gen.go b/internal/service/cognitoidentity/service_package_gen.go index 532647134075..2967349a3cc2 100644 --- a/internal/service/cognitoidentity/service_package_gen.go +++ b/internal/service/cognitoidentity/service_package_gen.go @@ -25,7 +25,7 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { return []*types.ServicePackageSDKDataSource{ { - Factory: DataSourcePool, + Factory: dataSourcePool, TypeName: "aws_cognito_identity_pool", Name: "Pool", Tags: &types.ServicePackageResourceTags{ @@ -38,7 +38,7 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePackageSDKResource { return []*types.ServicePackageSDKResource{ { - Factory: ResourcePool, + Factory: resourcePool, TypeName: "aws_cognito_identity_pool", Name: "Pool", Tags: &types.ServicePackageResourceTags{ @@ -46,12 +46,14 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourcePoolProviderPrincipalTag, + Factory: resourcePoolProviderPrincipalTag, TypeName: "aws_cognito_identity_pool_provider_principal_tag", + Name: "Provider Principal Tags", }, { - Factory: ResourcePoolRolesAttachment, + Factory: resourcePoolRolesAttachment, TypeName: "aws_cognito_identity_pool_roles_attachment", + Name: "Pool Roles Association", }, } } From d9cca3245c8816240ba7340304eda7a971e76f15 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 08:11:32 -0400 Subject: [PATCH 15/23] 'internal/service/cognitoidp/testdata' -> 'internal/service/cognitoidp/test-fixtures'. --- .../cognitoidp/{testdata => test-fixtures}/logo.png | Bin .../{testdata => test-fixtures}/logo_modified.png | Bin .../cognitoidp/user_pool_ui_customization_test.go | 12 ++++++------ 3 files changed, 6 insertions(+), 6 deletions(-) rename internal/service/cognitoidp/{testdata => test-fixtures}/logo.png (100%) rename internal/service/cognitoidp/{testdata => test-fixtures}/logo_modified.png (100%) diff --git a/internal/service/cognitoidp/testdata/logo.png b/internal/service/cognitoidp/test-fixtures/logo.png similarity index 100% rename from internal/service/cognitoidp/testdata/logo.png rename to internal/service/cognitoidp/test-fixtures/logo.png diff --git a/internal/service/cognitoidp/testdata/logo_modified.png b/internal/service/cognitoidp/test-fixtures/logo_modified.png similarity index 100% rename from internal/service/cognitoidp/testdata/logo_modified.png rename to internal/service/cognitoidp/test-fixtures/logo_modified.png diff --git a/internal/service/cognitoidp/user_pool_ui_customization_test.go b/internal/service/cognitoidp/user_pool_ui_customization_test.go index cd9b408f48c4..63152495932a 100644 --- a/internal/service/cognitoidp/user_pool_ui_customization_test.go +++ b/internal/service/cognitoidp/user_pool_ui_customization_test.go @@ -104,8 +104,8 @@ func TestAccCognitoIDPUserPoolUICustomization_AllClients_imageFile(t *testing.T) resourceName := "aws_cognito_user_pool_ui_customization.test" userPoolResourceName := "aws_cognito_user_pool.test" - filename := "testdata/logo.png" - updatedFilename := "testdata/logo_modified.png" + filename := "test-fixtures/logo.png" + updatedFilename := "test-fixtures/logo_modified.png" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -158,8 +158,8 @@ func TestAccCognitoIDPUserPoolUICustomization_AllClients_CSSAndImageFile(t *test userPoolResourceName := "aws_cognito_user_pool.test" css := ".label-customizable {font-weight: 400;}" - filename := "testdata/logo.png" - updatedFilename := "testdata/logo_modified.png" + filename := "test-fixtures/logo.png" + updatedFilename := "test-fixtures/logo_modified.png" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -305,8 +305,8 @@ func TestAccCognitoIDPUserPoolUICustomization_Client_image(t *testing.T) { clientResourceName := "aws_cognito_user_pool_client.test" userPoolResourceName := "aws_cognito_user_pool.test" - filename := "testdata/logo.png" - updatedFilename := "testdata/logo_modified.png" + filename := "test-fixtures/logo.png" + updatedFilename := "test-fixtures/logo_modified.png" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, From 182963fe7ab83b791c889afd52086b983cd128ab Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 09:02:29 -0400 Subject: [PATCH 16/23] r/aws_cognito_user_pool_ui_customization: Tidy up. --- internal/service/cognitoidp/exports_test.go | 14 ++- internal/service/cognitoidp/find.go | 28 ----- .../service/cognitoidp/service_package_gen.go | 3 +- .../cognitoidp/user_pool_ui_customization.go | 113 +++++++++--------- .../user_pool_ui_customization_test.go | 96 +++------------ 5 files changed, 86 insertions(+), 168 deletions(-) diff --git a/internal/service/cognitoidp/exports_test.go b/internal/service/cognitoidp/exports_test.go index 31d4b3d7fb55..d596a081716e 100644 --- a/internal/service/cognitoidp/exports_test.go +++ b/internal/service/cognitoidp/exports_test.go @@ -5,11 +5,13 @@ package cognitoidp // Exports for use in tests only. var ( - ResourceIdentityProvider = resourceIdentityProvider - ResourceManagedUserPoolClient = newResourceManagedUserPoolClient - ResourceUserGroup = resourceUserGroup - ResourceUserPoolClient = newResourceUserPoolClient + ResourceIdentityProvider = resourceIdentityProvider + ResourceManagedUserPoolClient = newResourceManagedUserPoolClient + ResourceUserGroup = resourceUserGroup + ResourceUserPoolClient = newResourceUserPoolClient + ResourceUserPoolUICustomization = resourceUserPoolUICustomization - FindGroupByTwoPartKey = findGroupByTwoPartKey - FindIdentityProviderByTwoPartKey = findIdentityProviderByTwoPartKey + FindGroupByTwoPartKey = findGroupByTwoPartKey + FindIdentityProviderByTwoPartKey = findIdentityProviderByTwoPartKey + FindUserPoolUICustomizationByTwoPartKey = findUserPoolUICustomizationByTwoPartKey ) diff --git a/internal/service/cognitoidp/find.go b/internal/service/cognitoidp/find.go index 4f546870ede2..edcda34b1deb 100644 --- a/internal/service/cognitoidp/find.go +++ b/internal/service/cognitoidp/find.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "reflect" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" @@ -16,33 +15,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// FindCognitoUserPoolUICustomization returns the UI Customization corresponding to the UserPoolId and ClientId. -// Returns nil if no UI Customization is found. -func FindCognitoUserPoolUICustomization(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolId, clientId string) (*cognitoidentityprovider.UICustomizationType, error) { - input := &cognitoidentityprovider.GetUICustomizationInput{ - ClientId: aws.String(clientId), - UserPoolId: aws.String(userPoolId), - } - - output, err := conn.GetUICustomizationWithContext(ctx, input) - - if err != nil { - return nil, err - } - - if output == nil || output.UICustomization == nil { - return nil, nil - } - - // The GetUICustomization API operation will return an empty struct - // if nothing is present rather than nil or an error, so we equate that with nil - if reflect.DeepEqual(output.UICustomization, &cognitoidentityprovider.UICustomizationType{}) { - return nil, nil - } - - return output.UICustomization, nil -} - // FindCognitoUserInGroup checks whether the specified user is present in the specified group. Returns boolean value accordingly. func FindCognitoUserInGroup(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, groupName, userPoolId, username string) (bool, error) { input := &cognitoidentityprovider.AdminListGroupsForUserInput{ diff --git a/internal/service/cognitoidp/service_package_gen.go b/internal/service/cognitoidp/service_package_gen.go index 4f2b9b622397..08ee2c2c8730 100644 --- a/internal/service/cognitoidp/service_package_gen.go +++ b/internal/service/cognitoidp/service_package_gen.go @@ -99,8 +99,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka TypeName: "aws_cognito_user_pool_domain", }, { - Factory: ResourceUserPoolUICustomization, + Factory: resourceUserPoolUICustomization, TypeName: "aws_cognito_user_pool_ui_customization", + Name: "User Pool UI Customization", }, } } diff --git a/internal/service/cognitoidp/user_pool_ui_customization.go b/internal/service/cognitoidp/user_pool_ui_customization.go index 4f81a42b7bb5..dd4009f5a7d1 100644 --- a/internal/service/cognitoidp/user_pool_ui_customization.go +++ b/internal/service/cognitoidp/user_pool_ui_customization.go @@ -6,22 +6,25 @@ package cognitoidp import ( "context" "encoding/base64" - "fmt" "log" - "strings" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/flex" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + itypes "github.com/hashicorp/terraform-provider-aws/internal/types" ) -// @SDKResource("aws_cognito_user_pool_ui_customization") -func ResourceUserPoolUICustomization() *schema.Resource { +// @SDKResource("aws_cognito_user_pool_ui_customization", name="User Pool UI Customization") +func resourceUserPoolUICustomization() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserPoolUICustomizationPut, ReadWithoutTimeout: resourceUserPoolUICustomizationRead, @@ -38,39 +41,32 @@ func ResourceUserPoolUICustomization() *schema.Resource { Optional: true, Default: "ALL", }, - "creation_date": { Type: schema.TypeString, Computed: true, }, - "css": { Type: schema.TypeString, Optional: true, AtLeastOneOf: []string{"css", "image_file"}, }, - "css_version": { Type: schema.TypeString, Computed: true, }, - "image_file": { Type: schema.TypeString, Optional: true, AtLeastOneOf: []string{"image_file", "css"}, }, - "image_url": { Type: schema.TypeString, Computed: true, }, - "last_modified_date": { Type: schema.TypeString, Computed: true, }, - "user_pool_id": { Type: schema.TypeString, Required: true, @@ -79,16 +75,19 @@ func ResourceUserPoolUICustomization() *schema.Resource { } } +const ( + userPoolUICustomizationResourceIDPartCount = 2 +) + func resourceUserPoolUICustomizationPut(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - clientId := d.Get("client_id").(string) - userPoolId := d.Get("user_pool_id").(string) - + userPoolID, clientID := d.Get("user_pool_id").(string), d.Get("client_id").(string) + id := errs.Must(flex.FlattenResourceId([]string{userPoolID, clientID}, userPoolUICustomizationResourceIDPartCount, false)) input := &cognitoidentityprovider.SetUICustomizationInput{ - ClientId: aws.String(clientId), - UserPoolId: aws.String(userPoolId), + ClientId: aws.String(clientID), + UserPoolId: aws.String(userPoolID), } if v, ok := d.GetOk("css"); ok { @@ -96,21 +95,20 @@ func resourceUserPoolUICustomizationPut(ctx context.Context, d *schema.ResourceD } if v, ok := d.GetOk("image_file"); ok { - imgFile, err := base64.StdEncoding.DecodeString(v.(string)) + v, err := base64.StdEncoding.DecodeString(v.(string)) if err != nil { - return sdkdiag.AppendErrorf(diags, "Base64 decoding image file for Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s): %s", userPoolId, clientId, err) + return sdkdiag.AppendFromErr(diags, err) } - - input.ImageFile = imgFile + input.ImageFile = v } _, err := conn.SetUICustomizationWithContext(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s): %s", userPoolId, clientId, err) + return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool UI Customization (%s): %s", id, err) } - d.SetId(fmt.Sprintf("%s,%s", userPoolId, clientId)) + d.SetId(id) return append(diags, resourceUserPoolUICustomizationRead(ctx, d, meta)...) } @@ -119,32 +117,22 @@ func resourceUserPoolUICustomizationRead(ctx context.Context, d *schema.Resource var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - userPoolId, clientId, err := ParseUserPoolUICustomizationID(d.Id()) - + parts, err := flex.ExpandResourceId(d.Id(), userPoolUICustomizationResourceIDPartCount, false) if err != nil { - return sdkdiag.AppendErrorf(diags, "parsing Cognito User Pool UI customization ID (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } + userPoolID, clientID := parts[0], parts[1] - uiCustomization, err := FindCognitoUserPoolUICustomization(ctx, conn, userPoolId, clientId) + uiCustomization, err := findUserPoolUICustomizationByTwoPartKey(ctx, conn, userPoolID, clientID) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - log.Printf("[WARN] Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s) not found, removing from state", userPoolId, clientId) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Cognito User Pool UI Customization %s not found, removing from state", d.Id()) d.SetId("") return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "getting Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s): %s", userPoolId, clientId, err) - } - - if uiCustomization == nil { - if d.IsNewResource() { - return sdkdiag.AppendErrorf(diags, "getting Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s): not found", userPoolId, clientId) - } - - log.Printf("[WARN] Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s) not found, removing from state", userPoolId, clientId) - d.SetId("") - return diags + return sdkdiag.AppendErrorf(diags, "reading Cognito User Pool UI Customization (%s): %s", d.Id(), err) } d.Set("client_id", uiCustomization.ClientId) @@ -162,36 +150,53 @@ func resourceUserPoolUICustomizationDelete(ctx context.Context, d *schema.Resour var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - userPoolId, clientId, err := ParseUserPoolUICustomizationID(d.Id()) - + parts, err := flex.ExpandResourceId(d.Id(), userPoolUICustomizationResourceIDPartCount, false) if err != nil { - return sdkdiag.AppendErrorf(diags, "parsing Cognito User Pool UI customization ID (%s): %s", d.Id(), err) - } - - input := &cognitoidentityprovider.SetUICustomizationInput{ - ClientId: aws.String(clientId), - UserPoolId: aws.String(userPoolId), + return sdkdiag.AppendFromErr(diags, err) } + userPoolID, clientID := parts[0], parts[1] - _, err = conn.SetUICustomizationWithContext(ctx, input) + log.Printf("[DEBUG] Deleting Cognito User Pool UI Customization: %s", d.Id()) + _, err = conn.SetUICustomizationWithContext(ctx, &cognitoidentityprovider.SetUICustomizationInput{ + ClientId: aws.String(clientID), + UserPoolId: aws.String(userPoolID), + }) if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting Cognito User Pool UI customization (UserPoolId: %s, ClientId: %s): %s", userPoolId, clientId, err) + return sdkdiag.AppendErrorf(diags, "deleting Cognito User Pool UI Customization (%s): %s", d.Id(), err) } return diags } -func ParseUserPoolUICustomizationID(id string) (string, string, error) { - idParts := strings.SplitN(id, ",", 2) +func findUserPoolUICustomizationByTwoPartKey(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolID, clientID string) (*cognitoidentityprovider.UICustomizationType, error) { + input := &cognitoidentityprovider.GetUICustomizationInput{ + ClientId: aws.String(clientID), + UserPoolId: aws.String(userPoolID), + } + + output, err := conn.GetUICustomizationWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } - if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { - return "", "", fmt.Errorf("please make sure ID is in format USER_POOL_ID,CLIENT_ID") + // The GetUICustomization API operation will return an empty struct + // if nothing is present rather than nil or an error, so we equate that with nil. + if output == nil || output.UICustomization == nil || itypes.IsZero(output.UICustomization) { + return nil, tfresource.NewEmptyResultError(input) } - return idParts[0], idParts[1], nil + return output.UICustomization, nil } diff --git a/internal/service/cognitoidp/user_pool_ui_customization_test.go b/internal/service/cognitoidp/user_pool_ui_customization_test.go index 63152495932a..1e5e7435d5f7 100644 --- a/internal/service/cognitoidp/user_pool_ui_customization_test.go +++ b/internal/service/cognitoidp/user_pool_ui_customization_test.go @@ -5,18 +5,16 @@ package cognitoidp_test import ( "context" - "errors" "fmt" "testing" - "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfcognitoidp "github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -517,21 +515,9 @@ func testAccCheckUserPoolUICustomizationDestroy(ctx context.Context) resource.Te continue } - userPoolId, clientId, err := tfcognitoidp.ParseUserPoolUICustomizationID(rs.Primary.ID) + _, err := tfcognitoidp.FindUserPoolUICustomizationByTwoPartKey(ctx, conn, rs.Primary.Attributes["user_pool_id"], rs.Primary.Attributes["client_id"]) - if err != nil { - return fmt.Errorf("error parsing Cognito User Pool UI customization ID (%s): %w", rs.Primary.ID, err) - } - - output, err := tfcognitoidp.FindCognitoUserPoolUICustomization(ctx, conn, userPoolId, clientId) - - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - continue - } - - // Catch cases where the User Pool Domain has been destroyed, effectively eliminating - // a UI customization; calls to GetUICustomization will fail - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidParameterException, "There has to be an existing domain associated with this user pool") { + if tfresource.NotFound(err) { continue } @@ -539,45 +525,25 @@ func testAccCheckUserPoolUICustomizationDestroy(ctx context.Context) resource.Te return err } - if testAccUserPoolUICustomizationExists(output) { - return fmt.Errorf("Cognito User Pool UI Customization (UserPoolId: %s, ClientId: %s) still exists", userPoolId, clientId) - } + return fmt.Errorf("Cognito User Pool UI Customization %s still exists", rs.Primary.ID) } return nil } } -func testAccCheckUserPoolUICustomizationExists(ctx context.Context, name string) resource.TestCheckFunc { +func testAccCheckUserPoolUICustomizationExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) - } - - if rs.Primary.ID == "" { - return errors.New("No Cognito User Pool Client ID set") - } - - userPoolId, clientId, err := tfcognitoidp.ParseUserPoolUICustomizationID(rs.Primary.ID) - - if err != nil { - return fmt.Errorf("error parsing Cognito User Pool UI customization ID (%s): %w", rs.Primary.ID, err) + return fmt.Errorf("Not found: %s", n) } conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn(ctx) - output, err := tfcognitoidp.FindCognitoUserPoolUICustomization(ctx, conn, userPoolId, clientId) - - if err != nil { - return err - } - - if output == nil { - return fmt.Errorf("Cognito User Pool UI customization (%s) not found", rs.Primary.ID) - } + _, err := tfcognitoidp.FindUserPoolUICustomizationByTwoPartKey(ctx, conn, rs.Primary.Attributes["user_pool_id"], rs.Primary.Attributes["client_id"]) - return nil + return err } } @@ -593,7 +559,7 @@ resource "aws_cognito_user_pool_domain" "test" { } resource "aws_cognito_user_pool_ui_customization" "test" { - css = %q + css = %[2]q # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -614,7 +580,7 @@ resource "aws_cognito_user_pool_domain" "test" { } resource "aws_cognito_user_pool_ui_customization" "test" { - image_file = filebase64(%q) + image_file = filebase64(%[2]q) # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -635,8 +601,8 @@ resource "aws_cognito_user_pool_domain" "test" { } resource "aws_cognito_user_pool_ui_customization" "test" { - css = %q - image_file = filebase64(%q) + css = %[2]q + image_file = filebase64(%[3]q) # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -663,7 +629,7 @@ resource "aws_cognito_user_pool_client" "test" { resource "aws_cognito_user_pool_ui_customization" "test" { client_id = aws_cognito_user_pool_client.test.id - css = %q + css = %[2]q # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -690,7 +656,7 @@ resource "aws_cognito_user_pool_client" "test" { resource "aws_cognito_user_pool_ui_customization" "test" { client_id = aws_cognito_user_pool_client.test.id - image_file = filebase64(%q) + image_file = filebase64(%[2]q) # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -716,7 +682,7 @@ resource "aws_cognito_user_pool_client" "test" { } resource "aws_cognito_user_pool_ui_customization" "ui_all" { - css = %q + css = %[2]q # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -725,7 +691,7 @@ resource "aws_cognito_user_pool_ui_customization" "ui_all" { resource "aws_cognito_user_pool_ui_customization" "ui_client" { client_id = aws_cognito_user_pool_client.test.id - css = %q + css = %[3]q # Refer to the aws_cognito_user_pool_domain resource's # user_pool_id attribute to ensure it is in an 'Active' state @@ -733,31 +699,3 @@ resource "aws_cognito_user_pool_ui_customization" "ui_client" { } `, rName, allCSS, clientCSS) } - -// testAccUserPoolUICustomizationExists validates the API object such that -// we define resource existence when the object is non-nil and -// at least one of the object's fields are non-nil with the exception of CSSVersion -// which remains as an artifact even after UI customization removal -func testAccUserPoolUICustomizationExists(ui *cognitoidentityprovider.UICustomizationType) bool { - if ui == nil { - return false - } - - if ui.CSS != nil { - return true - } - - if ui.CreationDate != nil { - return true - } - - if ui.ImageUrl != nil { - return true - } - - if ui.LastModifiedDate != nil { - return true - } - - return false -} From d9c0323a431459544ed242ef00eee537e9392c87 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 09:25:09 -0400 Subject: [PATCH 17/23] cognitoidp: Reduce visibility. --- internal/service/cognitoidp/exports_test.go | 9 +++-- .../cognitoidp/managed_user_pool_client.go | 24 ++++++------- .../service/cognitoidp/resource_server.go | 4 +-- .../service/cognitoidp/risk_configuration.go | 5 +-- .../service/cognitoidp/service_package_gen.go | 36 ++++++++++++------- .../cognitoidp/user_group_data_source.go | 12 +++---- .../cognitoidp/user_groups_data_source.go | 12 +++---- internal/service/cognitoidp/user_in_group.go | 4 +-- internal/service/cognitoidp/user_pool.go | 2 +- .../service/cognitoidp/user_pool_client.go | 24 ++++++------- .../user_pool_client_data_source.go | 4 +-- .../user_pool_clients_data_source.go | 4 +-- .../service/cognitoidp/user_pool_domain.go | 4 +-- ...er_pool_signing_certificate_data_source.go | 4 +-- .../cognitoidp/user_pools_data_source.go | 4 +-- 15 files changed, 84 insertions(+), 68 deletions(-) diff --git a/internal/service/cognitoidp/exports_test.go b/internal/service/cognitoidp/exports_test.go index d596a081716e..ec2687022151 100644 --- a/internal/service/cognitoidp/exports_test.go +++ b/internal/service/cognitoidp/exports_test.go @@ -6,9 +6,14 @@ package cognitoidp // Exports for use in tests only. var ( ResourceIdentityProvider = resourceIdentityProvider - ResourceManagedUserPoolClient = newResourceManagedUserPoolClient + ResourceManagedUserPoolClient = newManagedUserPoolClientResource + ResourceResourceServer = resourceResourceServer + ResourceRiskConfiguration = resourceRiskConfiguration ResourceUserGroup = resourceUserGroup - ResourceUserPoolClient = newResourceUserPoolClient + ResourceUserInGroup = resourceUserInGroup + ResourceUserPool = resourceUserPool + ResourceUserPoolClient = newUserPoolClientResource + ResourceUserPoolDomain = resourceUserPoolDomain ResourceUserPoolUICustomization = resourceUserPoolUICustomization FindGroupByTwoPartKey = findGroupByTwoPartKey diff --git a/internal/service/cognitoidp/managed_user_pool_client.go b/internal/service/cognitoidp/managed_user_pool_client.go index 68555623191c..ff2c35e1a4cc 100644 --- a/internal/service/cognitoidp/managed_user_pool_client.go +++ b/internal/service/cognitoidp/managed_user_pool_client.go @@ -36,21 +36,21 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @FrameworkResource -func newResourceManagedUserPoolClient(context.Context) (resource.ResourceWithConfigure, error) { - return &resourceManagedUserPoolClient{}, nil +// @FrameworkResource(name="Managed User Pool Client") +func newManagedUserPoolClientResource(context.Context) (resource.ResourceWithConfigure, error) { + return &managedUserPoolClientResource{}, nil } -type resourceManagedUserPoolClient struct { +type managedUserPoolClientResource struct { framework.ResourceWithConfigure } -func (r *resourceManagedUserPoolClient) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { +func (r *managedUserPoolClientResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = "aws_cognito_managed_user_pool_client" } // Schema returns the schema for this resource. -func (r *resourceManagedUserPoolClient) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { +func (r *managedUserPoolClientResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { s := schema.Schema{ Attributes: map[string]schema.Attribute{ "access_token_validity": schema.Int64Attribute{ @@ -338,7 +338,7 @@ func (r *resourceManagedUserPoolClient) Schema(ctx context.Context, request reso response.Schema = s } -func (r *resourceManagedUserPoolClient) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { +func (r *managedUserPoolClientResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { conn := r.Meta().CognitoIDPConn(ctx) var config resourceManagedUserPoolClientData @@ -534,7 +534,7 @@ func (r *resourceManagedUserPoolClient) Create(ctx context.Context, request reso response.Diagnostics.Append(response.State.Set(ctx, &config)...) } -func (r *resourceManagedUserPoolClient) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { +func (r *managedUserPoolClientResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { var state resourceManagedUserPoolClientData response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { @@ -590,7 +590,7 @@ func (r *resourceManagedUserPoolClient) Read(ctx context.Context, request resour response.Diagnostics.Append(response.State.Set(ctx, &state)...) } -func (r *resourceManagedUserPoolClient) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { +func (r *managedUserPoolClientResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var config resourceManagedUserPoolClientData response.Diagnostics.Append(request.Config.Get(ctx, &config)...) if response.Diagnostics.HasError() { @@ -671,7 +671,7 @@ func (r *resourceManagedUserPoolClient) Update(ctx context.Context, request reso response.Diagnostics.Append(response.State.Set(ctx, &config)...) } -func (r *resourceManagedUserPoolClient) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { +func (r *managedUserPoolClientResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { var state resourceManagedUserPoolClientData response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { @@ -684,7 +684,7 @@ func (r *resourceManagedUserPoolClient) Delete(ctx context.Context, request reso ) } -func (r *resourceManagedUserPoolClient) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { +func (r *managedUserPoolClientResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { parts := strings.Split(request.ID, "/") if len(parts) != 2 { response.Diagnostics.AddError("Resource Import Invalid ID", fmt.Sprintf("wrong format of import ID (%s), use: 'user-pool-id/client-id'", request.ID)) @@ -696,7 +696,7 @@ func (r *resourceManagedUserPoolClient) ImportState(ctx context.Context, request response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("user_pool_id"), userPoolId)...) } -func (r *resourceManagedUserPoolClient) ConfigValidators(ctx context.Context) []resource.ConfigValidator { +func (r *managedUserPoolClientResource) ConfigValidators(ctx context.Context) []resource.ConfigValidator { return []resource.ConfigValidator{ resourceManagedUserPoolClientAccessTokenValidityValidator{ resourceManagedUserPoolClientValidityValidator{ diff --git a/internal/service/cognitoidp/resource_server.go b/internal/service/cognitoidp/resource_server.go index 454a56cf3abd..ce98d553a8b1 100644 --- a/internal/service/cognitoidp/resource_server.go +++ b/internal/service/cognitoidp/resource_server.go @@ -22,8 +22,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_resource_server") -func ResourceResourceServer() *schema.Resource { +// @SDKResource("aws_cognito_resource_server", name="Resource Server") +func resourceResourceServer() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceResourceServerCreate, ReadWithoutTimeout: resourceResourceServerRead, diff --git a/internal/service/cognitoidp/risk_configuration.go b/internal/service/cognitoidp/risk_configuration.go index 51f6dc7f1726..722de53bbc51 100644 --- a/internal/service/cognitoidp/risk_configuration.go +++ b/internal/service/cognitoidp/risk_configuration.go @@ -22,13 +22,14 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_risk_configuration") -func ResourceRiskConfiguration() *schema.Resource { +// @SDKResource("aws_cognito_risk_configuration", name="Risk Configuration") +func resourceRiskConfiguration() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceRiskConfigurationPut, ReadWithoutTimeout: resourceRiskConfigurationRead, DeleteWithoutTimeout: resourceRiskConfigurationDelete, UpdateWithoutTimeout: resourceRiskConfigurationPut, + Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, diff --git a/internal/service/cognitoidp/service_package_gen.go b/internal/service/cognitoidp/service_package_gen.go index 08ee2c2c8730..e5cb9a886b46 100644 --- a/internal/service/cognitoidp/service_package_gen.go +++ b/internal/service/cognitoidp/service_package_gen.go @@ -18,11 +18,11 @@ type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { return []*types.ServicePackageFrameworkDataSource{ { - Factory: newDataSourceDataSourceUserGroup, + Factory: newUserGroupDataSource, Name: "User Group", }, { - Factory: newDataSourceDataSourceUserGroups, + Factory: newUserGroupsDataSource, Name: "User Groups", }, } @@ -31,10 +31,12 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { return []*types.ServicePackageFrameworkResource{ { - Factory: newResourceManagedUserPoolClient, + Factory: newManagedUserPoolClientResource, + Name: "Managed User Pool Client", }, { - Factory: newResourceUserPoolClient, + Factory: newUserPoolClientResource, + Name: "User Pool Client", }, } } @@ -42,20 +44,24 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { return []*types.ServicePackageSDKDataSource{ { - Factory: DataSourceUserPoolClient, + Factory: dataSourceUserPoolClient, TypeName: "aws_cognito_user_pool_client", + Name: "User Pool Client", }, { - Factory: DataSourceUserPoolClients, + Factory: dataSourceUserPoolClients, TypeName: "aws_cognito_user_pool_clients", + Name: "User Pool Clients", }, { - Factory: DataSourceUserPoolSigningCertificate, + Factory: dataSourceUserPoolSigningCertificate, TypeName: "aws_cognito_user_pool_signing_certificate", + Name: "User Pool Signing Certificate", }, { - Factory: DataSourceUserPools, + Factory: dataSourceUserPools, TypeName: "aws_cognito_user_pools", + Name: "User Pools", }, } } @@ -68,12 +74,14 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Identity Provider", }, { - Factory: ResourceResourceServer, + Factory: resourceResourceServer, TypeName: "aws_cognito_resource_server", + Name: "Resource Server", }, { - Factory: ResourceRiskConfiguration, + Factory: resourceRiskConfiguration, TypeName: "aws_cognito_risk_configuration", + Name: "Risk Configuration", }, { Factory: ResourceUser, @@ -85,18 +93,20 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "User Group", }, { - Factory: ResourceUserInGroup, + Factory: resourceUserInGroup, TypeName: "aws_cognito_user_in_group", + Name: "Group User", }, { - Factory: ResourceUserPool, + Factory: resourceUserPool, TypeName: "aws_cognito_user_pool", Name: "User Pool", Tags: &types.ServicePackageResourceTags{}, }, { - Factory: ResourceUserPoolDomain, + Factory: resourceUserPoolDomain, TypeName: "aws_cognito_user_pool_domain", + Name: "User Pool Domain", }, { Factory: resourceUserPoolUICustomization, diff --git a/internal/service/cognitoidp/user_group_data_source.go b/internal/service/cognitoidp/user_group_data_source.go index fe692af52a05..d95f3586189a 100644 --- a/internal/service/cognitoidp/user_group_data_source.go +++ b/internal/service/cognitoidp/user_group_data_source.go @@ -19,23 +19,23 @@ import ( ) // @FrameworkDataSource(name="User Group") -func newDataSourceDataSourceUserGroup(context.Context) (datasource.DataSourceWithConfigure, error) { - return &dataSourceDataSourceUserGroup{}, nil +func newUserGroupDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &userGroupDataSource{}, nil } const ( DSNameUserGroup = "User Group Data Source" ) -type dataSourceDataSourceUserGroup struct { +type userGroupDataSource struct { framework.DataSourceWithConfigure } -func (d *dataSourceDataSourceUserGroup) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { +func (d *userGroupDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { response.TypeName = "aws_cognito_user_group" } -func (d *dataSourceDataSourceUserGroup) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { +func (d *userGroupDataSource) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { response.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "description": schema.StringAttribute{ @@ -58,7 +58,7 @@ func (d *dataSourceDataSourceUserGroup) Schema(ctx context.Context, request data } } -func (d *dataSourceDataSourceUserGroup) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { +func (d *userGroupDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { var data dataSourceDataSourceUserGroupData response.Diagnostics.Append(request.Config.Get(ctx, &data)...) diff --git a/internal/service/cognitoidp/user_groups_data_source.go b/internal/service/cognitoidp/user_groups_data_source.go index 717af324a35a..67d82406230c 100644 --- a/internal/service/cognitoidp/user_groups_data_source.go +++ b/internal/service/cognitoidp/user_groups_data_source.go @@ -18,24 +18,24 @@ import ( ) // @FrameworkDataSource(name="User Groups") -func newDataSourceDataSourceUserGroups(context.Context) (datasource.DataSourceWithConfigure, error) { - return &dataSourceDataSourceUserGroups{}, nil +func newUserGroupsDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &userGroupsDataSource{}, nil } const ( DSNameUserGroups = "User Groups Data Source" ) -type dataSourceDataSourceUserGroups struct { +type userGroupsDataSource struct { framework.DataSourceWithConfigure } -func (d *dataSourceDataSourceUserGroups) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { +func (d *userGroupsDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { response.TypeName = "aws_cognito_user_groups" } // Schema returns the schema for this data source. -func (d *dataSourceDataSourceUserGroups) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { +func (d *userGroupsDataSource) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { response.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "id": framework.IDAttribute(), @@ -67,7 +67,7 @@ func (d *dataSourceDataSourceUserGroups) Schema(ctx context.Context, request dat } } -func (d *dataSourceDataSourceUserGroups) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { +func (d *userGroupsDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { // 🌱 For the person who migrates to sdkv2: // this should work by just updating the client, and removing the WithContext method. conn := d.Meta().CognitoIDPConn(ctx) diff --git a/internal/service/cognitoidp/user_in_group.go b/internal/service/cognitoidp/user_in_group.go index 764a19db415f..f46bfe2f8389 100644 --- a/internal/service/cognitoidp/user_in_group.go +++ b/internal/service/cognitoidp/user_in_group.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKResource("aws_cognito_user_in_group") -func ResourceUserInGroup() *schema.Resource { +// @SDKResource("aws_cognito_user_in_group", name="Group User") +func resourceUserInGroup() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserInGroupCreate, ReadWithoutTimeout: resourceUserInGroupRead, diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index 50a59bab376b..9b0eb9699583 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -31,7 +31,7 @@ import ( // @SDKResource("aws_cognito_user_pool", name="User Pool") // @Tags -func ResourceUserPool() *schema.Resource { +func resourceUserPool() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserPoolCreate, ReadWithoutTimeout: resourceUserPoolRead, diff --git a/internal/service/cognitoidp/user_pool_client.go b/internal/service/cognitoidp/user_pool_client.go index 02e0f7fa9fbf..86d0dbbedbc0 100644 --- a/internal/service/cognitoidp/user_pool_client.go +++ b/internal/service/cognitoidp/user_pool_client.go @@ -39,24 +39,24 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @FrameworkResource -func newResourceUserPoolClient(_ context.Context) (resource.ResourceWithConfigure, error) { - r := &resourceUserPoolClient{} +// @FrameworkResource(name="User Pool Client") +func newUserPoolClientResource(context.Context) (resource.ResourceWithConfigure, error) { + r := &userPoolClientResource{} r.SetMigratedFromPluginSDK(true) return r, nil } -type resourceUserPoolClient struct { +type userPoolClientResource struct { framework.ResourceWithConfigure } -func (r *resourceUserPoolClient) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { +func (r *userPoolClientResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = "aws_cognito_user_pool_client" } // Schema returns the schema for this resource. -func (r *resourceUserPoolClient) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { +func (r *userPoolClientResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { s := schema.Schema{ Attributes: map[string]schema.Attribute{ "access_token_validity": schema.Int64Attribute{ @@ -333,7 +333,7 @@ func (r *resourceUserPoolClient) Schema(ctx context.Context, request resource.Sc response.Schema = s } -func (r *resourceUserPoolClient) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { +func (r *userPoolClientResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { conn := r.Meta().CognitoIDPConn(ctx) var config resourceUserPoolClientData @@ -395,7 +395,7 @@ func (r *resourceUserPoolClient) Create(ctx context.Context, request resource.Cr response.Diagnostics.Append(response.State.Set(ctx, &config)...) } -func (r *resourceUserPoolClient) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { +func (r *userPoolClientResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { var state resourceUserPoolClientData response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { @@ -451,7 +451,7 @@ func (r *resourceUserPoolClient) Read(ctx context.Context, request resource.Read response.Diagnostics.Append(response.State.Set(ctx, &state)...) } -func (r *resourceUserPoolClient) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { +func (r *userPoolClientResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var config resourceUserPoolClientData response.Diagnostics.Append(request.Config.Get(ctx, &config)...) if response.Diagnostics.HasError() { @@ -532,7 +532,7 @@ func (r *resourceUserPoolClient) Update(ctx context.Context, request resource.Up response.Diagnostics.Append(response.State.Set(ctx, &config)...) } -func (r *resourceUserPoolClient) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { +func (r *userPoolClientResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { var state resourceUserPoolClientData response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { @@ -562,7 +562,7 @@ func (r *resourceUserPoolClient) Delete(ctx context.Context, request resource.De } } -func (r *resourceUserPoolClient) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { +func (r *userPoolClientResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { parts := strings.Split(request.ID, "/") if len(parts) != 2 { response.Diagnostics.AddError("Resource Import Invalid ID", fmt.Sprintf("wrong format of import ID (%s), use: 'user-pool-id/client-id'", request.ID)) @@ -574,7 +574,7 @@ func (r *resourceUserPoolClient) ImportState(ctx context.Context, request resour response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("user_pool_id"), userPoolId)...) } -func (r *resourceUserPoolClient) ConfigValidators(ctx context.Context) []resource.ConfigValidator { +func (r *userPoolClientResource) ConfigValidators(ctx context.Context) []resource.ConfigValidator { return []resource.ConfigValidator{ resourceUserPoolClientAccessTokenValidityValidator{ resourceUserPoolClientValidityValidator{ diff --git a/internal/service/cognitoidp/user_pool_client_data_source.go b/internal/service/cognitoidp/user_pool_client_data_source.go index 329b3aba191d..4c07dbaba4a4 100644 --- a/internal/service/cognitoidp/user_pool_client_data_source.go +++ b/internal/service/cognitoidp/user_pool_client_data_source.go @@ -15,8 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/flex" ) -// @SDKDataSource("aws_cognito_user_pool_client") -func DataSourceUserPoolClient() *schema.Resource { +// @SDKDataSource("aws_cognito_user_pool_client", name="User Pool Client") +func dataSourceUserPoolClient() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUserPoolClientRead, diff --git a/internal/service/cognitoidp/user_pool_clients_data_source.go b/internal/service/cognitoidp/user_pool_clients_data_source.go index e4d20ccda871..fcdfe5b96b61 100644 --- a/internal/service/cognitoidp/user_pool_clients_data_source.go +++ b/internal/service/cognitoidp/user_pool_clients_data_source.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_cognito_user_pool_clients") -func DataSourceUserPoolClients() *schema.Resource { +// @SDKDataSource("aws_cognito_user_pool_clients", name="User Pool Clients") +func dataSourceUserPoolClients() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceuserPoolClientsRead, Schema: map[string]*schema.Schema{ diff --git a/internal/service/cognitoidp/user_pool_domain.go b/internal/service/cognitoidp/user_pool_domain.go index 68127d852f4f..efa05d54a3e4 100644 --- a/internal/service/cognitoidp/user_pool_domain.go +++ b/internal/service/cognitoidp/user_pool_domain.go @@ -24,8 +24,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_user_pool_domain") -func ResourceUserPoolDomain() *schema.Resource { +// @SDKResource("aws_cognito_user_pool_domain", name="User Pool Domain") +func resourceUserPoolDomain() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserPoolDomainCreate, ReadWithoutTimeout: resourceUserPoolDomainRead, diff --git a/internal/service/cognitoidp/user_pool_signing_certificate_data_source.go b/internal/service/cognitoidp/user_pool_signing_certificate_data_source.go index 48df4e17f985..d4e779efe2c5 100644 --- a/internal/service/cognitoidp/user_pool_signing_certificate_data_source.go +++ b/internal/service/cognitoidp/user_pool_signing_certificate_data_source.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_cognito_user_pool_signing_certificate") -func DataSourceUserPoolSigningCertificate() *schema.Resource { +// @SDKDataSource("aws_cognito_user_pool_signing_certificate", name="User Pool Signing Certificate") +func dataSourceUserPoolSigningCertificate() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUserPoolSigningCertificateRead, diff --git a/internal/service/cognitoidp/user_pools_data_source.go b/internal/service/cognitoidp/user_pools_data_source.go index 828dacee1c53..c46d651d70fc 100644 --- a/internal/service/cognitoidp/user_pools_data_source.go +++ b/internal/service/cognitoidp/user_pools_data_source.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_cognito_user_pools") -func DataSourceUserPools() *schema.Resource { +// @SDKDataSource("aws_cognito_user_pools", name="User Pools") +func dataSourceUserPools() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUserPoolsRead, From 1aefb929cf2ae0e96d3fa69218d21d595756ec4e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:05:54 -0400 Subject: [PATCH 18/23] r/aws_cognito_user_pool: Tidy up. --- internal/service/cognitoidp/consts.go | 1 - internal/service/cognitoidp/exports_test.go | 2 + internal/service/cognitoidp/user.go | 4 +- internal/service/cognitoidp/user_pool.go | 337 +++++++----------- internal/service/cognitoidp/user_pool_test.go | 175 +++++---- 5 files changed, 246 insertions(+), 273 deletions(-) diff --git a/internal/service/cognitoidp/consts.go b/internal/service/cognitoidp/consts.go index b2e0c3f732ed..ea839accef24 100644 --- a/internal/service/cognitoidp/consts.go +++ b/internal/service/cognitoidp/consts.go @@ -12,7 +12,6 @@ const ( ResNameRiskConfiguration = "Risk Configuration" ResNameUserPoolClient = "User Pool Client" ResNameUserPoolDomain = "User Pool Domain" - ResNameUserPool = "User Pool" ResNameUser = "User" ) diff --git a/internal/service/cognitoidp/exports_test.go b/internal/service/cognitoidp/exports_test.go index ec2687022151..46b471b5392f 100644 --- a/internal/service/cognitoidp/exports_test.go +++ b/internal/service/cognitoidp/exports_test.go @@ -18,5 +18,7 @@ var ( FindGroupByTwoPartKey = findGroupByTwoPartKey FindIdentityProviderByTwoPartKey = findIdentityProviderByTwoPartKey + FindUserByTwoPartKey = findUserByTwoPartKey + FindUserPoolByID = findUserPoolByID FindUserPoolUICustomizationByTwoPartKey = findUserPoolUICustomizationByTwoPartKey ) diff --git a/internal/service/cognitoidp/user.go b/internal/service/cognitoidp/user.go index 74eb2f560be3..fb9b5b33317e 100644 --- a/internal/service/cognitoidp/user.go +++ b/internal/service/cognitoidp/user.go @@ -231,7 +231,7 @@ func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interfac var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - user, err := FindUserByTwoPartKey(ctx, conn, d.Get("user_pool_id").(string), d.Get("username").(string)) + user, err := findUserByTwoPartKey(ctx, conn, d.Get("user_pool_id").(string), d.Get("username").(string)) if !d.IsNewResource() && tfresource.NotFound(err) { create.LogNotFoundRemoveState(names.CognitoIDP, create.ErrActionReading, ResNameUser, d.Get("username").(string)) @@ -398,7 +398,7 @@ func resourceUserImport(ctx context.Context, d *schema.ResourceData, meta interf return []*schema.ResourceData{d}, nil } -func FindUserByTwoPartKey(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolID, username string) (*cognitoidentityprovider.AdminGetUserOutput, error) { +func findUserByTwoPartKey(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, userPoolID, username string) (*cognitoidentityprovider.AdminGetUserOutput, error) { input := &cognitoidentityprovider.AdminGetUserInput{ Username: aws.String(username), UserPoolId: aws.String(userPoolID), diff --git a/internal/service/cognitoidp/user_pool.go b/internal/service/cognitoidp/user_pool.go index 9b0eb9699583..4406fb74c6b5 100644 --- a/internal/service/cognitoidp/user_pool.go +++ b/internal/service/cognitoidp/user_pool.go @@ -20,7 +20,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/flex" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -42,7 +41,6 @@ func resourceUserPool() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - // https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html Schema: map[string]*schema.Schema{ "account_recovery_setting": { Type: schema.TypeList, @@ -643,11 +641,18 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) + name := d.Get("name").(string) input := &cognitoidentityprovider.CreateUserPoolInput{ - PoolName: aws.String(d.Get("name").(string)), + PoolName: aws.String(name), UserPoolTags: getTagsIn(ctx), } + if v, ok := d.GetOk("account_recovery_setting"); ok { + if config, ok := v.([]interface{})[0].(map[string]interface{}); ok { + input.AccountRecoverySetting = expandUserPoolAccountRecoverySettingConfig(config) + } + } + if v, ok := d.GetOk("admin_create_user_config"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) @@ -657,12 +662,6 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in } } - if v, ok := d.GetOk("account_recovery_setting"); ok { - if config, ok := v.([]interface{})[0].(map[string]interface{}); ok { - input.AccountRecoverySetting = expandUserPoolAccountRecoverySettingConfig(config) - } - } - if v, ok := d.GetOk("alias_attributes"); ok { input.AliasAttributes = flex.ExpandStringSet(v.(*schema.Set)) } @@ -675,15 +674,6 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in input.EmailConfiguration = expandUserPoolEmailConfig(v.([]interface{})) } - if v, ok := d.GetOk("admin_create_user_config"); ok { - configs := v.([]interface{}) - config, ok := configs[0].(map[string]interface{}) - - if ok && config != nil { - input.AdminCreateUserConfig = expandUserPoolAdminCreateUserConfig(config) - } - } - if v, ok := d.GetOk("deletion_protection"); ok { input.DeletionProtection = aws.String(v.(string)) } @@ -741,25 +731,29 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in input.SmsConfiguration = expandSMSConfiguration(v.([]interface{})) } + if v, ok := d.GetOk("sms_verification_message"); ok { + input.SmsVerificationMessage = aws.String(v.(string)) + } + if v, ok := d.GetOk("username_attributes"); ok { input.UsernameAttributes = flex.ExpandStringSet(v.(*schema.Set)) } - if v, ok := d.GetOk("user_attribute_update_settings"); ok { + if v, ok := d.GetOk("username_configuration"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) if ok && config != nil { - input.UserAttributeUpdateSettings = expandUserPoolUserAttributeUpdateSettings(config) + input.UsernameConfiguration = expandUserPoolUsernameConfiguration(config) } } - if v, ok := d.GetOk("username_configuration"); ok { + if v, ok := d.GetOk("user_attribute_update_settings"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) if ok && config != nil { - input.UsernameConfiguration = expandUserPoolUsernameConfiguration(config) + input.UserAttributeUpdateSettings = expandUserPoolUserAttributeUpdateSettings(config) } } @@ -786,37 +780,15 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in } } - if v, ok := d.GetOk("sms_verification_message"); ok { - input.SmsVerificationMessage = aws.String(v.(string)) - } + outputRaw, err := tfresource.RetryWhen(ctx, propagationTimeout, func() (any, error) { + return conn.CreateUserPoolWithContext(ctx, input) + }, userPoolErrorRetryable) - // IAM roles & policies can take some time to propagate and be attached - // to the User Pool - var resp *cognitoidentityprovider.CreateUserPoolOutput - err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - var err error - resp, err = conn.CreateUserPoolWithContext(ctx, input) - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleTrustRelationshipException, "Role does not have a trust relationship allowing Cognito to assume the role") { - log.Printf("[DEBUG] Received %s, retrying CreateUserPool", err) - return retry.RetryableError(err) - } - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleAccessPolicyException, "Role does not have permission to publish with SNS") { - log.Printf("[DEBUG] Received %s, retrying CreateUserPool", err) - return retry.RetryableError(err) - } - if err != nil { - return retry.NonRetryableError(err) - } - return nil - }) - if tfresource.TimedOut(err) { - resp, err = conn.CreateUserPoolWithContext(ctx, input) - } if err != nil { - return sdkdiag.AppendErrorf(diags, "creating Cognito User Pool: %s", err) + return sdkdiag.AppendErrorf(diags, "creating Cognito User Pool (%s): %s", name, err) } - d.SetId(aws.StringValue(resp.UserPool.Id)) + d.SetId(aws.StringValue(outputRaw.(*cognitoidentityprovider.CreateUserPoolOutput).UserPool.Id)) if v := d.Get("mfa_configuration").(string); v != cognitoidentityprovider.UserPoolMfaTypeOff { input := &cognitoidentityprovider.SetUserPoolMfaConfigInput{ @@ -835,31 +807,12 @@ func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta in } } - // IAM Roles and Policies can take some time to propagate - err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - _, err := conn.SetUserPoolMfaConfigWithContext(ctx, input) - - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleTrustRelationshipException, "Role does not have a trust relationship allowing Cognito to assume the role") { - return retry.RetryableError(err) - } - - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleAccessPolicyException, "Role does not have permission to publish with SNS") { - return retry.RetryableError(err) - } - - if err != nil { - return retry.NonRetryableError(err) - } - - return nil - }) - - if tfresource.TimedOut(err) { - _, err = conn.SetUserPoolMfaConfigWithContext(ctx, input) - } + _, err := tfresource.RetryWhen(ctx, propagationTimeout, func() (any, error) { + return conn.SetUserPoolMfaConfigWithContext(ctx, input) + }, userPoolErrorRetryable) if err != nil { - return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool (%s) MFA Configuration: %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool (%s) MFA configuration: %s", d.Id(), err) } } @@ -870,63 +823,51 @@ func resourceUserPoolRead(ctx context.Context, d *schema.ResourceData, meta inte var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - params := &cognitoidentityprovider.DescribeUserPoolInput{ - UserPoolId: aws.String(d.Id()), - } - - resp, err := conn.DescribeUserPoolWithContext(ctx, params) + userPool, err := findUserPoolByID(ctx, conn, d.Id()) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - create.LogNotFoundRemoveState(names.CognitoIDP, create.ErrActionReading, ResNameUserPool, d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Cognito User Pool %s not found, removing from state", d.Id()) d.SetId("") return diags } if err != nil { - return create.AppendDiagError(diags, names.CognitoIDP, create.ErrActionReading, ResNameUserPool, d.Id(), err) + return sdkdiag.AppendErrorf(diags, "reading Cognito User Pool (%s): %s", d.Id(), err) } - userPool := resp.UserPool - + if err := d.Set("account_recovery_setting", flattenUserPoolAccountRecoverySettingConfig(userPool.AccountRecoverySetting)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting account_recovery_setting: %s", err) + } if err := d.Set("admin_create_user_config", flattenUserPoolAdminCreateUserConfig(userPool.AdminCreateUserConfig)); err != nil { return sdkdiag.AppendErrorf(diags, "setting admin_create_user_config: %s", err) } if userPool.AliasAttributes != nil { - d.Set("alias_attributes", flex.FlattenStringSet(userPool.AliasAttributes)) + d.Set("alias_attributes", aws.StringValueSlice(userPool.AliasAttributes)) } - d.Set("arn", userPool.Arn) + d.Set("auto_verified_attributes", aws.StringValueSlice(userPool.AutoVerifiedAttributes)) + d.Set("creation_date", userPool.CreationDate.Format(time.RFC3339)) d.Set("custom_domain", userPool.CustomDomain) - d.Set("domain", userPool.Domain) - d.Set("estimated_number_of_users", userPool.EstimatedNumberOfUsers) - d.Set("endpoint", fmt.Sprintf("%s/%s", meta.(*conns.AWSClient).RegionalHostname(ctx, "cognito-idp"), d.Id())) - d.Set("auto_verified_attributes", flex.FlattenStringSet(userPool.AutoVerifiedAttributes)) - - d.Set("email_verification_subject", userPool.EmailVerificationSubject) - d.Set("email_verification_message", userPool.EmailVerificationMessage) - if err := d.Set("lambda_config", flattenUserPoolLambdaConfig(userPool.LambdaConfig)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda_config: %s", err) - } - d.Set("sms_verification_message", userPool.SmsVerificationMessage) - d.Set("sms_authentication_message", userPool.SmsAuthenticationMessage) d.Set("deletion_protection", userPool.DeletionProtection) - if err := d.Set("device_configuration", flattenUserPoolDeviceConfiguration(userPool.DeviceConfiguration)); err != nil { return sdkdiag.AppendErrorf(diags, "setting device_configuration: %s", err) } - - if err := d.Set("account_recovery_setting", flattenUserPoolAccountRecoverySettingConfig(userPool.AccountRecoverySetting)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting account_recovery_setting: %s", err) - } - + d.Set("domain", userPool.Domain) if err := d.Set("email_configuration", flattenUserPoolEmailConfiguration(userPool.EmailConfiguration)); err != nil { return sdkdiag.AppendErrorf(diags, "setting email_configuration: %s", err) } - + d.Set("email_verification_subject", userPool.EmailVerificationSubject) + d.Set("email_verification_message", userPool.EmailVerificationMessage) + d.Set("endpoint", fmt.Sprintf("%s/%s", meta.(*conns.AWSClient).RegionalHostname(ctx, "cognito-idp"), d.Id())) + d.Set("estimated_number_of_users", userPool.EstimatedNumberOfUsers) + if err := d.Set("lambda_config", flattenUserPoolLambdaConfig(userPool.LambdaConfig)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting lambda_config: %s", err) + } + d.Set("last_modified_date", userPool.LastModifiedDate.Format(time.RFC3339)) + d.Set("name", userPool.Name) if err := d.Set("password_policy", flattenUserPoolPasswordPolicy(userPool.Policies.PasswordPolicy)); err != nil { return sdkdiag.AppendErrorf(diags, "setting password_policy: %s", err) } - var configuredSchema []interface{} if v, ok := d.GetOk("schema"); ok { configuredSchema = v.(*schema.Set).List() @@ -934,33 +875,25 @@ func resourceUserPoolRead(ctx context.Context, d *schema.ResourceData, meta inte if err := d.Set("schema", flattenUserPoolSchema(expandUserPoolSchema(configuredSchema), userPool.SchemaAttributes)); err != nil { return sdkdiag.AppendErrorf(diags, "setting schema: %s", err) } - + d.Set("sms_authentication_message", userPool.SmsAuthenticationMessage) if err := d.Set("sms_configuration", flattenSMSConfiguration(userPool.SmsConfiguration)); err != nil { return sdkdiag.AppendErrorf(diags, "setting sms_configuration: %s", err) } - + d.Set("sms_verification_message", userPool.SmsVerificationMessage) if err := d.Set("user_attribute_update_settings", flattenUserPoolUserAttributeUpdateSettings(userPool.UserAttributeUpdateSettings)); err != nil { return sdkdiag.AppendErrorf(diags, "setting user_attribute_update_settings: %s", err) } - + if err := d.Set("user_pool_add_ons", flattenUserPoolUserPoolAddOns(userPool.UserPoolAddOns)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting user_pool_add_ons: %s", err) + } d.Set("username_attributes", flex.FlattenStringSet(userPool.UsernameAttributes)) - if err := d.Set("username_configuration", flattenUserPoolUsernameConfiguration(userPool.UsernameConfiguration)); err != nil { return sdkdiag.AppendErrorf(diags, "setting username_configuration: %s", err) } - - if err := d.Set("user_pool_add_ons", flattenUserPoolUserPoolAddOns(userPool.UserPoolAddOns)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting user_pool_add_ons: %s", err) - } - if err := d.Set("verification_message_template", flattenUserPoolVerificationMessageTemplate(userPool.VerificationMessageTemplate)); err != nil { return sdkdiag.AppendErrorf(diags, "setting verification_message_template: %s", err) } - d.Set("creation_date", userPool.CreationDate.Format(time.RFC3339)) - d.Set("last_modified_date", userPool.LastModifiedDate.Format(time.RFC3339)) - d.Set("name", userPool.Name) - setTagsOut(ctx, userPool.UserPoolTags) input := &cognitoidentityprovider.GetUserPoolMfaConfigInput{ @@ -969,18 +902,11 @@ func resourceUserPoolRead(ctx context.Context, d *schema.ResourceData, meta inte output, err := conn.GetUserPoolMfaConfigWithContext(ctx, input) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - create.LogNotFoundRemoveState(names.CognitoIDP, create.ErrActionReading, ResNameUserPool, d.Id()) - d.SetId("") - return diags - } - if err != nil { - return create.AppendDiagError(diags, names.CognitoIDP, create.ErrActionReading, ResNameUserPool, d.Id(), err) + return sdkdiag.AppendErrorf(diags, "reading Cognito User Pool (%s) MFA configuration: %s", d.Id(), err) } d.Set("mfa_configuration", output.MfaConfiguration) - if err := d.Set("software_token_mfa_configuration", flattenSoftwareTokenMFAConfiguration(output.SoftwareTokenMfaConfiguration)); err != nil { return sdkdiag.AppendErrorf(diags, "setting software_token_mfa_configuration: %s", err) } @@ -992,7 +918,7 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - // Multi-Factor Authentication updates + // MFA updates. if d.HasChanges( "mfa_configuration", "sms_authentication_message", @@ -1019,41 +945,24 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in } } - // IAM Roles and Policies can take some time to propagate - err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - _, err := conn.SetUserPoolMfaConfigWithContext(ctx, input) - - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleTrustRelationshipException, "Role does not have a trust relationship allowing Cognito to assume the role") { - return retry.RetryableError(err) - } - - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleAccessPolicyException, "Role does not have permission to publish with SNS") { - return retry.RetryableError(err) - } - - if err != nil { - return retry.NonRetryableError(err) - } - - return nil - }) - - if tfresource.TimedOut(err) { - _, err = conn.SetUserPoolMfaConfigWithContext(ctx, input) - } + _, err := tfresource.RetryWhen(ctx, propagationTimeout, func() (any, error) { + return conn.SetUserPoolMfaConfigWithContext(ctx, input) + }, userPoolErrorRetryable) if err != nil { - return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool (%s) MFA Configuration: %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "setting Cognito User Pool (%s) MFA configuration: %s", d.Id(), err) } } - // Non Multi-Factor Authentication updates + // Non MFA updates // NOTES: // * Include SMS configuration changes since settings are shared between verification and MFA. // * For backwards compatibility, include SMS authentication message changes without SMS MFA since the API allows it. if d.HasChanges( + "account_recovery_setting", "admin_create_user_config", "auto_verified_attributes", + "deletion_protection", "device_configuration", "email_configuration", "email_verification_message", @@ -1068,14 +977,18 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in "user_attribute_update_settings", "user_pool_add_ons", "verification_message_template", - "account_recovery_setting", - "deletion_protection", ) { input := &cognitoidentityprovider.UpdateUserPoolInput{ UserPoolId: aws.String(d.Id()), UserPoolTags: getTagsIn(ctx), } + if v, ok := d.GetOk("account_recovery_setting"); ok { + if config, ok := v.([]interface{})[0].(map[string]interface{}); ok { + input.AccountRecoverySetting = expandUserPoolAccountRecoverySettingConfig(config) + } + } + if v, ok := d.GetOk("admin_create_user_config"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) @@ -1089,12 +1002,6 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in input.AutoVerifiedAttributes = flex.ExpandStringSet(v.(*schema.Set)) } - if v, ok := d.GetOk("account_recovery_setting"); ok { - if config, ok := v.([]interface{})[0].(map[string]interface{}); ok { - input.AccountRecoverySetting = expandUserPoolAccountRecoverySettingConfig(config) - } - } - if v, ok := d.GetOk("deletion_protection"); ok { input.DeletionProtection = aws.String(v.(string)) } @@ -1159,6 +1066,10 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in input.SmsConfiguration = expandSMSConfiguration(v.([]interface{})) } + if v, ok := d.GetOk("sms_verification_message"); ok { + input.SmsVerificationMessage = aws.String(v.(string)) + } + if v, ok := d.GetOk("user_attribute_update_settings"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) @@ -1208,50 +1119,44 @@ func resourceUserPoolUpdate(ctx context.Context, d *schema.ResourceData, meta in } } - if v, ok := d.GetOk("sms_verification_message"); ok { - input.SmsVerificationMessage = aws.String(v.(string)) - } + _, err := tfresource.RetryWhen(ctx, propagationTimeout, + func() (any, error) { + return conn.UpdateUserPoolWithContext(ctx, input) + }, + func(err error) (bool, error) { + if ok, err := userPoolErrorRetryable(err); ok { + return true, err + } + + switch { + case tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidParameterException, "Please use TemporaryPasswordValidityDays in PasswordPolicy instead of UnusedAccountValidityDays") && input.AdminCreateUserConfig.UnusedAccountValidityDays != nil: + input.AdminCreateUserConfig.UnusedAccountValidityDays = nil + return true, err + + default: + return false, err + } + }) - // IAM roles & policies can take some time to propagate and be attached - // to the User Pool. - err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - _, err := conn.UpdateUserPoolWithContext(ctx, input) - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleTrustRelationshipException, "Role does not have a trust relationship allowing Cognito to assume the role") { - log.Printf("[DEBUG] Received %s, retrying UpdateUserPool", err) - return retry.RetryableError(err) - } - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleAccessPolicyException, "Role does not have permission to publish with SNS") { - log.Printf("[DEBUG] Received %s, retrying UpdateUserPool", err) - return retry.RetryableError(err) - } - if tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidParameterException, "Please use TemporaryPasswordValidityDays in PasswordPolicy instead of UnusedAccountValidityDays") { - log.Printf("[DEBUG] Received %s, retrying UpdateUserPool without UnusedAccountValidityDays", err) - input.AdminCreateUserConfig.UnusedAccountValidityDays = nil - return retry.RetryableError(err) - } - if err != nil { - return retry.NonRetryableError(err) - } - return nil - }) - if tfresource.TimedOut(err) { - _, err = conn.UpdateUserPoolWithContext(ctx, input) - } if err != nil { - return sdkdiag.AppendErrorf(diags, "updating Cognito User pool (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "updating Cognito User Pool (%s): %s", d.Id(), err) } } if d.HasChange("schema") { - oldSchema, newSchema := d.GetChange("schema") - if oldSchema.(*schema.Set).Difference(newSchema.(*schema.Set)).Len() == 0 { - params := &cognitoidentityprovider.AddCustomAttributesInput{ + o, n := d.GetChange("schema") + os, ns := o.(*schema.Set), n.(*schema.Set) + + if os.Difference(ns).Len() == 0 { + input := &cognitoidentityprovider.AddCustomAttributesInput{ + CustomAttributes: expandUserPoolSchema(ns.Difference(os).List()), UserPoolId: aws.String(d.Id()), - CustomAttributes: expandUserPoolSchema(newSchema.(*schema.Set).Difference(oldSchema.(*schema.Set)).List()), } - _, err := conn.AddCustomAttributesWithContext(ctx, params) + + _, err := conn.AddCustomAttributesWithContext(ctx, input) + if err != nil { - return sdkdiag.AppendErrorf(diags, "updating Cognito User Pool (%s): unable to add custom attributes from schema: %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "adding Cognito User Pool (%s) custom attributes: %s", d.Id(), err) } } else { return sdkdiag.AppendErrorf(diags, "updating Cognito User Pool (%s): cannot modify or remove schema items", d.Id()) @@ -1265,13 +1170,10 @@ func resourceUserPoolDelete(ctx context.Context, d *schema.ResourceData, meta in var diags diag.Diagnostics conn := meta.(*conns.AWSClient).CognitoIDPConn(ctx) - params := &cognitoidentityprovider.DeleteUserPoolInput{ + log.Printf("[DEBUG] Deleting Cognito User Pool: %s", d.Id()) + _, err := conn.DeleteUserPoolWithContext(ctx, &cognitoidentityprovider.DeleteUserPoolInput{ UserPoolId: aws.String(d.Id()), - } - - log.Printf("[DEBUG] Deleting Cognito User Pool: %s", params) - - _, err := conn.DeleteUserPoolWithContext(ctx, params) + }) if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { return diags @@ -1284,6 +1186,43 @@ func resourceUserPoolDelete(ctx context.Context, d *schema.ResourceData, meta in return diags } +// IAM roles & policies can take some time to propagate and be attached to the User Pool. +func userPoolErrorRetryable(err error) (bool, error) { + switch { + case tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleTrustRelationshipException, "Role does not have a trust relationship allowing Cognito to assume the role"), + tfawserr.ErrMessageContains(err, cognitoidentityprovider.ErrCodeInvalidSmsRoleAccessPolicyException, "Role does not have permission to publish with SNS"): + return true, err + + default: + return false, err + } +} + +func findUserPoolByID(ctx context.Context, conn *cognitoidentityprovider.CognitoIdentityProvider, id string) (*cognitoidentityprovider.UserPoolType, error) { + input := &cognitoidentityprovider.DescribeUserPoolInput{ + UserPoolId: aws.String(id), + } + + output, err := conn.DescribeUserPoolWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil || output.UserPool == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output.UserPool, nil +} + func expandSMSConfiguration(tfList []interface{}) *cognitoidentityprovider.SmsConfigurationType { if len(tfList) == 0 || tfList[0] == nil { return nil diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index b75a367a319b..e281b6b42480 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -5,22 +5,20 @@ package cognitoidp_test import ( "context" - "errors" "fmt" - "os" "strings" "testing" "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfcognitoidp "github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -36,6 +34,7 @@ func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc { func TestAccCognitoIDPUserPool_basic(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -48,7 +47,7 @@ func TestAccCognitoIDPUserPool_basic(t *testing.T) { { Config: testAccUserPoolConfig_name(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "cognito-idp", regexache.MustCompile(`userpool/.+`)), resource.TestMatchResourceAttr(resourceName, "endpoint", regexache.MustCompile(`^cognito-idp\.[^.]+\.amazonaws.com/[\w-]+_[0-9A-Za-z]+$`)), resource.TestCheckResourceAttr(resourceName, "name", rName), @@ -88,6 +87,7 @@ func TestAccCognitoIDPUserPool_basic(t *testing.T) { func TestAccCognitoIDPUserPool_deletionProtection(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -100,6 +100,7 @@ func TestAccCognitoIDPUserPool_deletionProtection(t *testing.T) { { Config: testAccUserPoolConfig_deletionProtection(rName, "ACTIVE"), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "deletion_protection", "ACTIVE"), ), @@ -122,6 +123,7 @@ func TestAccCognitoIDPUserPool_deletionProtection(t *testing.T) { func TestAccCognitoIDPUserPool_recovery(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -134,7 +136,7 @@ func TestAccCognitoIDPUserPool_recovery(t *testing.T) { { Config: testAccUserPoolConfig_accountRecoverySingle(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.#", "1"), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.0.recovery_mechanism.#", "1"), @@ -152,7 +154,7 @@ func TestAccCognitoIDPUserPool_recovery(t *testing.T) { { Config: testAccUserPoolConfig_accountRecoveryMulti(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.#", "1"), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.0.recovery_mechanism.#", "2"), @@ -169,7 +171,7 @@ func TestAccCognitoIDPUserPool_recovery(t *testing.T) { { Config: testAccUserPoolConfig_accountRecoveryUpdate(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.#", "1"), resource.TestCheckResourceAttr(resourceName, "account_recovery_setting.0.recovery_mechanism.#", "1"), @@ -185,6 +187,7 @@ func TestAccCognitoIDPUserPool_recovery(t *testing.T) { func TestAccCognitoIDPUserPool_withAdminCreateUser(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -197,7 +200,7 @@ func TestAccCognitoIDPUserPool_withAdminCreateUser(t *testing.T) { { Config: testAccUserPoolConfig_adminCreateConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "admin_create_user_config.0.allow_admin_create_user_only", "true"), resource.TestCheckResourceAttr(resourceName, "admin_create_user_config.0.invite_message_template.0.email_message", "Your username is {username} and temporary password is {####}. "), resource.TestCheckResourceAttr(resourceName, "admin_create_user_config.0.invite_message_template.0.email_subject", "FooBar {####}"), @@ -225,6 +228,7 @@ func TestAccCognitoIDPUserPool_withAdminCreateUser(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/11858 func TestAccCognitoIDPUserPool_withAdminCreateUserAndPasswordPolicy(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -237,7 +241,7 @@ func TestAccCognitoIDPUserPool_withAdminCreateUserAndPasswordPolicy(t *testing.T { Config: testAccUserPoolConfig_adminCreateAndPasswordPolicy(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "admin_create_user_config.0.allow_admin_create_user_only", "true"), resource.TestCheckResourceAttr(resourceName, "password_policy.0.temporary_password_validity_days", "7"), ), @@ -253,6 +257,7 @@ func TestAccCognitoIDPUserPool_withAdminCreateUserAndPasswordPolicy(t *testing.T func TestAccCognitoIDPUserPool_withAdvancedSecurityMode(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -265,7 +270,7 @@ func TestAccCognitoIDPUserPool_withAdvancedSecurityMode(t *testing.T) { { Config: testAccUserPoolConfig_advancedSecurityMode(rName, "OFF"), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "OFF"), ), }, @@ -292,6 +297,7 @@ func TestAccCognitoIDPUserPool_withAdvancedSecurityMode(t *testing.T) { func TestAccCognitoIDPUserPool_withDevice(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -304,7 +310,7 @@ func TestAccCognitoIDPUserPool_withDevice(t *testing.T) { { Config: testAccUserPoolConfig_deviceConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "device_configuration.0.challenge_required_on_new_device", "true"), resource.TestCheckResourceAttr(resourceName, "device_configuration.0.device_only_remembered_on_user_prompt", "false"), ), @@ -327,6 +333,7 @@ func TestAccCognitoIDPUserPool_withDevice(t *testing.T) { func TestAccCognitoIDPUserPool_withEmailVerificationMessage(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) subject := sdkacctest.RandString(10) updatedSubject := sdkacctest.RandString(10) @@ -343,7 +350,7 @@ func TestAccCognitoIDPUserPool_withEmailVerificationMessage(t *testing.T) { { Config: testAccUserPoolConfig_emailVerificationMessage(rName, subject, message), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "email_verification_subject", subject), resource.TestCheckResourceAttr(resourceName, "email_verification_message", message), ), @@ -366,6 +373,7 @@ func TestAccCognitoIDPUserPool_withEmailVerificationMessage(t *testing.T) { func TestAccCognitoIDPUserPool_MFA_sms(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -379,6 +387,7 @@ func TestAccCognitoIDPUserPool_MFA_sms(t *testing.T) { { Config: testAccUserPoolConfig_mfaConfigurationSMSConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "ON"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -415,6 +424,7 @@ func TestAccCognitoIDPUserPool_MFA_sms(t *testing.T) { func TestAccCognitoIDPUserPool_MFA_smsAndSoftwareTokenMFA(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -428,6 +438,7 @@ func TestAccCognitoIDPUserPool_MFA_smsAndSoftwareTokenMFA(t *testing.T) { { Config: testAccUserPoolConfig_mfaConfigurationSMSConfigurationAndSoftwareTokenMFAConfigurationEnabled(rName, false), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "ON"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -466,6 +477,7 @@ func TestAccCognitoIDPUserPool_MFA_smsAndSoftwareTokenMFA(t *testing.T) { func TestAccCognitoIDPUserPool_MFA_smsToSoftwareTokenMFA(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -479,6 +491,7 @@ func TestAccCognitoIDPUserPool_MFA_smsToSoftwareTokenMFA(t *testing.T) { { Config: testAccUserPoolConfig_mfaConfigurationSMSConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "ON"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -506,6 +519,7 @@ func TestAccCognitoIDPUserPool_MFA_smsToSoftwareTokenMFA(t *testing.T) { func TestAccCognitoIDPUserPool_MFA_softwareTokenMFA(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -518,6 +532,7 @@ func TestAccCognitoIDPUserPool_MFA_softwareTokenMFA(t *testing.T) { { Config: testAccUserPoolConfig_mfaConfigurationSoftwareTokenMFAConfigurationEnabled(rName, true), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "ON"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "0"), resource.TestCheckResourceAttr(resourceName, "software_token_mfa_configuration.#", "1"), @@ -552,6 +567,7 @@ func TestAccCognitoIDPUserPool_MFA_softwareTokenMFA(t *testing.T) { func TestAccCognitoIDPUserPool_MFA_softwareTokenMFAToSMS(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -565,6 +581,7 @@ func TestAccCognitoIDPUserPool_MFA_softwareTokenMFAToSMS(t *testing.T) { { Config: testAccUserPoolConfig_mfaConfigurationSoftwareTokenMFAConfigurationEnabled(rName, true), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "ON"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "0"), resource.TestCheckResourceAttr(resourceName, "software_token_mfa_configuration.#", "1"), @@ -592,6 +609,7 @@ func TestAccCognitoIDPUserPool_MFA_softwareTokenMFAToSMS(t *testing.T) { func TestAccCognitoIDPUserPool_smsAuthenticationMessage(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) smsAuthenticationMessage1 := "test authentication message {####}" smsAuthenticationMessage2 := "test authentication message updated {####}" @@ -606,7 +624,7 @@ func TestAccCognitoIDPUserPool_smsAuthenticationMessage(t *testing.T) { { Config: testAccUserPoolConfig_smsAuthenticationMessage(rName, smsAuthenticationMessage1), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "sms_authentication_message", smsAuthenticationMessage1), ), }, @@ -618,7 +636,7 @@ func TestAccCognitoIDPUserPool_smsAuthenticationMessage(t *testing.T) { { Config: testAccUserPoolConfig_smsAuthenticationMessage(rName, smsAuthenticationMessage2), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "sms_authentication_message", smsAuthenticationMessage2), ), }, @@ -628,6 +646,7 @@ func TestAccCognitoIDPUserPool_smsAuthenticationMessage(t *testing.T) { func TestAccCognitoIDPUserPool_sms(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -641,6 +660,7 @@ func TestAccCognitoIDPUserPool_sms(t *testing.T) { { Config: testAccUserPoolConfig_smsConfigurationExternalID(rName, "test"), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "OFF"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -674,6 +694,7 @@ func TestAccCognitoIDPUserPool_sms(t *testing.T) { func TestAccCognitoIDPUserPool_SMS_snsRegion(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -687,6 +708,7 @@ func TestAccCognitoIDPUserPool_SMS_snsRegion(t *testing.T) { { Config: testAccUserPoolConfig_smsConfigurationSNSRegion(rName, acctest.Region()), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "OFF"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.sns_region", acctest.Region()), @@ -704,6 +726,7 @@ func TestAccCognitoIDPUserPool_SMS_snsRegion(t *testing.T) { func TestAccCognitoIDPUserPool_SMS_externalID(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -717,6 +740,7 @@ func TestAccCognitoIDPUserPool_SMS_externalID(t *testing.T) { { Config: testAccUserPoolConfig_smsConfigurationExternalID(rName, "test"), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "OFF"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -743,6 +767,7 @@ func TestAccCognitoIDPUserPool_SMS_externalID(t *testing.T) { func TestAccCognitoIDPUserPool_SMS_snsCallerARN(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_cognito_user_pool.test" @@ -756,6 +781,7 @@ func TestAccCognitoIDPUserPool_SMS_snsCallerARN(t *testing.T) { { Config: testAccUserPoolConfig_smsConfigurationExternalID(rName, "test"), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", "OFF"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "sms_configuration.0.external_id", "test"), @@ -782,6 +808,7 @@ func TestAccCognitoIDPUserPool_SMS_snsCallerARN(t *testing.T) { func TestAccCognitoIDPUserPool_smsVerificationMessage(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) smsVerificationMessage1 := "test verification message {####}" smsVerificationMessage2 := "test verification message updated {####}" @@ -796,7 +823,7 @@ func TestAccCognitoIDPUserPool_smsVerificationMessage(t *testing.T) { { Config: testAccUserPoolConfig_smsVerificationMessage(rName, smsVerificationMessage1), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsVerificationMessage1), ), }, @@ -808,7 +835,7 @@ func TestAccCognitoIDPUserPool_smsVerificationMessage(t *testing.T) { { Config: testAccUserPoolConfig_smsVerificationMessage(rName, smsVerificationMessage2), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "sms_verification_message", smsVerificationMessage2), ), }, @@ -818,6 +845,7 @@ func TestAccCognitoIDPUserPool_smsVerificationMessage(t *testing.T) { func TestAccCognitoIDPUserPool_withEmail(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -830,6 +858,7 @@ func TestAccCognitoIDPUserPool_withEmail(t *testing.T) { { Config: testAccUserPoolConfig_emailConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "email_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "email_configuration.0.reply_to_email_address", ""), resource.TestCheckResourceAttr(resourceName, "email_configuration.0.email_sending_account", "COGNITO_DEFAULT"), @@ -847,15 +876,13 @@ func TestAccCognitoIDPUserPool_withEmail(t *testing.T) { func TestAccCognitoIDPUserPool_withEmailSource(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) replyTo := acctest.DefaultEmailAddress resourceName := "aws_cognito_user_pool.test" resourceName2 := "aws_ses_configuration_set.test" - sourceARN, ok := os.LookupEnv("TEST_AWS_SES_VERIFIED_EMAIL_ARN") - if !ok { - t.Skip("'TEST_AWS_SES_VERIFIED_EMAIL_ARN' not set, skipping test.") - } + sourceARN := acctest.SkipIfEnvVarNotSet(t, "TEST_AWS_SES_VERIFIED_EMAIL_ARN") emailTo := sourceARN[strings.LastIndex(sourceARN, "/")+1:] resource.ParallelTest(t, resource.TestCase{ @@ -867,6 +894,7 @@ func TestAccCognitoIDPUserPool_withEmailSource(t *testing.T) { { Config: testAccUserPoolConfig_emailConfigurationSource(rName, replyTo, sourceARN, emailTo, "DEVELOPER"), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "email_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "email_configuration.0.reply_to_email_address", replyTo), resource.TestCheckResourceAttr(resourceName, "email_configuration.0.email_sending_account", "DEVELOPER"), @@ -879,8 +907,9 @@ func TestAccCognitoIDPUserPool_withEmailSource(t *testing.T) { }) } -func TestAccCognitoIDPUserPool_withTags(t *testing.T) { +func TestAccCognitoIDPUserPool_tags(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -893,7 +922,7 @@ func TestAccCognitoIDPUserPool_withTags(t *testing.T) { { Config: testAccUserPoolConfig_tags1(rName, "key1", "value1"), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), @@ -914,7 +943,7 @@ func TestAccCognitoIDPUserPool_withTags(t *testing.T) { { Config: testAccUserPoolConfig_tags1(rName, "key2", "value2"), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), @@ -925,6 +954,7 @@ func TestAccCognitoIDPUserPool_withTags(t *testing.T) { func TestAccCognitoIDPUserPool_withAliasAttributes(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -937,7 +967,7 @@ func TestAccCognitoIDPUserPool_withAliasAttributes(t *testing.T) { { Config: testAccUserPoolConfig_aliasAttributes(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "alias_attributes.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "alias_attributes.*", "preferred_username"), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "0"), @@ -964,6 +994,7 @@ func TestAccCognitoIDPUserPool_withAliasAttributes(t *testing.T) { func TestAccCognitoIDPUserPool_withUsernameAttributes(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -976,7 +1007,7 @@ func TestAccCognitoIDPUserPool_withUsernameAttributes(t *testing.T) { { Config: testAccUserPoolConfig_nameAttributes(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "username_attributes.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "username_attributes.*", "phone_number"), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "0"), @@ -1003,6 +1034,7 @@ func TestAccCognitoIDPUserPool_withUsernameAttributes(t *testing.T) { func TestAccCognitoIDPUserPool_withPasswordPolicy(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1015,7 +1047,7 @@ func TestAccCognitoIDPUserPool_withPasswordPolicy(t *testing.T) { { Config: testAccUserPoolConfig_passwordPolicy(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "password_policy.#", "1"), resource.TestCheckResourceAttr(resourceName, "password_policy.0.minimum_length", "7"), resource.TestCheckResourceAttr(resourceName, "password_policy.0.require_lowercase", "true"), @@ -1048,6 +1080,7 @@ func TestAccCognitoIDPUserPool_withPasswordPolicy(t *testing.T) { func TestAccCognitoIDPUserPool_withUsername(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1060,7 +1093,7 @@ func TestAccCognitoIDPUserPool_withUsername(t *testing.T) { { Config: testAccUserPoolConfig_nameConfiguration(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "username_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "username_configuration.0.case_sensitive", "true"), ), @@ -1073,7 +1106,7 @@ func TestAccCognitoIDPUserPool_withUsername(t *testing.T) { { Config: testAccUserPoolConfig_nameConfigurationUpdated(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "username_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "username_configuration.0.case_sensitive", "false"), ), @@ -1084,6 +1117,7 @@ func TestAccCognitoIDPUserPool_withUsername(t *testing.T) { func TestAccCognitoIDPUserPool_withLambda(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" lambdaResourceName := "aws_lambda_function.test" @@ -1098,7 +1132,7 @@ func TestAccCognitoIDPUserPool_withLambda(t *testing.T) { { Config: testAccUserPoolConfig_lambda(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.create_auth_challenge", lambdaResourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.custom_message", lambdaResourceName, "arn"), @@ -1136,7 +1170,7 @@ func TestAccCognitoIDPUserPool_withLambda(t *testing.T) { { Config: testAccUserPoolConfig_name(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "0"), ), }, @@ -1144,17 +1178,9 @@ func TestAccCognitoIDPUserPool_withLambda(t *testing.T) { }) } -func testAccCheckUserPoolNotRecreated(pool1, pool2 *cognitoidentityprovider.DescribeUserPoolOutput) resource.TestCheckFunc { - return func(s *terraform.State) error { - if !aws.TimeValue(pool1.UserPool.CreationDate).Equal(aws.TimeValue(pool2.UserPool.CreationDate)) { - return fmt.Errorf("user pool was recreated. expected: %s, got: %s", pool1.UserPool.CreationDate, pool2.UserPool.CreationDate) - } - return nil - } -} - func TestAccCognitoIDPUserPool_WithLambda_email(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" lambdaResourceName := "aws_lambda_function.test" @@ -1169,7 +1195,7 @@ func TestAccCognitoIDPUserPool_WithLambda_email(t *testing.T) { { Config: testAccUserPoolConfig_lambdaEmailSender(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "lambda_config.0.custom_email_sender.0.lambda_arn", lambdaResourceName, "arn"), @@ -1206,6 +1232,7 @@ func TestAccCognitoIDPUserPool_WithLambda_email(t *testing.T) { func TestAccCognitoIDPUserPool_WithLambda_sms(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" lambdaResourceName := "aws_lambda_function.test" @@ -1220,7 +1247,7 @@ func TestAccCognitoIDPUserPool_WithLambda_sms(t *testing.T) { { Config: testAccUserPoolConfig_lambdaSMSSender(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_email_sender.#", "0"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.custom_sms_sender.#", "1"), @@ -1257,6 +1284,7 @@ func TestAccCognitoIDPUserPool_WithLambda_sms(t *testing.T) { func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" lambdaResourceName := "aws_lambda_function.test" @@ -1271,7 +1299,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) { Config: testAccUserPoolConfig_lambdaPreTokenGenerationConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "lambda_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), resource.TestCheckResourceAttr(resourceName, "lambda_config.0.pre_token_generation_config.#", "1"), @@ -1308,7 +1336,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) { ctx := acctest.Context(t) - var pool1, pool2 cognitoidentityprovider.DescribeUserPoolOutput + var pool1, pool2 cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1438,7 +1466,7 @@ func TestAccCognitoIDPUserPool_schemaAttributesModified(t *testing.T) { // Ref: https://github.com/hashicorp/terraform-provider-aws/issues/21654 func TestAccCognitoIDPUserPool_schemaAttributesStringAttributeConstraints(t *testing.T) { ctx := acctest.Context(t) - var pool cognitoidentityprovider.DescribeUserPoolOutput + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1468,6 +1496,7 @@ func TestAccCognitoIDPUserPool_schemaAttributesStringAttributeConstraints(t *tes func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1480,7 +1509,7 @@ func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { { Config: testAccUserPoolConfig_verificationMessageTemplate(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.default_email_option", "CONFIRM_WITH_LINK"), resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message", "foo {####} bar"), resource.TestCheckResourceAttr(resourceName, "verification_message_template.0.email_message_by_link", "{##foobar##}"), @@ -1523,6 +1552,7 @@ func TestAccCognitoIDPUserPool_withVerificationMessageTemplate(t *testing.T) { func TestAccCognitoIDPUserPool_update(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) optionalMfa := "OPTIONAL" offMfa := "OFF" @@ -1539,7 +1569,7 @@ func TestAccCognitoIDPUserPool_update(t *testing.T) { { Config: testAccUserPoolConfig_update(rName, optionalMfa, authenticationMessage), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "1"), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", optionalMfa), resource.TestCheckResourceAttr(resourceName, "email_verification_message", "Foo {####} Bar"), @@ -1566,7 +1596,7 @@ func TestAccCognitoIDPUserPool_update(t *testing.T) { { Config: testAccUserPoolConfig_update(rName, optionalMfa, updatedAuthenticationMessage), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "1"), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", optionalMfa), resource.TestCheckResourceAttr(resourceName, "email_verification_message", "Foo {####} Bar"), @@ -1588,7 +1618,7 @@ func TestAccCognitoIDPUserPool_update(t *testing.T) { { Config: testAccUserPoolConfig_update(rName, offMfa, updatedAuthenticationMessage), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "1"), resource.TestCheckResourceAttr(resourceName, "mfa_configuration", offMfa), resource.TestCheckResourceAttr(resourceName, "email_verification_message", "Foo {####} Bar"), @@ -1613,6 +1643,7 @@ func TestAccCognitoIDPUserPool_update(t *testing.T) { func TestAccCognitoIDPUserPool_disappears(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1625,7 +1656,7 @@ func TestAccCognitoIDPUserPool_disappears(t *testing.T) { { Config: testAccUserPoolConfig_name(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), acctest.CheckResourceDisappears(ctx, acctest.Provider, tfcognitoidp.ResourceUserPool(), resourceName), ), ExpectNonEmptyPlan: true, @@ -1636,6 +1667,7 @@ func TestAccCognitoIDPUserPool_disappears(t *testing.T) { func TestAccCognitoIDPUserPool_withUserAttributeUpdateSettings(t *testing.T) { ctx := acctest.Context(t) + var pool cognitoidentityprovider.UserPoolType rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cognito_user_pool.test" @@ -1652,7 +1684,7 @@ func TestAccCognitoIDPUserPool_withUserAttributeUpdateSettings(t *testing.T) { { Config: testAccUserPoolConfig_userAttributeUpdateSettings(rName, cognitoidentityprovider.VerifiedAttributeTypeEmail), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "1"), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.0", cognitoidentityprovider.VerifiedAttributeTypeEmail), resource.TestCheckResourceAttr(resourceName, "user_attribute_update_settings.#", "1"), @@ -1663,7 +1695,7 @@ func TestAccCognitoIDPUserPool_withUserAttributeUpdateSettings(t *testing.T) { { Config: testAccUserPoolConfig_name(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckUserPoolExists(ctx, resourceName, nil), + testAccCheckUserPoolExists(ctx, resourceName, &pool), resource.TestCheckResourceAttr(resourceName, "auto_verified_attributes.#", "0"), resource.TestCheckResourceAttr(resourceName, "user_attribute_update_settings.#", "0"), ), @@ -1681,54 +1713,55 @@ func testAccCheckUserPoolDestroy(ctx context.Context) resource.TestCheckFunc { continue } - params := &cognitoidentityprovider.DescribeUserPoolInput{ - UserPoolId: aws.String(rs.Primary.ID), - } + _, err := tfcognitoidp.FindUserPoolByID(ctx, conn, rs.Primary.ID) - _, err := conn.DescribeUserPoolWithContext(ctx, params) + if tfresource.NotFound(err) { + continue + } if err != nil { - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - return nil - } return err } + + return fmt.Errorf("Cognito User Pool %s still exists", rs.Primary.ID) } return nil } } -func testAccCheckUserPoolExists(ctx context.Context, name string, pool *cognitoidentityprovider.DescribeUserPoolOutput) resource.TestCheckFunc { +func testAccCheckUserPoolExists(ctx context.Context, n string, v *cognitoidentityprovider.UserPoolType) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) - } - - if rs.Primary.ID == "" { - return errors.New("No Cognito User Pool ID set") + return fmt.Errorf("Not found: %s", n) } conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn(ctx) - params := &cognitoidentityprovider.DescribeUserPoolInput{ - UserPoolId: aws.String(rs.Primary.ID), - } + output, err := tfcognitoidp.FindUserPoolByID(ctx, conn, rs.Primary.ID) - poolOut, err := conn.DescribeUserPoolWithContext(ctx, params) if err != nil { return err } - if pool != nil { - *pool = *poolOut + if v != nil { + *v = *output } return nil } } +func testAccCheckUserPoolNotRecreated(pool1, pool2 *cognitoidentityprovider.UserPoolType) resource.TestCheckFunc { + return func(s *terraform.State) error { + if !aws.TimeValue(pool1.CreationDate).Equal(aws.TimeValue(pool2.CreationDate)) { + return fmt.Errorf("user pool was recreated. expected: %s, got: %s", pool1.CreationDate, pool2.CreationDate) + } + return nil + } +} + func testAccPreCheckIdentityProvider(ctx context.Context, t *testing.T) { conn := acctest.Provider.Meta().(*conns.AWSClient).CognitoIDPConn(ctx) From 337812d386fd546c86cd1836a05b874095fc481a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:08:00 -0400 Subject: [PATCH 19/23] r/aws_cognito_risk_configuration: Handle 'ResourceNotFoundException' in Delete. --- internal/service/cognitoidp/resource_server.go | 11 +++++------ internal/service/cognitoidp/risk_configuration.go | 5 +++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/service/cognitoidp/resource_server.go b/internal/service/cognitoidp/resource_server.go index ce98d553a8b1..baf4e0c8257b 100644 --- a/internal/service/cognitoidp/resource_server.go +++ b/internal/service/cognitoidp/resource_server.go @@ -205,17 +205,16 @@ func resourceResourceServerDelete(ctx context.Context, d *schema.ResourceData, m return sdkdiag.AppendErrorf(diags, "deleting Cognito Resource Server (%s): %s", d.Id(), err) } - params := &cognitoidentityprovider.DeleteResourceServerInput{ + _, err = conn.DeleteResourceServerWithContext(ctx, &cognitoidentityprovider.DeleteResourceServerInput{ Identifier: aws.String(identifier), UserPoolId: aws.String(userPoolID), - } + }) - _, err = conn.DeleteResourceServerWithContext(ctx, params) + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return diags + } if err != nil { - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { - return diags - } return sdkdiag.AppendErrorf(diags, "deleting Cognito Resource Server (%s): %s", d.Id(), err) } diff --git a/internal/service/cognitoidp/risk_configuration.go b/internal/service/cognitoidp/risk_configuration.go index 722de53bbc51..1610664c7d39 100644 --- a/internal/service/cognitoidp/risk_configuration.go +++ b/internal/service/cognitoidp/risk_configuration.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -389,6 +390,10 @@ func resourceRiskConfigurationDelete(ctx context.Context, d *schema.ResourceData _, err = conn.SetRiskConfigurationWithContext(ctx, input) + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return diags + } + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting Cognito Risk Configuration (%s): %s", d.Id(), err) } From c7347568b6129e546887410de717b7130f9517d9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:10:42 -0400 Subject: [PATCH 20/23] r/aws_cognito_user: Handle 'ResourceNotFoundException' in Delete. --- internal/service/cognitoidp/exports_test.go | 1 + internal/service/cognitoidp/service_package_gen.go | 3 ++- internal/service/cognitoidp/user.go | 8 ++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/service/cognitoidp/exports_test.go b/internal/service/cognitoidp/exports_test.go index 46b471b5392f..3cdc814e86ef 100644 --- a/internal/service/cognitoidp/exports_test.go +++ b/internal/service/cognitoidp/exports_test.go @@ -9,6 +9,7 @@ var ( ResourceManagedUserPoolClient = newManagedUserPoolClientResource ResourceResourceServer = resourceResourceServer ResourceRiskConfiguration = resourceRiskConfiguration + ResourceUser = resourceUser ResourceUserGroup = resourceUserGroup ResourceUserInGroup = resourceUserInGroup ResourceUserPool = resourceUserPool diff --git a/internal/service/cognitoidp/service_package_gen.go b/internal/service/cognitoidp/service_package_gen.go index e5cb9a886b46..104d635d1bcb 100644 --- a/internal/service/cognitoidp/service_package_gen.go +++ b/internal/service/cognitoidp/service_package_gen.go @@ -84,8 +84,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Risk Configuration", }, { - Factory: ResourceUser, + Factory: resourceUser, TypeName: "aws_cognito_user", + Name: "User", }, { Factory: resourceUserGroup, diff --git a/internal/service/cognitoidp/user.go b/internal/service/cognitoidp/user.go index fb9b5b33317e..91f984df61d0 100644 --- a/internal/service/cognitoidp/user.go +++ b/internal/service/cognitoidp/user.go @@ -25,8 +25,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// @SDKResource("aws_cognito_user") -func ResourceUser() *schema.Resource { +// @SDKResource("aws_cognito_user", name="User") +func resourceUser() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserCreate, ReadWithoutTimeout: resourceUserRead, @@ -379,6 +379,10 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf UserPoolId: aws.String(d.Get("user_pool_id").(string)), }) + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + return diags + } + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting Cognito User (%s): %s", d.Id(), err) } From bc1b9faca3a9d90b5ee7c99b0dd3807dc28eb132 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:15:25 -0400 Subject: [PATCH 21/23] Fix semgrep 'ci.semgrep.migrate.error-check-service-id'. --- internal/service/cognitoidp/user_pool_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/cognitoidp/user_pool_test.go b/internal/service/cognitoidp/user_pool_test.go index e281b6b42480..7d4123724643 100644 --- a/internal/service/cognitoidp/user_pool_test.go +++ b/internal/service/cognitoidp/user_pool_test.go @@ -1292,7 +1292,7 @@ func TestAccCognitoIDPUserPool_WithLambda_preGenerationTokenConfig(t *testing.T) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIdentityProvider(ctx, t) }, - ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID), + ErrorCheck: acctest.ErrorCheck(t, names.CognitoIDPServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckUserPoolDestroy(ctx), Steps: []resource.TestStep{ From 9a3756455f8abe66aed03ee4aad4bea85a5ccedc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:19:03 -0400 Subject: [PATCH 22/23] Fixup example. --- examples/cognito-user-pool/main.tf | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/cognito-user-pool/main.tf b/examples/cognito-user-pool/main.tf index 3cb729998708..2afbc437c7d9 100644 --- a/examples/cognito-user-pool/main.tf +++ b/examples/cognito-user-pool/main.tf @@ -118,12 +118,13 @@ resource "aws_cognito_user_pool" "pool" { pre_authentication = aws_lambda_function.main.arn pre_sign_up = aws_lambda_function.main.arn pre_token_generation = aws_lambda_function.main.arn # Set this parameter for legacy purposes; for new instances of pre token generation triggers, set the LambdaArn of `pre_token_generation_config` - pre_token_generation_config { - lambda_arn = aws_lambda_function.main.arn # Should be a identical to the pre_token_generation lambda ARN if used - lambda_version = "V2_0" - } user_migration = aws_lambda_function.main.arn verify_auth_challenge_response = aws_lambda_function.main.arn + + pre_token_generation_config { + lambda_arn = aws_lambda_function.main.arn # Should be a identical to the pre_token_generation lambda ARN if used + lambda_version = "V2_0" + } } schema { From cb6c6f8c4609f577281e1c99dcb8061d6ee0a539 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 Mar 2024 12:47:01 -0400 Subject: [PATCH 23/23] r/aws_cognito_user: Handle 'UserNotFoundException' in Delete. --- internal/service/cognitoidp/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/cognitoidp/user.go b/internal/service/cognitoidp/user.go index 91f984df61d0..127afa56d712 100644 --- a/internal/service/cognitoidp/user.go +++ b/internal/service/cognitoidp/user.go @@ -379,7 +379,7 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf UserPoolId: aws.String(d.Get("user_pool_id").(string)), }) - if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeResourceNotFoundException) { + if tfawserr.ErrCodeEquals(err, cognitoidentityprovider.ErrCodeUserNotFoundException, cognitoidentityprovider.ErrCodeResourceNotFoundException) { return diags }