Edited at

AWS CDKとKotlinでHelloWorld

AWS CDKで単純なlambdaを作成し、処理をKotlinで実装、AWS SAMでローカル実行を行うまでの作業メモ。

AWS CDKはTypescriptを利用します。

(諸々理由はありますがCDKはJava(Kotlin)だと記述が煩雑になる感じがしたので)

また、各種ツールのインストールは長くなるので割愛します。


環境


  • macOS Mojave 10.14.6

  • AWS CDK関連


    • AWS CDK 1.8.0

    • nodenv 1.3.0

    • Node.js 10.15.3



  • AWS SAM関連


    • AWS SAM CLI 0.21.0

    • docker desktop 2.1.0.2

    • pyenv 1.2.13

    • Python 3.7.4



  • Kotlin関連


    • Kotlin 1.3.50

    • jenv 0.5.2

    • Java Corretto-8.222.10.1

    • Gradle 5.6.2




流れ


  1. AWS CDKプロジェクト作成

  2. Kotlinプロジェクト作成

  3. Lambda 作成

  4. CDK設定

  5. ローカル起動


AWS CDKプロジェクト作成

$ mkdir aws-lambda-kotlin && cd $_

$ nodenv local 10.15.3
$ cdk init --language typescript
Applying project template app for typescript
Initializing a new git repository...
Executing npm install...
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN aws-lambda-kotlin@0.1.0 No repository field.
npm WARN aws-lambda-kotlin@0.1.0 No license field.

# Useful commands

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template


Kotlinプロジェクト作成

$ mkdir hello-world && cd $_

$ jenv local 1.8
$ gradle init --type kotlin-application --dsl kotlin --project-name hello-world --package foo.bar

kotlinのバージョンを1.3.50に変更


hello-world/build.gradle.kts

id("org.jetbrains.kotlin.jvm") version "1.3.50"


ライブラリ追加


hello-world/build.gradle.kts

implementation("com.amazonaws:aws-lambda-java-core:1.2.0")

implementation("com.amazonaws:aws-lambda-java-events:2.2.7")
implementation("com.amazonaws:aws-lambda-java-log4j2:1.0.0")

mainClassName変更(これは不要かも?)


hello-world/build.gradle.kts

mainClassName = "foo.bar.Handler"


デプロイパッケージ作成設定の追加


hello-world/build.gradle.kts

tasks {

val buildZip by registering(Zip::class) {
from(compileKotlin)
from(processResources)
into("lib") {
from(configurations.compileClasspath)
}
}
named("build") {
dependsOn(buildZip)
}
}


Lambda 作成

Handlerクラス作成


hello-world/src/main/kotlin/foo/bar/Handler.kt

package foo.bar

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
import org.apache.logging.log4j.LogManager

data class Response(val body: String)

class Handler : RequestHandler<Map<String, Any>, Response> {
companion object {
private val log = LogManager.getLogger()
}

override fun handleRequest(input: Map<String, Any>, context: Context): Response {
log.info("received : $input")
return Response(input["param"]?.toString() ?: "empty")
}
}



CDK設定

依存追加

$ npm i @aws-cdk/aws-lambda @aws-cdk/aws-lambda-event-sources


Stack修正


lib/aws-lambda-kotlin-stack.ts

import cdk = require('@aws-cdk/core');

import { Function, Runtime, Code } from '@aws-cdk/aws-lambda';
import { Duration } from '@aws-cdk/core';

export class AwsLambdaKotlinStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const myFunction = new Function(this, 'hello-world-function', {
functionName: 'hello-function',
runtime: Runtime.JAVA_8,
code: Code.asset('hello-world/build/distributions/hello-world.zip'),
handler: 'foo.bar.Handler',
timeout: Duration.seconds(10),
});
}
}



ローカル起動

$ ./hello-world/gradlew -b ./hello-world/build.gradle.kts clean build

$ cdk synth --no-staging > template.yaml
$ sam local invoke `grep -B1 "AWS::Lambda::Function" template.yaml | head -n1 | sed -e 's/^ *//' -e 's/:$//'` --no-event
Invoking foo.bar.Handler (java8)
2019-09-11 17:29:33 Found credentials in shared credentials file: ~/.aws/credentials
Decompressing /Users/hoge/work/aws-lambda-kotlin/hello-world/build/distributions/hello-world.zip

Fetching lambci/lambda:java8 Docker container image...........................................
Mounting /private/var/folders/t7/mb1gz5z55y1dvsgkmyh22q580000gn/T/tmp1yczekpk as /var/task:ro,delegated inside runtime container
START RequestId: 23f83fd0-b396-439a-ac97-368e0fc4b353 Version: $LATEST
END RequestId: 23f83fd0-b396-439a-ac97-368e0fc4b353
REPORT RequestId: 23f83fd0-b396-439a-ac97-368e0fc4b353 Duration: 96.06 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 5 MB
2019-09-11 08:30:19 23f83fd0-b396-439a-ac97-368e0fc4b353 INFO Handler:15 - received : {}

{"body":"empty"}