Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add forceDeploy property in Cognito User Pools #10435

Merged
merged 5 commits into from Jan 5, 2022

Conversation

TsimpDim
Copy link
Contributor

@TsimpDim TsimpDim commented Jan 2, 2022

I tried to implement the proposed solution which can be found here. I added a forceDeploy flag that once set will set a random property in the custom resource that is used to attach triggers - if the flag is set to false then it sets the property to 0. I updated tests as well, and made sure the linter is happy.

Addresses: #9635

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @TsimpDim, that looks very promising. Have you confirmed locally it does the job?

@@ -171,6 +172,7 @@ class AwsCompileCognitoUserPoolEvents {
}

let customCognitoUserPoolResource;
const forceDeployProperty = forceDeploy ? Math.random() * 10 : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's maybe set it to Date.now(), and do not set ForceDeploy (we can assign undefined) if no forceDeploy was set

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated!

@TsimpDim
Copy link
Contributor Author

TsimpDim commented Jan 3, 2022

Have you confirmed locally it does the job?

During deployment the Triggers still get removed for a little while until CF updates all the resources, but they eventually get added back. I'm not sure if we could improve this at all, but either way it is a way better solution then what one has to implement to circumvent this issue currently :D

});

it('should create the necessary resources for the most minimal configuration with forceDeploy', () => {
awsCompileCognitoUserPoolEvents.serverless.service.functions = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, didn't notice that one earlier.

In new tests we always rely on runServerless util (we have already a tons of tests configured for it, which can self as reference).

Can you update that one, so it's also runServerless based?

Copy link
Contributor Author

@TsimpDim TsimpDim Jan 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! I had to do some reading because I'm not familiar at all with testing in Javascript (or the internals of Serverless) but I came up with this:

    it('should create the necessary resources for the most minimal configuration with forceDeploy', () =>
      runServerless({
        fixture: 'cognitoUserPool',
        configExt: {
          functions: {
            existingSimple: {
              events: [
                {
                  cognitoUserPool: {
                    forceDeploy: true
                  },
                },
              ],
            }
          }
        },
        command: 'package',
      }).then(({ awsNaming, cfTemplate }) => {
        const { Resources } = cfTemplate;
        let customResource = Resources[awsNaming.getCustomResourceCognitoUserPoolResourceLogicalId('existingSimple')];
        
        expect(customResource.Properties.ForceDeploy).to.not.deep.equal(undefined);
    }));

(only one expect() statement instead of the previous three, for now at least). Will something like this do?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that looks very good.
Just use async/await (instead of .then()), and rather confirm on property as expect(typeof ..).to.equal('string')

@TsimpDim
Copy link
Contributor Author

TsimpDim commented Jan 4, 2022

I updated the test:

I could not find a better way of specifying what ForceDeploy's value should be (especially since it varies from execution to execution) so I opted for a value range assessment.
I also tried to add
expect(addCustomResourceToServiceStub).to.have.been.calledOnce; which I would expect to run fine, but it always failed (0 calls instead of the expected one - not sure if that's expected or I did something wrong)

I also updated the documentation to show the new flag.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @TsimpDim I have just two minor suggestions, and otherwise, it looks good to me

@codecov
Copy link

codecov bot commented Jan 5, 2022

Codecov Report

Merging #10435 (4ad509c) into master (f893772) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master   #10435   +/-   ##
=======================================
  Coverage   85.43%   85.44%           
=======================================
  Files         336      336           
  Lines       14003    14004    +1     
=======================================
+ Hits        11964    11966    +2     
+ Misses       2039     2038    -1     
Impacted Files Coverage Δ
...gins/aws/package/compile/events/cognitoUserPool.js 100.00% <100.00%> (ø)
lib/plugins/aws/package/compile/functions.js 95.14% <0.00%> (+0.32%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f893772...4ad509c. Read the comment docs.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @TsimpDim that looks great!

@medikoo medikoo merged commit c67a3f1 into serverless:master Jan 5, 2022
@meirgbinahai
Copy link

I see that this feature was pushed to version 2.71.0 - can anyone confirm that it works in versions 2.71.0+ ?

@halx4
Copy link

halx4 commented Mar 29, 2022

I see that this feature was pushed to version 2.71.0 - can anyone confirm that it works in versions 2.71.0+ ?

It works for me!
This is how I set it:

...
functions:
  postConfirmation-cognitoTrigger:
    handler: foo.bar
    events:
      - cognitoUserPool:
          pool: ${self:custom.userPoolName}
          existing: true
          trigger: PostConfirmation
          forceDeploy: true
...

@chris
Copy link

chris commented Jun 8, 2023

One followup question, related to @TsimpDim 's comment about how the triggers seem to get removed for a little bit during the deploy, then added back in. If that's the case, it seems like unless you change your Cognito pool frequently, it'd be best to only add the forceDeploy: true part in when you know this issue will happen? i.e. if we are only rarely changing user pool config (so this issue would rarely occur), I wouldn't want to have the triggers disappear on every deploy, and risk problems in my system (e.g. triggers not getting called) for the more common deploy case. Does that make sense - i.e. would you agree that if you infrequently change your user pool, you should only use forceDeploy: true when making those occasional changes, and otherwise leave it out of serverless.yml?

@AEsmerio
Copy link

I have been struggling with this issue for a very long time, but finally been resolved! THANKS! By adding "forceDeploy: true" it solved the problem. 🍻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants