Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AWS CDKのKotlinラッパーを作った話
Search
トリナー
August 25, 2021
Programming
1
540
AWS CDKのKotlinラッパーを作った話
集まれKotlin好き!Kotlin愛好会 vol.31 @オンライン(
https://love-kotlin.connpass.com/event/221691/
) での発表資料です。
トリナー
August 25, 2021
Tweet
Share
More Decks by トリナー
See All by トリナー
KC3「Re: ゼロから始めるサーバーサイドKotlin」
toliner
0
170
Other Decks in Programming
See All in Programming
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
230
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
930
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
Click-free releases & the making of a CLI app
oheyadam
2
120
cmp.Or に感動した
otakakot
3
200
RubyLSPのマルチバイト文字対応
notfounds
0
120
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
Better Code Design in PHP
afilina
PRO
0
130
最新TCAキャッチアップ
0si43
0
190
CSC509 Lecture 13
javiergs
PRO
0
110
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
340
Quine, Polyglot, 良いコード
qnighy
4
650
Featured
See All Featured
Thoughts on Productivity
jonyablonski
67
4.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
Adopting Sorbet at Scale
ufuk
73
9.1k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Building Your Own Lightsaber
phodgson
103
6.1k
Statistics for Hackers
jakevdp
796
220k
Become a Pro
speakerdeck
PRO
25
5k
Transcript
関東財務局長(少額短期保険業)第87号 AWS CDKのKotlinラッパーを作った話 0 2021.8.25 toliner
1 自己紹介 ▪ Toliner(トリナー) ◆ Twitter: @toliner_ ◆ GitHub: toliner
▪ 大学3年生(情報系学科) ▪ Kotlin歴は4年ほど ◆ ただしAndroidはほぼやった事が無い
2 サマリー ▪ AWS公式のIaaCライブラリ/ツールであるAWS CDKを使う事になった ▪ 当時のサーバー側主力言語はKotlinなのでKotlinで良い感じに書くために CDK Javaのラッパーを作る事にした ▪
CDKのコード量は膨大なので自動生成する事にした ▪ 中身が闇の魔術
3 AWS CDK Kotlin DSL概要 ▪ AWS CDK JavaのKotlinラッパー ▪
Kotlin DSL形式で書けるようにラッパー関数を多数提供 ▪ Kotlin Poetによるコード自動生成 ▪ CIによるAWS CDK Javaの更新の自動検知 ▪ GradleによるAWS CDKの新バージョン検知 -> コード生成 -> ビルド -> 公開の自動化 ▪ OSS(現在別のところに移管済み)
4 コード生成の仕組み ▪ AWS CDK JavaはjsiiというツールによりAWS CDK TypeScript のラッパーが生成されている ◆
つまりAWS CDK Javaは自動生成されたコード ▪ 自動生成されたコードなら一定のパターンが存在する ◆ 特にAWS CDKは元のコードがデータの種類が多いだけでAPIとして はほぼ同じなのでその傾向が強い ▪ AWS CDKのパッケージの全クラスをスキャンし、条件にマッ チするクラスを抽出・そのクラスのラッパーを生成する
5 生成されたコードとAPI比較 ▪ AWS CDK Java ▪ AWS CDK Kotlin
DSL ▪ 生成されたコード
6 生成されたコードとAPI比較 ▪ AWS CDK Java ▪ AWS CDK Kotlin
DSL ▪ 生成されたコード BuilderScope???
7 BuilderScope ▪ DSLの処理の実態を持っている部分 ▪ 設定可能なプロパティを全部保持し、build()でAWS CDK Java のクラスに引き渡す ▪
実質的にAWS CDK Javaのほぼ全クラスを再定義している ◆ よってファイルサイズが莫大に(S3モジュールで4700行以上)
8 生成されたコードのビルド ▪ コードの生成や成果物の公開はAWS CDKのモジュール毎に行いたい ◆ AWS CDKを全て単一のモジュールに纏めると総サイズが無駄に肥大化 ▪ ビルドはGradleで行うので、AWS
CDKのモジュールに対応した Gradleのモジュールを追加すると楽にできそう ▪ AWS CDKにどんなモジュールがあるかは生成時にしか分からない ▪ => Gradleのビルドスクリプトも自動生成すれば良い
9 ビルドスクリプトを生成するビルドスクリプト ▪ GradleにはbuildSrcという、「Gradleのビルド実行前にビルドされ、ビル ドスクリプトから参照可能」な特殊なモジュールが存在する ▪ ここにビルドスクリプトの生成処理や生成されたビルドスクリプトを用い たGradleビルドの発行処理を記述し、一定の処理単位毎にGradleのタスク 設定する ▪
ビルドスクリプトの生成自体は単純にStringリテラルを用いたテンプレー ト型 ◆ 依存関係やMavenリポジトリのクレデンシャル等が生成時に埋め込まれる
10 生成されたプロジェクトの構造 ▪ 1つの被生成コード用のプロジェクトを作成し、各モジュール をルートプロジェクトに追加 ▪ 各CDKモジュール毎に「コード生成担当」のモジュールと「被 生成コード担当」のモジュールを作成 ▪ コード生成器は事前に”dsl-generator”という名前でmavenLocal
に公開しておき、コード生成担当のモジュールが参照して利用 ▪ 被生成コード担当は依存関係等のMaven Artifactに関する設定を 主に行い、ビルド&アーティファクト生成&アップロードまで担 当 ▪ 公開用のモジュールにdsl-generatorへの依存をさせたくなかっ た 図: プロジェクト構造
11 パッケージ/モジュール管理 ▪ 生成を自動で行うにはまずAWS CDKのモジュール一覧を取得し、 コード生成を行うモジュールとバージョンの決定が必要 ▪ buildSrc内でMaven Centralの検索とスクレイピングを行う ▪
AWS CDKの更新検知のためには過去に生成を行った最新バージ ョンを知る必要があるため、AWS CDK Kotlin DSLのリポジトリ の各モジュールのmaven-metadata.xmlもスクレイピング ▪ Gradleタスク毎にこの2つの情報を組み合わせて生成対象の決定 ◆ タスク例: 指定したモジュールの最新版, 指定したバージョンの全モ ジュール, 過去の生成と最新のCDKとの差分 ▪ スクレイピングだけで数分かかる 参考: GH上のパッケージ一覧 1ページ=最大30パッケージ
12 全体の処理フロー 1. Maven CentralをスクレイピングしてAWS CDKの存在するモ ジュールの情報を取得 2. (必要であれば) AWS
CDK Kotlin DSLの過去に公開したモジュ ールをスクレイピング 3. タスクに応じて生成対象となるモジュール/バージョンの決定 4. ビルドスクリプトの生成 5. -genモジュールで生成処理 6. 被生成モジュールのビルド 7. (必要であれば)Mavenリポジトリへのアップロード&公開
13 余談 ▪ ビルドが滅茶苦茶重い & 時間がかかる ◆ スクレイピングは数が多いので地味に時間がかかる。多すぎてロー カルでバッグしてるとたまにリクエストが弾かれる。 ◆
並列ビルドを有効にすると100を超えるモジュールの並列ビルドが 走るのでCPU資源を食い尽くす。I7-8750H(6C12T)でも数分かかる。 ◆ CIだと性能が低くて並列ビルドすると余計に時間がかかる/下手する と落ちるので並列ビルドをオフにする。すると10分以上かかる。 ▪ ファイルが大きい & 数が膨大 ◆ 生成対象のモジュールの大きさにファイルサイズが比例する。1万 行超えも存在。 ◆ コード生成 & ビルドを行ったフォルダはサイズが5GB以上
14 余談 ▪ buildSrc部分のデバッグが滅茶苦茶やりにくい ◆ デバッガーが繋げないのでprintlnデバッグ ◆ デバッグ用のGradleタスクを作って試さないといけない ▪ =>
教訓: buildSrcにロジックを詰めすぎない ▪ 元々Bintrayを利用していたが突然の閉鎖で爆発四散した ◆ 移行先の検討、対応、既存のパッケージの移行、etc… ◆ GH Packagesを採用したが同時アップロードするパッケージが多い せいか時々謎のConflictが出て途中でアップロードが止まったり ◆ GH Packages, 利便性でBintrayに劣っていてつらい
15 まとめ/感想 ▪ コード生成を上手く使えば膨大なサイズのライブラリのラッパ ーを記述できたりしてQoLが上がる ▪ コード生成自体はちゃんとロジックと生成したいコードが明確 ならそれほど黒魔術ではない ▪ コード生成よりもビルドが大変
▪ Gradleは何もかも自由 ▪ ビルド芸、やりすぎると黒魔術 ▪ キャッシュの活用など、Gradleビルドの高速化にも取り組んで みたい
16 最後に ▪ justInCaseではバックエンドエンジニアを絶賛大募集中です ▪ サーバーサイドKotlin, フレークワークにSpringを使っています ▪ サーバーサイドKotlinの経験はないけれどSlerでJavaでの経験を お持ちの方もOK
▪ webフロントエンドもこれまた募集しています (TypeScript, React) ▪ 採用ページはこちら