1. 概要
csvdecode— CSV文字列をリストのmapに変換- CSVファイルから設定を読み込むパターン
- 実際のユースケース(EC2インスタンス一覧・セキュリティグループルールの管理)
csvdecode(string)はCSV形式の文字列を、ヘッダー行をキーとしたmapのリストに変換します。多数のリソースをCSVで一元管理したい場合に使います。
2. 基本的な使い方
# terraform consoleで確認
> csvdecode("name,age\nAlice,30\nBob,25")
[
{"age" = "30", "name" = "Alice"},
{"age" = "25", "name" = "Bob"},
]
1行目はヘッダー(キー名)として扱われ、2行目以降が各行のmapになります。すべての値は文字列として返されます。
3. CSVファイルから読み込む
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
CSVファイル(instances.csv)の内容:
name,instance_type,disk_size
web,t3.micro,20
api,t3.small,30
worker,t3.medium,50
locals {
# CSVファイルを読み込んでパース
instances = csvdecode(file("${path.module}/instances.csv"))
# → [
# {name="web", instance_type="t3.micro", disk_size="20"},
# {name="api", instance_type="t3.small", disk_size="30"},
# {name="worker", instance_type="t3.medium", disk_size="50"},
# ]
# for_eachで使うためにname→設定のmapに変換
instance_map = {
for inst in local.instances :
inst.name => inst
}
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "servers" {
for_each = local.instance_map
ami = data.aws_ami.amazon_linux_2023.id
instance_type = each.value.instance_type
root_block_device {
# CSVの値はすべて文字列なのでtoneumberで変換
volume_size = tonumber(each.value.disk_size)
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-${each.key}"
Environment = var.environment
ManagedBy = "terraform"
Role = each.key
}
}
4. セキュリティグループルールをCSVで管理する
CSVファイル(sg_rules.csv):
port,protocol,cidr,description
80,tcp,0.0.0.0/0,HTTP
443,tcp,0.0.0.0/0,HTTPS
22,tcp,10.0.0.0/8,SSH from internal
locals {
sg_rules = csvdecode(file("${path.module}/sg_rules.csv"))
}
resource "aws_security_group" "web" {
name = "${var.environment}-web"
description = "${var.environment} web security group"
dynamic "ingress" {
for_each = local.sg_rules
content {
from_port = tonumber(ingress.value.port)
to_port = tonumber(ingress.value.port)
protocol = ingress.value.protocol
cidr_blocks = [ingress.value.cidr]
description = ingress.value.description
}
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
5. csvdecodeの注意点
- すべての値が文字列として返される。数値が必要な場合は
tonumber()で変換する - ヘッダー行は必須。ヘッダーなしのCSVは使えない
- 空のセルは空文字列
""になる - カンマを含む値はダブルクォートで囲む(
"value with, comma")
6. 関連記事
- yaml応用 — yamlencode / yamldecode — YAMLでの設定管理
- file / fileexists / fileset の使い方 — ファイル読み込み
- for_each の使い方 — CSVからfor_eachへ
7. まとめ
csvdecode(str)— CSV文字列をmap of listsに変換。ヘッダー行がキー名になるfile()と組み合わせてCSVファイルから設定を読み込める- 値はすべて文字列。数値が必要な場合は
tonumber()、boolにはtobool()で変換する for_eachと組み合わせてCSVの各行をリソースとして作成できる
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/csvdecode