【初心者向け】Terraform で最初から EC2 インスタンスを起動する手順（ハンズオン編）

# 【初心者向け】Terraform で最初から EC2 インスタンスを起動する手順（ハンズオン編）:rocket:

こんにちは！
初心者エンジニアの田中です:baby:
この記事では、先日投稿したTerraformの概要整理に引き続き、実際にTerraform を使ってAWS EC2を最初から起動するまで手順をまとめます。

## 記事内容
1. 事前準備（AWS アクセスキー、キーペア、Terraform のインストールなど）
2. プロジェクトフォルダ・TF ファイルの構成
3. 各 TF ファイルの内容例（機能ごとに分割）
4. Terraform の実行手順（`init` → `plan` → `apply`）
5. 動作確認（SSH・HTTP）
6. まとめ

---

## :star2:はじめに

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. :pick:事前準備

### 1-1. AWS アクセスキー・シークレットキーの準備

1. AWS 管理コンソール→**IAM**→左メニュー「**ユーザー**」→対象ユーザーを選択
2. **セキュリティ認証情報**タブ→「**アクセスキーの作成**」
※キーをすでに把握されている方は飛ばしてかまいません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/85443082-7522-466c-ac39-ca5b3a649b41.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/003c6579-51a1-4e34-9668-af1d8218d836.png)


3.下記をメモしておく

   * **Access Key ID**
   * **Secret Access Key**（一度しか表示されないので必ず保管）

 **ポイント**

 * 一度ウィンドウを閉じると **Secret Access Key** は再取得できません。

4 .ここでアクセスキーとシークレットアクセスキーを設定しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/d940e16d-a29a-4eba-88dc-5f593a92dba9.png)
↑上の２行が設定用コマンドです。
上から３行目の[set AWS]で設定内容の確認です。

---

### 1-2. EC2 用キーペアの作成

1. **AWS 管理コンソール**→**EC2**→左メニュー「ネットワーク＆セキュリティ」→「キーペア」
2. 「**キーペアの作成**」ボタンを押す

   * **キーペア名**：`tanaka.key`（例）
   * キーペアタイプ：デフォルト（RSA + PEM）で OK
3. キーペア作成後、ダウンロードされる `tanaka.key.pem` を安全な場所に保管する

   * この `.pem` ファイルをローカルに持っておかないと SSH 接続できません。
   * Windows で PuTTY を使う場合は `.ppk` 形式に変換しますが、Terraform で指定するのは **キーペア名（`tanaka.key`）** です。

---

### 1-3. Terraform のインストールと動作確認

#### 1-3-1. Terraform のダウンロード

1. [Terraform 公式ダウンロードページ](https://www.terraform.io/downloads.html) を開く
2. 「Terraform **1.x.x for Windows (64-bit)**」 の ZIP ファイルをダウンロード（例：`terraform_1.12.1_windows_amd64.zip`）

#### 1-3-2. 解凍・配置

1. ダウンロードした ZIP を右クリック→「すべて展開」→任意のフォルダに解凍

2. 解凍後、`terraform.exe` があることを確認

#### 1-3-3. PATH に登録（推奨）

1. **スタートメニュー**→「環境変数の編集」→「環境変数(N)…」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/584d2eda-9bf4-4f5f-972c-3076425701a0.png)

2. 「システム環境変数」→`Path` を選択→「編集(E)…」→「新規(N)」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/cf75144b-f83a-47e8-8dc0-1617dfd4d2f6.png)

3. 例"C:\Users\Owner\terraform_1.12.1_windows_amd64" を追加→「OK」を何度かクリックしてダイアログを閉じる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/45953531-a6d7-4c7a-8e09-b44fb2fd65f1.png)

4. **必ず**開いているコマンドプロンプト／PowerShell を **一度閉じて→再度開く**

#### 1-3-4. Terraform 動作確認

```powershell
terraform version
```

* 正常なら `Terraform v1.12.1 on windows_amd64` のようにバージョン情報が表示されます。

これでTerraformのインストールが完了しました！
次にEC2起動に関する複数のコマンド一式をを格納するフォルダーを先に作っていきます。

---

## 2. :pencil2:プロジェクトフォルダ・tf ファイル構成

### 2-1. プロジェクトフォルダ作成

1. デスクトップ上で右クリック→「新規作成」→「フォルダー」

2. フォルダー名を **`terraform-ec2`** に変更
下の例のように、上のフォルダのパスもメモしておくと後々便利かもしれません。
   ```
   例：C:\Users\Owner\OneDrive\Desktop\terraform-ec2
   ```
3. 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 等）
```
<br>

各ファイルは VSCode を使って直接作成し、以下の内容を貼り付けてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/d5b92f72-88af-4cd4-83e6-04a4e6882e0d.png)

↑↑↑順不同ですみません。:sweat:

---

## 3. :page_facing_up:各 tf ファイルの内容例

以下サンプルは、**東京リージョン (`ap-northeast-1`)** を前提に書いています。
実際に動かすときは、**AMI ID** や **キーペア名** をご自身の環境に合わせて書き換えてください。
今回は**AmazonLinux2023AMI**で作業しています。

---

### 3-1. provider.tf

```hcl
# 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

```hcl
# 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

```hcl
# 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

```hcl
# 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

```hcl
# 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. :zap:Terraform 実行手順

### 4-1. フォルダとファイルを最終確認

```
terraform-ec2/
├── provider.tf
├── data.tf
├── security_group.tf
├── ec2.tf
└── outputs.tf
```

1. 各ファイルに前章のコードをコピー＆ペーストし、**保存**する。
2. 必要な箇所（AMI ID、キーペア名、リージョンなど）が自分の環境に合っているか確認。

---

### 4-2. 初期化（`terraform init`）

```powershell
cd %USERPROFILE%\Desktop\terraform-ec2
terraform init
```

* `terraform init` は以下を実行する

  * `.terraform/` フォルダを作成
  * 必要なプロバイダプラグイン（hashicorp/aws）をダウンロード
  * `.terraform.lock.hcl` を生成（ロックファイル）
* 正常終了すると緑色のメッセージで「Terraform has been successfully initialized!」と表示される

---

### 4-3. プランの確認（`terraform plan`）

```powershell
terraform plan
```

* どのリソースが作成・変更・破棄されるかを確認できる
* 正常に動作していれば、**赤字のエラーが出ず**に以下のような行が表示されるはずです。

  ```
  Plan: 2 to add, 0 to change, 0 to destroy.
  ```

  * **2 to add** は、`aws_security_group.tanaka_sg` と `aws_instance.tanaka_ec2` の２リソースが作成対象であることを表す

 **もしエラーが出た場合**

 * `data.tf`、`security_group.tf`、`ec2.tf` 内のスペルミスや、`data` / `resource` ブロックの書き間違いが原因なことが多い。
 * エラー全文を読み、該当ファイルの該当行を修正して再度 `terraform plan` を実行する。

---

### 4-4. 適用（`terraform apply`）

```powershell
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. :eyes:動作確認

### 5-1. EC2 インスタンスの確認（AWS コンソール）

1. AWS 管理コンソール→**EC2**→左メニュー「インスタンス」
2. タグ `Name = tanaka-ec2` のインスタンスが作成されているか確認
3. インスタンス詳細を見ると、**Public IPv4 アドレス** が `54.123.45.67`（例）などとなっているはず


---

### 5-2. HTTP 接続確認（Apache を使ったサイト確認）

EC2 インスタンスを起動しただけでは、ブラウザでアクセスしても何も表示されません。ここでは、Apache をインストールして動作確認する手順を説明します。

#### 5-2-1. SSH で EC2 インスタンスにログイン

まずは SSH を使って EC2 インスタンスに接続し、コマンド操作ができる状態にします。

1. **パブリック IP を確認**
   Terraform 実行後に表示された `ec2_public_ip`（例：`54.123.45.67`）を控えておきます。
2. **.pem ファイルのパスを確認**
   例：`C:/Users/Owner/Downloads/tanaka.key.pem`
3. **SSH コマンドを実行**
   Windows のコマンドプロンプト／PowerShell から以下を入力します。

   ```powershell
   ssh -i "C:/Users/Owner/Downloads/tanaka.key.pem" ec2-user@54.123.45.67
   ```

   * キーペアを作成したときにダウンロードした `.pem` ファイルのフルパスを `-i` オプションで指定します。
   * Amazon Linux 2023 AMI のデフォルトユーザーは `ec2-user` です。
4. **初回接続時の警告**

   ```
   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。
5. **SSH 接続完了**
   プロンプトが `ec2-user@ip-172-31-5-179 ~]$` のように変われば接続成功です。

---

#### 5-2-2. Apache（httpd）のインストール

SSH 接続した EC2 インスタンス上で以下を実行します。

1. **パッケージリポジトリを最新化**

   ```bash
   sudo yum update -y
   ```

   * 最新のパッケージ情報に更新してから Apache をインストールします。
2. **Apache コマンドをインストール**

   ```bash
   sudo yum install -y httpd
   ```

   * `-y` を付けることで自動的にインストールが進みます。
3. **Apache サービスを起動**

   ```bash
   sudo systemctl start httpd
   ```
4. **ブート時の自動起動を有効化**

   ```bash
   sudo systemctl enable httpd
   ```
5. **ステータス確認**

   ```bash
   sudo systemctl status httpd
   ```

   * `active (running)` と表示されれば正常に起動しています。

---

#### 5-2-3. セキュリティグループの確認

Terraform の `security_group.tf` では以下のように HTTP（ポート 80）を許可しています。

```hcl
ingress {
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}
```

* もし設定が反映されていない場合は、ローカルで以下を実行して更新します。

  ```powershell
  terraform apply
  ```
* AWS コンソールの EC2 → セキュリティグループ → インバウンド ルール でもポート 80 が「0.0.0.0/0」で許可されているか確認できます。

---

#### 5-2-4. ブラウザでサイトにアクセス

1. ローカルの Web ブラウザを開きます。
2. アドレスバーに以下を入力します。

   ```
   http://54.123.45.67
   ```

   * `54.123.45.67` は実際の `ec2_public_ip` に置き換え。
3. Apache のデフォルトのウェルカムページ（例: “Amazon Linux 2023 Test Page”）が表示されれば成功です。

   * 成功例:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4087921/0d5eceea-c9cb-45cb-8e8c-f6c731653542.png)

---

#### 5-2-5. 動作しない場合のトラブルシューティング 

* **Apache サービスが起動していない**

  * インスタンスに SSH で再接続し、 `sudo systemctl status httpd` を実行して `running` か確認する。
  * 止まっていれば `sudo systemctl start httpd` を再実行する。

* **セキュリティグループでポート 80 が開放されていない**

  * AWS コンソールのセキュリティグループ設定を確認し、インバウンド 80 が許可されているかをチェック。

* **インスタンスのステータスが “running” ではない**

  * EC2 ダッシュボードでステータスが “running” か、正常に初期化できているか確認。

* **ブラウザが HTTPS でアクセスしている**

  * 今回は HTTP（ポート 80）でのみ動作するため、`http://` を明示してアクセスする。

---

## 6. :point_up:まとめ

1. **SSH（Secure Shell）で EC2 にログイン**

   * `.pem` を使って `ssh -i "tanaka.key.pem" ec2-user@<EC2_PUBLIC_IP>` でリモートシェルに接続
   * サーバー内部の操作（Apache インストール、設定変更、ログ確認など）は SSH で行う

2. **Apache（httpd）をインストールして起動**

   * `sudo yum update -y && sudo yum install -y httpd` でインストール
   * `sudo systemctl start httpd` でサービス起動、`sudo systemctl enable httpd` でブート時自動起動
   * ポート 80 がインバウンド許可されていることを確認

3. **ブラウザから `http://<EC2_PUBLIC_IP>` でアクセス**

   * Apache のデフォルトウェルカムページが表示されれば OK

4. **トラブルシューティング**

   * Apache が起動しているか、SG でポート 80 が開放されているかなどを順に確認

---
いかがでしたでしょうか？
今回の目的はTerraformでEC2を起動させるということでした。
今後Terraform×AWSのテーマをどんどん深掘りしていければと思います。
分かりづらい箇所も多々あるかと思いますので、コメント等いただけますと幸いです。
最後までありがとうございました。田中でした！:runner_tone2::dash: