Setup Queue with Serverless Laravel using bref

Chandresh
CS Code
Published in
4 min readAug 10, 2020
Serverless Laravel + SQS

This tutorial assumes you already have a Serverless Laravel setup in place, if not then you can follow this tutorial Deploy Serverless Laravel

Let’s see how we can setup AWS SQS with our Serverless Laravel Application.

If you would like to see me doing it then you can watch it here as well.

Let’s Start!

First thing we need to do is pull in this package in your laravel application using composer.

composer require bref/laravel-bridge

If you followed the previous tutorial then you should already be having serverless.yml file in your Laravel application directory. Make sure it looks something like this:

service: laravel-starter-serverless

provider:
name: aws
region: ap-south-1
runtime: provided

plugins:
- ./vendor/bref/bref

package:
exclude:
- node_modules/**
- public/storage
- resources/assets/**
- storage/**
- tests/**

functions:
website:
handler: public/index.php
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
layers:
- ${bref:layer.php-73-fpm}
events:
- http: 'ANY /'
- http: 'ANY /{proxy+}'
artisan:
handler: artisan
timeout: 120 # in seconds
layers:
- ${bref:layer.php-73} # PHP
- ${bref:layer.console} # The "console" layer
worker:
handler: worker.php
layers:
- ${bref:layer.php-73}
events:
# Declares that our worker is triggered by jobs in SQS
- sqs:
arn: !GetAtt AlertQueue.Arn
# If you create the queue manually, the line above could be:
# arn: 'arn:aws:sqs:us-east-1:1234567890:my_sqs_queue'
# Only 1 item at a time to simplify error handling
batchSize: 1

resources:
Resources:
# The SQS queue
AlertQueue:
Type: AWS::SQS::Queue
Properties:
RedrivePolicy:
maxReceiveCount: 3 # jobs will be retried up to 3 times
# Failed jobs (after the retries) will be moved to the other queue for storage
deadLetterTargetArn: !GetAtt DeadLetterQueue.Arn

# Failed jobs will go into that SQS queue to be stored, until a developer looks at these errors
DeadLetterQueue:
Type: AWS::SQS::Queue
Properties:
MessageRetentionPeriod: 1209600 # maximum retention: 14 days

Here we are creating a new lambda function which will act as a worker for our queue and will be invoked by a new job event from SQS.

We are also creating two queues in SQS, first one will act as a queue for processing jobs and second will be used for failed jobs.

Now, Create a new file worker.php inside application directory which will handle SQS event in AWS lambda.

<?php declare(strict_types=1);

use Bref\LaravelBridge\Queue\LaravelSqsHandler;
use Illuminate\Foundation\Application;

require __DIR__ . '/vendor/autoload.php';
/** @var Application $app */
$app = require __DIR__ . '/bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();

return $app->makeWith(LaravelSqsHandler::class, [
'connection' => 'sqs', // this is the Laravel Queue connection
'queue' => getenv('SQS_QUEUE'),
]);

Now we need to make a small change in config/queue.php file to add AWS session token. This may not be an issue in the latest version of laravel.

'sqs' => [
...
'token' => env('AWS_SESSION_TOKEN'),
],

Set two environment variables in .env file.

QUEUE_CONNECTION=sqs 
AWS_DEFAULT_REGION=ap-south-1

Now before we deploy our code we need to provide permission to AWS IAM user which you created for deploying Serverless Laravel.

So login into your AWS account and go to IAM.

Click on users link and then Select your user.

Select the policy and Click on Edit policy

Click on add additional permission.

Choose SQS in service.

I’m giving it full access to SQS but you can selectively give it READ and WRITE access.

Select all resource in resources.

Click on review policy.

If you get a popup asking for deleting older version of policy then click on delete version and save.

and That’s it.

Type in your terminal

serverless deploy

and this will take care of setting up your queue and lambda function.

If you get internal server error then try running:

php artisan config:cache 
#to build all cache files

And then

php artisan config:clear 
#to remove config cache file

Try again and this time you should see the welcome screen. Try sending a job to queue from your laravel application and you will see that that queue jobs are being processed instantly.

One thing to note here is this /dev/ prefix before every route.

This is because of AWS API Gateway which works in stages. If you want to remove this then you will have to setup a custom domain for your application on AWS or you will need to take this into account before using any route.

If you have followed till now you should be having a working queue with your serverless laravel application.

Hope you find this useful!

Originally published at https://dev.to.

--

--