はじめに
AWS素人の私が社内向けにIaCをテーマにしたAWS勉強会を行うことになったので、TerraformでEC2を構築してみようというが今回のテーマです。
何故、Terraformを選んだかというと、CloudFormationを取り扱った勉強会は他者が実施済みだったので、今回はTerraformに挑戦することにしました。
| この記事で扱うこと | この記事で扱わないこと |
|---|---|
| HCL(専用言語)によるコードの実装 | Terraformを使うまでの環境構築 |
Terraformとは
今更ですが、Terraformはクラウド環境構築の作業をコードで自動化するためのツールです。
AWSマネージメントコンソールから画面でポチポチ進める作業を実装されたコードを実行するだけで自動で作ってくれる仕組みです。
Terraformのインストールから実行するまでを超シンプルに説明すると以下の手順になります。
1.Terraformをインストールする
2.VSCodeにTerraformの拡張機能を入れる
3.新しい作業フォルダを作り、Terraform用ファイルを書く
4.TerraformがAWSにアクセスできるようにAWS認証情報を設定する
5.VSCodeのターミナルからTerraformを実行する
環境構築するまで色々なトラップに掛かり、Amazon Qで解決しながら進めたのですが、環境のバージョンによる違いまで説明していくとかなり大変なので、今回は端折ります。
今回の記事で扱うのは3.と5.になります。
TerraformとCloudFormationの違い
✅ Terraform と CloudFormation の違いまとめ(ざっくり)
| 項目 | Terraform | AWS CloudFormation |
|---|---|---|
| 提供元 | HashiCorp | AWS |
| 対応クラウド | マルチクラウド対応(AWS, Azure, GCP, etc) | AWS 専用 |
| 言語 | HCL(HashiCorp Configuration Language) | YAML / JSON |
| 状態管理 | Terraform state ファイル で管理 | AWS が自動で管理(state は意識不要) |
| 変更の流れ | plan → apply の2段階で安全 | create/update/delete をそのまま実行 |
| モジュール化 | 非常に強力(Terraform Registry あり) | AWS でも可能だが、Terraformより弱い |
| 学習コスト | やや高い | 低い(AWSを知っていれば理解しやすい) |
特にTerraformのお勧めとなるのは、以下の2つです。
・AWS以外のクラウドも扱える(マルチクラウド対応)
・再利用性が高く、モジュールが圧倒的に使いやすい
では、さっそく構築の手順をコード化していきます。
Terraform用ファイルを書く
VSCodeで新しいファイルを作成、EC2構築に必要な以下のコードを書きます。
provider "aws" {
profile = "terraform" # 利用するAWS CLI プロファイル名
region = "ap-northeast-1" # リージョン
}
resource "aws_instance" "my_ec2" { # <プロバイダー名>_<サービス名> <ローカル名称>
ami = "ami-0e68e34976bb4db93" # EC2のAMI名
instance_type = "t2.micro" # インスタンスのサイズ
}
EC2のAMI名は起動対象のインスタンスタイプによって異なりますので、以下の手順で確認します。
AWSのマネジメントコンソールからEC2→インスタンス→[インスタンスを起動]を選択します。
起動対象のOSイメージを選択すると、右側の概要欄のソフトウェアイメージ(AMI)にAMI名が表示されるのでコピペでtfファイルに転記します。

これだけでEC2インスタンス構築の定義が作れることに驚きですが、このままだとVPCはデフォルト設定になってしまいます。
もう少し実用的にしたいので、VPC内容も記載したのが以下です。
各所にコメントも入れてみました。
############################################
# プロバイダ設定(AWS を使う宣言)
############################################
provider "aws" {
profile = "terraform" # 利用する AWS CLI プロファイル名
region = "ap-northeast-1" # 東京リージョン
}
############################################
# VPC(仮想ネットワークの基盤)
############################################
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16" # VPC 全体のネットワーク範囲
}
############################################
# パブリックサブネット(EC2 を配置する場所)
############################################
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24" # サブネットのネットワーク
availability_zone = "ap-northeast-1a" # 配置ゾーン
map_public_ip_on_launch = true # EC2 起動時に Public IP を自動付与
}
############################################
# インターネットゲートウェイ(VPC からインターネットへ出るための装置)
############################################
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
}
############################################
# パブリックルートテーブル(インターネットへのルートを設定)
############################################
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0" # 全ての宛先
gateway_id = aws_internet_gateway.gw.id # IGW へルーティング
}
}
############################################
# サブネットとルートテーブルの紐付け
############################################
resource "aws_route_table_association" "public_assoc" {
subnet_id = aws_subnet.main.id
route_table_id = aws_route_table.public.id
}
############################################
# セキュリティグループ(EC2 のファイアウォール設定)
############################################
resource "aws_security_group" "ec2_sg" {
name = "ec2_sg"
vpc_id = aws_vpc.main.id
# ★SSH接続(ポート22) を全世界から許可
# 本番環境ではアクセス元 IP を絞ることが推奨
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"]
}
}
############################################
# EC2 インスタンス
############################################
resource "aws_instance" "ec2_Poc" { # "<プロバイダー名>_<サービス名>" "<ローカル名>"
ami = "ami-0e68e34976bb4db93" # Amazon Linux 2 (東京リージョン)
instance_type = "t2.micro" # 無料枠に含まれるサイズ
subnet_id = aws_subnet.main.id # 先ほど作成したサブネットに配置
vpc_security_group_ids = [aws_security_group.ec2_sg.id] # セキュリティグループを適用
# tags を付けると AWS 管理画面で分かりやすくなる
tags = {
Name = "ec2_AmazonLinux"
}
}
tagsのNameに設定した名前が、EC2のインスタンス一覧に表示される名前となります。
編集が終わったら、Terraform用ファイル(*.tf)を保存しておきましょう。
ファイル名は任意の名前でOKですが、main.tfが良く利用されるようです。
VSCodeからコマンドでTerraformを実行する
tfファイルの編集が終わったら、VS Codeのターミナルから実行していきます。
1.Terraformの初期化
terraform init
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v6.21.0
Terraform has been successfully initialized!
2.Terraformの構文チェック
terraform fmt
コードを整形してくれます
$ terraform fmt
main.tf
terraform validate
文法が正しいか確認を行います
$ terraform validate
Success! The configuration is valid.
3.変更内容の確認(plan)
terraform plan
作成するリソースの詳細が表示されます(ここでは先頭部の結果のみ表示)
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
4.環境を構築(apply)
terraform apply
構築内容の許可を問われるのでyesを入力後、Enterで実行します。
$ terraform apply
(中略)
Plan: 7 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
(中略)
Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
5.環境の削除(destroy)
terraform destroy
削除内容の許可を問われるので、yesを入力後、Enterで実行する。
Plan: 0 to add, 0 to change, 7 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
実行すると、EC2、VPCなど関連するリソースが削除されます。
Destroy complete! Resources: 7 destroyed.
作った環境に早速、接続してみましょう。
🔌 SSH 以外の接続方法(Amazon Linux)
今回はキーペアを作成していないので、SSH接続することはできません。
EC2 Instance Connectによる接続を試みます。
✅ EC2 Instance Connect(ブラウザでSSH)※おすすめ
AWS 管理コンソールのブラウザだけで接続でき、秘密鍵が不要です。
[利用条件]
・対象 AMI が Amazon Linux 2 / Amazon Linux 2023 であること
・セキュリティグループで ポート22が許可されていること
・インスタンスに EC2 Instance Connect がインストールされていること(初期状態で入っています)
[接続手順]
1.AWS コンソール → EC2 → 対象インスタンスを選択
2.右上の 「接続」 ボタンをクリック
3.「EC2 Instance Connect」 を選択
4.「接続」をクリック
➡ ブラウザ上にシェルが開きます(鍵不要)
TerraformとCloudFormationの違いを概念でしか理解できていないため、今後は両方を触って使用感を確認していこうと思います。
