Turn shell scripts into serverless functions in minutes
Custom AWS Lambda runtime for executing Bash functions as serverless applications. Deploy shell scripts directly to AWS Lambda with full access to common CLI tools like jq
, curl
, and AWS CLI.
- 🚀 Zero-config deployment - Just write Bash, deploy to Lambda
- 📦 Three optimized variants - Choose the right tools for your use case
- 🔧 Built-in utilities -
jq
,curl
,http-cli
, and optional AWS CLI - 🏗️ Multi-platform support - ARM64 and x86_64 architectures
- 🧪 Local testing - Full Lambda Runtime Interface Emulator support
- 📋 Production ready - Based on official AWS Lambda base images
- Create your handler function:
# handler.sh
main () {
local event="$1"
echo '{"message": "Hello from Bash Lambda!", "input": '"$event"'}'
}
- Create your Dockerfile:
FROM ghcr.io/ql4b/lambda-shell-runtime:tiny
COPY handler.sh .
- Deploy to AWS Lambda using container images
Choose the variant that matches your requirements:
Variant | Size | Tools Included | Best For |
---|---|---|---|
tiny |
~132MB | jq , curl , http-cli |
HTTP APIs, JSON processing |
micro |
~221MB | tiny + awscurl |
AWS API calls without full CLI |
full |
~417MB | tiny + AWS CLI |
Complete AWS operations |
# From GitHub Container Registry
ghcr.io/ql4b/lambda-shell-runtime:tiny
ghcr.io/ql4b/lambda-shell-runtime:micro
ghcr.io/ql4b/lambda-shell-runtime:full
# From AWS Public ECR
public.ecr.aws/j5r7n1v7/lambda-shell-runtime:tiny
public.ecr.aws/j5r7n1v7/lambda-shell-runtime:micro
public.ecr.aws/j5r7n1v7/lambda-shell-runtime:full
# handler.sh
api_handler() {
local event="$1"
local name=$(echo "$event" | jq -r '.queryStringParameters.name // "World"')
echo '{
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": '{"greeting": "Hello, '"$name"'!"}'
}'
}
# handler.sh (using micro variant)
list_buckets() {
local buckets=$(awscurl --service s3 https://s3.amazonaws.com/ | jq '.ListAllMyBucketsResult.Buckets')
echo '{"buckets": '"$buckets"'}'
}
# handler.sh (using full variant)
process_s3_file() {
local event="$1"
local bucket=$(echo "$event" | jq -r '.Records[0].s3.bucket.name')
local key=$(echo "$event" | jq -r '.Records[0].s3.object.key')
aws s3 cp "s3://$bucket/$key" /tmp/input.json
local result=$(jq '.data | length' /tmp/input.json)
echo '{"processed": true, "count": '"$result"'}'
}
Your handler functions receive the Lambda event as the first argument:
# handler.sh
my_function() {
local event="$1" # Lambda event JSON
local context="$2" # Lambda context (optional)
# Process the event
local result=$(echo "$event" | jq '.key')
# Return JSON response
echo '{"result": '"$result"'}'
}
Handler naming: Set your Lambda handler to handler.my_function
(filename.function_name)
# Build and push your image
docker build -t my-lambda .
docker tag my-lambda:latest 123456789012.dkr.ecr.region.amazonaws.com/my-lambda:latest
docker push 123456789012.dkr.ecr.region.amazonaws.com/my-lambda:latest
# Create/update Lambda function
aws lambda create-function \
--function-name my-bash-function \
--code ImageUri=123456789012.dkr.ecr.region.amazonaws.com/my-lambda:latest \
--role arn:aws:iam::123456789012:role/lambda-execution-role \
--package-type Image \
--architectures arm64 \
--timeout 30
resource "aws_lambda_function" "bash_function" {
function_name = "my-bash-function"
role = aws_iam_role.lambda_role.arn
package_type = "Image"
image_uri = "123456789012.dkr.ecr.region.amazonaws.com/my-lambda:latest"
timeout = 30
}
https://github.com/aws/aws-lambda-runtime-interface-emulator/
The emulator is already available on the image, you just need to override the entrypoint
to run test your lambda locally
# Run your function locally
docker run --rm -p 9000:8080 \
--env _HANDLER="handler.hello" \
--entrypoint /aws-lambda/aws-lambda-rie \
my-lambda:latest /var/runtime/bootstrap
# Test your function
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-d '{"name": "World"}'
# Clone the repository
git clone https://github.com/ql4b/lambda-shell-runtime.git
cd lambda-shell-runtime
# Build specific variant
./build --platform linux/arm64 --tag my-runtime --load tiny
# Build and push to registry
./build --platform linux/arm64 --tag my-registry/lambda-shell --push micro
--platform
: Target platform (default:linux/arm64
)--tag
: Image tag prefix--load
: Load image locally (default)--push
: Push to registry--secret
: Inject build secrets (e.g., GitHub token)
- Cold start: ~100-300ms depending on variant
- Memory usage: 64MB minimum recommended
- Timeout: Standard Lambda limits apply (15 minutes max)
- Package size: Varies by variant (132MB-417MB)
- Concurrent executions: Standard Lambda limits
Runtime | Size | Notes |
---|---|---|
AWS Python 3.12 | 534MB | Official Python runtime |
lambda-shell-runtime:full | 417MB | 22% smaller with complete AWS CLI |
AWS Node.js 20 | 410MB | Official Node.js runtime |
lambda-shell-runtime:micro | 221MB | 46% smaller with AWS API access |
lambda-shell-runtime:tiny | 132MB | 75% smaller with essential tools |
AWS provided | 128MB | Bare custom runtime base |
The shell runtime is highly competitive with official runtimes while providing the simplicity and power of Bash scripting.
Function not found:
# Ensure your function is defined and you override
# the CMD hander.my_function
Permission errors:
# Ensure Lambda execution role has required permissions
# For AWS API calls, add appropriate IAM policies
Timeout issues:
# Increase Lambda timeout setting
# Optimize shell script performance
The runtime includes http-cli for simplified HTTP operations. To update to a newer version:
-
Update version in all configuration files:
.github/workflows/build-and-release.yml
(2 locations).github/workflows/build-base.yml
.github/workflows/build-installers.yml
Dockerfile
(ARG HTTP_CLI_VERSION)build-enhanced
script (default value)
-
Trigger a new build:
# Push changes to trigger GitHub Actions git add . git commit -m "Update http-cli to vX.X.X" git push origin develop
-
Or build locally:
HTTP_CLI_VERSION=v1.2.0 ./build-enhanced --load tiny
We welcome contributions! Please see our contributing guidelines for details.
git clone https://github.com/ql4b/lambda-shell-runtime.git
cd lambda-shell-runtime
./build --load tiny # Build and test locally
lambda-shell-runtime/
├── runtime/ # Custom bootstrap and runtime logic
├── task/ # Helper functions and example handlers
├── test/ # Test functions and runners
├── scripts/ # Build and publishing utilities
├── Dockerfile # Multi-stage build definitions
└── build # Build script for all variants
MIT License - see LICENSE file for details.