【AWS】 CDKの始め方

## AWS CDKとは
- コードでクラウドインフラストラクチャを定義するサービスのこと
- AWS CloudFormationを介してプロビジョニングしてくれます
- 対応言語はTypeScript, JavaScript, Python, Java, C#, .NET
    - 今回はTypescriptを使用してみます
    - MacOS想定です

## チュートリアル
### AWS CDKイントロワークショップ
- https://cdkworkshop.com/15-prerequisites.html

### ドキュメント＆リファレンス
- https://docs.aws.amazon.com/cdk/index.html

## 環境構築方法

### AWS CLIをインストールする
- バージョン1をインストールします（2はβ版なので止めたほうが良い？）
- インストールにはpythonの3.4以降が必要です

```
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
```
```
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
```

### AWSユーザーを作成する
- 「プログラムによるアクセス」を許可したIAMユーザが必要なため、コンソールから作成しておきます
- ユーザを作成したら、以下コマンドでAWS CLIを実行するユーザとして設定します

```
aws configure
```
```
AWS Access Key ID [None]: <type key ID here>
AWS Secret Access Key [None]: <type access key>
Default region name [None]: <choose region (e.g. "us-east-1", "eu-west-1")>
Default output format [None]: <leave blank>
```

### Nodeをインストールする
- バージョン10.3以降をインストールします

### AWS CDKをインストールする
- 以下コマンドでインストールします

```
npm install -g aws-cdk
```

### Typescriptをインストールする
- 以下コマンドでインストールします

```console
npm install -g typescript
```

- 以上で開発環境の構築は完了です

## AWS CDKプロジェクトを作成する

### プロジェクトを初期化する
- 適当なフォルダを作成して、そのフォルダ内で初期化を行います

```
mkdir "適当なフォルダ"
cd "適当なフォルダ"
cdk init app --language typescript
```

### TypeScriptを自動でコンパイルされるようにする
- Typescriptを選んだ場合、実行前にJavaScriptにコンパイルする必要があります
- 新規ターミナルを開いて、以下のコマンドを実行します

```
npm run watch
```
- このターミナルは開いたままにしておきます
- ちなみにlambdaをTypescriptで記述する場合も自動的にコンパイルしてくれます

### 資格情報を設定する
- AWS CDKでdeployを実行する際のユーザは以下で指定できます（数字が小さい方が優先度高）
    1. cdkコマンドの--profileオプションで指定してユーザを使用する
    2. 環境変数を使用する
    3. AWSコマンドラインインターフェイス（AWS CLI）で設定されたユーザを使用する

## プロジェクト構造について
- 作成されたAWS CDKプロジェクトの構造について簡単に説明します↓

### lib/(アプリ名)-stack.ts
- メインスタックを定義するところ
- 基本的にこのファイルを編集していきます

### lib/(アプリ名).ts
- アプリのエントリーポイントで、スタックファイルをロードするところ

### cdk.json
- ツールキットにアプリの実行方法を指示するところ

### tsconfig.json
- TypeScriptの設定ファイル

## CDKで使用するコマンド

### CDKプロジェクト作成
```
cdk init [テンプレート]
```

- テンプレートはapp, lib, sample-appのいずれかを指定します
- cdkアプリケーションを作成したい場合はapp

### アプリ内のスタック一覧表示
```
cdk ls
```

### AWS CloudFormationテンプレートの作成
```
cdk synth
```

### ブートストラップ

```
cdk bootstrap
```

- アプリを初めてデプロイする際に行います
- CDKツールキットをAWS環境にデプロイします

### 差分確認

```
cdk diff
```

- デプロイする前にやっておくと安心

### アプリのデプロイ
```
cdk deploy
```

### アプリの削除
```
cdk destory
```

## CDKでHello Worldするサンプルプログラム

### スタック
- hello-stack.ts

```TypeScript
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apigw from '@aws-cdk/aws-apigateway';

export class CdkWorkshopStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // defines an AWS Lambda resource
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_10_X,    // execution environment
      code: lambda.Code.fromAsset('lambda'),  // code loaded from "lambda" directory
      handler: 'hello.handler'                // file is "hello", function is "handler"
    });

    // defines an API Gateway REST API resource backed by our "hello" function.
    new apigw.LambdaRestApi(this, 'Endpoint', {
      handler: hello
    });

  }
}
```

### ラムダ
- hello.js
- lambdaフォルダを作成して、その中においておく

```TypeScript
exports.handler = async function(event) {
  console.log("request:", JSON.stringify(event, undefined, 2));
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
    body: `Hello, CDK! You've hit ${event.path}\n`
  };
};
```

- 以上です。
- インフラ嫌いだったけどAWS CDKならインフラ好きになりそうですね