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. 関連記事
- sort / distinct / compact / reverse の使い方 — リスト整形関数
- for式の使い方 — rangeとfor式の組み合わせ
- count の使い方 — elementとcountの組み合わせ
- length / keys / values / contains — コレクション検査
- chunklist / coalescelist / one
- for_each — map/setでリソースを動的に作成
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