Getting a Simple Symfony 5 App On Amazon AWS As An API Gateway/Lambda For Amazon Cognito

This may involve way too many specific technologies for anyone to be able to answer, but I thought I’d give it a shot. I’ve ready SO Many tutorials and feel like I’m SO close…there’s maybe just one thing I’m missing.

My goal here is multi-part, and as far as I know my issue is only really with one part at this point

  • Take a simple Symfony app (it happens to be using version 5) with a single controller, put it up on Amazon AWS as an API Gateway. I’ve accomplished this with the help of bref
    (https://bref.sh/) and requiring it in my Symfony project. I have a serverless.yml file for which I can use the serverless deploy command to upload it as an API Gateway to AWS. It even tests out in a browser, no problem.
  • Take that API Gateway and link it to an AWS Lambda function, to eventually be used as a Lambda function for an event to be triggered upon sign-in etc. using Amazon Cognito. I’ve achieved this using tutorials, I can see it linked to the API Gateway when I go into my Lambda function that was uploaded during step 1 using bref.
  • Take this Lambda and link it to the Cognito Lambda trigger for Pre sign-up. I’ve done this, it’s a very simple setting.

Now in the single file PHP examples for how to use bref with AWS, you get something as follows:


require __DIR__.'/vendor/autoload.php';

lambda(function ($event) {
    return $event;
});

I have uploaded this as a different lambda (nothing to do with Symfony here), set that to be the trigger on Cognito’s Pre-sign-up event, and it works fine. It does nothing granted, but it passes the information along correctly to where it does not cause any errors of any kind.

Now when I try this same thing with a Symfony app, I have IndexController.php in my src/Controller directory, that looks like this:

<?php

namespace AppController;

use PsrLogLoggerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentRoutingAnnotationRoute;
use AwsCloudWatchLogsCloudWatchLogsClient;
use MaxbantonCwhHandlerCloudWatch;
use MonologLogger;
use MonologFormatterJsonFormatter;

class IndexController extends AbstractController
{
    /**
     * @Route("/", name="index")
     */
    public function index(Request $request, LoggerInterface $logger)
    {
        $this->awsLogger($request);
        return new JsonResponse(json_encode($request->query->all()));
    }

    private function awsLogger(Request $request)
    {
        /**
         * This is only here for now because I couldn't get CloudWatch logging working any better way.
         */
        $sdkParams = [
            'region' => 'us-east-2',
            'version' => 'latest',
            'credentials' => [
                'key' => 'AKIAIGFNOM3BKSE6HQ6A',
                'secret' => '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',
            ]
        ];

        // Instantiate AWS SDK CloudWatch Logs Client
        $client = new CloudWatchLogsClient($sdkParams);

        // Log group name, will be created if none
        $groupName = 'lambda_symfony_test';

        // Log stream name, will be created if none
        $streamName = 'dev';

        // Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.
        $retentionDays = 30;

        // Instantiate handler (tags are optional)
        $handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, ['tag' => 'lambda']);

        // Optionally set the JsonFormatter to be able to access your log messages in a structured way
        $handler->setFormatter(new JsonFormatter());

        // Create a log channel
        $log = new Logger('channel');

        // Set handler
        $log->pushHandler($handler);

        // Add records to the log
        $log->debug(print_r($request->query->all(), true));
    }
}

I completely understand this will cause an error as a lambda, because the JsonResponse is not what Cognito is expecting to see back. However I was at least hoping that I’d hit the call to the logger so I could see what my request object looked like, and I could see what I was working with in terms of what Cognito is passing into this Lambda. This will help me eventually figure out what I need to return. And as far as I know I can’t just use the “lambda” wrapper around a controller method like what was done in the simple example I mentioned I had working. However it’s not even getting this far, instead the following is what appears in my logs on CloudWatch:

21:34:58
Fatal error: Uncaught Exception: The lambda was not invoked via HTTP through API Gateway: this is not supported by this runtime in /var/task/vendor/bref/bref/src/Runtime/PhpFpm.php:120

So my question is what am I missing here? This API works completely fine through a browser when I just pass it something as a GET request. What am I missing in my configurations? Here is my serverless.yml file for the Symfony app:

service: lambda-test-symfony

provider:
  name: aws
  region: us-east-2
  runtime: provided
  environment:
    # Symfony environment variables
    APP_ENV: prod

plugins:
  - ./vendor/bref/bref

package:
  exclude:
    - node_modules/**
    - tests/**

functions:
  lambdatest:
    handler: public/index.php
    layers:
      - ${bref:layer.php-72-fpm}
    events:
      -   http: 'ANY /'
      -   http: 'ANY /{proxy+}'

Here are also some screenshots from my Lambda configurations on AWS:

https://i.stack.imgur.com/TDMZj.png

https://i.stack.imgur.com/ciehT.png

And here are some from the setup of the API Gateway:

https://i.stack.imgur.com/RL7D9.png

https://i.stack.imgur.com/LPcsh.png

https://i.stack.imgur.com/RVNwN.png

https://i.stack.imgur.com/4bs0u.png

I’m still fairly new to the whole AWS/serverless thing, so I could be missing something really obvious here. I’m not 100% sure whether the issue is with my code or my configuration though. Any help would be appreciated!

Source: Symfony Questions

Was this helpful?

0 / 0

Leave a Reply 0

Your email address will not be published. Required fields are marked *