terraform-cdk で AWSにリソースをdeployする


Sensyn Robotics の開発部マネージャー伴です。

皆さん[AWS CDK(Cloud Development Kit)](https://aws.amazon.com/jp/cdk/)はご存知でしょうか。
そうです。あのCloudFormationやSAMのテンプレート書き地獄に一筋の光が ...

個々のリソースだけでなくインフラ構成のベストプラクティスがクラス化されており、そのクラスをカスタマイズして使うことが出来て、よくあるパターンのインフラ構成であればわざわざ1から依存関係を整理してリソース定義を書かなくても良くなるとても素敵なツールです。

TypeScript, JavaScript, Python, Java, C#でインフラ構成を定義出来て、cliからデプロイ可能になります。
CIにもシンプルに組み込めそうです。


そして先日そのCDKでプロバイダーとしてterraformが使える [terraform-cdk](https://github.com/hashicorp/terraform-cdk) なるものが発表され注目していました。
CDKのプロバイダーとしてterraformを使うことで、AWSのみならず他のクラウドプラットフォームのリソースも管理出来るようになる優れものです。

良い機会なので、[terraform-cdk](https://github.com/hashicorp/terraform-cdk)を用いて実際にAWSにリソースをデプロイしてみようと思います。


# 手順
### 前提条件
OS: macOS

下記をインストール

- terraform
- Node.js
- npm


### 1. [terraform-cdk-example](https://github.com/Banchi0123/terraform-cdk-example) を clone  
[terraform-cdkのリポジトリのexamples](https://github.com/hashicorp/terraform-cdk/tree/master/examples)をそのまま使おうと思ったのですが、まだ少しバグがあったりドキュメントが足りないところがあったので、本記事用にテンプレートリポジトリを作って公開しました。

### 2. 必要なパッケージのインストール
`cd terraform-cdk-example`
`npm install`

### 3. cdktf.json にプロバイダと利用言語を設定
サンプルをそのまま動かす場合は編集不要です。
[example](https://github.com/Banchi0123/terraform-cdk-example)では`language`を`typescript`に設定、`terraformProviders`には`aws`のみ指定しています。  
GCPやAzureなど他のプロバイダを使う場合は`terraformProviders`に追加してください。
例: https://github.com/hashicorp/terraform-cdk/blob/master/examples/typescript/google/cdktf.json

### 4. ビルド
`npm run build`  
※ `cdktf get` が実行されて cdk-terraform用のawsプロバイダ等が　`.gen` ディレクトリに格納されます。

### 5. tfファイルの生成
`npm run synth`
※ `cdktf.out` の中に `cdk.tf.json` が作られます。

### 6. デプロイ用アクセスキーの作成
AWS IAM上で、DynamoDBのテーブルのcreate/deleteが出来る権限を付与しユーザー作成し、アクセスキー/シークレットキーを取得
(参考: [公式Doc](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_create.html#id_users_create_console)) 

### 7. デプロイ用アクセスキーの設定
`cdktf.out` の中の下記部分（20行目あたり）にアクセスキーを追記します。（本当はvar等から利用するように出来ると良いです）

```json
  "provider": {
    "aws": [
      {
        "region": "ap-northeast-1",
        "access_key": "[YOUR_ACCESS_KEY]", ←追加
        "secret_key": "[YOUR_SECRET_KEY]"  ←追加
      }
    ]
  }
}
```

### 8. Plan & Apply 
`npm run plan`
`npm run apply`

※ここは `cd ./cdktf.out` してから `terraform plan` と `terraform apply` してるだけです。

こんなログがterminalに出ます。

```terminal
> cd ./cdktf.out && terraform apply


An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_dynamodb_table.helloterra_Hello_69872235 will be created
  + resource "aws_dynamodb_table" "helloterra_Hello_69872235" {
      + arn              = (known after apply)
      + billing_mode     = "PAY_PER_REQUEST"
      + hash_key         = "id"
      + id               = (known after apply)
      + name             = "my-first-table-ap-northeast-1"
      + stream_arn       = (known after apply)
      + stream_label     = (known after apply)
      + stream_view_type = (known after apply)

      + attribute {
          + name = "id"
          + type = "S"
        }

      + point_in_time_recovery {
          + enabled = (known after apply)
        }

      + server_side_encryption {
          + enabled     = (known after apply)
          + kms_key_arn = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  ~ helloterra_tablename_E066AD25 = "my-first-table-eu-central-1" -> "my-first-table-ap-northeast-1"

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_dynamodb_table.helloterra_Hello_69872235: Creating...
aws_dynamodb_table.helloterra_Hello_69872235: Creation complete after 7s [id=my-first-table-ap-northeast-1]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

helloterra_tablename_E066AD25 = "my-first-table-ap-northeast-1"
```

AWS Management console でチェックしてみると...？

![スクリーンショット 2020-12-16 20.42.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52624/3c3eebf0-d09d-27f3-3ab5-422810d1dca0.png)

DynamoDBのテーブルがデプロイされました。

# まとめ
CDKをTypeScript等の型がある言語で使うと、IDEの支援も受けながらIACが書けてとても快適だと感じます。（CloudFormationで書いていたときはResourceやParameterの型を調べながらリソース定義していく作業になりとても時間と労力がかかってしまっていました）。また、CloudFormationよりも構成が抽象化・テンプレート化されていて記述量が減るのもメリットです。
そのCDKがterraformでも使えると聞いて実際に試してみました。