TerraformでAWSにWebサーバを作成する【04. EC2 - IGW編】


こんにちは、Masuyama です。

本記事は Terraform で AWS を操作する第一歩となる「TerraformでAWSにWebサーバを作成する【01. インストール編】」シリーズの一つです。

前回の記事 - 03. VPC編 にて、AWS リソースを実際に作ってみることで基本的な作成方法を学びました。
今回は残りのリソースである EC2、そして IGW (Internet Gateway - インターネットゲートウェイ) を作成してしまいます。

Internet Gateway 作成

ではインターネットゲートウェイと、インターネット向けのルートに関するリソースを作成します。

igw.tf

# Internet Gateway
resource "aws_internet_gateway" "tfweb_igw" {
  vpc_id = "${aws_vpc.tfweb_vpc.id}"
}

# Route Table
resource "aws_route_table" "tfweb_rt" {
  vpc_id = "${aws_vpc.tfweb_vpc.id}"

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_net_gateway.tfweb_igw.id
  }
}

# Associate route table with subnet
resource "aws_route_table_association" "tfweb_rt_association" {
  subnet_id      = aws_subnet.tfweb_subnet.id
  route_table_id = aws_route_table.tfweb_rt.id
}

ここでは 3つの操作を実行しています。

  1. IGW を作成
  2. IGW に向けたルートテーブルを作成
  3. 前回作成したサブネットにルートテーブルを紐付け

EC2 インスタンス (Web サーバ) 作成

それでは EC2、そして結びつけるセキュリティグループを作成します。

ec2.tf

# EC2 instance
resource "aws_instance" "tfweb_ec2" {
  ami                         = "ami-06098fd00463352b6" # AmazonLinux 2 (x86)
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.tfweb_subnet.id
  key_name                    = "xxxxxxxxxx_key" # 既存のキーペアを指定

  vpc_security_group_ids = [
    aws_security_group.tfweb_sg_web.id,
    aws_security_group.tfweb_sg_ssh.id
  ]

  user_data = <<EOF
  #!/bin/bash
  yum install -y httpd
  systemctl start httpd.service
  EOF
}

# Security Group
resource "aws_security_group" "tfweb_sg_web" {
  name   = "tfweb_sg_web"
  vpc_id = aws_vpc.tfweb_vpc.id

  ingress {
    description = "allow http"
    from_port   = "80"
    to_port     = "80"
    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"]
  }
}

resource "aws_security_group" "tfweb_sg_ssh" {
  name   = "tfweb_sg_ssh"
  vpc_id = aws_vpc.tfweb_vpc.id

  ingress {
    description = "allow ssh"
    from_port   = "22"
    to_port     = "22"
    protocol    = "tcp"
    cidr_blocks = ["x.x.x.x/32"] # 必要なIP制限を設定
  }

  egress {
    from_port   = "0"
    to_port     = "0"
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

ポイントをいくつか解説します。

  • キーペア
    • 予め AWS コンソール等から作成しておいた既存のキーペアを指定します
    • キーペアの名前を指定するだけで OK です
  • SSH 用セキュリティグループ内の "ingress" では必要な IP 制限のみ設定
    • EC2 への SSH アクセスを許可する IP アドレスは絞っておきましょう
  • ユーザデータ
    • EC2 インスタンス起動時に実行するスクリプトをユーザデータとして直接記述できます
      • ちなみに別ファイルにまとめておくことも可能
    • ここでは Apache をインストールして起動するスクリプトを指定しています

terraform apply

それでは追加したいリソース設定を terraform apply で適用します。

$ terraform apply
...
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.

これで設定した状態が実現され、Apache が起動した Web サーバが立ち上がっているはずです。
次はそのサーバのパブリック IP アドレスを確認し、Apache が起動していることを確認しましょう。

terraform show

作成したリソースの情報は terraform show コマンドから確認できます。

$ terraform show
# aws_instance.tfweb_ec2:
resource "aws_instance" "tfweb_ec2" {
    ami                                  = "ami-06098fd00463352b6"
    arn                                  = "arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxxx:instance/i-0a43d3240ae8a26f8"
    associate_public_ip_address          = true
    availability_zone                    = "ap-northeast-1a"
    cpu_core_count                       = 1
    cpu_threads_per_core                 = 1
    disable_api_termination              = false
...

この出力からパブリック IP を確認したいのですが、作成されるリソースが多いと見にくいですね。
今回は "public_ip" という形式でパブリック IP を確認できるので、grep で絞り込みをしながら出力を確認します。

$ terraform show | grep public_ip
    associate_public_ip_address          = true
    public_ip                            = "52.194.219.150"

EC2 インスタンスのパブリック IP が 52.194.219.150 であることを確認できました。
(適用の都度、変わります)

Web サーバへアクセス

それでは先ほど確認したパブリック IP へブラウザからアクセスしてみましょう。
問題がなければ、Apache のテストページが表示されているはずです。

リソース削除

これで今回の目的を達成できたので、作成したリソースはすべて削除しておきます。
基本的には terraform destroy コマンドから一括で削除できます。
※作成した EC2 に終了保護をかけていたり、作成した S3 バケットが空でない場合は本コマンド一発では削除できません。

$ terraform destroy
...
Destroy complete! Resources: 8 destroyed.

これで今回作成したリソースをすべて削除できました。