AWS-CDK使ってみた件

# AWS-CDKとは何ぞや

AWSの環境定義を"Java", "TypeScript", "JavaScript"の言語で定義するCDK（Cloud Development Kit）だそうな。

開発者レビューにも記載があるとおり、".NET", "Python"が近々対応予定とのこと。

個人的にはRubyもお願いしたいところではある。

以下を参考にしながらお試しでいじってみた。

- 参考ドキュメント
 - [開発者レビュー](https://aws.amazon.com/jp/blogs/news/aws-cdk-developer-preview/)
 - [公式git](https://github.com/awslabs/aws-cdk)
 - [公式ドキュメント](https://awslabs.github.io/aws-cdk/index.html)
 - [スタートガイド](https://awslabs.github.io/aws-cdk/getting-started.html)

# さっそくいじる

スタートガイドとリファレンスを読みながら試す。

## 検証環境
CentOS 6

## 必要なものをそろえる

- aws-cli
- Node.js (8.11.x 以上)
- aws-cdk

### aws-cli
pipがない場合、pipをインストール。
もしpipのインストールで `SyntaxError` がでる場合はPythonのバージョンが古いことが原因だったりするので
 `$ curl -O https://bootstrap.pypa.io/2.6/get-pip.py` で古いバージョンを持ってくる。

```
$ curl -O https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py --user
```

pip を使用してaws-cliをインストール

```
$ pip install awscli --upgrade --user
```

認証情報設定

```
$ aws configure
AWS Access Key ID [None]: AKIAIOSFO***********
AWS Secret Access Key [None]: wJalrX**********************************
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

### Node.js
ただ単に`sudo yum -y install nodejs`を叩いても古いバージョンがインストールされてしまうので以下を `root` でうつ。

```
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -
```

インストール実行/確認

```
$ sudo yum -y install nodejs

$ node -v
v8.11.4
```

### aws-cdk
スタートガイドのコマンドを叩くだけ。

```
$ npm install -g aws-cdk

$ cdk --version
0.9.0 (build b222731)
```


## プロジェクト作成

①ディレクトリ作成/移動

```
$ mkdir hello-cdk
$ cd hello-cdk
```

②プロジェクトの初期化（今回はtypescriptを使用）

```
$ cdk init app --language typescript
Applying project template app for typescript
Initializing a new git repository...
Executing npm install...
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN hello-cdk@0.1.0 No repository field.
npm WARN hello-cdk@0.1.0 No license field.

# Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template
```

```
$ ls
bin  cdk.json  node_modules  package.json  package-lock.json  README.md  tsconfig.json
$
$ ls bin/
hello-cdk.d.ts  hello-cdk.js  hello-cdk.ts
```

bin配下にはサンプルアプリケーションが配置される

## AWS CDKコアライブラリ（@aws-cdk/cdk）をインストール

```
npm install @aws-cdk/cdk @types/node
```

その他ライブラリが必要な場合は[リファレンス（2018/09/13時点で最新のver0.9.0）](https://awslabs.github.io/aws-cdk/versions/0.9.0/reference.html)を見て適宜インストール。

## AWS CDKアプリケーション作成

空のアプリケーションファイル`index.ts`の作成

```
$ cat bin/index.ts
import cdk = require('@aws-cdk/cdk');

class MyApp extends cdk.App {
    constructor(argv: string[]) {
        super(argv);
    }
}

process.stdout.write(new MyApp(process.argv).run());
```

作成後ビルド（ts -> js）

```
npm run build
```

エラーがでなければ問題なし

## 実行プログラム指定

プロジェクトのルートディレクトリの`cdk.json`を編集

```
$ cat cdk.json
{
  "app": "node bin/index.js"
}
```

## スタックリスト確認

プロジェクトフォルダ内で`cdk ls`コマンドを叩く（現時点では空の状態）

```
$ cdk ls -l
[]
```

## スタック定義

`index.ts`に追記

```
$ cat bin/index.ts
import cdk = require('@aws-cdk/cdk');

class MyStack extends cdk.Stack {
    constructor(parent: cdk.App, id: string, props?: cdk.StackProps) {
        super(parent, id, props);
    }
}

class MyApp extends cdk.App {
    constructor(argv: string[]) {
        super(argv);

        new MyStack(this, 'hello-cdk');
    }
}

process.stdout.write(new MyApp(process.argv).run());
```

追記後ビルド

```
$ npm run build
```

## 再度スタックリスト確認

プロジェクトフォルダ内で`cdk ls`コマンドを叩く

```
$ cdk ls -l
-
    name: hello-cdk
    environment:
        name: <AWSアカウントID>/<デフォルトリージョン>
        account: '<AWSアカウントID>'
        region: <デフォルトリージョン>

```

# ためしにEC2インスタンスを立ててみる

## EC2のライブラリをインストール

```
npm i @aws-cdk/aws-ec2
```

## 定義修正

個人の環境の合わせて修正。

```
$ cat bin/index.ts
import cdk = require('@aws-cdk/cdk');
import ec2 = require('@aws-cdk/aws-ec2');

class MyStack extends cdk.Stack {
    constructor(parent: cdk.App, id: string, props?: cdk.StackProps) {
        super(parent, id, props);

        new ec2.cloudformation.InstanceResource(this, 'MyInstance', {
            imageId: 'ami-XXXXXXX',
            instanceType: 't2.small',
            subnetId: 'subnet-XXXXXXXX',
            monitoring: false
        });
    }
}

class MyApp extends cdk.App {
    constructor(argv: string[]) {
        super(argv);

        new MyStack(this, 'hello-cdk');
    }
}

process.stdout.write(new MyApp(process.argv).run());
```

その他鍵ファイルやプライベートアドレスを指定する場合はリファレンスを参照。

## yamlで確認

```
$ cdk synth
Resources:
    MyInstance:
        Type: 'AWS::EC2::Instance'
        Properties:
            ImageId: ami-XXXXXXX
            InstanceType: t2.small
            Monitoring: false
            SubnetId: subnet-XXXXXXXX
    CDKMetadata:
        Type: 'AWS::CDK::Metadata'
        Properties:
            Modules: '@aws-cdk/aws-ec2=0.9.0,@aws-cdk/aws-elasticloadbalancing=0.9.0,@aws-cdk/cdk=0.9.0,@aws-cdk/cx-api=0.9.0,hello-cdk=0.1.0,js-base64=2.4.5'
```

## デプロイ

```
$ cdk deploy
 ⏳  Starting deployment of stack hello-cdk...
 [0/7] Currently in progress: 
 ✅  Deployment of stack HelloCdkStack completed successfully, it has ARN arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/hello-cdk/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX hello-cdk
```

## 確認

スタックが成功し、インスタンスが立ち上がっていれば問題なし。

aws-cliからでも確認可。

# 最後に

今回はTypeScriptを使用したが、これからPythonも使えるので今後に期待。

2018/9/13時点では最新バージョンは0.9.0となっているが、サポートしているサービスがかなり多いので興味ある人はいじってみるといいと思う。