AWS Lambda is what Microservices should be like
This post is my third post about AWS Lambda. (You can check my previous posts about AWS Lambda here) This time, I think I should talk more about my user experiences through my whole journey of using AWS Lambda to build a image resizing Microservice.
TL;DR
Building a Microservice with AWS Lambda and API Gateway is a great experience, especially in these aspects:
- Testing
- Deployment
- Microservice size
- Monitoring/Logging
- Web UI / CLI
Microservice size
First of all, every Lambda function is pretty small. (My image processing module only has 200 LOC in total.)
If a service only has ~100 lines of code, it would be super easy to develop/read/debug. (You can read more about small functions' advantages in my previous post Sandi Metz's Rules for OOP - dsdshome)
Testing
Amazon has provided docker images for all its available Lambda environments: lambci/docker-lambda: Docker images and test runners that replicate the live AWS Lambda environment
When I develop a Lambda function on local, I can just use these docker images to create containers that are almost identical to the production environments, and use them to test my function.
docker run \ -v "$PWD":/var/task \ lambci/lambda:nodejs6.10 index.handler '{"queryStringParameters": { "key": "100x100/test_image.jpg" }}'
(Although in this project, my function need to manipulate images, so it's a bit hard to write unit/integration test for it.)
Deployment
Amazon also provided a Makefile to build a lambda function zip file,
and we can deploy this zip file via aws-cli
easily.
.PHONY: all image package dist clean all: package image: docker build --tag amazonlinux:nodejs . package: image docker run --rm --volume ${PWD}/lambda:/build amazonlinux:nodejs npm install --production dist: package cd lambda && zip -FS -q -r ../dist/function.zip * clean: rm -r lambda/node_modules docker rmi --force amazonlinux:nodejs
After the function.zip
is generated, we can deploy it to AWS Lambda
via aws-cli
:
Deploy it to an existing function:
aws lambda update-function-code --function-name ServerlessImageResize-ResizeFunction-1CUW6FR1XJJEL --zip-file fileb://dist/function.zip
Setup the whole Microservice architecture via
CloudFormation
aws cloudformation deploy \ --template-file=deploy/output.yaml \ --stack-name="${stack_name}" \ --capabilities=CAPABILITY_NAMED_IAM
CloudFormation
is likedocker-compose
for AWS services, it can setup AWS services like S3, API Gateway, etc. based on a YAML template file.For this image resizing lambda function's
CloudFormation
template, you can check it here.
Monitoring/Logging
Amazon also provided builtin monitoring and logging support for Lambda.
Every lambda function comes with a monitoring console like this:
We can even go to the CloudWatch console for this Lambda function to see the logs.
Web UI / CLI
All the actions mentioned in this post, can all be done via AWS's web
user interface or through AWS's command line tool aws-cli
. This
gives developers enough choices to choose the one that suits them the
best.
Summary
So, what's the ideal Microservice development experience?
- The service codebase should be small enough.
- It has a way to reproduce the production environment on local. (e.g. Docker image)
- Developer can run tests in that environment by a single line of shell command (or a editor/IDE command)
- Developer can deploy changes using only a single command
- All the actions can be done via Web UI or CLI