Terraformについて基本的な知識だけでなく使い方を理解したい。と思い、
オライリー社のTerraformではじめる実践IaCを用いてハンズオン学習を進めています。
https://www.oreilly.co.jp/books/9784814400133/
ただ文章を読みながらコードを打つだけではあまり理解できないと感じました。
NATゲートウェイとルートテーブルの作成まで完了した現時点で一区切りとして、
アウトプットで理解を深めたいと思い、記事を作成しました。
1. IaCの基礎 / 1~2章
- IaC(Infrastructure as Code)はインフラをコードで管理するアプローチ
- 手作業での構築は人為的ミスや環境ごとの差異が生じやすい
- コード化することで、再現性があり、複数環境への自動デプロイも可能になる
Iacはインフラをソースコードとして管理するツール
IaCの利点を整理すると、以下の3つに集約できる。
- 再現性:コードを使うことで、どのっ今日でも同じインフラを再現できる
- レビュー可能:Gitでコードレビューを行えるため、品質やセキュリティを担保しやすい
- 自動化:CI/CDと組み合わせることで、手動作業を減らし迅速に環境構築が可能
※図や表は後で追記
2. Terraformコマンドの理解 / 3章
主なコマンドの流れは以下のようなものがある。
-
terraform init
:初期化、providerやbackendを準備 -
terraform plan
:差分を確認 -
terraform apply
:実際に反映 -
terraform destroy
:リソース削除
Terraformコマンドは、インフラの状態をコードと実環境で一致するための一連の流れ
- init:Terraformの作業環境を整える(初期化)
- plan:変更内容を事前に見える化(差分確認)
- apply:コード通りに実環境をつくる(実際に反映)
- destroy:削除する(リソース削除)
特に「plan → apply」の流れが、インフラを壊さず安全に更新させる肝になる。
3. 変数・validation・for_each / 4~6章
-
variable
:外部から値を渡して再利用性を高められる- Terraformの環境変数
- 再利用性:変数化してコードを簡潔にできる
-
validation
:入力値を正規表現や条件式で検証できる(例:CIDRフォーマットチェック)- 入力チェックのガードレール
- 安全性:validationで誤った値を事前に防ぐ
-
for_each
:リソースを繰り返し生成できる(サブネットなどを動的に定義可能)- for文みたいに繰り返しリソースを作れる
- 柔軟性:for_eachで数や要素に応じて自動生成可能
(※7,8章はメンテナンスとimportのため、フローの関係から後述します。)
4. VPC作成とモジュール化 / 9~10章
- VPCをリソースとして作成し、CIDRやタグを指定できる
- モジュール化により、VPC作成を使いまわし可能な部品として定義できる
-
terraform init
でモジュールを取得し、module
ブロックで呼び出す -
terraform workspace
を使うと、同じコードでdev/stg/prodなど複数環境を切り替えて管理できる
VPCをモジュール化し、workspaceで環境ごとに使い分けられる
- 再利用性:dev/stg/prod環境に横展開できる
- 保守性:修正箇所を複数環境に反映しやすい
- 環境切替:
terraform workspace select dev
のように切替可能
5. サブネット・NAT Gateway・ルートテーブル / 11章
- public / privateサブネットとの分割
- AZに分散させるためのラウンドロビン方式
- NAT Gatewayを経由してPrivate Subnetからインターネットへアクセス
- 各サブネットにルートテーブルを関連づける必要がある
- Publicサブネット:デフォルトルートをInternet Gatewayに向ける
- Privateサブネット:デフォルトルートを同じAZのNAT Gatewayに向ける
1. for_each を使ったサブネット作成
複数の AZ にサブネットを展開するとき、for_each を使うとコードがシンプルになる。
resource "aws_subnet" "public" {
for_each = toset(var.subnet_cidrs.public)
vpc_id = aws_vpc.main.id
cidr_block = each.key
availability_zone = data.aws_availability_zones.available.names[
index(var.subnet_cidrs.public, each.key) % local.number_of_availability_zones
]
tags = {
Name = "${var.service_name}-${var.env}-${availability_zone}-public"
Env = var.env
Scope = "public"
}
}
2. NAT Gateway と Elastic IP の関連付け
NAT Gateway は EIP とセットで作成する。
resource "aws_eip" "nat" {
count = length(var.subnet_cidrs.public)
domain = "vpc"
tags = {
Name = "${var.service_name}-${var.env}-nat-eip-${count.index}"
}
}
resource "aws_nat_gateway" "nat" {
count = length(var.subnet_cidrs.public)
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id
tags = {
Name = "${var.service_name}-${var.env}-nat-gateway-${count.index}"
Env = var.env
}
}
3. ルートテーブルとアソシエーション
ルートテーブルは「作る → 紐づける」の順で定義する。
Public サブネットは IGW に、Private サブネットは NAT Gateway にデフォルトルートを向ける。
Publicルートテーブルとアソシエーション ※ルートテーブルとサブネットの紐づけ
# Public Route Table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.service_name}-${var.env}-public-rt"
Env = var.env
Scope = "public"
}
}
# デフォルトルート → IGW
resource "aws_route" "public_default_route" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
# Public Subnet と RT の関連付け
resource "aws_route_table_association" "public" {
for_each = aws_subnet.public
subnet_id = each.value.id
route_table_id = aws_route_table.public.id
}
Privateルートテーブルとアソシエーション
# Private Route Table
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.service_name}-${var.env}-private-rt"
Env = var.env
Scope = "private"
}
}
# デフォルトルート → NAT Gateway
resource "aws_route" "private_default_route" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat[0].id
}
# Private Subnet と RT の関連付け
resource "aws_route_table_association" "private" {
for_each = aws_subnet.private
subnet_id = each.value.id
route_table_id = aws_route_table.private.id
}
まとめ
ここまでTerraformの概要に対する理解から始まり、
VPC、サブネット、GW、ルートテーブルの作成まで進めました。
引き続きECSサービスやCI/CDの構成について理解を深めていきたいと思います。
参考
- オライリー「Terraform 実践ガイド」 222〜251ページ
- AWS VPC ドキュメント
- Terraform AWS Provider