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:
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:
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:
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);