【初心者向け】Terraform で最初から EC2 インスタンスを起動する手順(ハンズオン編)
こんにちは!
初心者エンジニアの田中です
この記事では、先日投稿したTerraformの概要整理に引き続き、実際にTerraform を使ってAWS EC2を最初から起動するまで手順をまとめます。
記事内容
- 事前準備(AWS アクセスキー、キーペア、Terraform のインストールなど)
- プロジェクトフォルダ・TF ファイルの構成
- 各 TF ファイルの内容例(機能ごとに分割)
- Terraform の実行手順(
init
→plan
→apply
) - 動作確認(SSH・HTTP)
- まとめ
はじめに
Terraform はインフラストラクチャをコードとして定義し、自動化で資源を作成・更新できるツールです。本記事では、AWS の EC2 インスタンスを起動するまでを具体的に解説します。
所々にスクショ等貼っていきますので、参考にされてください♪
-
対象となる方
- Terraform を聞いたことがあるくらいの方
- AWS EC2 を Terraform で構築したい方
- S3、VPC、サブネットなどの基本操作はできるが、Terraform で EC2 を起動したことがない方
-
想定環境
- OS:Windows 10/11
- AWS リージョン:東京リージョン(
ap-northeast-1
) - Terraform:v1.x系 (例:v1.12.1)
1.
事前準備
1-1. AWS アクセスキー・シークレットキーの準備
3.下記をメモしておく
- Access Key ID
- Secret Access Key(一度しか表示されないので必ず保管)
ポイント
- 一度ウィンドウを閉じると Secret Access Key は再取得できません。
4 .ここでアクセスキーとシークレットアクセスキーを設定しておきましょう。
↑上の2行が設定用コマンドです。
上から3行目の[set AWS]で設定内容の確認です。
1-2. EC2 用キーペアの作成
-
AWS 管理コンソール→EC2→左メニュー「ネットワーク&セキュリティ」→「キーペア」
-
「キーペアの作成」ボタンを押す
-
キーペア名:
tanaka.key
(例) - キーペアタイプ:デフォルト(RSA + PEM)で OK
-
キーペア名:
-
キーペア作成後、ダウンロードされる
tanaka.key.pem
を安全な場所に保管する- この
.pem
ファイルをローカルに持っておかないと SSH 接続できません。 - Windows で PuTTY を使う場合は
.ppk
形式に変換しますが、Terraform で指定するのは キーペア名(tanaka.key
) です。
- この
1-3. Terraform のインストールと動作確認
1-3-1. Terraform のダウンロード
- Terraform 公式ダウンロードページ を開く
- 「Terraform 1.x.x for Windows (64-bit)」 の ZIP ファイルをダウンロード(例:
terraform_1.12.1_windows_amd64.zip
)
1-3-2. 解凍・配置
-
ダウンロードした ZIP を右クリック→「すべて展開」→任意のフォルダに解凍
-
解凍後、
terraform.exe
があることを確認
1-3-3. PATH に登録(推奨)
-
例"C:\Users\Owner\terraform_1.12.1_windows_amd64" を追加→「OK」を何度かクリックしてダイアログを閉じる
-
必ず開いているコマンドプロンプト/PowerShell を 一度閉じて→再度開く
1-3-4. Terraform 動作確認
terraform version
- 正常なら
Terraform v1.12.1 on windows_amd64
のようにバージョン情報が表示されます。
これでTerraformのインストールが完了しました!
次にEC2起動に関する複数のコマンド一式をを格納するフォルダーを先に作っていきます。
2.
プロジェクトフォルダ・tf ファイル構成
2-1. プロジェクトフォルダ作成
-
デスクトップ上で右クリック→「新規作成」→「フォルダー」
-
フォルダー名を
terraform-ec2
に変更
下の例のように、上のフォルダのパスもメモしておくと後々便利かもしれません。例:C:\Users\Owner\OneDrive\Desktop\terraform-ec2
-
VSCode でこのフォルダを開き、以降の tf ファイルは VSCode 上で作成する。
※私はVScodeで作成しましたが、cursor等のエディタでも構いません。
2-2. tf ファイルを機能別に分割
本記事では、ファイルを機能(役割)ごとに分割して管理します。分割例は下記のとおりです。
terraform-ec2/
├── provider.tf # AWS プロバイダ設定
├── data.tf # データソース定義(VPC / Subnets 取得)
├── security_group.tf # セキュリティグループ定義
├── ec2.tf # EC2 インスタンス定義
└── outputs.tf # 出力定義(Public IP / Instance ID 等)
各ファイルは VSCode を使って直接作成し、以下の内容を貼り付けてください。
↑↑↑順不同ですみません。
3.
各 tf ファイルの内容例
以下サンプルは、東京リージョン (ap-northeast-1
) を前提に書いています。
実際に動かすときは、AMI ID や キーペア名 をご自身の環境に合わせて書き換えてください。
今回はAmazonLinux2023AMIで作業しています。
3-1. provider.tf
# provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # AWS プロバイダ v5 系を利用する例(バージョン指定の意味は、5.0 以上かつ 6.0 未満の最新リリースを使用する、という指定方法です)
}
}
}
provider "aws" {
region = "ap-northeast-1" # 東京リージョン
}
3-2. data.tf
# data.tf
####################################################
# 1. デフォルト VPC の情報を取得
####################################################
data "aws_vpc" "default" {
default = true
}
####################################################
# 2. デフォルト VPC 内のサブネット一覧を取得
####################################################
data "aws_subnets" "default" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
3-3. security_group.tf
# security_group.tf
####################################################
# セキュリティグループ定義:SSH(22) と HTTP(80) を許可
# [tanaka-sg]のところは、分かりやすいように変えてください。
####################################################
resource "aws_security_group" "tanaka_sg" {
name = "tanaka-sg"
description = "Allow SSH and HTTP"
vpc_id = data.aws_vpc.default.id
# SSH(22) を全世界から許可
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# HTTP(80) を全世界から許可
ingress {
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"]
}
tags = {
Name = "tanaka-sg"
}
}
3-4. ec2.tf
# ec2.tf
####################################################
# EC2 インスタンス定義
# [tanaka-ec2]のところは、分かりやすいように変えてください。
####################################################
resource "aws_instance" "tanaka_ec2" {
# ────────────────────────────────────────────────────────
# 1. AMI ID:東京リージョン用の Amazon Linux 2 などに変更してください
# ────────────────────────────────────────────────────────
ami = "ami-027fff96cc515f7bc"
# ────────────────────────────────────────────────────────
# 2. インスタンスタイプ:t3.micro(無料枠対象/安価)
# ────────────────────────────────────────────────────────
instance_type = "t3.micro"
# ────────────────────────────────────────────────────────
# 3. キーペア名:作成済みのキーペア名に変更
# ────────────────────────────────────────────────────────
key_name = "tanaka.key"
# ────────────────────────────────────────────────────────
# 4. セキュリティグループ:先ほど作成した SG を参照
# ────────────────────────────────────────────────────────
vpc_security_group_ids = [aws_security_group.tanaka_sg.id]
# ────────────────────────────────────────────────────────
# 5. サブネットを指定:デフォルト VPC 内の最初のサブネットを使う例
# ────────────────────────────────────────────────────────
subnet_id = data.aws_subnets.default.ids[0]
# ────────────────────────────────────────────────────────
# 6. パブリック IP を必ず割り当てる設定
# ────────────────────────────────────────────────────────
associate_public_ip_address = true
tags = {
Name = "tanaka-ec2"
}
}
3-5. outputs.tf
# outputs.tf
####################################################
# 1. 公開 IP アドレスを出力
####################################################
output "ec2_public_ip" {
description = "作成された EC2 のパブリック IP アドレス"
value = aws_instance.tanaka_ec2.public_ip
}
####################################################
# 2. インスタンス ID を出力
####################################################
output "ec2_instance_id" {
description = "作成された EC2 のインスタンス ID"
value = aws_instance.tanaka_ec2.id
}
4.
Terraform 実行手順
4-1. フォルダとファイルを最終確認
terraform-ec2/
├── provider.tf
├── data.tf
├── security_group.tf
├── ec2.tf
└── outputs.tf
- 各ファイルに前章のコードをコピー&ペーストし、保存する。
- 必要な箇所(AMI ID、キーペア名、リージョンなど)が自分の環境に合っているか確認。
4-2. 初期化(terraform init
)
cd %USERPROFILE%\Desktop\terraform-ec2
terraform init
-
terraform init
は以下を実行する-
.terraform/
フォルダを作成 - 必要なプロバイダプラグイン(hashicorp/aws)をダウンロード
-
.terraform.lock.hcl
を生成(ロックファイル)
-
-
正常終了すると緑色のメッセージで「Terraform has been successfully initialized!」と表示される
4-3. プランの確認(terraform plan
)
terraform plan
-
どのリソースが作成・変更・破棄されるかを確認できる
-
正常に動作していれば、赤字のエラーが出ずに以下のような行が表示されるはずです。
Plan: 2 to add, 0 to change, 0 to destroy.
-
2 to add は、
aws_security_group.tanaka_sg
とaws_instance.tanaka_ec2
の2リソースが作成対象であることを表す
-
2 to add は、
もしエラーが出た場合
-
data.tf
、security_group.tf
、ec2.tf
内のスペルミスや、data
/resource
ブロックの書き間違いが原因なことが多い。 - エラー全文を読み、該当ファイルの該当行を修正して再度
terraform plan
を実行する。
4-4. 適用(terraform apply
)
terraform apply
-
実行すると「Do you want to perform these actions?」という確認が出るので、
yes
と入力して Enter -
作成処理が始まり、以下のように進行状況が表示される(一部例)
aws_security_group.tanaka_sg: Creating... aws_security_group.tanaka_sg: Creation complete after 3s [id=sg-0123456789] aws_instance.tanaka_ec2: Creating... aws_instance.tanaka_ec2: Still creating... [10s elapsed] aws_instance.tanaka_ec2: Creation complete after 15s [id=i-abcdifghij...] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: ec2_public_ip = 54.123.45.67 ec2_instance_id = i-0b0f022c9e649bb56
-
出力された
ec2_public_ip
をメモしておくと、SSH やブラウザ接続時に便利です。
5.
動作確認
5-1. EC2 インスタンスの確認(AWS コンソール)
- AWS 管理コンソール→EC2→左メニュー「インスタンス」
- タグ
Name = tanaka-ec2
のインスタンスが作成されているか確認 - インスタンス詳細を見ると、Public IPv4 アドレス が
54.123.45.67
(例)などとなっているはず
5-2. HTTP 接続確認(Apache を使ったサイト確認)
EC2 インスタンスを起動しただけでは、ブラウザでアクセスしても何も表示されません。ここでは、Apache をインストールして動作確認する手順を説明します。
5-2-1. SSH で EC2 インスタンスにログイン
まずは SSH を使って EC2 インスタンスに接続し、コマンド操作ができる状態にします。
-
パブリック IP を確認
Terraform 実行後に表示されたec2_public_ip
(例:54.123.45.67
)を控えておきます。 -
.pem ファイルのパスを確認
例:C:/Users/Owner/Downloads/tanaka.key.pem
-
SSH コマンドを実行
Windows のコマンドプロンプト/PowerShell から以下を入力します。ssh -i "C:/Users/Owner/Downloads/tanaka.key.pem" ec2-user@54.123.45.67
- キーペアを作成したときにダウンロードした
.pem
ファイルのフルパスを-i
オプションで指定します。 - Amazon Linux 2023 AMI のデフォルトユーザーは
ec2-user
です。
- キーペアを作成したときにダウンロードした
-
初回接続時の警告
The authenticity of host '54.123.45.67 (54.123.45.67)' can't be established. ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
と表示されるので、
yes
と入力して Enter。 -
SSH 接続完了
プロンプトがec2-user@ip-172-31-5-179 ~]$
のように変われば接続成功です。
5-2-2. Apache(httpd)のインストール
SSH 接続した EC2 インスタンス上で以下を実行します。
-
パッケージリポジトリを最新化
sudo yum update -y
- 最新のパッケージ情報に更新してから Apache をインストールします。
-
Apache コマンドをインストール
sudo yum install -y httpd
-
-y
を付けることで自動的にインストールが進みます。
-
-
Apache サービスを起動
sudo systemctl start httpd
-
ブート時の自動起動を有効化
sudo systemctl enable httpd
-
ステータス確認
sudo systemctl status httpd
-
active (running)
と表示されれば正常に起動しています。
-
5-2-3. セキュリティグループの確認
Terraform の security_group.tf
では以下のように HTTP(ポート 80)を許可しています。
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
-
もし設定が反映されていない場合は、ローカルで以下を実行して更新します。
terraform apply
-
AWS コンソールの EC2 → セキュリティグループ → インバウンド ルール でもポート 80 が「0.0.0.0/0」で許可されているか確認できます。
5-2-4. ブラウザでサイトにアクセス
-
ローカルの Web ブラウザを開きます。
-
アドレスバーに以下を入力します。
http://54.123.45.67
-
54.123.45.67
は実際のec2_public_ip
に置き換え。
-
-
Apache のデフォルトのウェルカムページ(例: “Amazon Linux 2023 Test Page”)が表示されれば成功です。
5-2-5. 動作しない場合のトラブルシューティング
-
Apache サービスが起動していない
- インスタンスに SSH で再接続し、
sudo systemctl status httpd
を実行してrunning
か確認する。 - 止まっていれば
sudo systemctl start httpd
を再実行する。
- インスタンスに SSH で再接続し、
-
セキュリティグループでポート 80 が開放されていない
- AWS コンソールのセキュリティグループ設定を確認し、インバウンド 80 が許可されているかをチェック。
-
インスタンスのステータスが “running” ではない
- EC2 ダッシュボードでステータスが “running” か、正常に初期化できているか確認。
-
ブラウザが HTTPS でアクセスしている
- 今回は HTTP(ポート 80)でのみ動作するため、
http://
を明示してアクセスする。
- 今回は HTTP(ポート 80)でのみ動作するため、
6.
まとめ
-
SSH(Secure Shell)で EC2 にログイン
-
.pem
を使ってssh -i "tanaka.key.pem" ec2-user@<EC2_PUBLIC_IP>
でリモートシェルに接続 - サーバー内部の操作(Apache インストール、設定変更、ログ確認など)は SSH で行う
-
-
Apache(httpd)をインストールして起動
-
sudo yum update -y && sudo yum install -y httpd
でインストール -
sudo systemctl start httpd
でサービス起動、sudo systemctl enable httpd
でブート時自動起動 - ポート 80 がインバウンド許可されていることを確認
-
-
ブラウザから
http://<EC2_PUBLIC_IP>
でアクセス- Apache のデフォルトウェルカムページが表示されれば OK
-
トラブルシューティング
- Apache が起動しているか、SG でポート 80 が開放されているかなどを順に確認
いかがでしたでしょうか?
今回の目的はTerraformでEC2を起動させるということでした。
今後Terraform×AWSのテーマをどんどん深掘りしていければと思います。
分かりづらい箇所も多々あるかと思いますので、コメント等いただけますと幸いです。
最後までありがとうございました。田中でした!