1. 概要
setintersection— 積集合(共通要素)setunion— 和集合(すべての要素)setsubtract— 差集合(一方にのみある要素)setproduct— 直積(デカルト積)- 実際のユースケース
Terraformのset操作関数は、セキュリティグループのCIDRブロック管理・IAM権限の差分比較・複数リストの組み合わせ生成などに使います。
2. setintersection — 積集合(共通要素)
setintersection(set1, set2, ...)は複数のsetに共通する要素を返します。
# terraform consoleで確認
> setintersection(["a", "b", "c"], ["b", "c", "d"])
toset(["b", "c"])
> setintersection(["1", "2", "3"], ["2", "3", "4"], ["3", "4", "5"])
toset(["3"])
複数環境で共通の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 "dev_allowed_cidrs" {
type = list(string)
default = ["10.0.0.0/8", "172.16.0.0/12", "192.168.1.0/24"]
}
variable "prd_allowed_cidrs" {
type = list(string)
default = ["10.0.0.0/8", "172.16.0.0/12", "203.0.113.0/24"]
}
locals {
# dev/prd 両方で許可するCIDRブロック(積集合)
common_cidrs = setintersection(
toset(var.dev_allowed_cidrs),
toset(var.prd_allowed_cidrs)
)
# → toset(["10.0.0.0/8", "172.16.0.0/12"])
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_security_group" "web" {
name = "${var.environment}-web"
description = "${var.environment} web security group"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = tolist(local.common_cidrs)
description = "HTTPS from common CIDRs"
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
3. setunion — 和集合(すべての要素)
setunion(set1, set2, ...)は複数のsetのすべての要素を重複なく返します。
# terraform consoleで確認
> setunion(["a", "b"], ["b", "c"], ["c", "d"])
toset(["a", "b", "c", "d"])
locals {
# すべての環境のCIDRブロックをマージ
all_allowed_cidrs = setunion(
toset(var.dev_allowed_cidrs),
toset(var.prd_allowed_cidrs)
)
# → toset(["10.0.0.0/8", "172.16.0.0/12", "192.168.1.0/24", "203.0.113.0/24"])
}
4. setsubtract — 差集合
setsubtract(set1, set2)はset1からset2の要素を除いた差集合を返します。
# terraform consoleで確認
> setsubtract(["a", "b", "c"], ["b", "c", "d"])
toset(["a"])
# prdにあってdevにないCIDR(prd固有のCIDR)
> setsubtract(toset(["10.0.0.0/8", "203.0.113.0/24"]), toset(["10.0.0.0/8"]))
toset(["203.0.113.0/24"])
5. setproduct — 直積(デカルト積)
setproduct(set1, set2, ...)は複数のsetのデカルト積(すべての組み合わせ)を返します。
# terraform consoleで確認
> setproduct(["ap-northeast-1a", "ap-northeast-1c"], ["public", "private"])
[
["ap-northeast-1a", "public"],
["ap-northeast-1a", "private"],
["ap-northeast-1c", "public"],
["ap-northeast-1c", "private"],
]
AZとサブネット種別の全組み合わせでサブネットを作成
data "aws_availability_zones" "available" {
state = "available"
}
locals {
az_types = setproduct(
slice(data.aws_availability_zones.available.names, 0, 2),
["public", "private"]
)
# → [["ap-northeast-1a","public"], ["ap-northeast-1a","private"],
# ["ap-northeast-1c","public"], ["ap-northeast-1c","private"]]
subnet_configs = {
for pair in local.az_types :
"${pair[0]}-${pair[1]}" => {
az = pair[0]
type = pair[1]
}
}
}
6. 関連記事
- flatten の応用 — setproductとflattenの組み合わせ
- for式の使い方 — set操作の代替パターン
- chunklist / coalescelist / one — リストの高度な操作
7. まとめ
setintersection(set1, set2, ...)— 共通要素。dev/prd両方で使うCIDRの特定などsetunion(set1, set2, ...)— すべての要素を重複なく合成setsubtract(set1, set2)— set1からset2の要素を除いた差集合setproduct(set1, set2, ...)— デカルト積。AZ × サブネット種別の全組み合わせ生成に便利- これらの関数はsetを返すため、リストが必要な場合は
tolist()で変換する
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/setintersection