Chessy - Episode 5
Another post about Chessy, application to reproduce chess matches. Many things happened during this time: I’ve enjoyed (and suffered) taking baby steps with SwiftUI, introduced myself into animations, fixed some tedious parser bugs, and more. One of the things I liked the most was to get into aws-cdk, the aws way to “code the cloud”, and that’s the topic for this post.
Cloud as Code
You don’t need a lot of time in AWS to realize that setting up the cloud through the web-ui (as I did before) is a bad idea for multiple reasons, like:
- you forget every configuration you touched (buttons, checkboxes) in a week or less. As a consequence, it’s hard to maintain, to share, to invite others to collaborate, and to replicate… (imagine you just want to do something ‘similar’ for another project..)
- you need extra effort to coordinate many people working together (who changed this? why? when?)
- you can’t do basic things without tons of effort, like “go back to how it was a month ago” (no history, no track of changes)
The solution to every problem I mentioned is quite straight-forward: write “the cloud” in a text file, in a way that humans can understand (and AWS too), and manage it with a version control system (p4
, git
, etc). There you go!
Such a solution have existed for a while and it’s called CloudFormation, which allows you to write everything in JSON files. This works, but the price is quite high: you need to learn and follow a very-specific -and not so human-friendly- JSON schema. Perhaps, that’s why aws provides a ton of “cloud-formation templates” to tackle the most common use cases.
But things got better, and not long ago AWS released Cloud Development Kit (CDK) which allows you to write the cloud infrastructure in a familiar programming language, like Python, Javascript, etc. This is a mini developer heaven, because:
- it is more enjoyable to program than to write JSON… right? RIGHT?
- you gradually discover what else is possible thanks to the type system itself (if you use a typed language like Typescript or C#)
- the ergonomics make sense. I.e: you create an S3 bucket with
const myS3 = new S3(...)
and refer to it later using the reference:myS3.grantPublicAccess()
- as you would expect in any OOP program. - it is easier to integrate components. I.e, Instead of creting a policy that’s attached to a role that’s assumed by a function that etc.., you allow a lambda function to read a database table with one statement:
myDbTable.grantRead(myLambdaFn)
. Concise and clear1.
chessy-cloud
I used aws-cdk to re-implement the chessy’s cloud side (described in parts 3 and 4) as part of the learning process. I really enjoyed doing it and the result is not bad, even with everything in one file :)
Since I was there, I did a small change in the API Gateway endpoint: Before, the endpoint accessed the database directly - well, in reality using an aws-specific integration. Though simple, this technique doesn’t give control - or at least I didn’t find how - and I wanted to transform the data before returning. Instead of answering with the raw database content, like:
{ "Event": { "S": "The Great Event" } }
I wanted to process it and return:
{ "Event": "The Great Event" }
This is because the database’s internal format is particular and applications/consumers should not care about that (besides being ugly). The conversion process is called marshall and unmarshall, and DynamoDB (my database) offers official methods to do it.
So I added a(nother) lambda function to handle HTTP requests that replaces the default integration. Its code is quite simple and, as you might guess, just unmarshalls the results before returning.
This change allowed me to put the lambda function code together with the cloud stack code. And so instead of providing code and libraries that live somewhere else, I could just point to a file and let aws-cdk do its magic.
As always, you can peak at the chessy-cloud
code in github.
Cheers!◆
-
this is only possible if one uses the Curated (L2) type of libraries, which address(es) specific use cases and simplify infrastructure development (…) providing sensible defaults and best-practice security policies (official documentation) ↩