1. 概要
cidrsubnet— CIDRブロックからサブネットを計算するcidrhost— CIDRブロックから特定のIPアドレスを計算するcidrnetmask— CIDRブロックのネットマスクを取得する- 実際のVPC・サブネット設計への応用
TerraformのIPアドレス計算関数を使うと、VPCのCIDRブロックからサブネットのアドレスを動的に計算できます。手動でIP範囲を計算してハードコードする必要がなくなります。
2. cidrsubnet — サブネットを計算する
cidrsubnet(prefix, newbits, netnum)は、CIDRブロックprefixからnewbitsビット拡張したnetnum番目のサブネットを返します。
# terraform consoleで確認
# cidrsubnet(親CIDR, 追加ビット数, サブネット番号)
> cidrsubnet("10.0.0.0/16", 8, 0)
"10.0.0.0/24" # 16+8=24ビット、0番目
> cidrsubnet("10.0.0.0/16", 8, 1)
"10.0.1.0/24" # 1番目
> cidrsubnet("10.0.0.0/16", 8, 10)
"10.0.10.0/24" # 10番目
> cidrsubnet("10.0.0.0/16", 4, 0)
"10.0.0.0/20" # 16+4=20ビット
3. cidrsubnetでVPC・サブネットを設計する
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 "vpc_cidr" {
description = "VPCのCIDRブロック"
type = string
default = "10.0.0.0/16"
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
ManagedBy = "terraform"
}
}
locals {
# /16から/24サブネットを自動計算
# パブリックサブネット: 0, 1, 2番
# プライベートサブネット: 10, 11, 12番(間隔を空けて管理しやすく)
public_subnets = [
cidrsubnet(var.vpc_cidr, 8, 0), # 10.0.0.0/24
cidrsubnet(var.vpc_cidr, 8, 1), # 10.0.1.0/24
cidrsubnet(var.vpc_cidr, 8, 2), # 10.0.2.0/24
]
private_subnets = [
cidrsubnet(var.vpc_cidr, 8, 10), # 10.0.10.0/24
cidrsubnet(var.vpc_cidr, 8, 11), # 10.0.11.0/24
cidrsubnet(var.vpc_cidr, 8, 12), # 10.0.12.0/24
]
availability_zones = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
}
resource "aws_subnet" "public" {
count = length(local.public_subnets)
vpc_id = aws_vpc.main.id
cidr_block = local.public_subnets[count.index]
availability_zone = local.availability_zones[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-${count.index + 1}"
Environment = var.environment
ManagedBy = "terraform"
Type = "public"
}
}
resource "aws_subnet" "private" {
count = length(local.private_subnets)
vpc_id = aws_vpc.main.id
cidr_block = local.private_subnets[count.index]
availability_zone = local.availability_zones[count.index]
tags = {
Name = "${var.environment}-private-${count.index + 1}"
Environment = var.environment
ManagedBy = "terraform"
Type = "private"
}
}
4. for式と組み合わせて動的にサブネットを生成する
locals {
az_count = 3
# for式でサブネットCIDRのリストを動的生成
public_cidr_blocks = [for i in range(local.az_count) : cidrsubnet(var.vpc_cidr, 8, i)]
private_cidr_blocks = [for i in range(local.az_count) : cidrsubnet(var.vpc_cidr, 8, i + 10)]
}
5. cidrhost — 特定のIPアドレスを計算する
cidrhost(prefix, hostnum)は、CIDRブロック内のhostnum番目のホストIPアドレスを返します。
# terraform consoleで確認
> cidrhost("10.0.0.0/24", 1)
"10.0.0.1" # 最初のホストIP(通常ゲートウェイ)
> cidrhost("10.0.0.0/24", 10)
"10.0.0.10"
> cidrhost("10.0.0.0/24", -1)
"10.0.0.254" # 最後のホストIP(負のインデックスも使える)
固定IPのEC2インスタンスに使う
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "bastion" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public[0].id
# サブネットの最初のホストIP(.4)を固定割り当て
private_ip = cidrhost(aws_subnet.public[0].cidr_block, 4)
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-bastion"
Environment = var.environment
ManagedBy = "terraform"
}
}
6. cidrnetmask — ネットマスクを取得する
# terraform consoleで確認
> cidrnetmask("10.0.0.0/24")
"255.255.255.0"
> cidrnetmask("10.0.0.0/16")
"255.255.0.0"
7. 関連記事
- range / element / index / slice の使い方 — rangeとfor式の組み合わせでサブネット計算に活用
- for式の使い方 — 動的なサブネットリスト生成
- count の使い方 — サブネットのcount管理
- resourceブロック — 基本構文と使い方
- locals(ローカル値)— DRYなコードを書く
- abs / ceil / floor / max / min / pow — 数値関数
8. まとめ
cidrsubnet(prefix, newbits, netnum)— 親CIDRからnewbitsビット拡張したnetnum番目のサブネットを計算cidrhost(prefix, hostnum)— CIDRブロック内の特定ホストIPを計算(負のインデックスで末尾から参照可能)cidrnetmask(prefix)— CIDRのネットマスクを取得range+for式+cidrsubnetの組み合わせで動的なサブネット設計が実現できる- VPCのCIDRをvariableで受け取り、cidrsubnetで自動計算するパターンが推奨
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/cidrsubnet