Skip to main content

Deploy Laravel API To AWS Lambda

· 6 min read

About two months ago, I was given a task to deploy Laravel API to Lambda. And then I found the ways to deploy it using Serverless Framework and Bref.

What is Serverless Framework?

The Serverless Framework is an open-source framework that allows developers to build and deploy serverless applications and functions. It simplifies the process of managing serverless architectures by abstracting away the underlying infrastructure management. With the Serverless Framework, developers can focus more on writing code and less on managing servers or provisioning resources.

To install serverless, you should using npm:

npm install -g serverless

What is Bref?

To managing the function, Bref provides a command-line interface (CLI) tool for initializing, deploying, and managing serverless PHP applications. Developers can use the CLI to create new projects, deploy functions to AWS Lambda, and manage configuration settings.

You guys also, set the runtime environment for running PHP applications using Bref. This environment includes support for PHP 7.x, 8.x, extensions commonly used in PHP applications, and features like HTTP request handling, environment variables, and logging.

Install Bref using composer:

cd laravel-project
composer require bref/bref bref/laravel-bridge --update-with-dependencies

Lastly, to deploy our function or application we need to define everything, including the runtime, runtime version, stage, environment, cloud provider in a file called serverless.yml

Setup

Okay, I think that's enough explanation and installation. Now let's do some setup. :)

cd laravel-project

Create serverless.yml:

php artisan vendor:publish --tag=serverless-config

Now, you need

service: laravel

provider:
name: aws
region: ap-southeast-2
stage: dev
runtime: provided.al2
environment:
DB_HOST: wwww.ap-southeast-2.rds.amazonaws.com
DB_DATABASE: xxxx
DB_USERNAME: yyyy
DB_PASSWORD: zzzz
vpc:
securityGroupIds:
- sg-xyz
subnetIds:
- subnet-abcd

package:
# Files and directories to exclude from deployment
patterns:
- '!node_modules/**'
- '!resources/assets/**'
- '!storage/**'
- '!tests/**'
- '!docker/'
- '!.husky/'
- '!.github/**'

functions:
# This function runs the athena website/API
athena:
handler: public/index.php
runtime: php-82-fpm
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
events:
- httpApi: '*'

# This function lets us run artisan commands in Lambda
artisan:
handler: artisan
runtime: php-82-console
timeout: 720 # in seconds
# Uncomment to also run the scheduler every minute
#events:
# - schedule:
# rate: rate(1 minute)
# input: '"schedule:run"'

plugins:
# We need to include the Bref plugin
- ./vendor/bref/bref

A bit of explanation

service: laravel

provider:
name: aws
region: ap-southeast-2
stage: dev
runtime: provided.al2
environment:
DB_HOST: wwww.ap-southeast-2.rds.amazonaws.com
DB_DATABASE: xxxx
DB_USERNAME: yyyy
DB_PASSWORD: zzzz
vpc:
securityGroupIds:
- sg-xyz
subnetIds:
- subnet-abcd
  • service: This specifies the name of our service. In this case, it's named "laravel".
  • provider:
    • name: Specifies that the cloud provider. For example we using AWS.
    • region: Specifies the AWS region where our resources will be deployed. In this case, it's the Asia Pacific (Sydney) region.
    • stage: Specifies the deployment stage or environment. Here, it's set to "dev", indicating a development stage, Or prod indicating production.
    • runtime: Specifies the Lambda runtime. provided.al2 indicates that we're using a custom runtime based on Amazon Linux 2. This is a common choice for PHP-based applications. Then you will using other runtime likes; Node Js, Python, .NET etc.
    • environment: Specifies the environment variable that will be available to our Lambda function. In this case I wrote an environment for RDS Database. Anyway, later I will write about AWS CDK using Python for creating database clusters, etc.
    • vpc: This indicates that we're configuring the Virtual Private Cloud settings for our Lambda functions. This is useful for scenarios where your Lambda functions need to interact with resources that are only accessible within your VPC, such as databases hosted on Amazon RDS or services running on Amazon EC2 instances.
    • securityGroupIds: Specifies the security groups associated with our Lambda functions.
    • subnetIds: Specifies the subnets in which our Lambda functions will be deployed. Subnets are segments of our VPC where you can place resources. subnet-abcd is the ID of the subnet where our Lambda functions will be deployed.
package:
# Files and directories to exclude from deployment
patterns:
- '!node_modules/**'
- '!resources/assets/**'
- '!storage/**'
- '!tests/**'
- '!docker/'
- '!.husky/'
- '!.github/**'

functions:
# This function runs the athena website/API
athena:
handler: public/index.php
runtime: php-82-fpm
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
events:
- httpApi: '*'

# This function lets us run artisan commands in Lambda
artisan:
handler: artisan
runtime: php-82-console
timeout: 720 # in seconds
# Uncomment to also run the scheduler every minute
#events:
# - schedule:
# rate: rate(1 minute)
# input: '"schedule:run"'

plugins:
# We need to include the Bref plugin
- ./vendor/bref/bref

Package

  • patterns: Specifies the files and directories to exclude from the deployment package. These are typically directories that contain development or testing files that aren't needed in the production deployment.

Functions

  • functions: Defines a Lambda function named responsible for running the Athena website/API.
  • handler: Specifies the entry point for the function. In this case, it's public/index.php, which is typical for Laravel applications.
  • runtime: Specifies the runtime for the Lambda function. It's set to php-82-fpm, indicating PHP 8.2 running as FastCGI Process Manager (FPM).
  • timeout: Sets the timeout for the function execution in seconds.
  • events: Defines the event trigger for the function. In this case, it's an HTTP API event trigger.
  • artisan: Defines a Lambda function named "artisan" responsible for running artisan commands in Lambda.
  • handler: Specifies the entry point for the function. Here, it's artisan, indicating the Laravel artisan CLI.
  • runtime: Specifies the runtime for the Lambda function. It's set to php-82-console, indicating PHP 8.2 running in console mode.

Plugins

  • ./vendor/bref/bref: Specifies the Bref plugin, which is necessary for deploying PHP applications to AWS Lambda. This plugin provides the necessary runtime and integration with AWS services.

Okay lastly, we'll deploy the function by running serverless command:

serverless deploy

or

sls deploy
Deploying laravel to stage dev (ap-southeast-2)

✔ Service deployed to stack laravel-dev (102s)

endpoint: ANY - https://xxyyzz.execute-api.ap-southeast-2.amazonaws.com
functions:
athena: laravel-dev-athena (45 MB)
artisan: laravel-dev-artisan (45 MB)

Want a better experience than the AWS console? Try out https://dashboard.bref.sh

Migration using bref, usually we use artisan command, like php artisan migrate but if using bref just use:

serverless bref:cli --args="migrate"

NB: You guys can use bref to run other artisan commands.

Accessing API, in this case i use api/health-check:

curl https://xxyyzz.execute-api.ap-southeast-2.amazonaws.com/api/health-check

Response:

"Hello to public API."

That's all for now, I will write about Lambda or other stuff about AWS later. Hope you enjoy it.