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:
- Imports: The code imports necessary classes from the AWS SDK for Kotlin, including S3 client classes and models. It also imports ByteStream for handling data streams and runBlocking for coroutine support.
- Constants:
- REGION: Specifies the AWS region (e.g., “eu-central-1”).
- BUCKET: A unique bucket name is generated using UUID.randomUUID().
- KEY: Defines the key name for the object to be stored in S3.
- Main Function:
- Initializes an S3 client with the specified region.
- Calls setupTutorial to create a new S3 bucket.
- Creates a text object in the bucket with the specified key.
- Cleans up by deleting the created object and bucket.
- setupTutorial Function:
- Creates an S3 bucket in the specified region.
- Uses CreateBucketRequest to configure and create the bucket.
- cleanUp Function:
- Deletes the previously created object and bucket.
- Uses DeleteObjectRequest and DeleteBucketRequest for deletion.
- Coroutine Usage: The runBlocking coroutine builder is used to execute suspend functions (setupTutorial and cleanUp) in main. AWS SDK calls are suspending functions and require a coroutine context.
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!