formatlist — リストの各要素をフォーマットする

1. 概要

  • formatlist — リストの各要素をフォーマット
  • formatとの違い
  • 実際のユースケース

formatlist(format, list...)はリストの各要素にフォーマット文字列を適用し、新しいリストを返します。複数のリソース名を一括生成したり、CIDRブロックのリストを変換したりする場面で使います。


2. 基本的な使い方

# terraform consoleで確認
> formatlist("dev-%s", ["web", "api", "worker"])
["dev-web", "dev-api", "dev-worker"]

> formatlist("%s.example.com", ["www", "api", "admin"])
["www.example.com", "api.example.com", "admin.example.com"]

# 複数リストの同時適用
> formatlist("%s-%s", ["dev", "stg", "prd"], ["web", "api", "worker"])
["dev-web", "stg-api", "prd-worker"]

3. format との違い

# format: 1つの文字列を返す
> format("hello %s", "world")
"hello world"

# formatlist: リストを返す(各要素に適用)
> formatlist("hello %s", ["Alice", "Bob", "Charlie"])
["hello Alice", "hello Bob", "hello Charlie"]

4. サブネットCIDRブロックの生成

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 "service_names" {
  description = "サービス名のリスト"
  type        = list(string)
  default     = ["web", "api", "worker"]
}

locals {
  # サービス名から環境プレフィックス付きの名前を生成
  resource_names = formatlist("${var.environment}-%s", var.service_names)
  # → ["dev-web", "dev-api", "dev-worker"]

  # セキュリティグループの説明文を生成
  sg_descriptions = formatlist("%s security group for ${var.environment}", var.service_names)
  # → ["web security group for dev", "api security group for dev", ...]
}

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

resource "aws_instance" "services" {
  count         = length(var.service_names)
  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        = local.resource_names[count.index]
    Service     = var.service_names[count.index]
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

5. S3バケット名の一括生成

locals {
  environments = ["dev", "stg", "prd"]
  service      = "myapp"

  # 環境ごとのバケット名を一括生成
  bucket_names = formatlist("%s-${local.service}-data", local.environments)
  # → ["dev-myapp-data", "stg-myapp-data", "prd-myapp-data"]
}

resource "aws_s3_bucket" "data" {
  count  = length(local.bucket_names)
  bucket = local.bucket_names[count.index]

  tags = {
    Name        = local.bucket_names[count.index]
    Environment = local.environments[count.index]
    ManagedBy   = "terraform"
  }
}

6. 関連記事


7. まとめ

  • formatlist(format, list...) — リストの各要素にフォーマット文字列を適用して新しいリストを返す
  • format()との違い: format()は1つの文字列、formatlist()はリストを返す
  • 複数リストを渡すと対応するインデックス同士でフォーマットが適用される
  • for式([for s in list : format(..., s)])でも同じ結果を得られるが、formatlist()の方が簡潔

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