アスペクト指向プログラミング（AOP）とAWS CDK

アスペクト指向プログラミングについて学習したので、AWS CDKでどのように利用されているか調査しました。

## アスペクト指向プログラミング(AOP)とは
Aspect Oriented Programming(AOP：[アスペクト指向プログラミング](https://e-words.jp/w/AOP.html) )とは、プログラミングの概念の一種です。簡単に言うと、共通処理を抜き出して、プログラム中の様々な箇所で横断的に呼び出すことです。
例：ログ出力等

アスペクト指向プログラミングは、JavaのSprigというフレームワークでよく利用されています。以下サイトのJavaに、SprigフレームワークでAOPを実現する場合の分かりやすい解説が載っています。

https://qiita.com/ughirose/items/a7c66782f93cd1ae0d68

このサイトではJavaの[アノテーション](https://e-words.jp/w/%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html)が出てきますが、Javaのアノテーションについては以下サイトにとても分かりやすい解説が載っています。

https://qiita.com/KenyaSaitoh/items/c8ef46b3746dab8ebcef


## AWS CDK（Typescipt）におけるAOP

AWS CDK において、アスペクト指向プログラミングは[Aspects](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Aspects.html)という形で活用されています。Aspectを使うことで、Cloudformationテンプレート生成前にConstructやStack、App内の全リソースに跨る変更やテストを行えます。

例１：特定のApp中の全リソースに共通のタグを付与。
例２：特定のコンストラクト中の全S3バケットについて、バージョニングが有効化されているかチェックし、有効化されていない場合、有効化する。

https://docs.aws.amazon.com/cdk/v2/guide/aspects.html
 
## CDKのベストプラクティスとAspects
Aspectsは、<b>コンプライアンスのためにConstructを使わない</b>というCDKの[ベストプラクティス](https://aws.amazon.com/jp/blogs/news/best-practices-for-developing-cloud-applications-with-aws-cdk/) を実現するために利用されています。

### 『コンプライアンスのためにConstructを使わない』の解説

まず、<b>コンプライアンスのためにConstructを使わない</b>というベストプラクティスについて理解するため、次のような状況を考えてみます。

cdkで同じ設定のS3バケットを大量に作成することを考えます。それぞれのバケットには、プロジェクト独自のルール（例、バージョニング、KMSによる暗号化、ライフサイクルルール等）の設定が必要です。

L2コンストラクトを使用してS3バケットを作成した場合、S3バケットはAWSのベストプラクティスに準拠して作られるため、上記のプロジェクト独自のルールは反映されません。したがって、プロジェクト独自のルールの設定が必要です。

一番単純な実装方法は、べた書きで１個ずつS3の設定を書いていく方式です。しかし、この方法では似たような設定が何度も繰り返されるため、プロジェクト要件が変更になった際の修正が大変です。繰り返しを避け、修正箇所を１か所にまとめることが重要です。

繰り返しを減らす方法として、独自クラスや関数を使ったConstructを利用する構成があります。共通要素はConstruct内で定義し、バケットごとに異なる設定を引数にすることで、似たような設定のバケットを大量作成できます。しかし、この方法を実現するためには、CDKのConstructの構造に関する綿密な設計が必要となります。また、[AWS Solution Constructs](https://docs.aws.amazon.com/solutions/latest/constructs/welcome.html) のような、便利な構成をそのまま利用することができません。

Aspectsを利用することで、AWS Solution Constructsのような便利な構成を利用しつつ、プロジェクト独自の要件を満たすことができます。前述したように、Aspectsを利用することで、ConstructやStack内の全リソースに共通の設定を付与することができます。例えば、[aws-cloudfront-s3](https://docs.aws.amazon.com/solutions/latest/constructs/aws-cloudfront-s3.html)を利用してS3バケットを作成した後、Aspectsを用いて、暗号化やライフサイクル設定の変更ができます。

## まとめ
・アスペクト指向プログラミング（AOP）とは、共通処理を抜き出して、プログラム中の様々な箇所で横断的に呼び出すこと。
・AWS CDK では、Aspectsという形でAOPが利用されている。
・Aspectsを用いることで、コンストラクトやスタック内の全リソースに共通の設定ができる。
・『コンプライアンスのためにConstructを使わない』というCDKのベストプラクティスは、Aspectsを利用することで実現できる。

## 参考文献


https://aws.amazon.com/jp/blogs/news/best-practices-for-developing-cloud-applications-with-aws-cdk/

https://aws.amazon.com/jp/blogs/news/align-with-best-practices-while-creating-infrastructure-using-cdk-aspects/#:~:text=CDK%20Aspects%20%E3%81%AF%E3%80%81%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E5%86%85%E3%81%AE%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%20construct%20%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E5%85%B1%E9%80%9A%E3%81%AE%E6%93%8D%E4%BD%9C%E3%82%92%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%A7%E3%81%99%E3%80%82%20Aspect,%E3%81%AF%E3%80%81construct%20%E3%81%AE%E7%8A%B6%E6%85%8B%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E4%BD%95%E3%82%89%E3%81%8B%E3%81%AE%E6%A4%9C%E8%A8%BC%20%28%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%81%8C%E6%9A%97%E5%8F%B7%E5%8C%96%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E4%BF%9D%E8%A8%BC%E3%81%99%E3%82%8B%E3%80%81%E3%81%AA%E3%81%A9%29%20%E3%82%92%E8%A1%8C%E3%81%AA%E3%81%A3%E3%81%9F%E3%82%8A%E3%80%81%E3%82%BF%E3%82%B0%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B%E3%81%AA%E3%81%A9%20construct%20%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E4%BF%AE%E6%AD%A3%E3%82%92%E8%A1%8C%E3%81%AA%E3%81%86%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

https://dev.classmethod.jp/articles/com302-advanced-aws-cdk-lessons-learned-from-4-years-of-use-com302-participation-report/

https://zenn.dev/intercept6/articles/629e160efd629f

https://dev.classmethod.jp/articles/aws-cdk-use-aspect/