join / split / format / replace — 文字列操作関数

1. 概要

  • join — リストを文字列に結合する
  • split — 文字列をリストに分割する
  • format — sprintfスタイルで文字列をフォーマットする
  • replace — 文字列の一部を置換する(正規表現対応)
  • 各関数の実用パターンと組み合わせ例

文字列操作はTerraformのリソース名・タグ・ARN構築で頻繁に使います。特にjoinformatは、リストや変数から動的に文字列を組み立てるために欠かせない関数です。


2. join — リストを文字列に結合する

join(sep, list)は、listの各要素をsep(区切り文字)でつなげた文字列を返します。

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

> join("-", ["myapp", "dev", "web"])
"myapp-dev-web"

> join("", ["Hello", " ", "World"])
"Hello World"

> join("\n", ["line1", "line2", "line3"])
"line1\nline2\nline3"

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 "allowed_cidrs" {
  description = "許可するCIDRブロックのリスト"
  type        = list(string)
  default     = ["10.0.0.0/8", "172.16.0.0/12"]
}

locals {
  # ログ出力やタグ用にリストを文字列化
  cidrs_string = join(", ", var.allowed_cidrs)

  # リソース名をパーツから組み立て
  name_parts = [var.environment, "web", "sg"]
  sg_name    = join("-", local.name_parts)
}

resource "aws_security_group" "web" {
  name        = local.sg_name
  description = "Allowed CIDRs: ${local.cidrs_string}"

  tags = {
    Name        = local.sg_name
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

3. split — 文字列をリストに分割する

split(sep, string)は、文字列をsepで分割したリストを返します。

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

> split("/", "ap-northeast-1/prod/web")
["ap-northeast-1", "prod", "web"]

> split(".", "terraform.tfstate")
["terraform", "tfstate"]

環境変数・設定値の解析

variable "subnet_ids_csv" {
  description = "サブネットIDのCSV(例: subnet-abc,subnet-def)"
  type        = string
  default     = "subnet-abc123,subnet-def456"
}

locals {
  # CSVをリストに変換してfor_eachやresourceで使う
  subnet_ids = split(",", var.subnet_ids_csv)
}

output "subnet_id_list" {
  value = local.subnet_ids
  # → ["subnet-abc123", "subnet-def456"]
}

ARNからリソースIDを取得する

locals {
  # ARN: arn:aws:s3:::my-bucket-name
  bucket_arn  = "arn:aws:s3:::my-bucket-name"
  arn_parts   = split(":", local.bucket_arn)
  bucket_name = local.arn_parts[5]
  # → "my-bucket-name"

  # VPC ARN: arn:aws:ec2:ap-northeast-1:123456789:vpc/vpc-abc123
  vpc_arn     = "arn:aws:ec2:ap-northeast-1:123456789:vpc/vpc-abc123"
  region_part = split(":", local.vpc_arn)[3]
  # → "ap-northeast-1"
}

4. format — sprintfスタイルでフォーマットする

format(format_str, args...)は、Goのfmt.Sprintfスタイルでフォーマットされた文字列を返します。

# terraform consoleで確認
> format("Hello, %s!", "Terraform")
"Hello, Terraform!"

> format("%s-%s-%03d", "app", "dev", 5)
"app-dev-005"          # 03d は3桁ゼロ埋め

> format("%.2f", 3.14159)
"3.14"

> format("%d個のリソース", 10)
"10個のリソース"

主なフォーマット指定子

指定子説明
%s文字列format("%s", "hello")"hello"
%d整数format("%d", 42)"42"
%f浮動小数点format("%.2f", 3.14)"3.14"
%qクォート文字列format("%q", "hello")"\"hello\""
%05dゼロ埋め5桁format("%05d", 7)"00007"

リソース名の連番生成

locals {
  # 連番のリソース名を生成
  server_names = [for i in range(1, 4) : format("web-%02d", i)]
  # → ["web-01", "web-02", "web-03"]
}

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

resource "aws_instance" "web" {
  for_each = toset(local.server_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        = each.key
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

補足: 複数の値を一括フォーマットする場合はformatlistが便利です。formatlist("web-%02d", [1, 2, 3])のように、リスト全体にformat処理を適用できます。


5. replace — 文字列の一部を置換する

replace(string, substr, replacement)は、文字列中のsubstrreplacementに置換します。正規表現にも対応しています。

# terraform consoleで確認
> replace("hello world", "world", "terraform")
"hello terraform"

# 正規表現(/pattern/ 形式)
> replace("2026-06-01", "/[^0-9]/", "")
"20260601"   # 数字以外を削除

> replace("My App Name", "/ /", "-")
"My-App-Name"   # スペースをハイフンに

> replace("us-east-1", "-", "_")
"us_east_1"

バケット名から不正文字を除去する

variable "project_name" {
  description = "プロジェクト名"
  type        = string
  default     = "My App Project"
}

locals {
  # S3バケット名はスペース禁止・小文字のみ
  safe_bucket_name = replace(
    lower(var.project_name),
    "/ /",
    "-"
  )
  # "My App Project" → "my-app-project"
}

resource "aws_s3_bucket" "app" {
  bucket = "${local.safe_bucket_name}-${var.environment}"

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

6. 関連する文字列関数

関数用途
lower(str)小文字化lower("ABC")"abc"
upper(str)大文字化upper("abc")"ABC"
trimspace(str)前後の空白削除trimspace(" hi ")"hi"
trim(str, chars)指定文字を両端から削除trim("--abc--", "-")"abc"
trimprefix(str, prefix)プレフィックス削除trimprefix("foo-bar", "foo-")"bar"
trimsuffix(str, suffix)サフィックス削除trimsuffix("bar-foo", "-foo")"bar"
startswith(str, prefix)プレフィックス一致判定startswith("hello", "he")true
endswith(str, suffix)サフィックス一致判定endswith("hello", "lo")true
substr(str, offset, len)部分文字列substr("hello", 1, 3)"ell"

7. 関連記事


8. まとめ

  • join(sep, list) — リストを区切り文字で結合。リソース名・タグ値の組み立てに使う
  • split(sep, string) — 文字列をリストに分割。CSV形式の変数やARN解析に便利
  • format(fmt, args...) — sprintfスタイルでフォーマット。連番名の生成やゼロ埋めに使う
  • replace(str, substr, replacement) — 文字列を置換。正規表現(/pattern/形式)も対応
  • これらはloweruppertrimspaceなどと組み合わせてリソース名を正規化するのが典型パターン

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