Search code examples
symfonyaws-lambdaaws-cdksymfony-consolebref

Unable to invoke symfony console command via "aws lambda invoke"


I'm trying to run symfony "bin/console" command like described in documentation.

Running command

aws lambda invoke \
    --function-name PhpCliLambdaName \
    --region us-east-1 \
    --cli-binary-format raw-in-base64-out \
    --payload '"d:s:u --dump-sql"' \
    response.json

returns

{
    "StatusCode": 200,
    "FunctionError": "Unhandled",
    "ExecutedVersion": "$LATEST"
}

and logs this

{
    "errorType": "TypeError",
    "errorMessage": "Bref\\Runtime\\FileHandlerLocator::{closure}(): Argument #1 ($context) must be of type array, string given, called in /var/task/vendor/bref/bref/src/Runtime/Invoker.php on line 29",
    "stack": [
        "#0 /var/task/vendor/bref/bref/src/Runtime/Invoker.php(29): Bref\\Runtime\\FileHandlerLocator->{closure}('d:s:u --dump-sq...', Object(Bref\\Context\\Context))",
        "#1 /var/task/vendor/bref/bref/src/Runtime/LambdaRuntime.php(89): Bref\\Runtime\\Invoker->invoke(Object(Closure), 'd:s:u --dump-sq...', Object(Bref\\Context\\Context))",
        "#2 /var/task/vendor/bref/bref/src/FunctionRuntime/Main.php(37): Bref\\Runtime\\LambdaRuntime->processNextEvent(Object(Closure))",
        "#3 /opt/bref/bootstrap.php(17): Bref\\FunctionRuntime\\Main::run()",
        "#4 {main}"
    ]
}

CDK

package.json

"@bref.sh/constructs": "^1.0.0",

brefStack.ts

this.fpm = new PhpFpmFunction(this, 'PhpFpm', {
  code,
  handler: 'public/index.php',
  timeout: Duration.seconds(20),
  ...lambdaProps,
});

this.cli = new ConsoleFunction(this, 'PhpCli', {
  code,
  handler: 'bin/console',
  timeout: Duration.seconds(120),
  ...lambdaProps, // contains architecture, environment, role, securityGroups, vpc and vpcSubnets
});

Symfony - code

composer.json (symfony 6.3)

"bref/bref": "^2.0",
"bref/symfony-bridge": "0.2.1",
"symfony/runtime": "6.3.*"

bin/console

#!/usr/bin/env php
<?php

use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;

if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
    throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
}

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);

    return new Application($kernel);
};

I've already tried to send payload as json object with APP_ENV, APP_DEBUG, but in this case I'm not able to figure out how should I provide command. Changing $context to string and creating Kernel with $_SERVER doesn't help either.

I was able to execute command with modified bin/console and payload {"command":"d:s:u", "--force": true}, but this time lambda could not return response and timed out (but schema did update).

#!/usr/bin/env php
<?php

use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;

if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
    throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
}

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);

    $application = new Application($kernel);

    $input = new Symfony\Component\Console\Input\ArrayInput($context);
    $output = new Symfony\Component\Console\Output\BufferedOutput();

    $application->run($input, $output);

    return new Symfony\Component\HttpFoundation\Response($output->fetch());
};

Looking at ConsoleRuntime I'm clearly missing "event". But how can I provide it?


Solution

  • As of @bref.sh/constructs version 1.0.1 this issue should be resolved.

    The problem was in @aws-cdk/aws-lambda:recognizeVersionProps flag set to true inside of cdk.json. This flag might change order in which lambda layers are created.

    If you encounter similar issue try to check if layers of your lambda are in correct order as they can override each other.