AWSCDKがGAになったのでAPIGateway+Lambdaをデプロイしてみる

# はじめに

以前から気になってアップデートを追いかけていた **AWS CDK** がついにGAになりました :tada: 
https://aws.amazon.com/jp/blogs/aws/aws-cloud-development-kit-cdk-typescript-and-python-are-now-generally-available/

AWS CDK とはAWSが公式でメンテしている **AWS構成管理ツール** です
大きな特徴としては、TypeScriptやPythonからCloudFormationのテンプレートファイルを生成してくれるという点です。
今まで半泣きになりながら書いていたYAMLファイルを、もう書かなくてもいいってことですw
特に普段からTypeScriptを使っている自分に対しては、ほんとにどストライクなツールでした…
ただ開発者プレビューということで、アップデートされるたびに破壊的な変更が発生して、アップデートを追いかけるのが大変だったのだけ覚えています…
そんな AWS CDK がGAになったということで、AWS上にRESSTAPIを構築する際の鉄板構成である「APIGateway+Lambda」をCDKでデプロイしてみようと思います！

## 環境構築

### AWS-CDK インストール

```terminal
$ npm i -g aws-cdk
```

### プロジェクト作成

```terminal
$ mkdir cdk-demo
$ cd cdk-demo
$ cdk init app --language=typescript
```

これでTypeScriptでCDKを書いてく準備ができました

## 書くぞ！！！

ということで今回は TypeScript で書いていきます

```ts:qiita_api_lambda.ts
import cdk = require("@aws-cdk/core")
import { Function, Runtime, Code } from "@aws-cdk/aws-lambda"
import { RestApi, Integration, LambdaIntegration, Resource,
  MockIntegration, PassthroughBehavior, EmptyModel } from "@aws-cdk/aws-apigateway"

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

    // Lambda Function 作成
    const lambdaFunction: Function = new Function(this, "qiita_demo", {
      functionName: "qiita_demo", // 関数名
      runtime: Runtime.NODEJS_10_X, // ランタイムの指定
      code: Code.asset("lambdaSoruces/demo_function"), // ソースコードのディレクトリ
      handler: "index.handler", // handler の指定
      memorySize: 256, // メモリーの指定
      timeout: cdk.Duration.seconds(10), // タイムアウト時間
      environment: {} // 環境変数
    })

    // API Gateway 作成
    const restApi: RestApi = new RestApi(this, "QiitaDemoAPI", {
      restApiName: "QiitaDemoAPI", // API名
      description: "Deployed by CDK" // 説明
    })

    // Integration 作成
    const integration: Integration = new LambdaIntegration(lambdaFunction)

    // リソースの作成
    const getResouse: Resource = restApi.root.addResource("get")

    // メソッドの作成
    getResouse.addMethod("GET", integration)

    // CORS対策でOPTIONSメソッドを作成
    getResouse.addMethod("OPTIONS", new MockIntegration({
      integrationResponses: [{
        statusCode: "200",
        responseParameters: {
          "method.response.header.Access-Control-Allow-Headers":
            "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
          "method.response.header.Access-Control-Allow-Origin": "'*'",
          "method.response.header.Access-Control-Allow-Credentials": "'false'",
          "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE'",
        }
      }],
      passthroughBehavior: PassthroughBehavior.NEVER,
      requestTemplates: {
        "application/json": "{\"statusCode\": 200}"
      }
    }), {
      methodResponses: [{
        statusCode: "200",
        responseParameters: {
          "method.response.header.Access-Control-Allow-Headers": true,
          "method.response.header.Access-Control-Allow-Origin": true,
          "method.response.header.Access-Control-Allow-Credentials": true,
          "method.response.header.Access-Control-Allow-Methods": true,
        },
        responseModels: {
          "application/json": new EmptyModel()
        },
      }]
    })
  }
}
```

```ts:cdk-app.ts
import "source-map-support/register"
import cdk = require("@aws-cdk/core")
import { QiitaAPILambda } from "./qiita_api_lambda"

const app: cdk.App = new cdk.App()
new QiitaAPILambda(app, "QiitaAPILambdaStack")
app.synth()
```

## デプロイする

TSをJSにtscでコンパイルしてデプロイコマンドを実行するだけです

```terminal
$ yarn build
$ cdk deploy
```

## さいごに

どうですか？簡単でしょう？(語彙力w)
ちなみに `cdk synth` というコマンドを実行すると、jsonのCFnテンプレートがローカルに生成されます
これを見てどのように変換されているのか確認するのもいいかもしれません
ではまた！！！