概要
- DynamoDBにてアプリケーションで使用する設定値を管理したい
- DynamoDB TableはTerraformで管理
- DynamoDB Tableに追加する項目(ここでは設定値)をTerraformで管理
- Terraformの
for_each
ファンクションを利用して、複数項目を追加
- Terraformの
動機
以下のjsonファイルの内容でDynamoDBに登録される項目が存在する。
登録するデータはマスターデータであるため、基本的に変更しない。
可能であれば、Terraformで管理したい。(Resource: aws_dynamodb_table_item)
sample.json
{
"device_code": {
"S": "3"
},
"parameter": {
"M": {
"input_key": {
"S": "path/to/directory"
},
"output_location": {
"S": "path/to/directory"
},
"instance_type": {
"S": "ml.m5.2xlarge"
}
}
}
}
対応方法
for_each
を活用することで、少ない定義で複数の項目を管理することが可能となる。
dynamodb.tf
resource "aws_dynamodb_table" "device_config" {
name = "sample_table"
billing_mode = "PROVISIONED"
hash_key = "device_code"
attribute {
name = "device_code"
type = "S"
}
}
locals {
json_data = file("./config.json") # jsonファイルの読み込み
config = jsondecode(local.json_data) # デコード
}
resource "aws_dynamodb_table_item" "device_config" {
for_each = local.config # for_eachにより、要素ごとに分割
table_name = aws_dynamodb_table.device_config.name
hash_key = aws_dynamodb_table.device_config.hash_key
item = jsonencode(each.value) # 各要素のバリューをエンコードしitemに挿入
}
例として以下のようなconfig.json
にすることにより、画像のようにまとめて項目を追加することができる。
config.json
{
"device_3": {
"device_code": {
"S": "3"
},
"parameter": {
"M": {
"input_key": {
"S": "path/to/directory/3"
},
"output_location": {
"S": "path/to/directory/3"
},
"instance_type": {
"S": "ml.m5.2xlarge"
}
}
}
},
"device_4": {
"device_code": {
"S": "4"
},
"parameter": {
"M": {
"input_key": {
"S": "path/to/directory/4"
},
"output_location": {
"S": "path/to/directory/4"
},
"instance_type": {
"S": "ml.m5.2xlarge"
}
}
}
},
"device_5": {
"device_code": {
"S": "5"
},
"parameter": {
"M": {
"input_key": {
"S": "path/to/directory/5"
},
"output_location": {
"S": "path/to/directory/5"
},
"instance_type": {
"S": "ml.m5.2xlarge"
}
}
}
}
}
項目を変更する際
Terraformで項目を管理できることにより、マスターに変更が加わった場合でもコードで変更点などを把握することが可能となる。
仮に上記例のdevice4を削除した場合、Terraformを実行すると以下のように出力され、apply
するとその項目のみが削除される。
$ terraform apply
aws_dynamodb_table.device_config: Refreshing state... [id=sample_table]
aws_dynamodb_table_item.device_config["device_5"]: Refreshing state... [id=sample_table|device_code||5|]
aws_dynamodb_table_item.device_config["device_3"]: Refreshing state... [id=sample_table|device_code||3|]
aws_dynamodb_table_item.device_config["device_4"]: Refreshing state... [id=sample_table|device_code||4|]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_dynamodb_table_item.device_config["device_4"] will be destroyed
- resource "aws_dynamodb_table_item" "device_config" {
- hash_key = "device_code" -> null
- id = "sample_table|device_code||4|" -> null
- item = jsonencode(
{
- device_code = {
- S = "4"
}
- parameter = {
- M = {
- input_key = {
- S = "path/to/directory/4"
}
- instance_type = {
- S = "ml.m5.2xlarge"
}
- output_location = {
- S = "path/to/directory/4"
}
}
}
}
) -> null
- table_name = "sample_table" -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
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_item.device_config["device_4"]: Destroying... [id=sample_table|device_code||4|]
aws_dynamodb_table_item.device_config["device_4"]: Destruction complete after 0s
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
まとめ
-
for_each
を利用することによりDynamoDBの項目管理が容易に実現できた - IaCすごい