serverless / serverless/serverless

Custom Resource Cognito Pool event triggers not responding to pool changes on updates

Open
#12,229 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
46.9k
Forks
5.7k
Avg merge
10h 7m
Merged PRs (30d)
57

Description

Are you certain it's a bug?
  • Yes, it looks like a bug
Is the issue caused by a plugin?
  • It is not a plugin issue
Are you using the latest v3 release?
  • Yes, I'm using the latest v3 release
Is there an existing issue for this?
  • I have searched existing issues, it hasn't been reported yet
Issue description

Context

I have a Lambda that's listening to a cognitoUserPool trigger event. (I've used CustomMessage in my example, but in my actual code i'm also using PreAuthentication, PostConfirmation etc.). I have previously deployed the stack, and now I want to change the pool that the lambda is hooked into (in the example from dev to prod). I'm doing this by changing the pool property on the cognitoUserPool object.

Problem

When I deploy following updating the pool, the resource-based policy statement attached to the Lambda to allow Cognito to invoke the Lambda doesn't get updated. The policy statement is still called serverless-custom-resource-issue-prod-hello-my-user-pool-dev, and it is still pointing at the arn of the dev pool. I would have expected this statement to become serverless-custom-resource-issue-prod-hello-my-user-pool-prod, and this statement to contain the arn of the prod pool.

It looks like this is because this is causing the AWS Custom Resource RequestType to be Update - which in turn is calling the update function here. The update function is successfully changing the config to point the Cognito pool at this Lambda - I've confirmed this in the Cognito Console. Crucially however, it's not doing the permission changes to allow Cognito to invoke the Lambda. If you look at both the create() and delete() functions in the same Lambda, you can see these are creating/deleting this permission respectively. Essentially, there's no way to update this policy statement without deleting and recreating the Custom Resource.

Proposed Fix

I'm not entirely sure what the best approach here would be, as not all update events would necessarily require a permissions change - e.g. if you're changing the trigger type, the permissions stay the same.

The approach that requires the least code changes would likely be to add both removePermission(..) then addPermission(..) to the update fn, but maybe that's too lazy? As sometimes it would be removing/deleting needlessly.

Could alternatively create an updatePermission function that checks the current permission, and sees if it matches what the new information would require - likely just check that the StatementId and SourceArn match what would be created? This could then inform whether or not to remove the old and add a new permission at that point.

Extra Notes

Initially I thought forceDeploy might be the fix, but I think that isn't actually helping here, as that just changes a property on the Custom Resource, which is the cause for an update RequestUpdate. Given the pool has changed - and the Custom::CognitoUserPool object in the cloudformation template update has successfully pulled across the Properties.UserPoolName as anonymous-user-pool-prod I don't think adding this did anything for this flow.

Service configuration (serverless.yml) content
First deploy 


service: serverless-custom-resource-issue

frameworkVersion: "3"

provider:
  name: aws
  runtime: nodejs18.x
  region: eu-west-2

functions:
  hello:
    handler: handler.hello
    events: 
      - cognitoUserPool:
          pool: "my-user-pool-dev"
          trigger: 'CustomMessage'
          existing: true
          forceDeploy: true


Second deploy

```yaml
service: serverless-custom-resource-issue

frameworkVersion: "3"

provider:
  name: aws
  runtime: nodejs18.x
  region: eu-west-2

functions:
  hello:
    handler: handler.hello
    events: 
      - cognitoUserPool:
          pool: "my-user-pool-prod"
          trigger: 'CustomMessage'
          existing: true
          forceDeploy: true


### Command name and used flags

sls deploy 

### Command output

```shell
N/A
Environment information
Framework Core: 3.36.0
Plugin: 7.1.0
SDK: 4.4.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in lib/plugins/aws/custom-resources/resources/cognito-user-pool/handler.js, especially the update function at lines 43-55, and compare it with the create() and delete() functions. Reproduce the change with sls deploy, switching the pool from dev to prod. Done means the Lambda permission statement and source ARN follow the updated Cognito pool without breaking unchanged trigger updates.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, javascript
Domain
authentication, backend, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.