diff --git a/.gitignore b/.gitignore index bd275db..00ee9c6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ notes.org .env - +.qlot bootstrap function.zip -response.txt \ No newline at end of file +response.txt diff --git a/Dockerfile b/Dockerfile index a5ba876..1d3813d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ -FROM amazonlinux:2 +FROM --platform=linux/amd64 amazonlinux:2023 -RUN yum install -y zip bzip2 zlib tar make && yum clean all +RUN yum install -y zip bzip2 zlib tar make which && yum clean all RUN mkdir /work RUN mkdir /scripts WORKDIR /work -ARG SBCL_VERSION=1.5.5 +ARG SBCL_VERSION=2.3.11 # install sbcl to /usr/local/bin/sbcl -RUN curl -s -f -O -L http://prdownloads.sourceforge.net/sbcl/sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 \ - && bzip2 -cd sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 | tar xvf - \ +RUN curl -s -f -O -L http://prdownloads.sourceforge.net/sbcl/sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 +RUN bzip2 -cd sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 | tar xvf - \ && cd sbcl-$SBCL_VERSION-x86-64-linux \ && sh install.sh \ && rm -rf sbcl-$SBCL_VERSION-x86-64-linux sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 @@ -25,10 +25,6 @@ RUN curl -s -f -O "https://beta.quicklisp.org/quicklisp.lisp" \ COPY build.lisp /scripts/build.lisp -RUN mkdir -p /root/quicklisp/local-projects/cl-aws-lambda/ - -COPY ./ /root/quicklisp/local-projects/cl-aws-lambda/ - RUN chmod +x /scripts/build.lisp CMD /scripts/build.lisp && zip function.zip bootstrap diff --git a/example/.env.default b/example/.env.default index bdb02e2..e7f754e 100644 --- a/example/.env.default +++ b/example/.env.default @@ -1 +1,9 @@ -ROLE_ARN="set your arn here" \ No newline at end of file +ROLE_ARN="set your arn here" + +# Other environment variables which you might set + +# AWS_PROFILE="" +# FUNCTION_NAME=hello-cl +# ROLE_ARN="set-your-arn-here" +# HANDLER="example-lambda:hello" +# REGION="us-east-1" diff --git a/example/Dockerfile b/example/Dockerfile new file mode 100644 index 0000000..758eb69 --- /dev/null +++ b/example/Dockerfile @@ -0,0 +1,7 @@ +FROM --platform=linux/amd64 public.ecr.aws/lambda/provided:al2023 + +# Copy custom runtime bootstrap +COPY bootstrap ${LAMBDA_RUNTIME_DIR} + +# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) +CMD [ "example-lambda:hello" ] diff --git a/example/Makefile b/example/Makefile index 30263ba..1bda559 100644 --- a/example/Makefile +++ b/example/Makefile @@ -5,7 +5,7 @@ ROLE_ARN ?= "set-your-arn-here" HANDLER ?= "example-lambda:hello" REGION ?= "us-east-1" -RUNC ?= podman +RUNC ?= docker PAYLOAD ?= '{"name": "Matt"}' @@ -22,11 +22,10 @@ bootstrap: $(wildcard *.asd) $(wildcard *.lisp) ## Build a lisp image as a provi $(RUNC) build ../ -t cl-lambda-builder $(RUNC) volume create cl-aws-asdf-cache || true $(RUNC) volume create cl-aws-quicklisp || true - $(RUNC) run --rm -it \ + $(RUNC) run --platform=linux/amd64 --rm -it \ -e ASDF_OUTPUT_TRANSLATIONS="/:/asdf-cache/" \ -v ${PWD}:/work/:Z \ - -v cl-aws-quicklisp:/root/quicklisp \ - -v ${HOME}/quicklisp/local-projects:/root/quicklisp/local-projects:Z \ + -v ${PWD}/.qlot:/root/quicklisp \ -v cl-aws-asdf-cache:/asdf-cache/ \ cl-lambda-builder @@ -35,29 +34,30 @@ function.zip: bootstrap zip function.zip bootstrap deploy: bootstrap function.zip ## Create a function.zip payload and create a new lambda function in AWS - aws lambda create-function \ + aws --profile ${AWS_PROFILE} lambda create-function \ --function-name ${FUNCTION_NAME} \ --zip-file fileb://function.zip \ --handler ${HANDLER} \ - --runtime provided.al2 \ + --runtime provided.al2023 \ --role ${ROLE_ARN} \ --region ${REGION} update: bootstrap function.zip ## Create a function.zip and update the existing lambda function in AWS - aws lambda update-function-code \ + aws --profile ${AWS_PROFILE} lambda update-function-code \ --function-name ${FUNCTION_NAME} \ --zip-file fileb://function.zip \ --region ${REGION} invoke: ## Invoke the function with a given payload - aws lambda invoke \ + aws --profile ${AWS_PROFILE} lambda invoke \ --function-name ${FUNCTION_NAME} \ + --cli-binary-format raw-in-base64-out \ --payload ${PAYLOAD} \ --region ${REGION} \ response.txt -invoke-local: bootstrap ## Invoke the function locally using a continer - $(RUNC) run --rm -v "${PWD}":/var/task:Z lambci/lambda:provided ${HANDLER} ${PAYLOAD} +invoke-local: bootstrap ## Invoke the function locally using a container + $(RUNC) run --platform=linux/amd64 -p 9000:8080 --rm -v "${PWD}":/var/runtime:Z public.ecr.aws/lambda/provided:al2023 ${HANDLER} clean-artifacts: ## Remove compiled artifacts rm -f function.zip bootstrap diff --git a/example/README.org b/example/README.org index 3462fd9..e19fda0 100644 --- a/example/README.org +++ b/example/README.org @@ -4,15 +4,18 @@ - Docker - zip - awscli + - qlot - 2. Furthermore, you'll need an AWS account with a basic lambda role defined. AWS has a [[https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html][Getting Started with AWS Lambda]] guide that might be useful for you, at this point. + 2. [[https://github.com/fukamachi/qlot][qlot]] can be installed via roswell. It serves as a local quicklisp directory, which contains fixed versions of your development dependencies. You need to invoke qlot update once in the example directory to get started. - 3. Once you have created a [[https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html][role]] for your lambda, use the ~cp .env.default .env~ and edit the file to set the role ARN for your lambda. You can also override the other variables in the ~Makefile~, here, if you wish. + 3. Furthermore, you'll need an AWS account with a basic lambda role defined. AWS has a [[https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html][Getting Started with AWS Lambda]] guide that might be useful for you, at this point. - 4. With your ARN set, you should be able to compile and deploy the example lambda. Run ~make deploy~, which should compile your lambda in docker (so we have a sufficiently new version of sbcl), zip it into ~function.zip~ and then create a lambda in AWS by uploading that zip as a custom runtime using the aws cli tool. + 4. Once you have created a [[https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html][role]] for your lambda, use the ~cp .env.default .env~ and edit the file to set the role ARN for your lambda. You can also override the other variables in the ~Makefile~, here, if you wish. - 5. You should now be able to run ~make invoke~, which will call your lambda with the aws cli to ask it to say hello to me. Thank you for saying hello to me. + 5. With your ARN set, you should be able to compile and deploy the example lambda. Run ~make deploy~, which should compile your lambda in docker (so we have a sufficiently new version of sbcl), zip it into ~function.zip~ and then create a lambda in AWS by uploading that zip as a custom runtime using the aws cli tool. - 6. If you want to, you can change the code of ~hello.lisp~ and then run ~make update~ to recompile and update your lambda function. + 6. You should now be able to run ~make invoke~, which will call your lambda with the aws cli to ask it to say hello to me. Thank you for saying hello to me. + + 7. If you want to, you can change the code of ~hello.lisp~ and then run ~make update~ to recompile and update your lambda function. Deleting a lambda is left as an exercise to the reader, I guess. diff --git a/example/example-lambda.asd b/example/example-lambda.asd index e93c278..c8672ff 100644 --- a/example/example-lambda.asd +++ b/example/example-lambda.asd @@ -1,4 +1,5 @@ (defsystem example-lambda :defsystem-depends-on ("cl-aws-lambda/asdf") :class :lambda-system + :serial t :components ((:file "hello"))) diff --git a/example/hello.lisp b/example/hello.lisp index 3c3e491..4d919a8 100644 --- a/example/hello.lisp +++ b/example/hello.lisp @@ -1,12 +1,22 @@ -(defpackage example-lambda +(uiop:define-package example-lambda (:use :cl) + (:import-from :cl-aws-lambda/runtime-interface + :request-id-of + :*context*) (:export #:hello)) (in-package :example-lambda) +(declaim (optimize (space 3) (speed 0))) + +(defmethod request-id-of ((object t)) + "some-id") + (defun hello (event) (let ((name (cdr (assoc "name" event :test #'string=)))) (if name - (list (cons "response" (format nil "Hello, ~a!" name)) - (cons "resquest-id" (cl-aws-lambda/runtime-interface:request-id-of cl-aws-lambda/runtime-interface:*context*))) - (error "No name supplied!")))) + `( ("statusCode" . 200) + ("body" . + (("response" . ,(format nil "Hello, ~a!" name)) + ("request-id" . ,(request-id-of *context*))))) + (error "No name supplied!")))) diff --git a/example/install-sbcl.sh b/example/install-sbcl.sh deleted file mode 100755 index cbc4a6f..0000000 --- a/example/install-sbcl.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -SBCL_VERSION=1.4.14 - -curl http://prdownloads.sourceforge.net/sbcl/sbcl-$SBCL_VERSION-x86-64-linux-binary.tar.bz2 -L -o sbcl.tar.bz2 - -tar xfj sbcl.tar.bz2 - -cd sbcl-$SBCL_VERSION-x86-64-linux - -sh install.sh - -cd .. - -rm -rf ./sbcl-$SBCL_VERSION-x86-64-linux diff --git a/example/qlfile b/example/qlfile new file mode 100644 index 0000000..a825a05 --- /dev/null +++ b/example/qlfile @@ -0,0 +1 @@ +github fisxoj/cl-aws-lambda diff --git a/example/qlfile.lock b/example/qlfile.lock new file mode 100644 index 0000000..d0bfc2c --- /dev/null +++ b/example/qlfile.lock @@ -0,0 +1,8 @@ +("quicklisp" . + (:class qlot/source/dist:source-dist + :initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) + :version "2023-10-21")) +("cl-aws-lambda" . + (:class qlot/source/github:source-github + :initargs (:repos "fisxoj/cl-aws-lambda" :ref nil :branch nil :tag nil) + :version "github-6ed1efbacd4a98410b9b1b340614e0d35c4507de"))