Fusic Tech Blog

Fusion of Society, IT and Culture

TerraformでDynamoDBのItemをjsonファイルで管理する
2021/10/07

TerraformでDynamoDBのItemをjsonファイルで管理する

DynamoDBのItemsは一時的なものや流動的なものが多く、あまりコード管理したことがありませんでした。
今回、初めてTerraformでDynamoDBのItemsまで定義する機会があったのでそのTipsのご紹介です。

Itemsはjsonファイルをデータ元として利用します。

環境

Terraform v1.0.5

Terraform

provider "aws" {
  region  = "ap-northeast-1"
}

terraform {
  required_version = "~> 1.0.0"
}


# --------------------------------------------------------
# DynamoDB

resource "aws_dynamodb_table" "members" {
  name           = "members"
  billing_mode   = "PROVISIONED"
  read_capacity  = 1
  write_capacity = 1

  hash_key       = "mail"

  attribute {
    name = "mail"
    type = "S"
  }

  tags = {
    Name = "members"
  }
}

# # --------------------------------------------------------
# # DynamoDB Values

locals {
  json_data = file("./members.json")
  members    = jsondecode(local.json_data)
}

resource "aws_dynamodb_table_item" "members" {
  for_each = local.members

  table_name = aws_dynamodb_table.members.name
  hash_key   = aws_dynamodb_table.members.hash_key

  item = jsonencode(each.value)
}

DynamoDBのテーブルを成し、ローカルの同階層にある members.json を読み込み、eachで都度追加をしています。
取得元のファイルがjsonなので、 item = jsonencode(each.value) で雑に突っ込めるのがいいですね。

{
    "user01": {
        "mail": {"S": "user01@fusic.co.jp"},
        "name": {"S": "user01"},
        "github": {"S": "user01"}
    },
    "user02": {
        "mail": {"S": "user02@fusic.co.jp"},
        "name": {"S": "user02"}
    },
    "user03": {
        "mail": {"S": "user03@fusic.co.jp"},
        "name": {"S": "user03"}
    },
    "user04": {
        "mail": {"S": "user04@fusic.co.jp"},
        "name": {"S": "user04"},
        "github": {"S": "user04"}
    }
}

jsonはこんな感じで書いてみます。
DybamoDBのhash_keyにmailを指定しているので、それは必ず入れてそれ以外は何を入れても問題ありません。

apply

❯ terraform apply
aws_dynamodb_table.members: Refreshing state... [id=members]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_dynamodb_table_item.members["user01"] will be created
  + resource "aws_dynamodb_table_item" "members" {
      + hash_key   = "mail"
      + id         = (known after apply)
      + item       = jsonencode(
            {
              + github = {
                  + S = "user01"
                }
              + mail   = {
                  + S = "user01@fusic.co.jp"
                }
              + name   = {
                  + S = "user01"
                }
            }
        )
      + table_name = "members"
    }

  # aws_dynamodb_table_item.members["user02"] will be created
  + resource "aws_dynamodb_table_item" "members" {
      + hash_key   = "mail"
      + id         = (known after apply)
      + item       = jsonencode(
            {
              + mail = {
                  + S = "user02@fusic.co.jp"
                }
              + name = {
                  + S = "user02"
                }
            }
        )
      + table_name = "members"
    }
....

applyまでの差分確認でもちゃんとjsonの要素が追加されていることが分かります。
反映後、jsonを編集して、planするとちゃんと差分も出て Insert, Update, Delete がされます。

おわり

APIキーやメンバーの属性などあまり流動的ではない値をDynamoDBに保存する場合、その値をIaCで管理するのも悪くないなと思いました。
ただ、IaC以外から追加したItemは管理外になるので、実運用との兼ね合い次第なところもありますね。

tutida

tutida

福岡でWebエンジニアやってます。PHP, クラウド, インフラあたりが好き。AWS 五冠