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
Allow AWS Subscription Filters to be reordered #6471
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @sameer-s thanks for working on this 👍
I just looked through the code and added some comments. It looks like this change could result in a breaking change because resource logical ids could be too long. Perhaps we can check the length or use a trimmed and hashed version of the log group name we're using instead of the index to mitigate this problem.
Also I'm not sure if people overwrite this resource via the Resources
section in their serverless.yml
file.
lib/plugins/aws/lib/naming.js
Outdated
@@ -363,7 +363,7 @@ module.exports = { | |||
getCloudWatchLogLogicalId(functionName, logsIndex) { | |||
return `${this.getNormalizedFunctionName( | |||
functionName | |||
)}LogsSubscriptionFilterCloudWatchLog${logsIndex}`; | |||
)}LogsSubscriptionFilterCloudWatchLog${this.normalizePath(logsIndex)}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO we should rename this variable since it's not a numerical index anymore.
lib/plugins/aws/lib/naming.test.js
Outdated
'FunctionNameLogsSubscriptionFilterCloudWatchLog0' | ||
it('should normalize the function name and add the standard suffix including the log group name', () => { | ||
expect(sdk.naming.getCloudWatchLogLogicalId('functionName', '/aws/lambda/test')).to.equal( | ||
'FunctionNameLogsSubscriptionFilterCloudWatchLogAwsLambdaTest' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could result in a breaking change because the logical id can be too long (that was the reason we've used integers in the past). I'm not sure what the limit for the length of the resource logical id is, but it might make sense to check that we're compliant with that.
How do you think the best way to approach this problem is, then? It seems like it would be a bad idea to just assume that no one would be overriding these resources - I could definitely imagine a situation where someone was doing that to maybe set a custom Today I'll try to take a look to see if there's any way to get the sequential serial numbers from the |
Alright, this latest iteration reverts back to using the serial numbers, but continues checking if the logical ID matches what is expected. Turns out it was not nearly as difficult as I thought - I'd simply gotten confused because when I added a print statement, it appeared as if the loop through the cloudwatchLog events in Anyway, this solution should resolve the issues of the original bug report without introducing some of the other potential ones you brought up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating this PR @sameer-s 👍
I just looked through the code and it seems like a good solution since it doesn't touch that many different parts. Tested it with an example service and everything worked as expected.
LGTM
What did you implement:
Closes #5817
Closes #6263
How did you implement it:
As suggested in #6263, changed cloudwatch log subscription filters to name their logical IDs using their log group name rather than using an incrementing serial number. This prevents CloudFormation from getting confused (due to new subscription filters having the same name but different log groups than older ones) when a subscription filter is added to or removed from anywhere except the end of a template.
However, this brings up another problem: this would break any projects that already existed using the serial number naming scheme (I tested and confirmed that this problem does exist). Therefore, I also added an extra condition to the code that removes subscription filters if the old and new destination ARNs don't match: they must also have the same logical ID.
One last thing to note: while this second fix could be implemented on its own to solve the problem in #5817, there are some issues with taking that approach. First of all, continuing to implement subscription filters using serial numbers rather than filter names would end up causing many more deletions than are necessary. Additionally, this second fix is pretty much impossible (or at least very difficult) to implement without the first one, as there isn't really a way to calculate the "expected" logical ID from the
fixLogGroupSubscriptionFilters
method, since there's no good way to get which serial number will correspond to a log group.How can we verify it:
Create/deploy a project with CloudWatch logs subscriptions, and then re-deploy it with the order of some of the subscriptions swapped. This will throw a
Resource limit exceeded
on the upstream but should work fine on the PR. For the sake of brevity and time, I'm not going to rewrite it here, but there's a good example listed in the initial bug report (#5817).I've tested this locally, but you would also probably want to verify that a project deployed using the upstream version (with serial numbers) would redeploy fine on the newer version.
Todos:
Note: Run
npm run test-ci
to run all validation checks on proposed changesValidate via
npm test
Validate via
npm run lint-updated
Note: Some reported issues can be automatically fixed by running
npm run lint:fix
Validate via
npm run prettier-check-updated
Note: All reported issues can be automatically fixed by running
npm run prettify-updated
Is this ready for review?: YES
Is it a breaking change?: NO