0
0

More than 1 year has passed since last update.

AWS CDK WorkshopをJavaでやってみた

Posted at

概要

AWS CDK WorkshopをJavaでやってみた。
その際に感じたことのメモ。

前提

OS: macOS Ventura 13.2
プロセッサ: 2.4 GHz 8コアIntel Core i9
cdkのversion: 2.63.2 (build e08e34a)

New Project

(自分用メモ)cdkコマンドをインストール

npm install -g aws-cdkコマンドを実行する。

cdk init

上記ページの通り、ディレクトリを作って cdk init をする。 Executing 'mvn packageが長くかかったが焦らず待つ。

Project structure

上記ページの通りの構成になっていることを眺める。
なんとなくSQS,SNSのことを操作していることを感じ取る。

cdk synth

上記ページに従ってcdk synthを実行すると、標準出力にCloudFormationのtemplateが出力される。

cdk deploy

ここから実際にAWS上にリソースを作ることになるので若干慎重に。

まずaws sts get-caller-identityして、aws cliの向き先があっていることを確認する。

ここからはこのページに従って、まずcdk bootstrapする。
これでCloudFormationスタックとしてAWS CDKが利用するリソースを準備できる模様。

そこからmvn packageして、cdk deploy実行する。
下記のような感じでどんな影響が出るか確認できる。

IAM Statement Changes
┌───┬─────────────────────────┬────────┬─────────────────┬───────────────────────────┬─────────────────────────────────────────────────────────┐
│   │ Resource                │ Effect │ Action          │ Principal                 │ Condition                                               │
├───┼─────────────────────────┼────────┼─────────────────┼───────────────────────────┼─────────────────────────────────────────────────────────┤
│ + │ ${CdkWorkshopQueue.Arn} │ Allow  │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": {                                          │
│   │                         │        │                 │                           │   "aws:SourceArn": "${CdkWorkshopTopic}"                │
│   │                         │        │                 │                           │ }                                                       │
└───┴─────────────────────────┴────────┴─────────────────┴───────────────────────────┴─────────────────────────────────────────────────────────┘

終わるとSQS,SNSのリソースが作成されている。

Hello, CDK

API GatewayとLambdaを使ったサンプルを作っていきますよ、と。

Cleanup sample

コードからSQS, SNSの記述を消し去り(テストも消す)、再度デプロイする。

cdk diffして、差分を確認できる。terraform planみたいなものかな。

┌───┬─────────────────────────────────┬────────┬─────────────────┬───────────────────────────┬─────────────────────────────────────────────────────────────────┐
│   │ Resource                        │ Effect │ Action          │ Principal                 │ Condition                                                       │
├───┼─────────────────────────────────┼────────┼─────────────────┼───────────────────────────┼─────────────────────────────────────────────────────────────────┤
│ - │ ${CdkWorkshopQueue50D9D426.Arn} │ Allow  │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": {                                                  │
│   │                                 │        │                 │                           │   "aws:SourceArn": "${CdkWorkshopTopicD368A42F}"                │
│   │                                 │        │                 │                           │ }                                                               │
└───┴─────────────────────────────────┴────────┴─────────────────┴───────────────────────────┴─────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[-] AWS::SQS::Queue CdkWorkshopQueue50D9D426 destroy
[-] AWS::SQS::QueuePolicy CdkWorkshopQueuePolicyAF2494A5 destroy
[-] AWS::SNS::Subscription CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106 destroy
[-] AWS::SNS::Topic CdkWorkshopTopicD368A42F destroy

差分を確認して、cdk deployすると、コードから消したリソースがAWSからも消える。

Hello Lambda

lambdaにjsのコードをあげてみる。
書きながら、どんなリソースを作ろうとしているのか理解していく。
lambdaの作成は手順に従っていけばすんなりできる。

このページで、簡単にcdkのsdkで提供しているクラスの概念的なものを説明している。
cdkのsdkで提供されているクラスはconstruct(何かの要素を組み合わせてできたもの、というイメージ?)であると説明している。
constructを組み合わせたものがconstructを構成するという、入れ子なイメージ。
また、各クラスのコンストラクタが(scope, id, props)というシグニチャを持っており、それらが何を意図しているか説明している。

  • scopeはそのconstructが作成されたscope(scopeとは?という気持ちになるが我慢して進める。コンテキスト、みたいなイメージか?)を指し示す。基本的にthisを渡す。
  • idはconstruct内で一意になる値を渡す。
  • propsは各constructの性質によって取りうる値が異なる。lambda.Functionならruntime,code,handlerなど

CDK Watch

lambdaのコードだけ変えるのに、cdk deployするのだと時間かかってしょうがないよね。。?みたいな問題提起からこの章は始まる。
cdk deploy --hotswapを使えば、cloud formationを経由せずにデプロイできるため、デプロイ時間短縮につながる。

実際、この章でやってるコマンドを私の環境でやってみたところ、普通のcdk deployだと40s近かったが、cdk deploy --hotswapだと10秒くらいで完了した。

そして、CDKではcdk watchコマンドなるものを用意している。
手元でcdk watchコマンドを流しておけば、コードの変更を勝手に検知して、AWSリソースに変更を加えてくれる。
コードに変更を加えた際にhotswapで変更可能(cloud formationを介さくても良い変更)であればhotswapでデプロイし、そうでなければcloud formationでデプロイする。

手元でcdk watchを試してみたところ、lambdaにあげているjsファイルを変更した際にはhotswapでのデプロイが走り、lambdaのhandler名を変えた場合にはcloud formationを介したデプロイが走った。

API Gateway

API Gatewayを上で作成したLambdaの前段に置いてあげましょう、という章。
コードを記述してcdk deployすると、標準出力に

Outputs:
CdkWorkshopStack.Endpoint~~~~~~~~ = https://~~~~~~~~~~~~.execute-api.ap-northeast-1.amazonaws.com/prod/

みたいな感じでエンドポイントが表示されるのでcurlなりブラウザなりでアクセスできる。

Writing constructs

これまでの構成要素にDynamoDBを加えて、URLをアクセスした回数をカウントするようにする。

Define the HitCounter API

HitCounter.javaなるクラスと、HitCounterProps.javaなるインターフェースを作成する。

Hit counter Lambda handler

hitcounter.jsなるLambdaにあげるファイルを作成する。
hitcounter.jsを記述するにあたって必要なLambdaの識別子、DynamoDBの接続先はdeployの際に確定するので、コード上は環境変数としている。
これらはconstructのコード(Javaのコード)に記述していく。

Define resources

HitCounter.javaにDynamoDBのリソース定義とLambdaのリソース定義を記述している。
1つ前の章で言及した環境変数は、ここで注入するためのコードを書いている。

Use the hit counter

CdkWorkshopStack.javaHitCounter.javaというconstructを利用する旨を記述する。
API Gatewayからはhitcounter.jsを携えたlambdaを呼ぶようにする。

この状態でcdk deployしたものにアクセスすると502 Bad Gatewayになる。

CloudWatch Logs

CloudWatchにエラーをみにいく方法が書いてある。DynamoDBに書き込みにいく権限が無さげなエラーが出ていることがわかる。
(Lambdaあまり使ってない勢からするとこういうエラー解析の説明はかなり助かる)

Granting permissions

hitcounterのLambdaから、DynamoDBとhelloのLambdaを叩く権限を与える。
すると、200が返るようになる。

Test the hit counter

色々なパスにアクセスして、DynamoDBのコンソールから正しくカウントされていることを確認する。

また、HitCounterは再利用可能で、maven centralにあげて、誰でも容易に同じようなことができるよ、と言及している。

Using construct libraries

cdk-dynamo-table-viewerというconstructのライブラリを利用して、Webページからhitcounterのテーブル情報をみれるようにする。

Learning about the Table Viewer construct

cdk-dynamo-table-viewerの紹介。
ざっとみた感じ、DynamoDBから情報を取得し、それを元にhtmlを組み立て返すLambdaを作成しているようだった。
(TypeScriptで記述されているっぽいが、これをどうやってJavaのライブラリとして固めているんだ、、?jsiiがよしなにやってくれるのだろうか)

あと、これは権限制御とかせずにDynamoDBの中身が見れちゃうので本番では使うなよ、と。

Installing the library

pom.xmlにライブラリの設定を加える。

Add a table viewer to your stack

上記ライブラリ由来のconstructを加えるコードをCdkWorkshopStack.javaに付け足す。

Deploying our app

cdk deployしてブラウザから、どのパスに何回アクセスしたか見れることを確認する。

また、Constuctライブラリは便利な反面、IAMの権限などをいじったりするので、信頼できるもの以外は使わないようにとの注意喚起をしている。

Extra credit

ブラウザ表示された表はhitsの降順であるとのこと。
(extra creditは、おまけ、みたいな意味なのだろうか)

Clean up

cdk destroyで作ったリソースを消していく。
この際、DynamoDBのテーブルはデフォルトの設定だと残り続けるので、明示的にRemovalPolicy.DESTROYの設定を入れてやることで消せるようになる。

また、CloudWatch Logsのログは手で消すしかないとのこと。

所感

私の環境だと全く詰まることなく実行できた。

IaCはこんなに進んでいるのか、という感想を得た(今更感)。

特にcdk watchのあたりはリアルタイムにローカルのコードがAWSに反映されており、開発スピード向上に役立ちそうである。

実際に導入するとなると、

  • test、staging、productionの資材をどう書き分けるか
  • ディレクトリ構成をどうするのか
  • 汎用化したクラスを作るべきなのか(terraform のmoduleみたいな感じで)

とかを考える必要がありそう。この辺はどんなIaCツールを使おうとも考慮が必要だろう。

cdkの対抗馬として考えるならterraform。
例えばJavaを専門に扱っているチームなのであれば、JavaでやってしまえばHCLを新たに覚える必要はなくなるので良いのかなぁ。(AWSを離れるという選択がありうる場合はterraformの方が安心感はあるが)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0