In part one and part two of this series, we looked at how to build a ClojureScript environment that we can deploy to AWS Lambda and the API Gateway that will respond to the outside world as a web service. With that done, today we’ll see how to go about deploying it.

First, you’ll need to have an Amazon AWS account, with your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables set. Doing that is exhaustively documented elsewhere, so I’ll skip it. Instead, let’s dig into our project.clj, which has a number of things we need to set up to take care of deployment.

Under the :cljs-lambda key, we first need to set a role for our function that will define the permissions it has to access various AWS resources on our behalf. If you have other Lambda functions already deployed, you’ll have roles you’ve defined for them before; if not, you can run lein cljs-build default-iam-role. In either case, what you need is the resulting ARN (that looks like arn:aws:iam::123456789012:role/lambda_basic_execution); replace "FIXME" as the :role with that ARN.

Next, change the function :name to "JWTify" (this is the human-readable name our function goes by) and :invoke to jwtify.core/jwtify. You should now be able to run lein cljs-lambda deploy, and cljs-lambda will compile your ClojureScript, upload it to AWS, and create the associated Lambda function:

Compiling "target/jwtify/jwtify.js" from ["src"]...
Successfully compiled "target/jwtify/jwtify.js" in 3.761 seconds.
Writing index to /Users/josh/projects/jwtify/target/jwtify/index.js
Writing zip to /Users/josh/projects/jwtify/target/jwtify/jwtify.zip
$LATEST  The last step is connecting our new Lambda function to the web. Log into the API Gateway, click on “APIs”, then “Create API”, enter “JWTify” as the API name, and then click “Create API.” You should be in your new Gateway’s settings page, where you can then click the “Actions” dropdown, select “Create Resource”, click the “Configure as a proxy resource” checkbox (this will just forward everything from the web request directly to our Lambda function), and click “Create Resource.” You’ll then be in a proxy setup screen. Your integration type should be “Lambda Function Proxy” (of course), then you can select the region your Lambda function was deployed to (either “us-east-1” by default or whichever region you’ve configured your account to use; you can also set this in project.clj), and finally enter “JWTify” in the Lambda Function text input. “JWTify” should autocomplete there; if it doesn’t, you might not have the right region selected. Click “Save,” then confirm the request for the API Gateway to invoke your function. Now you should have a testable API Gateway/Lambda integration. Click the “Test” button, and create a POST to /sign with a request body like {"payload": {"test": "payload"}, "secret": "secret"}. Testing that should return a 200 status with a JWT token in the response body. If it works, you’re ready to deploy. Click the “Actions” dropdown, then “Deploy API.” Give your deployment stage a name (“test” works fine here), and then click “Deploy.” The result will be a deploy URL you can test with CURL on the command line, like so: $ curl -X POST "https://jlfyyiazkb.execute-api.us-east-1.amazonaws.com/test/sign" -d '{"payload": {"test": "payload"}, "secret": "secret"}'