serverless / serverless

⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.
https://serverless.com
MIT License
46.51k stars 5.72k forks source link

Cognito deploys only 8 custom:attributes (max allowable is 50) #11850

Open lopezdp opened 1 year ago

lopezdp commented 1 year ago

Are you certain it's a bug?

Is the issue caused by a plugin?

Are you using the latest v3 release?

Is there an existing issue for this?

Issue description

ive deployed cognito resources to create a large amount of custom:attributes. here is a code sample of how I do it in my serverless.yml

resources:
  # Cognito User-Pool and Identity-Pool Services
  Resources:
    CognitoUserPool:
      Type: AWS::Cognito::UserPool
      Properties:
        # Need to generate a name based on the stage
        UserPoolName: ${self:custom.stage}-smart-notes-user-pool
        # User Pool Tags
        UserPoolTags:
          PROJECT: "smart-notes"
          FEATURE: "user-authentication"
          RESOURCE: "jwt-store"
        # Set email as an alias
        UsernameAttributes:
          - email
          # EVENTUALLY DYNAMIC
        AutoVerifiedAttributes:
          - email

        Schema:
          - Name: "userRole"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "superId"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "nickname"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "firstName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "lastName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "middleName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "initials"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "organization"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "title"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1

everything works fine when I do this with anything <= 8 attributes.

however, this time I need more than 8 as you can see by the list above.

unfortunately, server less framework only deploys 8 to cognito even though cloudformation advertises that it can be up to 50.

please help ?!

Service configuration (serverless.yml) content

service: smart-notes-authentication-api

frameworkVersion: "3"

custom:
  # Stages are based on what is passed into the CLI when running
  # serverless commands. Or fallback to settings in provider section.
  #
  stage: ${opt:stage, self:provider.stage}

provider:
  name: aws
  runtime: nodejs16.x
  stage: dev
  region: us-east-1
  tags:
    PROJECT_OWNER: smart-notes
    PROJECT_ENGINEER: lopezdp
  stackTags:
    PROJECT_RESOURCE: smart-notes-authentication-api
  tracing:
    # Optional, can be true (true equals 'Active'), 'Active' or 'PassThrough'
    lambda: true

  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - cognito-idp:*
            - "ses:SendEmail"
            - "ses:SendRawEmail"
          # Need to restrict IM Role to the specific table and stage
          Resource:
            - "*"

resources:
  # Cognito User-Pool and Identity-Pool Services
  Resources:
    CognitoUserPool:
      Type: AWS::Cognito::UserPool
      Properties:
        # Need to generate a name based on the stage
        UserPoolName: ${self:custom.stage}-smart-notes-user-pool
        # User Pool Tags
        UserPoolTags:
          PROJECT: "smart-notes"
          FEATURE: "user-authentication"
          RESOURCE: "jwt-store"
        # Set email as an alias
        UsernameAttributes:
          - email
          # EVENTUALLY DYNAMIC
        AutoVerifiedAttributes:
          - email

        Schema:
          - Name: "userRole"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "superId"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "nickname"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "firstName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "lastName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "middleName"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "initials"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "organization"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1
          - Name: "title"
            AttributeDataType: "String"
            Mutable: true
            StringAttributeConstraints:
              MaxLength: 256
              MinLength: 1

        VerificationMessageTemplate:
          DefaultEmailOption: CONFIRM_WITH_CODE
          EmailMessage: 'verify with this code {####}'
          EmailSubject: "Confirm your Registration!"

        EmailConfiguration:
          EmailSendingAccount: DEVELOPER
          From: no-reply@physiciansmart.ai
          ReplyToEmailAddress: no-reply@physiciansmart.ai
          SourceArn: arn:aws:ses:us-east-1:325676776482:identity/no-reply@physiciansmart.ai

    CognitoUserPoolClient:
      Type: AWS::Cognito::UserPoolClient
      Properties:
        # Generate an app client name based on the dev/prod stage
        # FIXME: UPDATE USERPOOL!
        ClientName: ${self:custom.stage}-smart-notes-user-pool-client
        UserPoolId:
          Ref: CognitoUserPool
        ExplicitAuthFlows:
          - ALLOW_ADMIN_USER_PASSWORD_AUTH # See also: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolclient.html
          - ALLOW_USER_PASSWORD_AUTH
          - ALLOW_REFRESH_TOKEN_AUTH
          - ALLOW_USER_SRP_AUTH
        GenerateSecret: false

    UserPoolDomain:
      Type: AWS::Cognito::UserPoolDomain
      Properties:
        #CustomDomainConfig:
        #CertificateArn: arn:aws:acm:us-west-1:564811092027:certificate/3257712f-7f32-44f4-b859-136a25006b6f
        UserPoolId:
          Ref: CognitoUserPool
        Domain: "physiciansmart"

    # This is the federated identity I need for the user pool
    # to authenticate with
    CognitoIdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        # Generate a name based on the stage of development
        IdentityPoolName: ${self:custom.stage}SmartNotesIdentityPool
        # Prevent unauthenticated users from using app
        AllowUnauthenticatedIdentities: false
        # Link this to the user-pool created
        CognitoIdentityProviders:
          - ClientId:
              Ref: CognitoUserPoolClient
            ProviderName:
              Fn::GetAtt: ["CognitoUserPool", "ProviderName"]

    # IAM Roles
    CognitoIdentityPoolRoles:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      Properties:
        IdentityPoolId:
          Ref: CognitoIdentityPool
        Roles:
          authenticated:
            Fn::GetAtt: [CognitoAuthRole, Arn]

    # IAM role used for authenticated users
    CognitoAuthRole:
      Type: AWS::IAM::Role
      Properties:
        Path: /
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Federated: "cognito-identity.amazonaws.com"
              Action:
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals:
                  "cognito-identity.amazonaws.com:aud":
                    Ref: CognitoIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAuthorizedPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"

                # Allow users to invoke the API
                - Effect: "Allow"
                  Action:
                    - "execute-api:Invoke"
                  Resource:
                    Fn::Join:
                      - ""
                      - - "arn:aws:execute-api:"
                        - Ref: AWS::Region
                        - ":"
                        - Ref: AWS::AccountId
                        - ":"
                        - "Fn::ImportValue": ${self:custom.stage}-ApiGatewayRestApiId
                        - "/*"

                # Allow users to upload attachments to their
                # folder inside of the s3 bucket created
                - Effect: "Allow"
                  Action:
                    - "s3:*"
                  Resource:
                    Fn::Join:
                      - ""
                      - - "Fn::ImportValue": ${self:custom.stage}-smartNotesAttachmentsBucketArn
                        - "/private/"
                        - "$"
                        - "{cognito-identity.amazonaws.com:sub}/*"

  # Print out the Id of the User Pool that is created
  Outputs:
    UserPoolId:
      Value:
        Ref: CognitoUserPool

    UserPoolClientId:
      Value:
        Ref: CognitoUserPoolClient

    # Print out the Id of the Identity Pool that is created
    # Outputs:
    IdentityPoolId:
      Value:
        Ref: CognitoIdentityPool

Command name and used flags

SLS_DEBUG=* serverless deploy --verbose --stage dev | tee deploy.out

Command output

[Container] 2023/03/21 19:33:09 Running command npm install -g serverless
48  npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
49  npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
50  npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
51  npm WARN deprecated superagent@7.1.6: Please downgrade to v7.1.5 if you need IE/ActiveXObject support OR upgrade to v8.0.0 as we no longer support IE and published an incorrect patch version (see https://github.com/visionmedia/superagent/issues/1731)
52  
53  added 407 packages, and audited 408 packages in 11s
54  
55  67 packages are looking for funding
56    run `npm fund` for details
57  
58  found 0 vulnerabilities
59  
60  [Container] 2023/03/21 19:33:20 Phase complete: INSTALL State: SUCCEEDED
61  [Container] 2023/03/21 19:33:20 Phase context status code:  Message: 
62  [Container] 2023/03/21 19:33:20 Entering phase PRE_BUILD
63  [Container] 2023/03/21 19:33:20 Phase complete: PRE_BUILD State: SUCCEEDED
64  [Container] 2023/03/21 19:33:20 Phase context status code:  Message: 
65  [Container] 2023/03/21 19:33:20 Entering phase BUILD
66  [Container] 2023/03/21 19:33:20 Running command SLS_DEBUG=* serverless deploy --verbose --stage dev | tee deploy.out
67  
68  Deploying smart-notes-authentication-api to stage dev (us-east-1)
69  
70  Uploading CloudFormation file to S3
71  Uploading State file to S3
72  Creating new change set
73  Waiting for new change set to be created
74  Created change set does not include any changes, removing it
75  Removing unnecessary service artifacts from S3
76  
77  Change set did not include any changes to be deployed. (1s)
78  
79  [Container] 2023/03/21 19:33:26 Running command echo build complete!
80  build complete!
81  
82  [Container] 2023/03/21 19:33:26 Phase complete: BUILD State: SUCCEEDED
83  [Container] 2023/03/21 19:33:26 Phase context status code:  Message: 
84  [Container] 2023/03/21 19:33:26 Entering phase POST_BUILD
85  [Container] 2023/03/21 19:33:26 Running command serverless info --verbose
86  service: smart-notes-authentication-api
87  stage: dev
88  region: us-east-1
89  stack: smart-notes-authentication-api-dev
90  
91  Stack Outputs:
92    UserPoolClientId: 5m8ejpnn2ohk8638qv9go3i986
93    UserPoolId: us-east-1_PC1cZPBeP
94    IdentityPoolId: us-east-1:15e6ad97-06ec-4859-b3a6-7dd2d5ab4616
95    ServerlessDeploymentBucketName: smart-notes-authenticati-serverlessdeploymentbuck-1a9xx1hssrr0n
96  
97  [Container] 2023/03/21 19:33:29 Running command echo post-build complete!
98  post-build complete!
99  
100 [Container] 2023/03/21 19:33:29 Phase complete: POST_BUILD State: SUCCEEDED
101 [Container] 2023/03/21 19:33:29 Phase context status code:  Message: 

### Environment information

```shell
`npm install -g serverless`

latest
medikoo commented 1 year ago

unfortunately, server less framework only deploys 8 to cognito even though cloudformation advertises that it can be up to 50.

@lopezdp where this assumption comes from? Framework passes content of resources sections as is to CloudFormation template, it doesn't strip it in any way (and you can confirm that by inspecting the deployed template). Now if you don't see attributes on end resources which are part of the deployed template, it looks as some issue on AWS side, and for that, I advise to contact their support, or search forums to find similar issues reported.

lopezdp commented 1 year ago

unfortunately, server less framework only deploys 8 to cognito even though cloudformation advertises that it can be up to 50.

@lopezdp where this assumption comes from? Framework passes content of resources sections as is to CloudFormation template, it doesn't strip it in any way (and you can confirm that by inspecting the deployed template). Now if you don't see attributes on end resources which are part of the deployed template, it looks as some issue on AWS side, and for that, I advise to contact their support, or search forums to find similar issues reported.

Good point i have convo with AWS rep today i will bring this up