Serverless: Duplicate Cognito User pool create when resource and function defined with same name

Created on 11 Sep 2018  ·  10Comments  ·  Source: serverless/serverless

This is a (Bug Report )

Description

For bug reports:
cognito-user-pool.yml

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      # Generate a name based on the stage
      UserPoolName: ${self:provider.stage}MyUserPool

serverless.yml

functions:
  preSignUp:
    handler: presignup.handler
    events:
      - cognitoUserPool:
          pool: ${self:provider.stage}MyUserPool
          trigger: PreSignUp

resources:
  - ${file(resources/cognito-user-pool.yml)}

It end up with created two UserPools with same name and one with attached trigger function, other with attached policies and other things that i define in cognito-user-pool

Similar or dependent issues:

  • #4207

Additional Data

"serverless": "1.30.3"

bug caaws-event-cognito

Most helpful comment

Your solution worked like a charm @robotlemons !! 🎉 Thank you very much for sharing it!

The part that was really confusing for me was that the docs call the CognitoUserPool as MyUserPool all the time, and I was setting UserPoolName: ${self:provider.stage}-user-pool, so I thought that when declaring the lambda, we should be doing:

- cognitoUserPool:
  pool: ${self:provider.stage}-user-pool
  trigger: PostConfirmation

I thought that this way I was setting the same name for both, but the key here is to give the pool attribute the same value as your CognitoUserPool, hence why the docs set it as MyUserPool.

So I finally just declared my user pool in cognito-user-pool.yml as:

Resources:
  CognitoUserPoolMyUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: ${self:provider.stage}-user-pool

And in serverless.yml the lambda is declared as:

  postConfirmation:
    handler: src/cognito/postConfirmation.handler
    events:
      - cognitoUserPool:
          pool: MyUserPool  // Notice that this one is the declared name of my pool CognitoUserPoolMyUserPool but without the CognitoUserPool part.
          trigger: PostConfirmation

Hope this helps someone else in the future!

Big thanks again for your help! 💯

All 10 comments

Having the same issue. Curious when a resolution may be reached?

I'm also having this problem and can't get to solve it by following the examples in the docs or other closed issues

@Ccastillo06 I was able to correct the issue by doing so... (bolded parts are the important piece. This did work for me even after I was experiencing all the issues.

CognitoUserPoolMyUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: mypool_${self:provider.stage}_auth_pool
UsernameAttributes:
- email
Schema:
- Name: given_name
AttributeDataType: String
Mutable: true
Required: true
- Name: family_name
AttributeDataType: String
Mutable: true
Required: true
- Name: email
AttributeDataType: String
Mutable: false
Required: true
- Name: phone_number
AttributeDataType: String
Mutable: true
Required: true
AutoVerifiedAttributes:
- email

postConfirmation:
handler: ..
memorySize: ...
events:
- http:
path: ...
method: put
integration: lambda
cors: true
authorizer:
type: COGNITO_USER_POOLS
authorizerId:
Ref: ApiGatewayAuthorizer
- cognitoUserPool:
pool: MyUserPool
trigger: PostConfirmation

Your solution worked like a charm @robotlemons !! 🎉 Thank you very much for sharing it!

The part that was really confusing for me was that the docs call the CognitoUserPool as MyUserPool all the time, and I was setting UserPoolName: ${self:provider.stage}-user-pool, so I thought that when declaring the lambda, we should be doing:

- cognitoUserPool:
  pool: ${self:provider.stage}-user-pool
  trigger: PostConfirmation

I thought that this way I was setting the same name for both, but the key here is to give the pool attribute the same value as your CognitoUserPool, hence why the docs set it as MyUserPool.

So I finally just declared my user pool in cognito-user-pool.yml as:

Resources:
  CognitoUserPoolMyUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: ${self:provider.stage}-user-pool

And in serverless.yml the lambda is declared as:

  postConfirmation:
    handler: src/cognito/postConfirmation.handler
    events:
      - cognitoUserPool:
          pool: MyUserPool  // Notice that this one is the declared name of my pool CognitoUserPoolMyUserPool but without the CognitoUserPool part.
          trigger: PostConfirmation

Hope this helps someone else in the future!

Big thanks again for your help! 💯

@Ccastillo06
I'm sorry, I'm super confused and would love some help.

So in teh PostConfirmation declaration, in the cognitoUserPool events section. What should be the value for 'pool'? I've tried the actual name of the user pool and it keeps creating new user pools. I've also tried the value directly under 'Resources' (in your case 'CognitoUserPoolMyUserPool').

Now in your 'pool' value you said you input 'MyUserPool' without the CognitoUserPool part, but my resource name is different. So what should my name be? I've tried the full name and that doesn't work.

@Studio2133

Resources:
  CognitoUserPoolMyUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: ${self:provider.stage}-user-pool

This example, you would use whatever is after CognitoUserPool as your pool value. In this case, it would be MyUserPool

@robotlemons Thanks for the prompt response!

So I should rename my resource. Currently I don't have it starting with CognitoUserPool. Currently it's just called: MycompanyUserPool. I'll change it to: CognitoUserPoolMyCompanyUserPool... Is that correct?

Yes

Sent from my iPhone

On Apr 11, 2019, at 12:33 PM, Studio2133 notifications@github.com wrote:

@robotlemons Thanks for the prompt response!

So I should rename my resource. Currently I don't have it starting with CognitoUserPool. Currently it's just called: MycompanyUserPool. I'll change it to: CognitoUserPoolMyCompanyUserPool... Is that correct?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@Studio2133 In your case you should do what @robotlemons said, just add CognitoUserPool before the name of your actual user pool MycompanyUserPool.

So in the end you should have: CognitoUserPoolMycompanyUserPool for that pool name.

So your user pool definition in cognito-user-pool.yml should be:

Resources:
  CognitoUserPoolMycompanyUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: ${self:provider.stage}-user-pool

And then the lambda trigger definition in serverless.yml should be:

 postConfirmation:
    handler: src/cognito/postConfirmation.handler
    events:
      - cognitoUserPool:
          pool: MycompanyUserPool  
          trigger: PostConfirmation

I've had this working fine for us in our latest project (calling other lambdas and services from AWS using the PostConfirmation trigger) and didn't have any problems at all.

Remember to remove every duplicated pool before you create the fixed pools so there's nothing confusing in the AWS control panel.

Hope this is useful and solves the issue!

@Studio2133
When you add a cognitoUserPool event to a lambda, Serverless automatically generates a new Cognito User Pool and adds it to your generated CloudFormation template. The CloudFormation logical resource name of this pool is CognitoUserPool{normalizedPoolId}, where normalizedPoolId is the name you provide for pool in your cognitoUserPool event. This is the pool that the trigger will be connected to. In order to connect the trigger to your own pool that you declare in Resources, you can take advantage of this naming convention to override the pool generated by adding the cognitoUserPool event. To do this, you need to use CognitoUserPool{normalizedPoolId} as the logical resource name of your pool in your Resources section. This will cause Serverless to use this pool to connect your trigger to, instead of generating a new one.

More details on this approach can be found in this article.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brianneisler picture brianneisler  ·  3Comments

jthomas picture jthomas  ·  3Comments

bradgreens picture bradgreens  ·  3Comments

anreved picture anreved  ·  3Comments

kevindiamond picture kevindiamond  ·  3Comments