If you want to run bash scripts on AWS Lambda, create a Lambda function with a custom runtime. Here are the steps to follow:
Create a Lambda function with the "Author from scratch" option and "Use default bootstrap on Amazon Linux 1" as runtime.
![Lambda function with the "Author from scratch" option and "Use default bootstrap on Amazon Linux 1" as runtime](https://cdn.awsjunkie.com/content/2023/09/aws-lambda-custom-runtime.jpg)
Once the function is created, you will see the bootstrap.sh
file and the hello.js
handler function in the code editor.
![](https://cdn.awsjunkie.com/content/2023/09/rename-aws-lambda-bootstrap.sh.jpg)
As mentioned in the README
file, the executable runtime file name of Bash should be bootstrap
. So, rename bootstrap.sh
to bootstrap
. Otherwise, you'll get the following Runtime.InvalidEntrypoint
error.
{
"errorType": "Runtime.InvalidEntrypoint",
"errorMessage": "RequestId: f611525c-7589-440d-92e0-f9d066486df6 Error: Couldn't find valid bootstrap(s): [/var/task/bootstrap /opt/bootstrap]"
}
Generated bootstrap file:
#!/bin/sh
set -euo pipefail
# Handler format: <script_name>.<bash_function_name>
#
# The script file <script_name>.sh must be located at the root of your
# function's deployment package, alongside this bootstrap executable.
source $(dirname "$0")/"$(echo $_HANDLER | cut -d. -f1).sh"
while true
do
# Request the next event from the Lambda runtime
HEADERS="$(mktemp)"
EVENT_DATA=$(curl -v -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
INVOCATION_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the handler function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# Send the response to Lambda runtime
curl -v -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$INVOCATION_ID/response" -d "$RESPONSE"
done
handler ()
) from the script (e.g. hello.js
) and finally post the response to Lambda runtime using Runtime API.Generated sample handler function (hello.js)
function handler () {
EVENT_DATA=$1
RESPONSE="{\"statusCode\": 200, \"body\": \"Hello from Lambda!!\"}"
echo $RESPONSE
}
Add your bash scripts in the handler function. For example, I added just one command to retrieve the date and echo the same in the response.
function handler () {
EVENT_DATA=$1
COMMAND=`date`
RESPONSE="{\"statusCode\": 200, \"body\": \"Date: $COMMAND\"}"
echo $RESPONSE
}
Now, deploy the change and test the lambda function.
Sample Execution Results:
Response
{
"statusCode": 200,
"body": "Date: Mon Sep 25 17:11:56 UTC 2023"
}
Function Logs
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9001 (#0)
> GET /2018-06-01/runtime/invocation/next HTTP/1.1
> Host: 127.0.0.1:9001
> User-Agent: curl/7.61.1
> Accept: */*
>
START RequestId: 5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb Version: $LATEST
< HTTP/1.1 200 OK
< Content-Type: application/json
< Lambda-Runtime-Aws-Request-Id: 5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb
< Lambda-Runtime-Deadline-Ms: 1695661919762
< Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:us-west-2:551672154962:function:BashOnLambda
< Lambda-Runtime-Trace-Id: Root=1-6511bf5c-3cd07ebd5ffeef84556961d0;Parent=5f0d38345ecb74e9;Sampled=0;Lineage=03f3abf3:0
< Date: Mon, 25 Sep 2023 17:11:56 GMT
< Content-Length: 49
<
{ [49 bytes data]
* Connection #0 to host 127.0.0.1 left intact
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9001 (#0)
> POST /2018-06-01/runtime/invocation/5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb/response HTTP/1.1
> Host: 127.0.0.1:9001
> User-Agent: curl/7.61.1
> Accept: */*
> Content-Length: 65
> Content-Type: application/x-www-form-urlencoded
>
} [65 bytes data]
* upload completely sent off: 65 out of 65 bytes
< HTTP/1.1 202 Accepted
< Content-Type: application/json
< Date: Mon, 25 Sep 2023 17:11:56 GMT
< Content-Length: 16
<
{ [16 bytes data]
* Connection #0 to host 127.0.0.1 left intact
{"status":"OK"}
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9001 (#0)
> GET /2018-06-01/runtime/invocation/next HTTP/1.1
> Host: 127.0.0.1:9001
> User-Agent: curl/7.61.1
> Accept: */*
>
END RequestId: 5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb
REPORT RequestId: 5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb Duration: 263.19 ms Billed Duration: 338 ms Memory Size: 128 MB Max Memory Used: 28 MB Init Duration: 73.87 ms
Request ID
5d883ecd-fa32-4c74-a5aa-de96d6f2d1eb