AWS Black Belt Online Seminarで学んだAWS Cloud Development Kit (CDK) をまとめる

会社でAWS CDKに触れる機会があったため、一度動画を見て学ぶことに。
視聴した動画は[こちら](https://www.youtube.com/watch?v=1i7kWqpqtoY&t=452s)

## AWSの環境を構築するには

AWS環境を構築する上でマネジメントコンソール、スクリプト（SDK,CLI）、プロビジョニングツール、DOMsと環境構築の管理レベルは上がってきた。一方でそんな環境定義を抽象化する機能が組み込まれることは少なく、定義を作り込むのが大変だった。それを解決するがごとく現れたのがCDK。

`CDK = あるべき状態の定義のコード化 + 抽象化`

## AWS CDKの紹介
一言で言えばAWS環境をプログラミング言語で記述できるツールキット。

### 特徴
* ソースコードからCloudFormationテンプレートを作成
* AWSのベストプラクティスが定義されたライブラリ（Construct）によって少ないコードで記述できる
* オープンソースなのでユーザが拡張可能
* 対応言語はJavaScript、TypeScript、Python、Java、C#

### CDKのメリット
* 一般のプログラミング言語が使える
  * 制御構文だけでなく、クラスや継承など抽象化の概念も使える
  * エディタを使って型チェックや補完もできる
* コード量が少なくなる
* テストコードを記述できる
* 複数スタック間の依存関係を記述できる
* バックエンドがCloudFormation

### CDKのデメリット
動画の中ではデメリットの紹介はなかったが個人で思うところを記載する
* マイナーバージョンのアプデ（週1がざら）が多く、その中には破壊的変更がある時もあるのでメンテは大変そう

### CloudFormationとの位置付け
* デプロイ自体は最終的にCloudFormationで行われる
* 詳細な設定にはCloudFormationと同様の記載が必要
* 従来の資産やSAMの活用はCloudFormation


## How to use AWS CDK

### 開発環境準備
#### 1. 事前に必要なもの
* AWS CLI
* Node.js 10.3.0以上の環境（Windows:MSIインストーラ/ Mac:homebrew & nodebrew）。準備には [こちら](https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09)の記事が参考になるかも。

#### 2. CDKの導入
```console
$ npm install -g aws-cdk
```

#### 3. 各言語の開発環境を用意（エディタ含め）

#### 4. 初期コードを生成
```console
$ cdk init app --language=typescript
```

サンプルコード付きはこっち↓らしい
```console
$ cdk init sample-app --language=typescript
```
#### 5. あとはコーディングするだけ


### デプロイ
作成するためのアカウント情報の設定は事前に必要

#### 1. CDKデプロイ管理用の環境（S3バケット）を作成 ※初回のみ
```console
$ cdk bootstrap
```

#### 2. ビルドとCloudFormationテンプレートの作成

ビルド（例：Typescript）
```console
$ npm run build
```

CloudFormationテンプレートの作成
```console
$ cdk synth [STACKS..]
```

#### 3. デプロイ
デプロイに利用するコマンドは次のコマンド。
```console
$ cdk deploy [STACKS..]
```

すべてのスタックをデプロイする場合は次のコマンド。
```console
cdk deploy --all
```

cdkによってデプロイしたものを削除したい場合は
```
$ cdk destroy [STACKS..]
```

## コアコンセプト
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2296212/17b23d84-adff-7b9e-cc6d-595c7a02765e.png)](https://youtu.be/1i7kWqpqtoY?t=2123)

### App
* CloudFormationテンプレートの作成とデプロイに利用する最上位要素
* 複数のStackとその依存関係を定義

### Stack
* CloudFormation Stackに該当し、デプロイ可能な最小単位
* リージョンとアカウントを保持

### Construct
* Stackに作成されるAWSリソース
* 標準でAWS Construct Libraryを提供
* 独自に定義したり配布可能

#### さらに具体的に
##### AWS Construct Library
* High-level constructs(L2)
  * デフォルト値や便利なメソッドを定義したAWSリソースを表すクラス

* Low-level constructs(L1)
  * CloudFormationリソースおよびプロパティと1:1で対応（自動生成)
  * CfnXXという名前（例：s3.CfnBucketはAWS::S3**Bucketを意味）
  * すべてのプロパティを明示的に設定する必要がある

* Patterns
  * 複数のリソースを含む一般的な構成パターンを事前定義したもの（aws-esc-patterns.LoadBalancedFargateServiceなど）

### アプリケーションに外からパラメータを渡す場合に利用できる
Environment/ Context/ SSM ParameterStore / SecretManager

#### Environment
* デプロイ先となるアカウントとリージョンの組み合わせ
* デプロイ先は明示することが推奨されてる
* cdkコマンドで --profileオプションを指定した場合はCDK_DEFAULT_ACCOUNT,CDK_DEFAULT_REGIONで参照可能

#### Context
パラメータ指定で一番よく使われるもの

* CDKコードを実行するための各種パラメータ(Dev/Prd とか)をキーバリュー型で定義
  * 最新のAMI IDが変わるなどで意図せぬ変更を防げる
  * Contructが情報を持ち、 `this.node.tryGetContext('key')` のようにアクセス
  * `cdk context` で参照可能

* 定義方法
  * `cdk --context key=value` で指定
  * cdk.jsonファイルに指定
  * ~/.cdk.jsonファイルに指定
  * コード内で `construct.node.setContext()` で指定

* CDKコードで既存環境から情報を参照可能
  * stack.availavilityZones(),Vpc.fromLookup()など  
 

#### SSM ParameterStore / SecretManager
cdk.jsonなどは手元にある情報だが、複数での開発やシステム全体で特定の値を見たいときに使う。 `cdk synth`時またはデプロイ時に値を取得できる。

* SSM ParameterStore
  * aws-ssm.StringParameter.valueForLookup()
    * `cdk synth` 時に値を取得 
  * aws-ssm.StringParameter.valueForStringParameter()
    *  デプロイ時にプレーンテキストを取得
  * aws-ssm.StringParameter.valueForSecureStringParameter()
    *  デプロイ時にセキュアな文字列を取得
    *  渡せる場所はCloudFormationの仕様に従う

* SecretManager
  * aws-secretsmanager.Secret.fromSecretAttributes()
    * デプロイ時にセキュアな文字列を取得 


## DiveDeep
CDKの開発を好む人向けの話

### jsii
Javascriptで書かれたクラスに他の言語からアクセスするためのコンパイラ。
これによりマルチランゲージの実装が可能となる。

### CDK RFCs
CDKの新機能の方向性を検討するDesign Docsのリスト。

### FeatureFlags
CDKの新バージョンで破壊的変更が行われた場合に古い仕様のコードも正しく動作可能とするために導入されたフラグ。
* ランタイムコンテキスト（cdk.json または ~/.cdk.json）に設定。
* 設定可能なすべての値はfeature.tsに記載

### CDK Node.js Lambda Construct 
LambdaとCDKのコードをすべてTypeScriptで一括開発&デプロイできるライブラリ。LambdaとCDKで同じモジュールを参照して開発できる。故にCDKのソースとLambdaのソースを別で管理しなくても済む。