mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
added aws lambda adapter + improvements to handle concurrency
This commit is contained in:
53
examples/aws-lambda/clean.sh
Executable file
53
examples/aws-lambda/clean.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set variables
|
||||
FUNCTION_NAME="bknd-lambda"
|
||||
ROLE_NAME="bknd-lambda-execution-role"
|
||||
|
||||
echo "Starting cleanup of AWS resources..."
|
||||
|
||||
# Delete Function URL if it exists
|
||||
echo "Checking if Function URL exists for '$FUNCTION_NAME'..."
|
||||
FUNCTION_URL=$(aws lambda get-function-url-config --function-name $FUNCTION_NAME --query "FunctionUrl" --output text 2>/dev/null)
|
||||
|
||||
if [ -n "$FUNCTION_URL" ]; then
|
||||
echo "Deleting Function URL for '$FUNCTION_NAME'..."
|
||||
aws lambda delete-function-url-config --function-name $FUNCTION_NAME
|
||||
echo "Function URL deleted."
|
||||
else
|
||||
echo "No Function URL found for '$FUNCTION_NAME'."
|
||||
fi
|
||||
|
||||
# Delete Lambda function if it exists
|
||||
echo "Checking if Lambda function '$FUNCTION_NAME' exists..."
|
||||
LAMBDA_EXISTS=$(aws lambda get-function --function-name $FUNCTION_NAME --query "Configuration.FunctionArn" --output text 2>/dev/null)
|
||||
|
||||
if [ -n "$LAMBDA_EXISTS" ]; then
|
||||
echo "Deleting Lambda function '$FUNCTION_NAME'..."
|
||||
aws lambda delete-function --function-name $FUNCTION_NAME
|
||||
echo "Lambda function deleted."
|
||||
else
|
||||
echo "Lambda function '$FUNCTION_NAME' does not exist."
|
||||
fi
|
||||
|
||||
# Delete IAM role and attached policies if role exists
|
||||
echo "Checking if IAM role '$ROLE_NAME' exists..."
|
||||
ROLE_EXISTS=$(aws iam get-role --role-name $ROLE_NAME --query "Role.Arn" --output text 2>/dev/null)
|
||||
|
||||
if [ -n "$ROLE_EXISTS" ]; then
|
||||
echo "Detaching policies from IAM role '$ROLE_NAME'..."
|
||||
ATTACHED_POLICIES=$(aws iam list-attached-role-policies --role-name $ROLE_NAME --query "AttachedPolicies[].PolicyArn" --output text)
|
||||
|
||||
for POLICY_ARN in $ATTACHED_POLICIES; do
|
||||
aws iam detach-role-policy --role-name $ROLE_NAME --policy-arn $POLICY_ARN
|
||||
echo "Detached policy: $POLICY_ARN"
|
||||
done
|
||||
|
||||
echo "Deleting IAM role '$ROLE_NAME'..."
|
||||
aws iam delete-role --role-name $ROLE_NAME
|
||||
echo "IAM role deleted."
|
||||
else
|
||||
echo "IAM role '$ROLE_NAME' does not exist."
|
||||
fi
|
||||
|
||||
echo "AWS resource cleanup completed successfully!"
|
||||
131
examples/aws-lambda/deploy.sh
Executable file
131
examples/aws-lambda/deploy.sh
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set variables
|
||||
FUNCTION_NAME="bknd-lambda"
|
||||
ROLE_NAME="bknd-lambda-execution-role"
|
||||
RUNTIME="nodejs22.x"
|
||||
HANDLER="index.handler"
|
||||
ARCHITECTURE="arm64" # or "x86_64"
|
||||
MEMORY="1024" # in MB, 128 is the minimum
|
||||
TIMEOUT="30"
|
||||
ENTRY_FILE="index.mjs"
|
||||
ZIP_FILE="lambda.zip"
|
||||
|
||||
# Build step
|
||||
echo "Building Lambda package..."
|
||||
rm -rf dist && mkdir dist
|
||||
|
||||
# copy assets
|
||||
node_modules/.bin/bknd copy-assets --out=dist/static
|
||||
|
||||
# Run esbuild and check for errors
|
||||
# important to use --platform=browser for libsql dependency (otherwise we need to push node_modules)
|
||||
if ! npx esbuild $ENTRY_FILE --bundle --format=cjs --platform=browser --external:fs --minify --outfile=dist/index.js; then
|
||||
echo "Error: esbuild failed to build the package"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# zip
|
||||
( cd dist && zip -r $ZIP_FILE . )
|
||||
|
||||
# Read .env file and export variables
|
||||
if [ -f .env ]; then
|
||||
export $(grep -v '^#' .env | xargs)
|
||||
else
|
||||
echo ".env file not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prepare environment variables string for Lambda
|
||||
ENV_VARS=$(awk -F= '{printf "%s=\"%s\",", $1, $2}' .env | sed 's/,$//')
|
||||
|
||||
# Create a trust policy file for the Lambda execution role
|
||||
cat > trust-policy.json << EOL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": "lambda.amazonaws.com"
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOL
|
||||
|
||||
# Create IAM role if it doesn't exist
|
||||
ROLE_ARN=$(aws iam get-role --role-name $ROLE_NAME --query "Role.Arn" --output text 2>/dev/null)
|
||||
|
||||
if [ -z "$ROLE_ARN" ]; then
|
||||
echo "Creating IAM role..."
|
||||
aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust-policy.json
|
||||
aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
||||
|
||||
# Wait for IAM role to propagate
|
||||
echo "Waiting for IAM role to propagate..."
|
||||
sleep 10
|
||||
|
||||
# Get the role ARN after creation
|
||||
ROLE_ARN=$(aws iam get-role --role-name $ROLE_NAME --query "Role.Arn" --output text)
|
||||
else
|
||||
echo "Using existing IAM role: $ROLE_ARN"
|
||||
fi
|
||||
|
||||
# Create or update Lambda function
|
||||
echo "Creating or updating Lambda function..."
|
||||
LAMBDA_ARN=$(aws lambda get-function --function-name $FUNCTION_NAME --query "Configuration.FunctionArn" --output text 2>/dev/null)
|
||||
|
||||
if [ -z "$LAMBDA_ARN" ]; then
|
||||
echo "Creating new Lambda function..."
|
||||
aws lambda create-function \
|
||||
--function-name $FUNCTION_NAME \
|
||||
--zip-file fileb://dist/$ZIP_FILE \
|
||||
--handler $HANDLER \
|
||||
--runtime $RUNTIME \
|
||||
--role $ROLE_ARN \
|
||||
--architectures $ARCHITECTURE \
|
||||
--memory-size $MEMORY \
|
||||
--timeout $TIMEOUT \
|
||||
--environment Variables="{$ENV_VARS}"
|
||||
else
|
||||
echo "Updating existing Lambda function..."
|
||||
aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://dist/$ZIP_FILE
|
||||
|
||||
echo "Waiting for Lambda function to become active..."
|
||||
aws lambda wait function-updated --function-name $FUNCTION_NAME
|
||||
|
||||
# Update function configuration, including env variables
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $FUNCTION_NAME \
|
||||
--memory-size $MEMORY \
|
||||
--timeout $TIMEOUT \
|
||||
--environment Variables="{$ENV_VARS}"
|
||||
fi
|
||||
|
||||
# Check if Function URL exists, if not create it
|
||||
echo "Checking if Function URL exists..."
|
||||
FUNCTION_URL=$(aws lambda get-function-url-config --function-name $FUNCTION_NAME --query "FunctionUrl" --output text 2>/dev/null)
|
||||
|
||||
if [ -z "$FUNCTION_URL" ]; then
|
||||
echo "Creating Function URL..."
|
||||
FUNCTION_URL=$(aws lambda create-function-url-config \
|
||||
--function-name $FUNCTION_NAME \
|
||||
--auth-type NONE \
|
||||
--query "FunctionUrl" --output text)
|
||||
|
||||
# Make the Function URL publicly accessible (log output)
|
||||
aws lambda add-permission \
|
||||
--function-name $FUNCTION_NAME \
|
||||
--action lambda:InvokeFunctionUrl \
|
||||
--principal "*" \
|
||||
--statement-id public-access \
|
||||
--function-url-auth-type NONE
|
||||
|
||||
echo "Created Lambda Function URL: $FUNCTION_URL"
|
||||
else
|
||||
echo "Lambda Function URL: $FUNCTION_URL"
|
||||
fi
|
||||
|
||||
echo "Deployment completed successfully!"
|
||||
14
examples/aws-lambda/index.mjs
Normal file
14
examples/aws-lambda/index.mjs
Normal file
@@ -0,0 +1,14 @@
|
||||
import { serveLambda } from "bknd/adapter/aws";
|
||||
|
||||
export const handler = serveLambda({
|
||||
// to get local assets, run `npx bknd copy-assets`
|
||||
// this is automatically done in `deploy.sh`
|
||||
assets: {
|
||||
mode: "local",
|
||||
root: "./static",
|
||||
},
|
||||
connection: {
|
||||
url: process.env.DB_URL,
|
||||
authToken: process.env.DB_TOKEN,
|
||||
},
|
||||
});
|
||||
21
examples/aws-lambda/package.json
Normal file
21
examples/aws-lambda/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "aws-lambda",
|
||||
"version": "1.0.0",
|
||||
"main": "index.mjs",
|
||||
"scripts": {
|
||||
"test": "esbuild index.mjs --bundle --format=cjs --platform=node --external:fs --outfile=dist/index.js && node test.js",
|
||||
"deploy": "./deploy.sh",
|
||||
"clean": "./clean.sh"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"bknd": "file:../../app/bknd-0.9.0-rc.1-11.tgz"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"dotenv": "^16.4.7"
|
||||
}
|
||||
}
|
||||
31
examples/aws-lambda/test.js
Normal file
31
examples/aws-lambda/test.js
Normal file
@@ -0,0 +1,31 @@
|
||||
require("dotenv").config();
|
||||
const handler = require("./dist/index.js").handler;
|
||||
|
||||
const event = {
|
||||
httpMethod: "GET",
|
||||
path: "/",
|
||||
//path: "/api/system/config",
|
||||
//path: "/assets/main-B6sEDlfs.js",
|
||||
headers: {
|
||||
//"Content-Type": "application/json",
|
||||
"User-Agent": "curl/7.64.1",
|
||||
Accept: "*/*",
|
||||
},
|
||||
};
|
||||
|
||||
const context = {
|
||||
awsRequestId: "mocked-request-id",
|
||||
functionName: "myMinimalLambda",
|
||||
functionVersion: "$LATEST",
|
||||
memoryLimitInMB: "128",
|
||||
getRemainingTimeInMillis: () => 5000,
|
||||
};
|
||||
|
||||
// Execute the handler
|
||||
handler(event, context)
|
||||
.then((response) => {
|
||||
console.log(response.statusCode, response.body);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
12
examples/aws-lambda/trust-policy.json
Normal file
12
examples/aws-lambda/trust-policy.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": "lambda.amazonaws.com"
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user