chunklist / coalescelist / one — リストの高度な操作

1. 概要

  • chunklist — リストを指定サイズのチャンクに分割
  • coalescelist — 最初の空でないリストを返す
  • one — 0または1要素のリストから値を取り出す
  • 実際のユースケース

2. chunklist — リストを分割

chunklist(list, chunk_size)はリストを指定サイズのリストのリストに分割します。

# terraform consoleで確認
> chunklist(["a", "b", "c", "d", "e"], 2)
[["a", "b"], ["c", "d"], ["e"]]

> chunklist(range(1, 7), 3)
[[1, 2, 3], [4, 5, 6]]

サブネットIDを複数のターゲットグループに分散する

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 "subnet_ids" {
  description = "サブネットIDのリスト"
  type        = list(string)
  default     = ["subnet-1", "subnet-2", "subnet-3", "subnet-4"]
}

locals {
  # 2つずつのチャンクに分割(2グループのALBに振り分け)
  subnet_chunks = chunklist(var.subnet_ids, 2)
  # → [["subnet-1", "subnet-2"], ["subnet-3", "subnet-4"]]
}

resource "aws_s3_bucket" "chunks_demo" {
  bucket = "${var.environment}-chunks-demo"

  tags = {
    Name        = "${var.environment}-chunks-demo"
    Environment = var.environment
    ManagedBy   = "terraform"
    ChunkCount  = tostring(length(local.subnet_chunks))
  }
}

3. coalescelist — 最初の空でないリストを返す

coalescelist(list1, list2, ...)は引数の中で最初の空でないリストを返します。coalesce()のリスト版です。

# terraform consoleで確認
> coalescelist([], ["a", "b"])
["a", "b"]

> coalescelist(["first"], ["second"])
["first"]

> coalescelist([], [], ["fallback"])
["fallback"]

デフォルトサブネットのフォールバック

variable "custom_subnet_ids" {
  description = "カスタムサブネットID(省略可能)"
  type        = list(string)
  default     = []
}

data "aws_subnets" "default" {
  filter {
    name   = "default-for-az"
    values = ["true"]
  }
}

locals {
  # カスタムサブネットが指定されていればそちらを、なければデフォルトサブネットを使う
  subnet_ids = coalescelist(
    var.custom_subnet_ids,
    data.aws_subnets.default.ids
  )
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"
  subnet_id     = local.subnet_ids[0]

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-web"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

4. one — 0または1要素のリストから値を取り出す

one(list)はリストが0要素ならnullを、1要素なら値を返します。2要素以上の場合はエラーになります。条件付きリソースの参照に便利です。

# terraform consoleで確認
> one([])
null

> one(["value"])
"value"

> one(["a", "b"])
# エラー: list must have 0 or 1 elements

count = 0 or 1 のリソースの安全な参照

variable "enable_bastion" {
  description = "Bastionホストを作成するか"
  type        = bool
  default     = false
}

resource "aws_instance" "bastion" {
  count         = var.enable_bastion ? 1 : 0
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-bastion"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

# one()でcount=0の場合はnull、count=1の場合はIDを返す
output "bastion_ip" {
  value = one(aws_instance.bastion[*].public_ip)
  # enable_bastion=false → null
  # enable_bastion=true  → "xxx.xxx.xxx.xxx"
}

5. 関連記事


6. まとめ

  • chunklist(list, size) — リストを指定サイズのチャンクに分割。バッチ処理的な分散に使う
  • coalescelist(list1, list2, ...) — 最初の空でないリストを返す。デフォルト値のフォールバックに使う
  • one(list) — 0/1要素リストから値を取り出す。count=0/1リソースの参照に定番

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/chunklist