AWS Lambda Containers - Shell

· 273 words · 2 minute read

I am trying to run a shell script in AWS Lambda. I packaged it in a Docker image based on Alpine. The logs show that it runs fine, but the Lambda shows an error, even though my script exited with 0.

This blog post was my key to understanding what went wrong.

The docs page I had found mentioned the Lambda Runtime API, and how the container needs to implement that API. But that didn’t make enough sense to me.

The gist of it was that my container was running a script to do one thing and exit. However, the script needs to let Lambda determine when to stop, and it needs to continue to execute the business logic while there’s more executions in the Lambda queue.

The relevant piece of the blog post was this part of the script:

...
while true
do
  # Create a temporary file
  HEADERS="$(mktemp)"
  # Get an event. The HTTP request will block until one is received
  EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
  # Extract request ID by scraping response headers received above
  REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

  ############################
  # Run my arbitrary program #
  ############################

  /businesscode.sh

  ############################

  # Send the response
  curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d '{"statusCode": 200}'

done

To liken this to a Go lambda in a zip file, anything occuring before the while true is like the func init() {} in Go. It’s the startup logic for cold starts. Anything in the loop is what is run when the Lambda is called.

This loop watches the queue, and notifies the API the result of each call.