Serverless :: The Highway to NanoService Architecture Era !!
Serverless is the newest trend in designing and re-thinking the architecture of web applications. This design paradigm incorporates third-party BaaS (Backend as a Service) or FaaS (Function as a Service) and simplifies the life of a Developer, such that they don’t need to deal with servers, instead they simply focus on their code. Hello Developers, welcome to NanoServices world !!
Serverless is the HighWay to the era of NanoServices — “Karan Singh”
The most popular FaaS in town in undoubtedly AWS Lambda. AWS Lambda provides out of the box support for Node.js, Python, Java, Go, .Net, Ruby as well as custom runtimes, which means you can BYOR (bring your own runtime) in the form of Lambda Layer and run your application function on top of it.
Recently I have been playing around PHP Laravel framework and learning to refactor a monolithic app to micro-service based architecture using Laravel/Lumen. With serverless architecture as the future goal (NanoService Architecture), I started leveraging AWS Lambda Function on top of custom built runtimes.
Lambda Custom Runtime is a newborn baby (25 days old as of writing this section) and there are very few resources available our there, especially for Laravel Lambda Custom Runtimes.
In this blog post we will explain you the process that i use to build Laravel Lambda Custom Runtime together with its source code . Go Build !!
git clone https://gitlab.com/scogo/laravel_custom_runtime_lambda.git
Once you have cloned our repository, you might need to edit a few files based on your requirements.
- Edit
build.sh
if you like to add PHP library to the Lambda Layer - Edit
regions.sh
, if you like to make Lambda Layer available across multiple AWS accounts within your AWS account. By defaultus-east-1
is configured for Lambda Layer - The default bucket name is
lambda-php-laravel-layer-us-east-1
. Editcreate-buckets.sh
upload.sh
publish.sh
andunpublish.sh
to change the bucket name (they are globally unique) - Edit
php.ini
if you like to enable PHP extensions of your choice (make sure you have installed them usingbuild.sh
before you enable them) - You might want to consider creating a separate IAM user for this testing having access to various AWS resources (Lambda, Cloudformation, IAM, S3, API Gateway etc). You can use
user-permission.yaml
a cloudformation template to create an IAM user for you. Once user creation is done it is expected that you manually generate an AWS access and secret keys and configure AWS CLI with the appropriate profile. In our case, IAM user profile name islambda-poc-IAM-user
, change this as needed.
Before we build our Custom Layer containing Laravel project files and libraries, we first need to set storage_path
as /tmp
because Lamda provides a stateless read-only filesystem, for any type of storage needs we need to use external storage services like S3, DynamoDB, CloudWatch or External Databases.
- Add your project files under
src/laravel
like you do for a standard Laravel project. For the sake of example, we have created a fresh laravel project using composer
cd src
composer create-project --prefer-dist laravel/laravel laravel
- Under
bootstrap/app.php
file, add line$app->useStoragePath(‘/tmp’);
beforereturn $app;
- Search for
storage_path
in your laravel project and empty all the occurrences ofstorage_path
parameter.
- (Important) Make sure to use one or more external storage options for your laravel application before you deploy it in production. Failing to do so will result in loss of data.
- Execute
make
command to generatephp71.zip
file in the current working directory. This is your Lambda Custom Layer file containing your application and its dependencies. AWS Lambda will simply use this as Custom Runtime and run your Application Functions. - Execute
create-buckets.sh
script to createS3
bucket before uploading Lambda Layer to S3 - Execute
upload.sh
script to upload Lambda Layer toS3
bucket - Execute
publish.sh
script to publish your Custom Lambda Layer to your preferred AWS regions. - Optionally you can also make your Lambda Layer publicly available by editing necessary section from
publish.sh
- Once the Custom Layer is published to AWS Lambda, login to AWS Console => Lambda => Layers and grab the Layer ARN
- Edit
template.yaml
and update the Lambda Layer ARN. You should also look for any other edits you want to do in the application template file
aws s3 mb s3://lambda-php-laravel-layer-us-east-1 \
— region us-east-1 \
— profile lambda-poc-IAM-user
- Package your serverless application using SAM CLI
sam package \
--template-file template.yaml \
--output-template-file output/serverless-laravel.yaml \
--s3-bucket lambda-php-laravel-layer-us-east-1 \
--profile ksingh-lambda-v2
- Deploy your serverless application
sam deploy \
— template-file output/serverless-laravel.yaml \
— stack-name serverless-laravel \
— capabilities CAPABILITY_IAM \
— profile lambda-poc-IAM-useraws lambda list-functions --profile lambda-poc-IAM-user
- Once SAM deploys your Lambda function, Login to AWS Lambda console select your serverless application
- Click on API Gateway to get your Lambda Endpoint.
- Most probably you might see a
404 Error
after hitting API Gateway, don’t panic, you just need to call the right file i.e.server.php
- Hopefully, everything goes well and you should see your Laravel Application
- Destroying PHP Laravel Serverless Application
aws cloudformation delete-stack \
— stack-name serverless-laravel \
— profile lambda-poc-IAM-useraws s3 rb — force s3://lambda-php-laravel-layer-us-east-1 \
— profile lambda-poc-IAM-user
That’s all Folks : Leverage the power of Custom Runtimes , now we don’t have any excuse Not to go Serverless.