Terraformを使用したDynamoDBの作成

# 概要
`tfvars`ファイルの管理を`S3`で行う運用を開始しました。それに先立ち、`DynamoDB`を構築する必要があった為、今回は`Terraform`を用いた構築手順について記載します。

# 事前情報
- `Terraform`が動作する環境である
- `Terraform`のバージョンは、`v1.5.0`以上
- `AWS`の操作権限がある

# ディレクトリ構造
```sh
.
├── .terraform/
│   └── # terraformに必要なファイル、ディレクトリが自動生成される
├── .terraform.lock.hcl　# 自動生成
├── .gitignore
├── providers.tf
├── aws_authentication.tf
├── variables.tf
├── terraform.tfvars
├── main.tf
└── dynamodb/
    ├── dynamodb.tf
    └── variables.tf # 必要に応じて作成
```

# 構築手順
## 立ち上げ時に必要なファイル一覧
:::note alert
注意
- AWSの認証情報がある為、`Git`で管理する場合は必ず`.gitignore`を作成し、下記の設定を記述する
:::
```.gitignore
**/.terraform/*
.terraform.lock.hcl

# .tfstate files
*.tfstate
*.tfstate.backup
*.tfstate.*

# .tfstate files
*.tfvars
*.tfvars.*

crash.log

override.tf
override.tf.json
*_override.tf
*_override.tf.json
```

---------------------------------------

- `Terraform`で使用するプロバイダ(provider)の設定を記述
```providers.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.64.0"
    }
  }
}
```
- プロバイダ(provider) : `Terraform`が特定のインフラやサービスを作成、管理する為、`API`を提供するプラグイン

---------------------------------------
- AWSの認証情報を設定する

```aws_authentication.tf
provider "aws" {
  region  = "${var.region}"
  profile = "${var.profile}"
  access_key = "${var.aws_access_key}"
  secret_key = "${var.aws_secret_key}"
}
```

```variables.tf
# 変数の設定
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region"{}
variable "profile"{}
```

```terraform.tfvars
aws_access_key="********************" // 
aws_secret_key="****************************************" //
region="**************" // 
profile="*********" // 設定していれば記述する
```

---------------------------------------

```main.tf
module "dynamodb" {
  source = "./dynamodb"
}
```

## DynamoDB構築に必要ファイル一覧
- variables.tfに関しては、必要に応じて設定する
```dynamodb.tf
resource "aws_dynamodb_table" "terraform_state_lock" {
  name           = "dynamodb_sample" # 任意の名前を記述する
  write_capacity = 1
  read_capacity  = 1
  hash_key       = "LockID"

  attribute {
    name = "LockID"
    type = "S" #　String型の[S]
  }
}
```

| メソッド | 説明 |
| - | - |
| `write_capacity` | `DynamoDB`テーブルに対する書き込み操作のスループットを指定する。これは、キャパシティーユニットで表され、最小**1**ユニット、最大**40,000**ユニットまで設定可能 |
| `read_capacity` | `DynamoDB`テーブルに対する読み込み操作のスループットを指定する。これもキャパシティーユニットで表され、最小**1**ユニット、最大**40,000**ユニットまで設定可能 |
| `hash_key` |  テーブル内のアイテムを一意に識別する為の主要なキーであり、`DynamoDB`がデータをどのパーティションに割り当てるかを決定する為に使用する |
| `LockID` | 自身がTerraformを更新する際、他のユーザーが同じファイルを更新出来ない様する |
| `attribute`(属性) | `hash_key`で指定した属性（今回の場合は`LockID`）が、どの様なデータ型を持つかを定義する。ここでは`S`を指定しており、これは`String`型（文字列）を表す |

### 用語説明
- **スループット** : 一定の時間内に処理されるデータの量や、システムが処理出来るトランザクションの数を示す
- **パーティション** : データを分割して保存する為の論理的な単位を示す

## コマンド操作
- 下記のコマンドで、AWSプロバイダーがインターネットからダウンロードし、Terraformの環境を使用出来る様にする
```sh
terraform init
```

- 構築した内容に問題がないか確認する
```sh
terraform plan
```

- DynamoDBを作成する
```sh
terraform apply
# or
terraform apply -auto-approve
```
- `-auto-approve` : 強制的に全ての確認をYesで進める

# 参考資料
- [Amazon DynamoDB](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html)
- [[AWS公式] プロビジョンドキャパシティモード](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/provisioned-capacity-mode.html)
- [[AWS公式] 読み込みと書き込みのオペレーション](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/read-write-operations.html)
- [[hashicorp] aws_dynamodb_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table)
- [Terraform Locking State Mechanism using DynamoDB (LockID)](https://medium.com/@wd.sandeepnayak/terraform-locking-state-mechanism-using-dynamodb-lockid-b43298ae7489)

# まとめ
簡単な概念程度ですが、DynamoDBについて知れて良かったと思っています。今後、`NoSQL`を使用した開発を行う機会があれば、仕組みや設定、扱い方について書ければと考えています。