SAM Application for a simple chat application based on API Gateways new WebSocket API feature. This was originally developed as an experiment to see how viable running a chat-bot in a fully serverless environment, as opposed to just running on a container in ECS.
This repository is based on Announcing WebSocket APIs in Amazon API Gateway, with the cloudformation and lambdas from simple-websockets-chat-app.
A build-harness created with make
is available for the repository. This harness simplifies the command necessary to build and deploy the project. You can see the available targets by running make help
:
Usage: make <target>
help This help text.
Deploy
pack Package the yaml files as a single
package Package an AWS SAM application.
deploy Deploy an AWS SAM application.
publish Re-package and deploy an AWS SAM application.
Cloudformation
describe Describes the deployed cloudformation stack.
outputs Describes the outputs of the deployed cloudformation stack.
Docker
docker Runs AWS SAM in docker.
Tests
chat Login to one of the chat sessions.
stop Halt the existing chat services.
logs Dump the logs from the docker image.
The build-harness does a bit more in this case, as I experimented with a couple different tools while working on this. Notably:
AWS SAM
for packaging and deploying the codecfpack.js
for bundling multiple cloudformation templates into a single onedocker-compose
for testing the service withwscat
awscli
for describing and working with the deployed cloudformation stack
Using docker, you can build and deploy the sample using the following steps:
make docker
make pack
make package
make deploy
You can get the URL for the websocket by calling make outputs
. This can then be provided to the docker-compose template in docker/.
make outputs
echo "WSCAT_URI=wss://<id>.execute-api.<region>.amazonaws.com/<env>" > docker/.env
make chat
# wscat -c $WSCAT_URI
# {"message":"sendmessage", "data":"hello world"}
I built this while I was looking into serverless chat-ops. At the time I was tinkering with ideas about chat-ops like services that could be used to manage key rotation in external services. This lead to some experiments with Hubot and AWS Lambda. I thought this example would offer sufficient complexity for tinkering with the idea of a lambda-based application for working with different services. The ideas were as follows:
- If each service is its own lambda, permissions to service tokens (GitHub / CircleCI / TravisCI / Jenkins) can be locked down at the route level
- Each service token could have its own secret store, allowing granular access permissions
- Rotations would occur on set intervals, which meant the service didn't need to remain running at all times
- Trigger actions (revocations / deletes / freezes) could be trigger by API Routes
- Authentication could potentially leverage existing AWS services (useful for a secure service)
I had originally intended to write this in terraform, however at time of development (& writing), Terraform does not have support for the new version of API Gateway (V2). I have included CloudFormation in Terraform prototype in the directory tests/ for future reference. Rather than trying to get this working, I looked for ways to setup a terraform-like experience in cloudformation.
I used cfpack.js
to split the cloudformation template into smaller templates. Although this added another dependency (& build step), I found it a lot easier to work with multiple smaller templates as opposed to one big one. I did some early experiments with nested stacks, but personally found it like juggling.
cfpack is a small CLI tool that can help you to deal with huge CloudFormation templates by splitting it into multiple smaller templates. Using this tool you can also build sharable drop-in templates that you can share across your projects.