DEV Community

Cover image for Deploy a Symfony application with AWS Lambda, a quick guide
AlessandroMinoccheri
AlessandroMinoccheri

Posted on • Originally published at Medium

Deploy a Symfony application with AWS Lambda, a quick guide

When I first heard the word Serverless I thought I would soon lose my job. No more servers, no more code, no more work to do, it's simple, isn't it?

What happened instead is that, like all other back-end developers, I have a new tool to do my job better.

In this article, I will briefly explain what Serverless is and what advantages it brings us. We will see the Bref library and how to deploy a Symfony application on AWS Lambda.

In the next article I will go into the details of the deployment, analyzing the various components involved and proposing solutions and use cases for this architecture.

Let's begin!

What does it mean really serverless?

Serverless is a word that very often may misguide one into thinking that there is no server where the application is running.

Serverless just means that developers don't have to maintain the infrastructure anymore because AWS will take care of it: developers can focus only on the code.

AWS provides a serverless service called Lambda where you can run code without provisioning or managing servers. Lambda is based on two main concepts: functions and events. A function is a piece of code (which can be written using various languages) that performs some sort of operation. An event is something that happened in your infrastructure, for instance:

  • A file is uploaded on an S3 bucket

  • A record is inserted in an Amazon DynamoDB table

When an event happens it will trigger the Lambda function and our code will run.

A big advantage of AWS Lambda service is a “pay-per-use” model: you are charged only for the actual compute time used — there is no charge when your code is not running. Let's compare it to a “traditional” EC2 scenario. In the graph below, you can see costs (green areas) are constant during the time: you pay the same amount of money, regardless of the actual use of your servers (blue area).

In a serverless scenario, costs are always tied to the actual use of your infrastructure.

Lambda is a very cheap service: 0,0000002 USD per request (a function run) with the first million requests per month free. This will increase if you need more memory or some other configurations.

When Lambda was released it supported very few languages and PHP wasn't one of them. In December 2018 AWS announced:

“Native PHP support on Lambda wasn't one of those features, but the new AWS Lambda runtime API and layers capabilities give us the ability to build a clean, supportable implementation of PHP on Lambda of our own.”

This means that you can import PHP binaries file into Lambda layer, thus being able to run any PHP code, even your Symfony Application.

PHP binaries need to be created following certain rules. Creating and maintaining those files is a very expensive and time-consuming activity but, lucky for us, Matthieu Napoli has created an open-source library called Bref that helps developers to deploy PHP applications on Lambda.

It provides:

  • PHP runtimes for AWS Lambda

  • A library to interface PHP code with Lambda API

  • Rich documentation

  • Deployment tools

Image from https://blog.theodo.com/2019/05/serverless-symfony-on-aws-lambda-with-bref/

Requirements

To deploy a Symfony Application into a Lambda with Bref you need:

  • AWS account with Access Key ID, Secret Access Key

  • Install and configure the serverless framework

  • Install and initialize Bref library

The first step is to configure AWS with your command line interface with this command

aws configure
Enter fullscreen mode Exit fullscreen mode

The terminal will ask you to enter the Access Key ID, the Secret Access Key, the default region name and default output format.

Now you need to install the serverless framework, a tool to develop, deploy, test, secure, and monitor your Serverless applications

npm install -g serverless
Enter fullscreen mode Exit fullscreen mode

To use this tool you need to associate your credentials with it by the following command:

serverless config credentials — provider aws — key <key> — secret <secret>
Enter fullscreen mode Exit fullscreen mode

Now your terminal is configured so we can start to work into our Symfony application.

Bref

After you have created and configured your Symfony Application you can install Bref

To install it you need to launch into your command line interface:

composer require bref/bref
Enter fullscreen mode Exit fullscreen mode

Now you need to initialize the project by running

vendor/bin/bref init
Enter fullscreen mode Exit fullscreen mode

When you initialize bref, it creates automatically two files into the project root:

  • index.php that contains the function code

  • serverless.yml that contains the configuration for deploying on AWS

Example of standard configuration:

    service: symfony-bref
        provider:
            name: aws
            region: eu-central-1
            runtime: provided
            environment:
                APP_ENV: prod
        plugins:
            - ./vendor/bref/bref
        functions:
            api:
            handler: public/index.php
            description: ''
            timeout: 30 # in seconds (API Gateway has a timeout of 30 seconds)
            layers:
            - ${bref:layer.php-73-fpm}
            events:
            - http: 'ANY /'
            - http: 'ANY /{proxy+}'
Enter fullscreen mode Exit fullscreen mode

Usually, you have to add the environment with APP_ENV and change the region name.

Configure serverless to deploy your Symfony application

Before doing it, it's important to understand why the serverless framework can help us.

Some months ago bref make the deploy with AWS SAM an open-source framework that you can use to build serverless applications on AWS, it's a tool for CloudFormation with a not simple configuration.

AWS SAM has:

  • Template specification

  • Command-line interface

This is a standard SAM configuration:

    AWSTemplateFormatVersion: '2010–09–09'
    Transform: AWS::Serverless-2016–10–31
    Description: 'Symfony test'
    Resources:
        MyFunction:
        Type: AWS::Serverless::Function
        Properties:
        FunctionName: 'symfony-test'
        Description: ''
        CodeUri: .
        Handler: public/index.php
        Timeout: 30 # in seconds (API Gateway has a timeout of 30 seconds)
        MemorySize: 1024 # The memory size is related to the pricing and CPU power
        Runtime1sw: provided
        Layers:
            - 'arn:aws:lambda:eu-central-1:209497400698:layer:php-73-fpm:7'
        Events:
            # The function will match all HTTP URLs
            HttpRoot:
            Type: Api
            Properties:
            Path: /
            Method: ANY
            HttpSubPaths:
            Type: Api
            Properties:
            Path: /{proxy+}
            Method: ANY
        Environment:
            Variables:
            MY_CUSTOM_ENV_VARIABLES: 'this is my custom env variables'
            AWS_ENV_VARIABLES: '{{resolve:ssm:/env-aws-variable:1}}'
    # Outputs show up in the CloudFormation dashboard
        Outputs:
            DemoHttpApi:
            Description: 'URL of our function in the *Prod* environment'
            Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/'
Enter fullscreen mode Exit fullscreen mode

The configuration is more complex and longer than serverless framework configuration.

In serverless framework you can add SAM configuration for complex configuration and another advantage of serverless framework is the multi-provider: you can use it for AWS or Azure or other providers without changing the configuration. AWS SAM is only for AWS.

For these reasons, Bref community decided to switch from AWS SAM to serverless framework.

To start your deploy you need to install Composer dependencies optimized for production launching this command into your CLI:

composer install --optimize-autoloader --no-dev
Enter fullscreen mode Exit fullscreen mode

Now launching this command you will deploy your application:

serverless deploy
Enter fullscreen mode Exit fullscreen mode

Now some subroutines start and in the end, you can see a link, if you click on it you can see your application works!

What really happened?

When you deploy into a Lambda service you will do it through a CloudFormation stack.

A stack is simply a group of service that composes an application, for example:

  • Databases

  • S3 Buckets

The serverless framework translates configuration from serverless.yaml file and creates an AWS CloudFormation template from it.

Based on that template, a stack is created (if needed), with no resources except for an S3 Bucket used to store your code as a zip file.

Lambda will get the new code, unzip it and replace the older code.

Serverless framework optimizes these operations by comparing hashes of the files and performing a new deploy only if needed.

That's it, simple as promised, a Symfony application deployed on Lambda.
In the next article, I'll tackle some issues like Symfony tweaks, use of environment variable and trigger upon events.

Top comments (0)