Ramp Me Up, Scotty!

EN | DE

AWS SDK with Kotlin

2024-05-28

Boy was I happy when I read the news about the general availability of the AWS SDK for Kotlin. Finally—time to use Kotlin for my infrastructure-as-code projects.

https://aws.amazon.com/about-aws/whats-new/2023/11/aws-sdk-kotlin/

In this tutorial I follow Amazon’s guide on how to create an S3 bucket, put an object from a ByteStream into the S3 bucket, and then clean up everything using the AWS SDK for Kotlin. I had to make a few changes to the original tutorial to make it work in my development environment. All in all, it was straightforward.

Here is the general AWS SDK for Kotlin page: https://aws.amazon.com/sdk-for-kotlin/

The tutorial I followed is here: https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/get-started.html

First, create a Gradle project. I kept the default settings.

% mkdir aws-cdk-kotlin
% cd aws-cdk-kotlin
% gradle init --type kotlin-application --dsl kotlin

Project name (default: aws-cdk-kotlin):

Source package (default: aws.cdk.kotlin):

Enter target version of Java (min. 7) (default: 21):

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]

> Task:init
To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.5/samples/sample_building_kotlin_applications.html

BUILD SUCCESSFUL in 5s
2 actionable tasks: 2 executed
%

Next, add the AWS SDK dependency.

in build.gradle.kts

...

dependencies {
    ...
    implementation("aws.sdk.kotlin:s3:1.0.0")
}

Here is the tutorial code, slightly adapted to newer syntax:

import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.*
import aws.smithy.kotlin.runtime.content.ByteStream
import kotlinx.coroutines.runBlocking
import java.util.*

val REGION = "eu-central-1"
val BUCKET = "bucket-${UUID.randomUUID()}"
val KEY = "my-s3-bucket-key"

fun main(): Unit = runBlocking {
    S3Client.fromEnvironment { region = REGION }.use { s3 ->
        setupTutorial(s3)

        println("Creating object $BUCKET/$KEY...")

        val putObjectRequest = PutObjectRequest {
            bucket = BUCKET
            key = KEY
            body = ByteStream.fromString("Testing with the Kotlin SDK")
        }
        s3.putObject(putObjectRequest)

        println("Object $BUCKET/$KEY created successfully!")
        cleanUp(s3)
    }
}

suspend fun setupTutorial(s3: S3Client) {
    println("Creating bucket $BUCKET...")
    val createBucketRequest = CreateBucketRequest {
        bucket = BUCKET
        createBucketConfiguration {
            locationConstraint = BucketLocationConstraint.fromValue(REGION)
        }
    }
    s3.createBucket(createBucketRequest)
    println("Bucket $BUCKET created successfully!")
}

suspend fun cleanUp(s3: S3Client) {
    println("Deleting object $BUCKET/$KEY...")
    val deleteObjectRequest = DeleteObjectRequest {
        bucket = BUCKET
        key = KEY
    }
 s3.deleteObject(deleteObjectRequest)

 println("Object $BUCKET/$KEY deleted successfully!")

 println("Deleting bucket $BUCKET...")
 val deleteBucketRequest = DeleteBucketRequest {
  bucket = BUCKET
 }
 s3.deleteBucket(deleteBucketRequest)
 println("Bucket $BUCKET deleted successfully!")
}

Let my friend ChatGPT explain what the code does:

Thank you, ChatGPT.

Finally, I ran the code and received the expected output:

Creating bucket bucket-bad30829-1f4f-432a-acf3-fccafac14ecf...
Bucket bucket-bad30829-1f4f-432a-acf3-fccafac14ecf created successfully!
Creating object bucket-bad30829-1f4f-432a-acf3-fccafac14ecf/my-s3-bucket-key...
Object bucket-bad30829-1f4f-432a-acf3-fccafac14ecf/my-s3-bucket-key created successfully!
Deleting object bucket-bad30829-1f4f-432a-acf3-fccafac14ecf/my-s3-bucket-key...
Object bucket-bad30829-1f4f-432a-acf3-fccafac14ecf/my-s3-bucket-key deleted successfully!
Deleting bucket bucket-bad30829-1f4f-432a-acf3-fccafac14ecf...
Bucket bucket-bad30829-1f4f-432a-acf3-fccafac14ecf deleted successfully!

That was easy!

If you have any further questions, need specific code examples, or require additional assistance, please leave a comment or send me a message.

Thank you for reading!