Serverless :: The Highway to NanoService Architecture Era !!

Karan Singh
5 min readDec 24, 2018

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 default us-east-1 is configured for Lambda Layer
  • The default bucket name is lambda-php-laravel-layer-us-east-1 . Edit create-buckets.sh upload.sh publish.sh and unpublish.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 using build.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 is lambda-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’); before return $app;
  • Search for storage_path in your laravel project and empty all the occurrences of storage_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 generate php71.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 create S3 bucket before uploading Lambda Layer to S3
  • Execute upload.sh script to upload Lambda Layer to S3 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-user
aws 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-user
aws 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.

--

--

Karan Singh

Co-Founder & CTO @ Scogo ♦ I Love to solve problems using Tech