range / element / index / slice — リスト生成・操作関数

1. 概要

  • range — 連番のリストを生成する
  • element — インデックスで要素を取得する(循環アクセス対応)
  • index — 値のインデックスを取得する
  • slice — リストの一部を切り出す
  • 各関数の実用パターンと組み合わせ例

これらの関数はリストへのアクセスや部分取得に使います。rangeで連番生成、elementでループ的なアクセス、indexで値の位置確認、sliceでサブリスト取得が主な用途です。


2. range — 連番リストを生成する

range(max)またはrange(start, limit, step)で整数の連番リストを生成します。

# terraform consoleで確認
> range(5)
[0, 1, 2, 3, 4]

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

> range(0, 10, 2)
[0, 2, 4, 6, 8]   # ステップ2

> range(5, 0, -1)
[5, 4, 3, 2, 1]   # 逆順

for式と組み合わせてリソース名を生成する

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 "server_count" {
  description = "作成するサーバー数"
  type        = number
  default     = 3
}

locals {
  # 1始まりの連番でサーバー名を生成
  server_names = [for i in range(1, var.server_count + 1) : 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        = "${var.environment}-${each.key}"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

3. element — インデックスで要素を取得する

element(list, index)はリストのインデックス位置の要素を返します。インデックスがリスト長を超えた場合は循環(wrap-around)します。

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

> element(["a", "b", "c"], 2)
"c"

# 循環アクセス(インデックスが範囲外でもエラーにならない)
> element(["a", "b", "c"], 3)
"a"   # 0と同じ(3 % 3 = 0)

> element(["a", "b", "c"], 4)
"b"   # 1と同じ(4 % 3 = 1)

countリソースをAZにラウンドロビン配置する

variable "subnet_ids" {
  description = "配置先のサブネットIDリスト"
  type        = list(string)
  default     = ["subnet-001", "subnet-002", "subnet-003"]
}

resource "aws_instance" "web" {
  count = 5  # サブネット数(3)より多くても循環して配置される

  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"
  # 0→subnet-001, 1→subnet-002, 2→subnet-003, 3→subnet-001, 4→subnet-002
  subnet_id     = element(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"
  }
}

4. index — 値のインデックスを取得する

index(list, value)は、リスト内でvalueが最初に現れるインデックスを返します。値が存在しない場合はエラーになります。

# terraform consoleで確認
> index(["dev", "stg", "prd"], "stg")
1

> index(["a", "b", "c"], "c")
2

# 存在しない値はエラー
# > index(["a", "b"], "z")  ← エラーになる

現在の環境のインデックスで設定を切り替える

locals {
  environments    = ["dev", "stg", "prd"]
  instance_types  = ["t3.micro", "t3.small", "t3.medium"]

  env_index     = index(local.environments, var.environment)
  instance_type = local.instance_types[local.env_index]
  # dev→t3.micro, stg→t3.small, prd→t3.medium
}

5. slice — リストの一部を切り出す

slice(list, start, end)は、startからend(含まない)までの部分リストを返します。

# terraform consoleで確認
> slice(["a", "b", "c", "d", "e"], 1, 3)
["b", "c"]   # インデックス1〜2(3は含まない)

> slice(["a", "b", "c"], 0, 2)
["a", "b"]

> slice(range(10), 3, 7)
[3, 4, 5, 6]

AZリストから先頭N個だけ使う

variable "max_az_count" {
  description = "使用するAZの最大数"
  type        = number
  default     = 2
}

locals {
  all_azs      = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  selected_azs = slice(local.all_azs, 0, min(var.max_az_count, length(local.all_azs)))
  # max_az_count=2 → ["ap-northeast-1a", "ap-northeast-1c"]
}

6. 関連記事


7. まとめ

  • range(max) / range(start, limit, step) — 連番リストを生成。for式と組み合わせてリソース名生成に使う
  • element(list, index) — インデックスで要素を取得。範囲外は循環するためcountとのラウンドロビン配置に便利
  • index(list, value) — 値の最初のインデックスを返す。存在しない値はエラー
  • slice(list, start, end) — 部分リストを取得。AZリストの先頭N個取得などに使う

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