1. 概要
length— 文字列・リスト・mapの長さを返すkeys— mapのキー一覧をリストで返すvalues— mapの値一覧をリストで返すcontains— リストやsetに値が含まれるか判定する- 各関数の実用パターンと組み合わせ例
これらの関数はコレクション(list・set・map)やmapの内容を検査するために使います。lengthによる件数チェック、keys/valuesによるmap操作、containsによる存在確認が主な用途です。
2. length — 長さを取得する
length(value)は、文字列の文字数、リスト/setの要素数、mapのキー数を返します。
# terraform consoleで確認
> length("hello")
5
> length(["a", "b", "c"])
3
> length({"a" = 1, "b" = 2})
2
> length([])
0
変数バリデーションでの使用
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"
}
variable "allowed_ports" {
description = "許可するポート番号のリスト(最大10件)"
type = list(number)
default = [80, 443]
validation {
condition = length(var.allowed_ports) >= 1 && length(var.allowed_ports) <= 10
error_message = "allowed_portsは1〜10件の範囲で指定してください。"
}
}
variable "bucket_name" {
description = "S3バケット名(3〜63文字)"
type = string
validation {
condition = length(var.bucket_name) >= 3 && length(var.bucket_name) <= 63
error_message = "バケット名は3〜63文字にしてください。"
}
}
countとの組み合わせ
variable "subnet_ids" {
description = "サブネットIDのリスト"
type = list(string)
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
# サブネット数分のインスタンスを作成
count = length(var.subnet_ids)
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
subnet_id = var.subnet_ids[count.index]
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = format("%s-web-%02d", var.environment, count.index + 1)
Environment = var.environment
ManagedBy = "terraform"
}
}
3. keys / values — mapのキーと値を取り出す
keys(map)はmapのキー一覧をソート済みリストで返し、values(map)は値一覧をキーのソート順で返します。
# terraform consoleで確認
> keys({ b = 2, a = 1, c = 3 })
["a", "b", "c"] # アルファベット順でソートされる
> values({ b = 2, a = 1, c = 3 })
[1, 2, 3] # keysのソート順(a=1, b=2, c=3)に対応した値
> keys({})
[]
ポイント:
values(map)はmapに定義された順序ではなく、keys(map)のアルファベット順に対応した値を返します。順序に依存する処理では注意が必要です。
mapから環境名一覧を取得する
variable "environment_configs" {
description = "環境ごとの設定"
type = map(object({
instance_type = string
volume_size = number
}))
default = {
dev = { instance_type = "t3.micro", volume_size = 20 }
stg = { instance_type = "t3.small", volume_size = 50 }
prd = { instance_type = "t3.medium", volume_size = 100 }
}
}
locals {
# 環境名の一覧を取得
environment_names = keys(var.environment_configs)
# → ["dev", "prd", "stg"](ソート済み)
# 全インスタンスタイプの一覧
instance_types = values({ for k, v in var.environment_configs : k => v.instance_type })
}
output "environments" {
value = local.environment_names
}
keys + for_each でリソースを動的生成する
resource "aws_s3_bucket" "env_buckets" {
# mapのキー(環境名)でfor_each
for_each = var.environment_configs
bucket = "myapp-${each.key}-data"
tags = {
Name = "myapp-${each.key}-data"
Environment = each.key
ManagedBy = "terraform"
}
}
output "bucket_names" {
# 全バケット名をkeys順で表示
value = [for env in keys(var.environment_configs) : aws_s3_bucket.env_buckets[env].bucket]
}
4. contains — 値が含まれるか判定する
contains(list, value)は、listまたはsetにvalueが含まれる場合trueを返します。
# terraform consoleで確認
> contains(["dev", "stg", "prd"], "prd")
true
> contains(["dev", "stg", "prd"], "prod")
false
> contains([1, 2, 3], 2)
true
> contains([], "any")
false
validationブロックでの使用(最頻出パターン)
variable "environment" {
description = "環境名(dev/stg/prd のいずれか)"
type = string
default = "dev"
validation {
condition = contains(["dev", "stg", "prd"], var.environment)
error_message = "environmentはdev、stg、prdのいずれかを指定してください。"
}
}
variable "instance_type" {
description = "EC2インスタンスタイプ"
type = string
default = "t3.micro"
validation {
condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
error_message = "instance_typeはt3.micro/t3.small/t3.mediumのいずれかを指定してください。"
}
}
条件分岐での使用
locals {
# 本番環境かどうか判定
is_production = contains(["prd", "production"], var.environment)
# 本番のみ詳細ログを有効化
enable_detailed_logging = local.is_production ? true : false
}
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = var.instance_type
root_block_device {
volume_size = local.is_production ? 100 : 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-app"
Environment = var.environment
ManagedBy = "terraform"
}
}
contains と index の使い分け:
containsは「存在するか否か」を判定し、index(list, value)は「何番目にあるか」を返します。インデックスが不要な場合はcontains、位置も必要な場合はindexを使います。
5. 関連するコレクション検査関数
| 関数 | 説明 | 例 |
|---|---|---|
length(v) | 長さ/件数を返す | length(["a","b"]) → 2 |
keys(map) | キー一覧(ソート済みlist)を返す | keys({b=2,a=1}) → ["a","b"] |
values(map) | 値一覧(keysのソート順)を返す | values({b=2,a=1}) → [1,2] |
contains(list, val) | 値が含まれるか判定 | contains(["a","b"],"a") → true |
index(list, val) | 値の最初のインデックスを返す | index(["a","b"],"b") → 1 |
lookup(map, key, default) | mapからキーで取得 | lookup({a=1},"b",0) → 0 |
6. 関連記事
- variable(入力変数)の使い方 — validationブロックでcontains/lengthを使う
- for式の使い方 — keysやvaluesと組み合わせてmapを変換する
- toset / tolist / tomap の使い方 — コレクション型変換
- lookup関数の使い方 — mapから安全に値を取り出す
- sort / distinct / compact / reverse — リスト整形
- range / element / index / slice — リスト生成・操作
7. まとめ
length(value)— 文字列の文字数、リスト/setの要素数、mapのキー数を返す。validationやcountとの組み合わせが典型keys(map)— mapのキーをアルファベット順のリストで返すvalues(map)— mapの値をkeysのソート順のリストで返す(定義順ではない点に注意)contains(list, value)— リスト/setに値が含まれるか判定。validationブロックでの選択肢チェックに最適- これらは
validationブロック・count・for_each・for式と組み合わせて使うことが多い
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/length