AWSとVPSの違いを7軸で比較|個人開発と実務学習の選び分け
目次
自分で作ったWebアプリを初めて公開するとき、最初に決まらないのが「VPSを1台借りるか、AWSを使うか」です。月数千円という予算感では両者は近いのに、契約の考え方、障害が起きたときに誰が何をするか、あとから規模を広げられるか、学んだことが実務や資格につながるかがまるで違います。
この記事では、VPSとAWSの違いを7つの軸で整理し、同じWebアプリを動かす前提での費用と作業量の見積もり方、目的別の選び方、AWSを選んだ場合の学習ロードマップ、VPSからAWSへ移行するときの落とし穴までを扱います。料金は改定されるため、最終的な金額は各サービスの公式料金ページとAWS Pricing Calculatorで確認してください。
🔍 VPSとAWSは何が違うのか(レンタルサーバー・クラウドとの位置づけ)
まず位置づけを揃えます。ホスティングは大きく3層に分かれます。
| 種別 | 代表例 | 利用者が触れる範囲 |
|---|---|---|
| 共用レンタルサーバー | 各社のレンタルサーバープラン | 用意されたPHP/DB/管理画面のみ。root権限なし |
| VPS | ConoHa VPS、さくらのVPS、Xserver VPSなど | ゲストOSのroot権限。ミドルウェアは自由 |
| クラウド(IaaS/PaaS) | AWS、Google Cloud、Azure | 仮想サーバーに加えLB・DB・ストレージ・IAMなどをAPIで組み合わせる |
WordPressのサイトを運用したいだけなら、共用レンタルサーバーの中にも、更新・セキュリティ対策・バックアップまで任せられるWordPress専用のサービスがあります。サーバーの管理を自分でしたくない場合の選び方は、XServer for WordPressとエックスサーバーの違いで整理しています。
技術的には、VPSもAWSのEC2も「物理サーバー上のハイパーバイザで動く仮想マシンを貸す」という点は同じです。KVMベースの仮想化で、利用者はゲストOS以上を自分で管理します。この一点だけを見ればVPSとEC2は似ています。
大きく違うのは提供の単位です。
VPSは「vCPU・メモリ・ディスク・転送量をセットにしたプラン」を月単位で契約します。サーバーは原則1台ずつで、増やすなら追加契約して自分で束ねます。AWSでは「コンピュート」「ブロックストレージ」「ロードバランサー」「マネージドDB」「DNS」「権限管理」などが個別のサービスとしてAPI経由で提供され、必要な部品を選んで組み立てる形になります。
つまりVPSは完成品のサーバー1台、AWSは部品のカタログです。VPSは意思決定の数が少ないぶん早く動き出せますが、冗長化やスケールは自分で設計するしかありません。AWSは部品が揃っている代わりに、どの部品をどう繋ぐかという設計判断と、部品ごとの課金体系の理解が必要になります🧩
なお、AWSにも「VPSに近いもの」があります。Amazon Lightsailは、vCPU・メモリ・SSD・データ転送枠をバンドルした月額固定プランで提供され、感覚としてはVPSに極めて近いサービスです。「AWSアカウントの中でVPS的に使う」という選択肢として覚えておくと、判断の幅が広がります。
⚖️ 7つの軸で比較するVPSとAWSの違い
先に全体像を示します。
| 軸 | VPS | AWS |
|---|---|---|
| 1. 料金体系 | 月額固定(転送量込みが多い) | 従量課金。リソースごとに単価が異なる |
| 2. スペック変更 | プラン変更(制約あり) | インスタンスタイプ変更・ボリューム拡張が随時可能 |
| 3. 障害時の責任 | ホスト障害は事業者が対処することが多い | 退役予告・再起動は利用者が対応。自動復旧は自作 |
| 4. 冗長化・スケール | 自分でLB・レプリカを構築 | ALB/ASG/Multi-AZ/リードレプリカが標準機能 |
| 5. マネージドサービス | 原則なし(全部自前) | RDS・S3・ElastiCache等を組み合わせられる |
| 6. セキュリティ・権限 | OSのユーザーとSSH鍵、iptables系 | IAM・SG・CloudTrail・SSMによる多層管理 |
| 7. 撤退・移行コスト | 低い(OS上の資産は可搬) | 使うサービス次第。マネージドに寄せるほど上がる |
軸1・2:料金体系(固定課金と従量課金)とスペック変更の自由度
VPSは「メモリ2GB・vCPU3・SSD100GBで月額いくら」という固定料金です。転送量は無制限または大きな枠が含まれることが多く、請求額の上限が事前に読めます。個人開発では、この予測可能性そのものが価値になります。
AWSは要素ごとの従量課金です。EC2で1台動かすだけでも、請求は次のように分解されます。
- インスタンス稼働時間(秒単位課金。停止中は課金されない)
- EBSボリュームのプロビジョニング量(インスタンスを停止しても課金される)
- gp3ならベースラインを超えるIOPS・スループットの追加分
- データ転送(インターネットへのアウトバウンド。受信は無料)
- Elastic IPの未使用分、ALBの時間課金+LCU、NAT Gatewayの時間課金+処理データ量
- CloudWatch Logsの取り込み量・保存量、スナップショット保存量
この「止めても消えない課金」と「通信量で動く課金」が、月末の請求を読みにくくする主因です。逆に、夜間に止める開発環境や、数日だけ立てる検証環境ではAWSの秒課金がかなり有利になります😇
スペック変更の自由度では、AWSに軍配が上がります。EC2はインスタンスを停止してタイプを変更すれば即座にスケールアップ/ダウンでき、EBSはオンラインで拡張できます(縮小はできないので、後述の注意が必要)。
# EC2インスタンスタイプの変更(要停止)
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 modify-instance-attribute --instance-id i-0123456789abcdef0 \
--instance-type '{"Value":"t3.small"}'
aws ec2 start-instances --instance-ids i-0123456789abcdef0
# EBSボリュームのオンライン拡張(縮小は不可)
aws ec2 modify-volume --volume-id vol-0123456789abcdef0 --size 40
# OS側でファイルシステムも拡張する
sudo growpart /dev/nvme0n1 1 && sudo resize2fs /dev/nvme0n1p1
VPSのプラン変更は事業者ごとに条件が異なり、上位プランへの変更は可能でも下位プランへの変更ができない、ディスクサイズの縮小を伴う変更は不可、といった制約があります。契約前に「プラン変更の可否とダウングレード条件」を確認してください。
軸3:障害時の責任分界点とSLAの読み方
両者とも基本構造は同じ「責任共有モデル」です。物理サーバー・電源・ネットワーク・ハイパーバイザは事業者、ゲストOS以上(OSのパッチ、ミドルウェア、アプリ、データ、設定)は利用者の責任です。ここを誤解して「AWSならバックアップも勝手に取ってくれる」と思い込むのが、最初の事故につながります💥
違いが出るのは、ホスト側に異常が起きたときの振る舞いです。多くのVPSでは、物理ホストの障害時に事業者が別ホストへの移送や復旧を行い、利用者は再起動確認だけで済むことがあります(保証内容は事業者次第)。AWSでは、基盤のハードウェア劣化を検知すると「scheduled event(退役・再起動予定)」として通知され、指定期日までに利用者が自分で停止・起動して別ホストへ載せ替える運用になります。
AWSは「壊れる前提で、復旧を自動化する仕組みを利用者が組む」という設計思想です。単一インスタンスの可用性を上げたいなら、以下を自分で入れます。
# CloudWatchアラームによるインスタンス自動復旧(ステータスチェック失敗時)
aws cloudwatch put-metric-alarm \
--alarm-name ec2-auto-recover \
--namespace AWS/EC2 --metric-name StatusCheckFailed_System \
--statistic Maximum --period 60 --evaluation-periods 2 --threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
--alarm-actions arn:aws:automate:ap-northeast-1:ec2:recover
SLAの読み方も押さえておきたい点です。EC2のSLAは、複数AZにまたがる構成に対する月間稼働率と、単一インスタンスに対する稼働率で数値が分かれています。押さえておきたいのは、SLAが「壊れない保証」ではなく、下回った場合のサービスクレジット(返金)規定だという点です。1台構成でSLAの上限値を期待するのは設計ミスです。VPS側も同様で、SLAが明記されていない、あるいは免責範囲が広い契約もあるため、約款の「データの保全は利用者責任」という条項を読んでおいてください。
責任分界点そのものはVPSとAWSでほぼ同じで、違うのは自動復旧をサービスとして買えるか、自前で作るかです。
軸4・5:冗長化・スケールのしやすさとマネージドサービスの有無
ここがVPSとAWSの差が最も開く部分です。
VPS 1台構成でWebとDBを同居させた場合、可用性はそのホスト1台に依存します。冗長化したければVPSを複数契約し、ロードバランサー役のサーバーを立て、DBのレプリケーションを自分で組み、フェイルオーバーの判定ロジックまで用意することになります。技術的には可能ですが、個人開発の工数としては重い作業です😩
AWSは同じことをサービスとして買えます。ALB+Auto Scaling Groupでアプリ層を冗長化し、DBはRDSのマルチAZ配置にする、という構成が標準手順で組めます。
RDSマルチAZの内部動作を理解しておくと、何を買っているのかが明確になります。PostgreSQLのマルチAZインスタンス構成では、プライマリのWAL(先行書き込みログ)を別AZのスタンバイへ同期的に転送し、スタンバイ側の書き込み完了を待ってからコミットを返します。書き込みレイテンシはAZ間往復のぶん増えますが、プライマリが失われてもコミット済みトランザクションは失われません。フェイルオーバーはエンドポイントのDNSレコードをスタンバイ側に切り替える形で行われ、切り替え完了までにおおむね1〜2分程度かかります。このため、アプリ側にはDNS TTLを長くキャッシュしない設定と、接続リトライの実装が必要です。
同じ保護をVPSで自作するなら、こうなります。
# プライマリ側 postgresql.conf(ストリーミングレプリケーション)
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1GB
archive_mode = on
archive_command = 'rsync -a %p backup@10.0.0.20:/var/lib/pgsql/wal_archive/%f'
# スタンバイ側の初期構築
pg_basebackup -h 10.0.0.10 -U replicator -D /var/lib/pgsql/16/data -R -P -Xs
さらに、任意時点への復元(PITR)をやるには、ベースバックアップとWALアーカイブを別ホストに保管し、世代管理と復元リハーサルまで運用に組み込む必要があります。RDSの自動バックアップは、この「ベースバックアップ+WALの継続アーカイブ」を裏で行っているので、保持期間内の任意の時刻を指定して復元できます。マネージドサービスの価値は、機能そのものよりも、この運用手順を自分で維持しなくてよいことにあります。
⚠️ 一方で、マネージドDBには制約があります。RDS for PostgreSQLではOSにログインできず、postgresのsuperuser権限も付与されません(rds_superuserロール止まり)。設定変更はpostgresql.confを直接編集するのではなくパラメータグループ経由になり、pg_hba.confも編集できないため、接続制御はセキュリティグループとrds.force_sslパラメータで行います。shared_buffersはデフォルトで{DBInstanceClassMemory/32768}のような式で自動設定され、インスタンスクラスを変えるとメモリ配分も追随します。拡張機能も許可リスト方式で、使えるものはrds.extensions(あるいはshared_preload_librariesの許容値)に依存します。
-- RDSで利用可能な拡張の確認
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('pg_trgm','pgcrypto','pg_stat_statements','postgis');
-- 自動設定されたメモリ関連パラメータの確認
SELECT name, setting, unit, source FROM pg_settings
WHERE name IN ('shared_buffers','work_mem','effective_cache_size','max_connections');
「PostgreSQLの拡張を自由に入れたい」「OSレベルでチューニングしたい」「Oracleをライセンス持ち込みで細かく制御したい」といった要件があるなら、マネージドではなくVPSやEC2上の自前構築のほうが自由度は高くなります。自由度と運用責任はトレードオフです。
軸6・7:セキュリティと権限管理、撤退・移行コスト
VPSのセキュリティ対策は、OSの中に閉じています。
# sshd_config の最低ライン
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
# ファイアウォール(Ubuntu/ufw)
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw enable
# 自動セキュリティ更新
sudo apt install unattended-upgrades && sudo dpkg-reconfigure unattended-upgrades
これに加えてfail2ban、ログローテート、定期的なパッケージ更新と再起動を自分でスケジュールします。シンプルですが、「誰がいつ何をしたか」の監査ログは標準では残りません🤔
AWSは多層です。IAMでユーザー・ロール・ポリシーを分け、ルートユーザーにはMFAを設定して日常利用しない。ネットワークはセキュリティグループ(ステートフル)とネットワークACL(ステートレス)で制御。APIの操作履歴はCloudTrailに残ります。SSH自体をやめて、Systems Manager Session Manager経由でシェルを取る構成にすれば22番ポートを閉じられます。
# Session Manager でSSHポートを開けずに接続
aws ssm start-session --target i-0123456789abcdef0
この仕組みは強力ですが、設定ミスがそのまま公開事故になるのもAWSの特徴です。S3バケットのパブリック公開、セキュリティグループで0.0.0.0/0に3306や5432を開放、アクセスキーをGitにコミット、といった事故は定番です。IAMの最小権限とアクセスキーの扱いは、学習の初期段階で押さえるべき項目です💣
撤退・移行コストは、VPSのほうが低くなりやすいです。VPS上の資産はOSの中にあるので、rsyncとpg_dumpがあれば別事業者へでもAWSへでも持ち出せます。AWSはEC2+自前PostgreSQLなら同等に可搬ですが、Aurora、DynamoDB、Cognito、SQS、Step Functionsのような固有サービスに寄せると、移植時にアプリの書き換えが発生します。さらに、データを外に出すときのアウトバウンド転送料も撤退コストに含まれます。
ロックインを避けたいなら、「アプリはコンテナ化し、DBは標準SQLの範囲で書き、固有サービスは差し替え可能な層に隠す」という設計方針を最初から持っておくことです。ただし、個人開発で移植性を優先しすぎてマネージドの利点を全部捨てるのも本末転倒なので、「壊れたら困るデータの置き場だけ可搬にしておく」程度が現実的です。
💰 同じWebアプリを動かす場合の費用と作業量を見積もる
条件を揃えて比較します。前提は「Webアプリ(Rails/Django/Next.jsなど)+PostgreSQL、独自ドメイン、HTTPS、月間数万PV、常時稼働」とします。
VPS 1台構成:初期構築で何をやることになるか
VPS 1台にWeb・アプリ・DBを同居させる構成です。初期構築のタスクリストはおおむね次のとおりです。
- OS選定とインスタンス作成、SSH鍵の登録
- rootログイン無効化、パスワード認証無効化、一般ユーザー作成
- ファイアウォール設定(22/80/443のみ)
- Nginxインストールとリバースプロキシ設定
- Let’s Encryptでの証明書取得と自動更新(certbot)
- PostgreSQLインストール、初期化、チューニング
- アプリのデプロイとsystemdサービス化
- バックアップのcron設定と、外部ストレージへの退避
- 死活監視(外部の無料監視サービス等)とログローテート
- OSの自動セキュリティ更新と、定期再起動の運用ルール
DBのチューニングは最低限、次の観点を押さえます。1台同居構成で最も多い事故はメモリ不足によるOOM Killerです。
# postgresql.conf(メモリ2〜4GBの同居構成の出発点)
shared_buffers = 512MB # 搭載メモリの25%程度から
effective_cache_size = 1500MB # OSキャッシュ込みの想定値。プランナのヒント
work_mem = 8MB # ソート/ハッシュ1回あたり。接続数×並列度で膨らむ点に注意
maintenance_work_mem = 128MB
max_connections = 50 # 多すぎるとwork_mem合計でメモリ枯渇
random_page_cost = 1.1 # SSD前提。デフォルト4.0はHDD想定で不当にSeq Scanへ寄る
work_memは「1接続あたり」ではなく「ソートやハッシュ結合の1操作あたり」に割り当てられます。並列クエリが走るとwork_mem × 並列ワーカー数まで膨らむため、同居構成では控えめにし、接続数はPgBouncerで絞るのが安全です。メモリ2GBでmax_connections=100のまま放置すると、アクセス増でアプリごとOOMで落ちます。落ちたときはdmesg -T | grep -i oomで確認し、swapの有無を先に見ます🥵
⚠️ バックアップは「取っている」だけでは不足で、同じホストに置かないこと、そして戻せることを確認することが要件です。
#!/bin/bash
# /usr/local/bin/pgbackup.sh cronで日次実行
set -euo pipefail
DATE=$(date +%F)
pg_dump -Fc -U postgres myapp > /var/backups/myapp_${DATE}.dump
# 外部ストレージへ退避(rclone/S3/別VPSなど)
rclone copy /var/backups/myapp_${DATE}.dump remote:db-backup/
find /var/backups -name 'myapp_*.dump' -mtime +14 -delete
コスト面では、メモリ2〜4GB程度のプランが月額数百円〜2,000円台という水準で、ここにドメイン費用が加わる程度です。上限が読めるのが最大の利点で、工数は初回に半日〜数日、以降は月1回のパッチ適用と再起動が主になります✨
AWS最小構成(Lightsail/EC2+RDS):料金が読みにくくなる要因
AWSで同じアプリを動かす場合、選択肢は大きく2つあります。
Lightsailは月額固定のバンドル(vCPU・メモリ・SSD・データ転送枠)で、VPSに近い課金感覚です。別途マネージドDBのプランもあり、スナップショットや固定IPの扱いも簡潔です。「AWSアカウント上で運用したいが、請求の予測可能性は保ちたい」場合の中間解になります。注意点として、Lightsailだけで運用すると、VPC設計やIAM設計、ALB/Auto ScalingといったAWSらしい設計スキルには触れないままになります。学習を目的に含めるなら、この点は割り引いて考える必要があります。
EC2+RDSは本格的なAWS構成です。新規アカウントには一定期間・一定量の無料利用枠がありますが(対象インスタンスや時間数、ストレージ量などの条件は変わるため公式の無料利用枠ページで確認してください)、枠の期限や条件を過ぎた時点で請求が跳ねます。
料金が読みにくくなる主要因を整理します。
- データ転送。インターネットへのアウトバウンドが課金対象で、画像や動画が多いサイトではVPSの定額転送のほうが有利になりやすい
- 止めても消えない課金。EBS、スナップショット、未アタッチのElastic IP。RDSは停止しても一定期間後に自動起動する仕様がある
- NAT Gateway。プライベートサブネットからの外部通信用に作ると、時間課金+処理データ量課金が発生する。VPC作成ウィザードで意図せず作ってしまいやすい代表格
- ALB。時間課金に加えてLCU(接続数・帯域・ルール評価数)で変動する
- RDSマルチAZ。スタンバイ分のインスタンス料金が加算されるため、シングルAZの約2倍が目安
- CloudWatch Logs。取り込み量と保存量で課金。デバッグログを大量に送ると無視できない額になる
対策は先手で打ちます。
# 予算アラート(しきい値超過をメール通知)
aws budgets create-budget --account-id 123456789012 \
--budget '{"BudgetName":"monthly-5usd","BudgetLimit":{"Amount":"5","Unit":"USD"},
"TimeUnit":"MONTHLY","BudgetType":"COST"}' \
--notifications-with-subscribers file://notify.json
# 未アタッチのElastic IPを洗い出す
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==null].[PublicIp,AllocationId]' --output table
# 全リージョンの稼働中インスタンスを確認(リージョン残骸の検出)
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "== $r"; aws ec2 describe-instances --region $r \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].InstanceId' --output text
done
見積もりはAWS Pricing Calculatorで、インスタンス・EBS・転送量・ALB・RDSを個別に入力して出すのが確実です。「EC2の単価だけを見て安いと判断する」のが最も多い見積もりミスです😇
🧭 目的別の判断基準:あなたのケースならどちらを選ぶか
個人開発・ポートフォリオを低コストで公開したい場合
この目的なら、VPS 1台、またはLightsailが第一候補になります。月額上限が読めるので想定外の請求を心配せずに済み、1台構成のシンプルさはトラブル時の切り分けを楽にします(ログの場所が1か所で済む)。Linux・Nginx・PostgreSQLを直接触るので、サーバーの基礎も身につきます。
次の条件に当てはまるなら、さらにVPSが有利です。
- 画像・動画・ファイルダウンロードが多く、アウトバウンド転送量が読めない
- 常時稼働で、止める時間帯がない(従量課金の利点が効かない)
- cronやバッチ、常駐プロセスを自由に置きたい
逆に、静的サイトやSPAだけならS3+CloudFrontのほうが安く速いことも多いので、「そもそもサーバーが必要か」を先に検討してください。
実務スキル・転職・AWS資格を狙う場合
学習価値を重視するならAWSです。求人票に並ぶのはVPCやIAM、ALB、RDS、CloudWatch、IaCといった語彙であり、これらはVPSでは登場しません。AWS認定(CLF/SAA)の出題範囲も、実機での構築経験と直結します。
| 学習テーマ | 対応するハンズオン |
|---|---|
| IAM・責任共有モデル | ルートMFA設定、最小権限ポリシー作成、ロールでのEC2アクセス |
| VPC・サブネット・ルーティング | VPCを手動作成し、パブリック/プライベートを分離 |
| EC2・ELB・Auto Scaling | ALB配下に2台配置し、片方を落として挙動確認 |
| RDS・バックアップ | マルチAZ化、スナップショット復元、PITRの実施 |
| S3・CloudFront | 静的アセット配信と署名付きURL |
| CloudWatch・CloudTrail | メトリクスアラーム、ログ集約、操作履歴の追跡 |
ただし「VPSは学習価値がない」というのは誤りです。OSのパーミッション、systemd、Nginxのリバースプロキシ、TLS証明書、PostgreSQLの実行計画やvacuum、待機イベントの読み方といったスキルは、EC2やRDSを運用するときの土台そのものです。実際の現場では、AWS上のLinuxとDBを触る仕事が大半を占めます。
おすすめの順序は、VPSでOSとDBの手触りを掴み、その後AWSで設計を学ぶことです。なぜVPCやIAMが必要なのかは、1台構成で不自由を味わったあとのほうが理解が早くなります。
XServer VPS
国内最大級のサーバー会社が提供するVPS。root権限のあるLinux環境を月額制で使え、DockerやDBの検証環境にも向いています。
XServer VPSの公式サイトを見るアクセス数の変動やサービス拡大が読めない場合
スパイクや成長が想定されるならAWSが有利です。ALB+Auto Scalingでアプリ層を水平に伸ばし、DBはリードレプリカを追加し、静的配信はCloudFrontに逃がす、という段階的な拡張が設定変更の範囲でできます。
ただし前提があります。アプリ側がスケールできる設計になっていないと、クラウドに置いても伸びません。阻害要因としてよく見かけるのは次の3つです。
- セッションをローカルファイルやプロセスメモリに保持している → ElastiCacheやDB、あるいはクッキーへ
- アップロードファイルをローカルディスクに保存している → S3へ
- スケジュール実行をアプリサーバーのcronに書いている → EventBridge+Lambda、または専用ノードへ
💡 これらを整理して「アプリサーバーをステートレスにする」ことが、スケールアウトの前提条件です。逆に、この整理をしたうえでVPSを複数台並べる選択も成立します。
🗺️ AWSを選ぶ場合の学習ロードマップ(公開まで4ステップ)
AWSを選んだ場合、いきなりEC2を立ててSSHするのではなく、次の順序で進めると迷いが減ります。
ステップ1は、アカウントの安全設計です。
- ルートユーザーにMFAを設定し、以後は使わない
- 管理作業用のIAMユーザー(またはIAM Identity Centerのユーザー)を作り、MFAを設定
- AWS Budgetsで予算アラートを設定(最初は小さい金額で)
- CloudTrailが有効であることを確認
- 作業リージョンを1つに固定する(残骸の発生源を減らす)
ステップ2は、ネットワークを自分の手で作ることです。
VPCウィザードに頼らず、VPC → サブネット(パブリック/プライベート、AZを分ける)→ インターネットゲートウェイ → ルートテーブル → セキュリティグループの順に手作業で作ります。「パブリックサブネットとは、ルートテーブルのデフォルトルートがIGWを向いているサブネットのこと」という定義が体で分かると、以後のトラブルシュートが速くなります。
ステップ3は、アプリの公開です。
パブリックサブネットにEC2、プライベートサブネットにRDSを配置し、RDSのセキュリティグループではEC2のセキュリティグループIDを送信元に指定します(CIDRではなくSG参照にするのが基本形)。証明書はACMで発行してALBに紐付け、DNSはRoute 53でALBへのAliasレコードを作ります。
ステップ4は、運用の形を作ることです。
CPU・ディスク・DB接続数のCloudWatchアラーム、RDSの自動バックアップ保持期間の設定、スナップショットからの復元リハーサル、そして構成をCloudFormationやTerraformでコード化します。IaC化しておくと「壊して作り直す」学習が安全にできるようになります🎉
資格学習と実機検証を組み合わせる進め方と、課金事故を防ぐ設定
資格は、AWSの全体像を用語レベルで揃えるのに向いています。進め方としては、CLF(クラウドプラクティショナー)で用語とサービスの役割を把握し、SAA(ソリューションアーキテクト アソシエイト)で可用性・耐久性・コスト最適化の判断軸を学ぶ流れが標準的です。出題範囲や問題数は改定されるため、受験前にAWS公式の試験ガイドで最新版を確認してください。
💡 効果が高いのは、テキストの章を読んだ直後に、その章のサービスを実際に1回作って壊す進め方です。「マルチAZの章を読んだらRDSをマルチAZ化してフェイルオーバーを手動実行する」「Auto Scalingの章を読んだら希望台数を変えてALBのターゲット登録を眺める」といった具合です。座学だけでは、SAAで問われる「この要件ならどのサービスの組み合わせか」という判断がつきません。
課金事故を防ぐチェックリストも持っておいてください。
- 予算アラートを最初に作る(作る前にリソースを触らない)
- NAT Gatewayを作ったら、検証が終わったら削除する。時間課金なので放置が最も高くつく
- ALB・Elastic IP・EBS・スナップショットは「インスタンスを消しても残る」ことを前提に、削除チェックを行う
- 検証は1リージョンに固定。別リージョンの残骸は気づきにくい
- RDSを削除するときは最終スナップショットの取得有無を意識する(不要ならスキップ、必要なら保存料が発生することを理解する)
- 「停止」と「削除」の違いを区別する。EC2は停止で課金が止まるがEBSは残る。RDSは停止しても一定期間後に自動起動する
# 検証後の棚卸し:NAT GatewayとALBの残骸チェック
aws ec2 describe-nat-gateways \
--query 'NatGateways[?State==`available`].[NatGatewayId,VpcId]' --output table
aws elbv2 describe-load-balancers \
--query 'LoadBalancers[].[LoadBalancerName,Type,State.Code]' --output table
🚚 VPSからAWSへ移行するときの手順とつまずきやすいポイント
すでにVPSで動いているアプリをAWSへ移す場合、以下の順序で進めます。
1つ目は棚卸しです。OSとミドルウェアのバージョン、cronの一覧、証明書の有効期限、外部連携先とIP制限の有無、DNSのTTL、環境変数・シークレットの置き場所を書き出します。ここを飛ばすと、切替後に「毎晩動いていたバッチが消えていた」といった事故が起きます。
2つ目はネットワークとインスタンスの構築です。VPC、サブネット、セキュリティグループを作り、EC2とRDSを用意します。まずは本番と同スペックでなくても構いません。
3つ目はデータ移行です。
ダウンタイムを許容できるなら論理バックアップでの移行が最も単純です。RDSにはsuperuserがないため、所有者やACLをそのまま復元しようとすると失敗します。
# 移行元でダンプ(カスタム形式)
pg_dump -Fc -h old-vps -U app_user -d myapp -f myapp.dump
# RDSへリストア(所有者・権限はスキップし、RDS側のロールに合わせる)
pg_restore -h myapp.xxxxx.ap-northeast-1.rds.amazonaws.com -U app_user \
-d myapp --no-owner --no-acl --jobs=4 myapp.dump
ダウンタイムを最小化したい場合は、PostgreSQLの論理レプリケーションを使います。移行元でwal_level = logicalにしてパブリケーションを作り、RDS側でサブスクリプションを張って初期同期+差分追従を行います。RDSをサブスクライバにする場合は、パラメータグループでrds.logical_replication = 1を有効化して再起動が必要です。
-- 移行元(VPS側)
ALTER SYSTEM SET wal_level = 'logical'; -- 再起動が必要
CREATE PUBLICATION pub_all FOR ALL TABLES;
-- 移行先(RDS側)
CREATE SUBSCRIPTION sub_all
CONNECTION 'host=old-vps dbname=myapp user=repl password=***'
PUBLICATION pub_all;
-- 遅延の監視
SELECT subname, latest_end_lsn, latest_end_time FROM pg_stat_subscription;
⚠️ 論理レプリケーションはDDLを複製しないこと、シーケンスの現在値が同期されないこと、主キーまたはREPLICA IDENTITYのないテーブルでUPDATE/DELETEが複製できないことに注意します。切替直前にシーケンスを手動で合わせる手順を必ず組み込んでください。
4つ目は切替です。DNSのTTLを事前に短く(60秒など)しておき、アプリを読み取り専用にして差分を収束させ、DNSを切り替えます。切り戻し手順(旧環境を数日残す、ダンプを保持する)も同時に用意します。
つまずきやすいポイントは次のとおりです。
- 送信元IPが変わる。外部APIやパートナー側のIP許可リストに旧VPSのIPが登録されている場合、Elastic IPやNAT Gatewayで固定IPを用意し、事前に申請しておく
- メール送信。クラウド環境では25番ポートの送信が制限されるのが一般的。Amazon SESや外部SMTPサービスに切り替える前提で設計する
- 設定ファイルが編集できない。RDSでは
postgresql.confとpg_hba.confを直接触れない。SSL強制はrds.force_ssl、接続元制限はセキュリティグループ、ログはCloudWatch Logsへのエクスポート設定で行う - 拡張機能の差。移行元で使っていた拡張がRDSの許可リストにない場合がある。移行前に
\dxで一覧を取り、対応可否を確認する - タイムゾーンと照合順序。RDSのデフォルトはUTCなので、
timezoneパラメータを変えるか、アプリ側で統一する。さらに、照合順序(collation)はOSのlocaleライブラリに依存するため、移行でソート順が変わるとテキスト列のインデックスが壊れる可能性がある。移行後にREINDEXと整合性チェックを行うのが安全側の判断 - 統計情報と実行計画。ダンプ/リストア方式では統計情報(
pg_statistic)が引き継がれません。リストア直後は実行計画が悪化しがちなので、ANALYZEを必ず実行します。あわせてrandom_page_costやeffective_io_concurrencyをEBS前提に見直します
-- リストア後に必ず実行
VACUUM (ANALYZE, VERBOSE) ;
-- 計画が変わったクエリの特定(pg_stat_statementsを有効化しておく)
SELECT queryid, calls, mean_exec_time, rows, query
FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 20;
- autovacuum設定の引き継ぎ漏れ。テーブル単位の
autovacuum_vacuum_scale_factorなどのストレージパラメータはダンプに含まれますが、postgresql.confでチューニングしていた全体設定はパラメータグループに移し替える必要があります。放置すると更新の多いテーブルで不要行が溜まり、テーブル膨張とプラン悪化を招きます - バースト型インスタンスのクレジット枯渇。t系インスタンスはCPUクレジットを消費して動きます。常時高負荷だとクレジットが枯渇してベースライン性能まで落ち、「移行したら急に遅くなった」という症状になります。
CPUCreditBalanceメトリクスを監視し、必要ならUnlimitedモード(追加課金)かm系への変更を検討します🐢 - EBSの性能特性。gp3はベースラインIOPS/スループットがあり、それを超える要求は追加プロビジョニングが必要です。旧VPSのローカルSSDより遅く感じるケースがあるため、移行後は
iostatやPerformance Insightsで待機イベント(IO:DataFileReadなど)を確認します
性能問題の切り分けには、RDSのPerformance Insightsが有効です(インスタンスクラスや保持期間によって料金条件が異なるため公式ドキュメントで確認してください)。待機イベントの内訳が見えると、「CPU不足なのか、I/O待ちなのか、ロック待ちなのか」を推測ではなく数値で判断できます📊
❓ VPSとAWSの違いについてよくある質問
Q. 結局どちらが安いですか?
常時稼働・転送量が多い・構成が固定なら、VPSの月額固定が安く収まりやすいです。稼働時間が短い、負荷の波が大きい、複数の環境を作って消すといった使い方ならAWSの従量課金が有利になります。判断は「月間の稼働時間」と「アウトバウンド転送量」の2つを見積もることから始めてください。
Q. AWSの無料利用枠が終わったらどうなりますか?
枠の対象だったインスタンス時間やストレージが通常料金の請求に切り替わります。終了時期を把握し、Budgetsのアラートを設定しておいてください。継続して使うなら、Savings PlansやReserved Instanceによる割引、インスタンスタイプの見直し、Lightsailへの移し替えなどを検討します。
Q. VPSしか触っていなくてもAWS資格の勉強はできますか?
テキストベースの学習は可能ですが、VPCやIAMは実際に作ってみないと定着しにくい領域です。無料利用枠か、数百円程度の予算で短時間だけリソースを立てて消す(検証したらすぐ削除する)運用で、実機確認を挟むことをおすすめします。
Q. LightsailはAWSの学習になりますか?
サーバー運用の練習にはなりますが、VPC設計、IAM、ALB、Auto Scaling、CloudWatchといったAWS特有の設計領域には触れません。学習目的がある場合は、LightsailでアプリをホストしつつEC2+VPCで別途ハンズオンを行う、という併用が現実的です。
Q. 個人開発のDBは、RDSとEC2同居のどちらにすべきですか?
コスト最小化を優先するならEC2(またはVPS)同居、データを失いたくない・運用を軽くしたいならRDSです。RDSの自動バックアップとPITRを自前で構築・維持する手間をどう評価するかが分岐点になります。同居構成を選ぶ場合は、バックアップの外部保管と復元リハーサルを必ずセットで用意してください。
Q. SSHの22番ポートは開けるべきではないのですか?
公開IPに22番を開ける場合は、パスワード認証を無効化し、鍵認証のみにするのが最低条件です。AWSではSSM Session Managerを使えばインバウンドを一切開けずに接続できるため、可能ならそちらに寄せるほうが安全です。VPSでも、接続元IPの制限やポート変更、fail2banの導入で総当たりのノイズを減らせます。
Q. 移行後に遅くなったとき、最初に何を見ればよいですか?
順序としては、(1) CPUクレジット残量とCPU使用率、(2) ディスクI/Oの待機(IO:DataFileReadなどの待機イベント)、(3) 統計情報の有無と実行計画(EXPLAIN (ANALYZE, BUFFERS))、(4) ロック待ち(pg_locks、pg_stat_activityのwait_event_type)、(5) 接続数とwork_memの合計です。「クラウドだから遅い」ではなく、どの層で待っているかを特定してから対処します。
VPSとAWSの違いは、機能の優劣ではなく、運用責任と予測可能性をどう分担するかの違いです。上限の読める固定費と1台のシンプルさを取るならVPS、冗長化・スケール・マネージドサービスと学習価値を取るならAWS。目的が「公開すること」なのか「スキルを積むこと」なのかで、答えは変わります。
まずは自分のアプリの稼働時間と転送量、許容できるダウンタイム、そして半年後にやりたいことを紙に書き出してみてください。判断材料が揃えば、どちらを選んでも後悔しにくくなります。