Introduction
Using AWS Lambda we are able to run micro-service sized applications without any traditional server infastruture. These are called "serverless functions", which run inside ephemeral containers that offer several advantages over the traditional server/host configuration.
We've used AWS Lambda functions for some time now. They're a great way to perform a simple computing at a large scale. And the best part - it comes without the need to manage server instances and other resources.
Lambda allows you to write functions in a variety of different langauges (Java, Node.js, C# and Python). Our functions run on NodeJS.
The latest function we're working on has a single third-party library dependency. This adds an additional step to the development process, since we can't simply paste the function code into the inline editor for testing and deployment. The application package must be manually created via CLI - yet after doing that 2 or 3 times it starts to become redundant. Run a command, wait for it to complete, then run the next and so on...
It was time to automate this process. The solution was to use Make. It's super easy to setup, it's available on Mac and it's grown-up software.
Making things
Our packaging process has the following steps:
- Remove any old package.
- Install Node non-dev dependencies.
- Package the function and dependencies together.
Our Makefile
is almost an exact representation of that recipe:
lambda.zip: clean
rm -rf node_modules/
npm install --only=production
zip -r $@ lambda.js node_modules/
clean:
rm *.zip
It's possible to have several "rules" to make a target in your file. Here, we have two targets: lambda.zip
and clean
. Simply running make
– without params – from the command line will build the ZIP package. However running make clean
will just remove all the ZIP files in the directory.
Our lambda.zip
target depends on clean
to run. But clean
depends on nothing. Multiple dependencies are also allowed, if needed. If that's the case, separate them using spaces.
Below the target and its dependencies, there are the commands used to build the target. They must be indented using a tab. The $@
is a reference to the target name.
Going further
We have a third target to test the app. It runs the test
command declared in the package.json
file.
test:
rm -rf node_modules/
npm install
npm test
Notice the difference in the dependencies install? Here we add all packages, not just the non-dev. That's because we have some libraries that are used for testing purposes.
Since we removed the node_modules
directory in both lambda.zip
and test
targets, we could move it to a separated target and add it as a dependency. We ended up not doing that because it's a single liner and we don't use it alone. In contrast with clean
, which is occasionally used with make clean
.
Conclusion
This post demonstrates a very simple way to use Make in your development workflow. Its powerful, yet flexible and there are people using it to build far more complex recipes.
If you want to dig deeper and learn more about Make and Makefile
structure, there are lots of resources on the web. Though, you'll quickly find articles are about compiling C/C++ programs. This Digital Ocean article is a good starting place to learn how Make works and how it can be used to automate tasks. The man page is also handy, especially after you have some experience.
Thanks for reading! If you have any comments or questions please leave them below.