AWS CDK オレオレベストプラクティス集

仕事でAWS CDKを使っています(Python)。

とても便利なのですが、適当に書いていたのですぐツラくなりました。

そこでオレオレベストプラクティスをまとめました。誰かの参考になれば嬉しいです。

(あくまで俺のベストプラクティスです。他の人にとってベストかどうかわかりません。公式と意見が違うかもしれません。話半分に聞いてください。)

# CDK以外のドキュメントも参照する
[公式ドキュメント](https://docs.aws.amazon.com/cdk/api/latest/python/modules.html)だけでは説明が不十分なことがあります。[CloudFormation](https://docs.aws.amazon.com/cloudformation/)はもちろん[boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)のドキュメントも参照しましょう。

例えば[SageMakerCreateTrainingJob](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_stepfunctions_tasks/SageMakerCreateTrainingJob.html)パラメーターの一つに

```hyperparameters (Optional[Mapping[str, Any]]) ```

とあります。これは機械学習モデルに渡すパラメーターなのですが、``Any``なのでこれだけではなにが必要なのかわかりません。(これ、別のコンストラクターではこの手のパラメーターが必須の場合もあります。)

そういう場合にはboto3やCloudFormationのドキュメントも参照してください。

あくまで経験ですが、CloudFormationは特定のパラメーターの説明がCDkのドキュメントよりも詳しい気がします。また、Boto3にはリソースの操作に必要なjsonの例が書いてあることがあります。

どちらを見てもさっぱり、というときはコンソール上のリソース作成画面も見てみましょう。

# まずはコンソールで

扱いに慣れないリソースをいきなりCDKでつくるとたいていドハマりします。一回コンソールで作ってみることをおすすめします。

例えば[Glueクローラー](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/setup-vpc-for-glue-access.html)。コネクションを作ったり、セキュリティグループに少し設定が必要だったりと設定がちょっと大変です。

コンソールから作っても、設定が漏れていてうまく動かないことがよくありました。

使うリソースにもよりますが``cdk deploy``は多少時間がかかります。ドハマリして修正を繰り返すと時間が溶けていきます。

こういうリソースはまず、コンソールで作ってからコード化してみると良いです。そうすると設定項目の意味もよくわかります。

# コードは細分化する

1ファイルにどかっと書いていくと死にます。

例えばStepfunctionのように複数のサービスを連携させる場合。

- 個別のサービスを定義して、
- 各プロセスの監視をLambdaでして
- 状態によってはワークフローを分岐させて

とやっていくとどんどんコードが増えます。

CDKのコンストラクター名は長くて、よく似ています。わけがわからなくなってきます。
(実際分割せずに適当に書き始めたコードベースはすぐにイミフになりました。)

Stackなど別クラスにしても良いです。

そうでなくとも、単純に別ファイルの別関数にするだけでも整理がつきます

# サービスの名前でフォルダをわける

細分化するとファイル数が増えてきます。フォルダ分けしたほうがいいですね。どう分類しましょう?

・・・サービス名でやってみては?

``lambda/do_foobar/code/handler.py``
``lambda/do_foobar/infra/infra.py``

などです。Lambdaはファンクションのコードとファンクション自体の設定の両方を書くことができます。Lambdaを複数使うとなるとこれが複数に。

さらにGlueも使う、となるとGlueのコードも入ってきます。

(別にこの方法でなくともよいと思います。ただ整理方法はきちんと決めたほうが良いでしょう。)

# すべてを管理しようとしない

CDKで作ったものはCDK(正確にはCloudFormation?)で管理し続けたほうが良いです。CDKで作ったのに、コンソールで変更してしまうと、以降CDKでうまく変更できなかったり、意図しないことが起きたりします。

誰かがコンソールから触るかも? と思ったらおとなしくコンソールで作ったほうがいいかもしれません。

検証環境で実験として、CDKで作ったリソース(たしかRDS)をコンソールから設定変更したことがあります。このときは``cdk deploy``のときにエラーが出て止まりました。CDKで作ったEC2をコンソール上から停止してみたこともあります。このときは``cdk deploy``すると停止したのと同じEC2が新しくできました。

また、作成や設定がそれほど複雑でないリソース、あまり変更を加えそうにないリソースはコンソールで作ることも考えてください。

扱いに慣れているリソースでも、CDKのドキュメントを見ながら設定をしていくのはなかなか大変な作業です。

「コンソールだったらここをチェックするだけなのは知ってる。でも、CDKではどう書いたらいいの?困ったね。」というのはよくありました。

# TypeScriptもやったほうがいい
[CDKのコードベース](https://github.com/aws/aws-cdk)はTypeScriptです。

このためTSのコード例が豊富。Pythonだけでなく、TSがある程度読めると参照できる資料が増えます。

また、TSもPythonもどっちも同じくらいやれるよ、という方はTSを選ぶのをおすすめします。[テスト](https://docs.aws.amazon.com/cdk/latest/guide/testing.html)がPythonには対応していないからです。

# Boto3+Lambdaでやることも考える
CDKは発展途上のライブラリーです。AWSのAPIすべてを扱えるわけではありません。

例えば、Stepfunction上でSagemakerをコントロールする場合。
[一通り揃っている](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_stepfunctions_tasks/README.html#sagemaker)ように見えますがそうではありません。

ModelPackageからモデルを作る、モデルを削除する、などは未対応です(2021年10月時点)。

途中が歯抜けになるぐらいなら、全てBoto3でやってもいいかもしれません。

ただし、Boto3の処理は非同期なことを忘れないでください。実行中の処理が終わったかどうか確認する処理を入れないと、次の処理に渡すものがないのに次に進んでしまって、処理が止まります。

# 参考になる資料

- [aws-cdk-examples](https://github.com/aws-samples/aws-cdk-examples)
  - 活用例を探すならまずはここ。
- [AWS Samples](https://github.com/aws-samples)
 - 漁るとCDKの活用例がたくさん出てくる。

- [SIEM on Amazon OpenSearch Service](https://github.com/aws-samples/siem-on-amazon-opensearch-service)
 - AWS上の各種ログをまとめてくれる。一部CDK。