I think I have settled on how I will create serverless webapp applications. I am going to use AWS Cloudformation to manage the deployment of serverless infrastructure, and I am going to use the AWS Cloud Development Toolkit to build the components. CDK allows me to write Java code, programmatically declaring infrastructure components like AWS S3 Buckets, Lambda functions, and much more. Of course, I won't be writing in Java, I'll write in Kotlin - but for now, I'll need to use the Java libraries.
The example projects for AWS CDK in Java all use the maven build tool, but I wanted to use gradle instead, as it's commonly used in Kotlin. So it took me a while to work out how to convert the maven code to gradle.
I now have a template project available on Github, which you are free to clone to get started. The project uses gradle 7.4.2, is written in Kotlin 1.7.10, and makes use of the AWS CDK library 2.31.0.
There's a few things I needed to do to set this up. First, in build.gradle.kts
:
plugins {
kotlin("jvm") version "1.7.10"
`maven-publish`
id("com.github.johnrengelman.shadow") version "7.1.2"
application
}
The application
plugin makes it easier to run the code; I had to set the name of the Main class in this configuration block - the name is based on the filename of the Kotlin source for the function (HelloKotlinCDKApp.kt, in this case):
application {
mainClass.set("org.liamjd.aws.cdk.HelloKotlinCDKAppKt")
}
The main entry point is a simple standalone Kotlin main
function:
fun main() {
val app = App()
val stack = HelloKotlinCdkStack(app, "HelloKotlinCDKStack", StackProps.builder().build())
app.synth()
}
The Cloudformation stack is defined in the HelloKotlinCdkStack
class:
class HelloKotlinCdkStack(scope: Construct, id: String, props: StackProps?) : Stack(scope, id, props) {
constructor(scope: Construct, id: String) : this(scope, id, null)
init {
Tags.of(this).add("experiment", "cdk-kotlin")
Bucket.Builder.create(this, "MyFirstKotlinCDKBucket")
.versioned(false)
.removalPolicy(RemovalPolicy.DESTROY)
.autoDeleteObjects(true)
.build()
}
}
This is about the simplest stack I could create - a single S3 bucket - but even that results in 6 resources created in CloudFormation. I like to add some AWS tags in at the start of a project - it's always to easy to create an AWS resource without a tag, and then forget what it's for down the line...
I also had to create a file called cdk.json
in the root of the project. I don't know all details, but the key thing is the first line. The sample in the github repo has the rest:
{
"app": "gradlew run",
"context": {
... // other stuff here
}
}
}
The gradlew run
command comes from the application
plugin set up in build.gradle.kts
.
Once all this is in place, you can execute the command line command cdk synth
, which prepares the Cloudformation templates. And then cdk deploy
to deploy them to AWS. Finally, clean it all up with cdk destroy
.
I can think of some improvements to this template, so I'll continue to refine it over time.