0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS IaC入門】Phase3: TerraformでVPC・EC2を構築した

0
Posted at

はじめに

前回のPhase2ではTerraformの基礎とリモートステートを学んだ。
Phase3ではいよいよ**ネットワーク(VPC)とサーバー(EC2)**をTerraformでコード化した記録。


目次

  1. 作った構成
  2. ファイル構成
  3. 各リソースの解説
  4. デプロイ結果
  5. 学んだこと

1. 作った構成

VPC (10.0.0.0/16)
  └── パブリックサブネット (10.0.1.0/24)
        └── EC2 (t3.micro)
              └── セキュリティグループ(SSH許可)
  └── インターネットゲートウェイ
        └── ルートテーブル → サブネットに紐付け

登場するリソースは7つ:

リソース 役割
aws_vpc ネットワーク全体
aws_subnet ネットワークの区画
aws_internet_gateway インターネットへの出入り口
aws_route_table 通信の経路設定
aws_route_table_association ルートテーブルとサブネットの紐付け
aws_security_group ファイアウォール
aws_instance EC2サーバー本体

2. ファイル構成

phase3/
  ├── provider.tf    # AWSプロバイダー + S3バックエンド
  ├── variables.tf   # 変数定義
  ├── main.tf        # リソース定義
  └── outputs.tf     # 出力定義

variables.tf

variable "project_name" {
  type    = string
  default = "tf-practice"
}

variable "az" {
  type    = string
  default = "ap-northeast-1a"
}

変数化することで、project_name を変えるだけで全リソース名が一括変更できる。

outputs.tf

output "ec2_public_ip" {
  value = aws_instance.web.public_ip
}

output "vpc_id" {
  value = aws_vpc.main.id
}

apply 後に自動表示される。public_ip.id はAWSが決めた属性名で、Terraformのドキュメントで確認できる。


3. 各リソースの解説

VPC

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${var.project_name}-vpc"
  }
}

10.0.0.0/16 はこのVPC内で使えるIPアドレスの範囲。約65,000個のIPが使える。

パブリックサブネット

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = var.az
  map_public_ip_on_launch = true
  tags = {
    Name = "${var.project_name}-public-subnet"
  }
}

map_public_ip_on_launch = true でこのサブネットにEC2を置くと自動でパブリックIPが割り当てられる。

インターネットゲートウェイ

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "${var.project_name}-igw"
  }
}

VPCとインターネットをつなぐ出入り口。これがないと外と通信できない。

ルートテーブル + サブネット紐付け

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "${var.project_name}-public-rt"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

IGWを作っただけでは通信できない。ルートテーブルで「全ての通信をIGWに流す」という道案内を設定し、サブネットに紐付ける必要がある。

2つに分かれている理由は、ルートテーブル自体の定義と、どのサブネットに適用するかの設定を分離するため。

セキュリティグループ

resource "aws_security_group" "web" {
  vpc_id = aws_vpc.main.id
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "${var.project_name}-sg"
  }
}
ingress = 入ってくる通信の制御
  └── ポート22(SSH)を全IPから許可

egress = 出ていく通信の制御
  └── protocol = "-1" は全プロトコルを意味する
  └── 全ての通信を許可

今回は学習用なので 0.0.0.0/0(全IP許可)にしているが、本番環境では自分のIPだけに絞るべき。

EC2

resource "aws_instance" "web" {
  ami                    = "ami-0599b6e53ca798bb2"
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web.id]
  tags = {
    Name = "${var.project_name}-ec2"
  }
}
ami           → EC2のOSイメージ(Amazon Linux 2023)
instance_type → サーバーのスペック(t3.microは無料枠対象)

4. デプロイ結果

terraform plan
# Plan: 7 to add, 0 to change, 0 to destroy.

terraform apply
# Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
#
# Outputs:
# ec2_public_ip = "13.113.1.68"
# vpc_id        = "vpc-0ec33bc5ba81dbd35"

AWSコンソールでEC2が 実行中 になっていることを確認。
outputsで出たIPアドレスとコンソールの表示が一致していた。


5. 学んだこと

リソース間の参照

# VPCのIDをサブネットで参照
vpc_id = aws_vpc.main.id

# サブネットのIDをEC2で参照
subnet_id = aws_subnet.public.id

Terraformはリソース同士を参照できる。これによりTerraformが依存関係を自動で判断して正しい順番でデプロイしてくれる。

IGWだけでは通信できない

IGW作成だけでは不十分
  └── ルートテーブルで「IGWに流す」設定
        └── サブネットに紐付け
              └── これで初めてインターネットと通信できる

パブリック vs プライベートサブネット

パブリック → インターネットから直接アクセス可能(Webサーバー向け)
プライベート → インターネットから直接アクセス不可(DBサーバー向け)

DBをパブリックに置くと漏洩リスクがある。プライベートサブネット + NAT Gatewayが本番構成の基本。


コードはGitHubで公開しています:
https://github.com/Allure2140/aws-iac-learning

次のPhase4ではAWS CDKに挑戦します。


参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?