awscli-local + LocalStackでSpringBootアプリケーションを動かしてみます!
ここでは、ローカル環境にAWS環境を作成する「LocalStack」を使い、SpringBootアプリケーションを動かします。
また、LocalStack用のCLIである「awscli-local」のインストールも行います。
awscli-localコマンドのインストールにPythonが必要になりますので、インストールがまだの人は下記の記事を参考にして下さい。
LocalStackを使ってSpringBootアプリケーションを動かす
AWS-CLI本体のインストール
awscli-localをインストールする前に前提となるaws-cli本体をインストールします。
macの場合
# install
$ brew install awscli
# 確認
$ aws --version
aws-cli/2.6.2 Python/3.9.12 Darwin/19.6.0 source/x86_64 prompt/off
Linux (Ubuntu)の場合
# homeディレクトリに移動
$ cd ~
# install (curl -> unzip -> ./aws/install の順に実行)
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 44.8M 100 44.8M 0 0 10.4M 0 0:00:04 0:00:04 --:--:-- 10.4M
$ unzip awscliv2.zip
Archive: awscliv2.zip
creating: aws/
creating: aws/dist/
・・・
$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version
# 確認
$ aws --version
aws-cli/2.6.2 Python/3.9.11 Linux/4.15.0-142-generic exe/x86_64.linuxmint.18 prompt/off
awscli-localのインストール
mac、Linuxともに以下のコマンドでインストールします。
※エラーが発生する場合はこちらを参照
# install
$ pip install awscli-local
# 確認
$ awslocal --version
aws-cli/2.6.2 Python/3.9.11 Linux/4.15.0-142-generic exe/x86_64.linuxmint.18 prompt/off
docker-composeでLocalStackを起動
下記の通りLocalStack起動用のdocker-compose.yamlを作成します。
version: "3"
services:
localstack:
image: 'localstack/localstack'
ports:
- "4566:4566"
environment:
- SERVICES=s3
- DEFAULT_REGION=us-east-1
以下のコマンドでLocalStackを起動します。
$ docker-compose up -d
S3バケットの作成
下記のコマンドでS3バケットを作成します。
$ awslocal s3 mb s3://kotlin-web-app-local
make_bucket: kotlin-web-app-local
サンプルアプリケーションの作成
動作を確認するためのSpringBootアプリケーションを作成します。
プロジェクトの構成
プロジェクトの構成は下記の通りです。
kotlin-web-app
├── build.gradle.kts
├── settings.gradle.kts
└── src
├── main
│ ├── kotlin
│ │ └── com
│ │ └── example
│ │ └── kotlinwebapp
│ │ ├── CreateFileRestController.kt
│ │ ├── KotlinWebAppApplication.kt
│ │ └── config
│ │ └── S3Config.kt
│ └── resources
│ └── application.yaml
└── ・・・
build.gradle.ktsの作成
build.gradle.ktsを設定します。
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.6.7"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.6.21"
kotlin("plugin.spring") version "1.6.21"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk
implementation("com.amazonaws:aws-java-sdk:1.12.213")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
AmazonS3クライアントの作成
AmazonS3へ接続するクライアントを作成します。
package com.example.kotlinwebapp.config
import com.amazonaws.client.builder.AwsClientBuilder
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class S3Config {
@Bean
fun amazonS3(): AmazonS3 {
return AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(
AwsClientBuilder.EndpointConfiguration(
"http://localhost:4566/",
"us-east-1"
)
)
.withPathStyleAccessEnabled(true)
.build()
}
}
RestControllerの作成
WebアプリケーションのエンドポイントとなるRestControllerを作成します。
package com.example.kotlinwebapp
import com.example.kotlinwebapp.config.S3Config
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStreamWriter
@RestController
class CreateFileRestController(
val s3Config: S3Config
) {
@GetMapping("create-file")
fun createFile(): String {
val file = File.createTempFile("hello", ".txt")
FileOutputStream(file).use { fos ->
OutputStreamWriter(fos).use { osw ->
osw.write("Hello! from spring boot app")
}
}
s3Config.amazonS3().putObject("kotlin-web-app-local", "sample", file)
return "create hello.txt"
}
@GetMapping("get-file")
fun getFile(): String {
val s3Obj = s3Config.amazonS3().getObject("kotlin-web-app-local", "sample")
val fileContents = s3Obj.objectContent.use { s3is ->
s3is.bufferedReader().readText()
}
return "file contents: $fileContents"
}
}
Serverポートの設定
application.yamlにServerポートを設定します。
server:
port: 18080
SpringBootアプリケーションの起動
下記のコマンドでSpringBootアプリケーションを起動します。
$ gradlew bootRun
S3へファイル作成
下記のコマンドを実行してS3にファイルを作成します。
$ curl -XGET http://localhost:18080/create-file
create hello.txt
S3からファイルの読み込み
下記のコマンドを実行して、先ほどS3に作成したhello.txtの内容を表示します。
$ curl -XGET http://localhost:18080/get-file
Hello! from spring boot app
S3に作成したファイルの内容を読み込むことができました!
お疲れ様でした。
まとめ
今回はLocalStackを利用してAmazonS3を使用したSpringBootアプリケーションを作成しました。
LocalStackはCommunityEditionとProEditionがあるようですが、管理人の場合はCommunityEditionでも十分だと思いました。
AWSアプリケーションをローカル環境で動作できるのはとっても便利ですね!