hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.77k stars 9.12k forks source link

[Bug]: `cognito_user_pool` hardcodes email as non-required attribute #32750

Open braunsonm opened 1 year ago

braunsonm commented 1 year ago

Terraform Core Version

1.5.3

AWS Provider Version

5.10.0

Affected Resource(s)

aws_cognito_user_pool

Expected Behavior

During the create experience on the AWS console you have the option to multi-select attributes that a user can use to sign in with. You can pick username, email, and phone_number. There is currently no way to replicate this flow with the Terraform resource because these attributes are hard-coded to be not required during sign-up. On the console, checking the box email results in the schema for the email attribute to set required=true.

image

Console generated JSON:

            {
                "Name": "email",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },

Actual Behavior

Terraform provider hardcoding this required value: https://github.com/hashicorp/terraform-provider-aws/blob/f50629451b1e3195af5737598e54426dbf454d6b/internal/service/cognitoidp/user_pool.go#L2011-L2018

TLDR: When alias_attributes is set to preferred_username and email, then the schema should require that attribute during sing up. Right now the TF provider creates the resource incorrectly with the required field set to false.

Note this is NOT the same as username_attributes which only lets you set email and phone_number. It does not allow preferred_username.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

resource "aws_cognito_user_pool" "pool" {
  name = "mypool"
  alias_attributes = ["preferred_username", "email"]
  auto_verified_attributes = ["email"]
}

Steps to Reproduce

  1. Apply
  2. aws cognito-idp describe-user-pool --user-pool-id
  3. Notice the email attribute is not required
  4. Attempt a sign-up using the hosted UI, see that an email is not asked from the user and therefore will not be auto-verified.

Debug Output

No response

Panic Output

No response

Important Factoids

I thought maybe you could work around this by defining a custom schema with your resource but that results in an error as it is treated as a custom attribute.

resource "aws_cognito_user_pool" "pool" {
  name = "mypool"
  alias_attributes = ["preferred_username", "email"]
  auto_verified_attributes = ["email"]

  schema {
    name                     = "email"
    attribute_data_type      = "String"
    developer_only_attribute = false
    mutable                  = true
    required                 = true
    string_attribute_constraints {
      min_length = 0
      max_length = 2048
    }
  }
}
Error: updating Cognito User Pool (ID): unable to add custom attributes from schema: InvalidParameterException: Required custom attributes are not supported currently.

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

georgesmith2017 commented 10 months ago

Actually there is a away. Here are the relevant parts:

resource "aws_cognito_user_pool" "enduser_pool" {
    name = "userpool-for-ecommerce-microservices"

    schema {
      name = "email"
      attribute_data_type = "String"
      mutable = true
      developer_only_attribute = false
      required = true
    }

required = true in the schema is the critical part. By default only "username" is the default for signing up and signing in. So, need to specify any of these two, so I had them commented out.

# alias_attributes = ["email"]
# username_attributes = ["email"]

I tried all sort of combinations of the above two settings, but none of them allowed me to have all three items in Cognito's Hosted UI: Username, email, and password.. With no settings and required = true for email, I got all three.

All this will be part of a demo in a course that I will be releasing on Pluralsight in about 3 weeks - Node JS Securing Micro Services. Please, watch it when you get a chance :).

braunsonm commented 10 months ago

Interesting @georgesmith2017

I mentioned that solution in my issue and at the time of writing it I got an error from the AWS API as I posted at the end of my issue. Are you saying you don't get an error that required custom attributes are not supported?

Either way, that's a workaround and I think the default the behaviour should be to mark email as required when it is an alias attribute.

georgesmith2017 commented 10 months ago

I am not calling the API directly. Yes, I was getting an error similar to what you posted above: required custom attributes are not supported. However, that was just in Terraform. It appears Terraform does not recognize "username" as standard attribute and it treats it as custom. It does recognize "email" and "phone_number".

There two things I was experiencing that led me here to your post:

  1. I wasn't getting "Username" on the Hosted UI when I had only "email" specified in username_attributes = [""user_name"]. I tried alias attributes as well, to no availa (generally they are for the top part and I expected that specifying "username" there would get it to show on the Hosted UI popup)
  2. I was getting an error on the Hosted UI when registering with only "Username" and "Password" - the "Email" field was not shown.

Hope this helps. It is possible that at the time writing your post, the workaround was not available. I almost gave up when I read the above, but then started wondering about the purpose of the schema settings in aws_cognito_user_pool and decided to give it one more try by setting "email" as "required", which worked.

Sorry I didn't respond sooner. I am in Europe and it is really late here. Just saw your previous response.

braunsonm commented 10 months ago

Appreciate it! @georgesmith2017

I'll keep this open as the provider should either recognize email as non-custom or mark it as required but good to know there's a workaround now.