Documentation
Console runtime

Console runtime

Bref's "Console" runtime lets us run CLI scripts on AWS Lambda.

This can be used to run PHP scripts, like cron tasks, the Symfony Console (opens in a new tab), Laravel Artisan (opens in a new tab), and more.

How it works

When the function is invoked, the Console runtime will execute the PHP script defined as the handler in a sub-process.

The result of the execution (exit code and output) will be returned as the result of the AWS Lambda invocation. All the CLI output is also logged (learn more about logs).

Console functions can be invoked:

  • via a cron schedule
  • via the serverless bref:cli command
  • manually by invoking the function via the AWS API

Usage

The Lambda function used for running console applications must use the php-xx-console runtime. Here is an example:

serverless.yml
service: app
provider:
    name: aws
plugins:
    - ./vendor/bref/bref
functions:
    hello:
        handler: the-php-script-to-run.php
        runtime: php-81-console

Behind the scenes, the php-xx-console runtime will deploy a Lambda function configured to use Bref's php-81 AWS Lambda layer plus Bref's console layer (read more about these in the runtimes documentation).

Running commands

When invoked, the "Console" runtime executes the handler script in a sub-process. For example, if the following handler was defined:

serverless.yml
functions:
    hello:
        handler: the-php-script-to-run.php
        runtime: php-81-console

Then the following command would run in Lambda every time the function is invoked:

php the-php-script-to-run.php

The Lambda function can be invoked with a payload. It must be a JSON string, for example "arg1 arg2 --option1=foo". Note that it is a string encoded in JSON, that is why it is in quotes, json_decode($payload) would return the string itself.

In our example, the following command would run in Lambda when invoked with such a payload:

php the-php-script-to-run.php arg1 arg2 --option1=foo

Cron

Read the dedicated documentation for running cron tasks on AWS Lambda.

CLI invocation

To manually run a console command on AWS Lambda, run serverless bref:cli on your computer:

serverless bref:cli --args="<command to run in lambda>"

The bref:cli command will automatically detect which function (in serverless.yml) uses the console runtime and will run the command on that function.

Pass your command arguments and options in the --args flag (shortcut: -a). Remember to escape quotes properly. Some examples:

# Runs the CLI application without arguments and displays the help
$ serverless bref:cli
# ...
 
$ serverless bref:cli --args="doctrine:migrations:migrate"
Your database will be migrated.
To execute the SQL queries run the command with the `--force` option.
 
$ serverless bref:cli -a "doctrine:migrations:migrate --force"
Your database has been migrated.
 
$ serverless bref:cli --stage=prod -a "db:dump --file='/tmp/dump.sql' --verbose"
# ...
 
# You can use environment variables to configure AWS credentials (e.g. in CI)
$ AWS_ACCESS_KEY_ID=foo AWS_SECRET_ACCESS_KEY=bar serverless bref:cli
# ...

The bref:cli command can be used to run CLI commands in Lambda from your machine, but can also be used in CI/CD to run DB migrations for example.

Interactive terminal

As an alternative to the CLI, the Bref Dashboard (opens in a new tab) provides a convenient way to run commands via a terminal:

Bref Dashboard terminal for Laravel (opens in a new tab)

Functions using the "console" runtime are automatically detected, and colors are enabled by default for Laravel Artisan and Symfony Console.

Without Serverless Framework

If you do not use serverless.yml but something else, like SAM/AWS CDK/Terraform, you can invoke your console function via the AWS CLI. For example:

aws lambda invoke \
    --function-name <console function name> \
    --region <region> \
    --cli-binary-format raw-in-base64-out \
    --payload '"<command arguments and options>"' \
    <file to store the output>.json
 
# For example:
aws lambda invoke \
    --function-name myapp-dev-myfunction \
    --region us-east-1 \
    --cli-binary-format raw-in-base64-out \
    --payload '"doctrine:migrations:migrate --force"' \
    response.json
 
# To extract the command output from the response.json file using jq
# https://stedolan.github.io/jq/
aws lambda invoke \
    --function-name myapp-dev-myfunction \
    --region us-east-1 \
    --cli-binary-format raw-in-base64-out \
    --payload '"doctrine:migrations:migrate --force"' \
    response.json && jq -r .output response.json

Note: The --payload needs to contain a JSON string, that is why it is quoted twice: '"..."'. This is intentional.

Lambda context

Lambda provides information about the invocation, function, and execution environment via the lambda context.

This context is usually available as a parameter (alongside the event), within the defined handler. However, within the console runtime we do not have direct access to this parameter. To work around that, Bref puts the Lambda context in the $_SERVER['LAMBDA_INVOCATION_CONTEXT'] variable as a JSON-encoded string.

$lambdaContext = json_decode($_SERVER['LAMBDA_INVOCATION_CONTEXT'], true);