1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraformについて

Last updated at Posted at 2025-10-02

Terraformについて基本的な知識だけでなく使い方を理解したい。と思い、
オライリー社のTerraformではじめる実践IaCを用いてハンズオン学習を進めています。
https://www.oreilly.co.jp/books/9784814400133/

ただ文章を読みながらコードを打つだけではあまり理解できないと感じました。
NATゲートウェイとルートテーブルの作成まで完了した現時点で一区切りとして、
アウトプットで理解を深めたいと思い、記事を作成しました。

image.png

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 を使うとコードがシンプルになる。

subnets.tf
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 とセットで作成する。

nat.tf
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ルートテーブルとアソシエーション ※ルートテーブルとサブネットの紐づけ

route_tables.tf
# 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ルートテーブルとアソシエーション

route_table.tf
# 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の構成について理解を深めていきたいと思います。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?