What would be the best way to update the code of a single function without having to package and deploy the whole stack (which is getting quite slow as the app grows)? Basically, do the equivalent of this AWS Deploy Function of Serverless framework.
I was thinking about using the update-function-code of the lambda cli but not sure what the impact will be on the stack if it start updating some of its resources outside of the normal package->deploy process
From our (arguably anecdotal) experience, we've had zero issues updating lambdas outside of SAM. The issues can come if you replace a lambda (actually delete the lambda an APIGW is pointing to).
@brunomorency You'd be ok with updating the lambda directly since you're not modifying the infrastructure, just the application code that the lambda runs.
We're working through this problem right now, by looking into running a separate pipeline for updating our API + Lambdas only.
Why do you want to work around CloudFormation? Is it the cost of running aws cloudformation package command or simply the time taken to deploy the stack?
I have heard this sentiment in many places that updating Lambda is easier than updating via CloudFormation. Want to dissect to the bottom of the issue here to drive some fixes on our end.
@sanathkr I want to work around CloudFormation because deploy is _very_ slow (package is fine). It would be fine in the context of continuous deployment of latest commits but if you just want to apply a quick fix to a lambda function in a development iteration, it's unbearable how much it slows down the iterations.
One option would be to figure out a local setup to run the SAM app during development and deploy the stack to AWS only when done but I found it very cumbersome to replicate everything locally and prefer my dev setup to be in AWS.
I ended up writing my own deployment script and since you said this is a sentiment you heard in many places, I just published it as a package if other people would like to use it: https://www.npmjs.com/package/sampique
Okay, there are two parts to this:
aws cloudformation deploy command's waiter timer - it polls CloudFormation for status of the stack every 30 seconds. So even if the stack finished faster the command will take at least 30 seconds to complete. I can change the polling interval to 5 seconds for quicker response.I like the sampique project but I wish to get the same speed directly with deploy. Will send out a PR for polling interval, and let's see if that helps.
From experience, deploys often took multiple minutes. Changing the polling down from 30 seconds to 5 seconds would shave off a few seconds but the impact would be marginal at best, unfortunately.
If that helps, my stack currently has 9 dynamodb tables (declared as AWS::DynamoDB::Table, not the simple table SAM provides), one API gateway with a custom authorizer (swagger file external to the template file, 9 lambda functions (most triggered by API gateway but some are triggered on a cron schedule and some are triggered by files uploaded to an S3 bucket), 2 S3 buckets, 5 IAM roles used by functions so they can access what they need. It doesn't seem to be a particularly large stack, I've seen bigger. Not sure why CF is taking so long to process
I think slow deployments are also affected by the fact that they update _all_ of function resources every time, even if there wasn't any code change in any of them. Support for native versioning based on code hash could help with this.
updating _all_ functions is a concern if you use the package command which doesn't do a good job at producing zips with consistent hashes. CI/CD tools often do a better job of creating consistent builds artifacts
Agreed. I ended up calculating the hash explicitly and passing it to my templates.
Closing this as there is nothing actionable
@dinvlad could you elaborate more your solution?
@rizidoro here's a script I used for deployment: https://github.com/cumulous/backend/blob/master/scripts/package.sh
(alas I moved away to Firebase since then, so may not be able to provide further help)
@brunomorency out of genuine curiosity, why did you not simply choose to use Serverless Framework? Because SAM _is_ AWS ecosystem?
@alexdilley SAM is already a layer on to p of CLoudFormation, I really didn't want to add yet another layer on top of everything. Especially one that is outside AWS ecosystem and will always attempt to find a common denominator with other platforms.
After finding this issue, I ended up writing a small script to deploy individual functions bypassing CloudFormation. In medium-sized stacks, I'm getting 20x faster deployments. Hope it helps!
https://dev.to/spalladino/speed-up-your-aws-sam-development-by-deploying-individual-functions-d74
FWIW, it'd be great to have this feature natively as part of the SAM CLI.
Most helpful comment
@alexdilley SAM is already a layer on to p of CLoudFormation, I really didn't want to add yet another layer on top of everything. Especially one that is outside AWS ecosystem and will always attempt to find a common denominator with other platforms.