🍰

【AWS】TerraformでSubnetをモジュール化する

2024/08/27に公開
1

Terraformでは、コードの再利用性を高めるために、モジュールを活用することが推奨されています。
ここでは、Subnetをモジュール化する方法について説明します。

モジュールの作成

まず、00_modules/subnetsディレクトリを作成し、その中に以下のファイルを作成します。

  • main.tf
  • variables.tf
  • outputs.tf

main.tf

main.tfでは、Subnetのリソースを定義します。

resource "aws_subnet" "rds_private_subnet_1" {
 count             = var.create_rds_private_subnets ? 1 : 0
 availability_zone = "${var.region}a"
 cidr_block        = cidrsubnet(var.vpc_cidr, 8, 0)
 vpc_id            = var.vpc_id
 tags = {
   Name = "${var.environment}-rds-private-subnet-1"
 }
}

resource "aws_subnet" "rds_private_subnet_2" {
 count             = var.create_rds_private_subnets ? 1 : 0
 availability_zone = "${var.region}c"
 cidr_block        = cidrsubnet(var.vpc_cidr, 8, 1)
 vpc_id            = var.vpc_id
 tags = {
   Name = "${var.environment}-rds-private-subnet-2"
 }
}

resource "aws_subnet" "rds_private_subnet_3" {
 count             = var.create_rds_private_subnets ? 1 : 0
 availability_zone = "${var.region}d"
 cidr_block        = cidrsubnet(var.vpc_cidr, 8, 2)
 vpc_id            = var.vpc_id
 tags = {
   Name = "${var.environment}-rds-private-subnet-3"
 }
}

resource "aws_subnet" "public_subnet_1" {
 availability_zone       = "${var.region}a"
 cidr_block              = cidrsubnet(var.vpc_cidr, 8, 3)
 vpc_id                  = var.vpc_id
 map_public_ip_on_launch = true
 tags = {
   Name = "${var.environment}-public-subnet-1"
 }
}

ここで注目すべきは、以下の2点です。

  1. countを使用した条件分岐
  2. cidrsubnet関数の使用

countを使用した条件分岐

countは、リソースを複数作成する際に使用します。ここでは、var.create_rds_private_subnetsの値によって、RDS用のプライベートサブネットを作成するかどうかを制御しています。

count = var.create_rds_private_subnets ? 1 : 0

var.create_rds_private_subnetsがtrueの場合、countは1となり、サブネットが1つ作成されます。falseの場合、countは0となり、サブネットは作成されません。

cidrsubnet関数の使用

cidrsubnet関数は、VPCのCIDRブロックを分割して、サブネットのCIDRブロックを計算するために使用します。

cidr_block = cidrsubnet(var.vpc_cidr, 8, 1)

この例では、var.vpc_cidrで指定されたVPCのCIDRブロックを、8ビットのサブネットマスクで分割し、1番目のサブネットのCIDRブロックを計算しています。

例えば、var.vpc_cidrが"10.0.0.0/16"の場合、以下のようなサブネットのCIDRブロックが計算されます。

  • rds_private_subnet_1: "10.0.0.0/24" (8ビット分割, 0番目)
  • rds_private_subnet_2: "10.0.1.0/24" (8ビット分割, 1番目)
  • rds_private_subnet_3: "10.0.2.0/24" (8ビット分割, 2番目)
  • public_subnet_1: "10.0.3.0/24" (8ビット分割, 3番目)

このように、cidrsubnet関数を使用することで、VPCのCIDRブロックを柔軟に分割し、サブネットのCIDRブロックを自動的に計算することができます。

variables.tf

variables.tfでは、モジュールで使用する変数を定義します。

variable "environment" {
 description = "環境名 (dev, stg, prd)"
 type        = string
}

variable "vpc_id" {
 description = "VPC ID"
 type        = string
}

variable "region" {
 description = "AWSリージョン"
 type        = string
 default     = "ap-northeast-1"
}

variable "vpc_cidr" {
 description = "VPCのCIDRブロック"
 type        = string
 default     = "172.31.0.0/16"
}

variable "create_rds_private_subnets" {
 description = "RDS用のプライベートサブネットを作成するかどうか"
 type        = bool
 default     = true
}

outputs.tf

outputs.tfでは、モジュールの出力値を定義します。

output "rds_subnet_ids" {
 value = [
   aws_subnet.rds_private_subnet_1[0].id,
   aws_subnet.rds_private_subnet_2[0].id,
   aws_subnet.rds_private_subnet_3[0].id
 ]
}

output "public_subnet_1_id" {
 value = aws_subnet.public_subnet_1.id
}

モジュールの使用

作成したSubnetモジュールを使用するには、main.tfで以下のように記述します。

module "subnets" {
 source      = "./00_modules/subnets"
 environment = var.environment
 vpc_id      = module.vpc.vpc_id
}

これにより、各環境に応じたSubnetを柔軟に作成することができます。

まとめ

Subnetをモジュール化することで、コードの再利用性が高まり、管理がしやすくなります。
環境ごとに異なる設定を適用する場合でも、モジュールを活用することで、コードの重複を避けることができます。

また、countを使用した条件分岐やcidrsubnet関数の使用により、より柔軟かつ自動化されたサブネットの作成が可能になります。

GitHubで編集を提案

Discussion

rakiraki

記事を否定する意図はないけど、公式モジュールがあるものは公式モジュールを使いましょう
https://github.com/terraform-aws-modules/terraform-aws-vpc

ちなみに、ぱっと見でしかないですが、サブネットを配置するazを決め打ちしているので、リージョンが変わるとazの記号は変わってしまって役に立ちません(例えばパリ{eu-west-3}はa,b,cです)