EC2 を 1 台起動して SSH で入るところまでは進んだのに、「止めたら何が消えるのか」「再起動すると IP が変わるのはなぜか」「アクセスキーを置いていないのに S3 が呼べるのはなぜか」が、バラバラの知識のままになっていないでしょうか。これらは別々の話に見えて、実はすべて「インスタンスが起動して使えるようになるまでの流れ」の中に並んでいます。この記事では、その流れを順にたどります。
この記事の結論
- インスタンスは pending → running → stopping → stopped、または shutting-down → terminated と状態を移り、利用料がかかるのは running の間です。
- 再起動は同じホストのままで何も変わりません。停止して開始すると別のホストになることがあり、インスタンスストアは消え、パブリック IPv4 アドレスは変わります(Elastic IP なら残ります)。
- ユーザーデータは既定では最初の起動時に 1 回だけ、root 権限で動きます。サイズの上限は 16 KB です。
- インスタンスメタデータは 169.254.169.254 から取ります。IMDSv2 はトークンを取ってから読む 2 段階です。
- AWS の API を呼ぶ処理には、インスタンスプロファイルで IAM ロールを付け、アクセスキーを置きません。
EC2 は起動するとどんな状態を通るのか
EC2 のインスタンスは、作ってから消えるまでに決まった状態を通ります。起動の要求を出すと、まず pending(準備中)になり、準備が終わると running(実行中)になります。ここで初めて、OS が動いてログインや通信ができる状態になり、インスタンスの利用料がかかり始めます。
止めるときの道は 2 本あります。1 本目は「停止」で、stopping(停止処理中)を経て stopped(停止済み)になります。stopped からは開始でき、そのときはまた pending に戻ります。2 本目は「終了」で、shutting-down を経て terminated になります。terminated になったインスタンスは元に戻せません。しばらくは一覧に表示が残りますが、再び使うことはできません。
INSTANCE STATES状態の移り変わり
利用料がかかるのはrunning の間。終了は戻せない
-
pending
起動の準備中
-
running
使える・利用料がかかる
-
stopping → stopped
停止。開始で pending に戻る
-
shutting-down → terminated
終了。元に戻せない
課金は running の間、ただし付随する資源は別
利用料のかかり方は、状態ごとに違います。running の間は利用した時間に応じてかかります。stopped の間はインスタンス自体の利用料はかかりませんが、アタッチしたままの EBS ボリュームや、割り当てたままの Elastic IP のように、インスタンスの外にある資源の料金は続く可能性があります。夜間や週末に使わない開発用インスタンスを、スケジュールで自動的に停止・開始してコストを抑える使い方があるのは、この性質のためです。EventBridge Scheduler のようにタイムゾーンを指定できる仕組みから、EC2 の停止・開始の API を直接呼ぶ形が代表的です。
具体的な料金の単価は改定されるので、ここには書きません。最新の料金は公式の料金ページで確認してください。
状態チェックと、障害時の自動復旧
running になっても、必ず「正常」とは限りません。EC2 には 2 種類のステータスチェックがあります。1 つは AWS 側のホストなど基盤を見る「システムステータスチェック」、もう 1 つは OS やネットワーク設定などインスタンスの中を見る「インスタンスステータスチェック」です。
基盤の障害でシステムステータスチェックが失敗したときは、CloudWatch アラームに復旧(recover)のアクションを設定して、自動で別のホストへ移せます。この復旧では、インスタンス ID とプライベート IP アドレスが保たれます。つまり「同じインスタンス」として戻ってくるので、1 台構成のシステムでも、IP を前提にした設定を作り直さずに済みます。
再起動・停止・休止・終了は何が違うのか
「止める」操作は 4 つあり、残るものと消えるものが違います。最初に押さえるのは、ホストが変わるかどうかです。インスタンスストアは、ホスト(物理サーバー)に付いている記憶域だからです。
| 操作 | ホスト | インスタンスストア | EBS のルートボリューム | パブリック IPv4(Elastic IP でない場合) |
|---|---|---|---|---|
| 再起動 | 同じ | 残る | 残る | 変わらない |
| 停止 → 開始 | 別になることがある | 消える | 残る | 変わる |
| 休止(ハイバネート) | 別になることがある | 消える | 残る(メモリの中身も保存される) | 変わる |
| 終了 | なくなる | 消える | 既定では削除される | 解放される |
プライベート IPv4 アドレスは、停止して開始しても保たれます。変わってしまうのはパブリック側です。固定したいアドレスがあるなら、Elastic IP を割り当てると、停止・開始をまたいで同じアドレスのままになります。
STOP VS TERMINATE停止と終了の違い
停止ならEBS は残り、終了なら戻せない
停止して開始
また使うとき
- インスタンスストア消える
- ルートボリューム残る
- パブリック IPv4変わる
- Elastic IP同じまま
終了
もう使わないとき
- インスタンスストア消える
- ルートボリューム既定で削除
- パブリック IPv4解放される
- Elastic IP関連付けが外れる
休止と終了保護
休止は、メモリの内容を EBS に書き出してから止める方法です。開始すると、止める前のメモリの状態から再開できます。ただし、使える条件があるので、使う前に公式の休止のページで対応を確認してください。
また、うっかり終了してしまう事故を防ぐ「終了保護」の設定があります。本番のインスタンスには入れておく価値があります。調査のためにインスタンスを保全したい場面でも、終了させずに隔離してから、メモリ・ディスクの証拠を取るのが定石です。
CHECK 1ここまでの確認
EBS をルートにしたインスタンスを停止して、もう一度開始した。消えているのはどれ?
答えと解説
答え: 2. インスタンスストアのデータ
停止して開始すると別のホストで起動することがあり、ホストに付いているインスタンスストアは消えます。EBS のルートボリュームとプライベート IPv4 は残ります。「再起動・停止・休止・終了は何が違うのか」の表を読み直してください。
ユーザーデータとは何か
インスタンスを起動するたびに、人が SSH で入ってパッケージを入れていては、同じ状態を再現できません。そこで使うのがユーザーデータです。起動時に渡しておいたスクリプトや設定が、インスタンスの初期設定として自動で実行されます。AMI が「OS とソフトウェアの元の姿」なら、ユーザーデータは「起動のたびに足す初期設定」にあたります。
主な性質は次のとおりです。
- 実行されるのは既定では最初の起動時の 1 回だけ。 停止して開始しても、再起動しても、再実行はされません。毎回動かしたいときは設定を変える必要があります。
- root 権限で動く。 そのため
sudoはいりませんが、書き間違いの影響も大きくなります。 - サイズの上限は 16 KB。 大きな処理は、スクリプトの中で S3 などから取ってくる形にします。
- 停止中なら内容を編集できる。 ただし書き換えても、既定では次の開始で再実行されません。
Linux の AMI では、この処理を cloud-init という初期化の仕組みが担います。スクリプトの先頭に #!/bin/bash を書くと、シェルスクリプトとして実行されます。
#!/bin/bash
dnf install -y nginx
systemctl enable --now nginx
「起動した」と「初期設定が終わった」は別
ここで見落としやすいのが、ユーザーデータはインスタンスが running になった後に、非同期で動くことです。running になった時点では、まだパッケージのインストール中かもしれません。CloudFormation でインスタンスを作る場合、インストールの完了前に「作成完了」と扱われてしまうと、後続の処理が失敗します。そこで CreationPolicy を設定し、スクリプトの最後で cfn-signal により完了を知らせる、という形で完了を待ちます。
「running =使える」ではなく、「ユーザーデータが終わってから使える」と考えると、起動の順番がつかめます。
BOOT SEQUENCE起動時の順番
起動はAMI → 初期設定 → 自分の情報 → ロールの順に進む
-
AMI でインスタンスを起動する
OS とソフトウェアの元の姿
-
ユーザーデータで初期設定する
既定では最初の 1 回だけ・root で実行
-
メタデータで自分の情報を取る
169.254.169.254 から。IMDSv2 はトークン付き
-
ロールの一時認証情報で AWS を呼ぶ
キーは置かず、自動で更新される
CHECK 2ここまでの確認
追加の設定をしていない場合、ユーザーデータのスクリプトが動くのはいつ?
答えと解説
答え: 2. 最初に起動したときの 1 回だけ
ユーザーデータは既定では最初の起動時に 1 回だけ実行されます。毎回動かしたいときは、設定で変えるか、別の仕組みを使います。「ユーザーデータとは何か」を読み直してください。
インスタンスメタデータとは何か
スクリプトやアプリが「自分は何というインスタンス ID か」「どのアベイラビリティゾーンにいるか」を知りたいときがあります。その情報は、インスタンスの中から特別なアドレス 169.254.169.254 にアクセスして取れます。これがインスタンスメタデータです。インスタンスの外からは届かず、そのインスタンス自身だけが読める窓口です。
この窓口には 2 つの方式があります。
- IMDSv1: 目的の項目へ、そのまま GET を送る方式です。
- IMDSv2: 先にセッショントークンを取得し、以降の GET にそのトークンを付ける 2 段階の方式です。トークンの有効期間は秒数で指定でき、最大 6 時間です。
IMDSv2 が望ましいとされるのは、トークンを挟むことで、アプリの不具合などを悪用して外から内部のアドレスを読ませる種類の攻撃を防ぎやすくなるからです。新しく作るインスタンスは IMDSv2 を使う前提で書きましょう。
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id
1 行目の PUT でトークンを取り、2 行目でそれをヘッダーに付けて、インスタンス ID を読んでいます。ユーザーデータの中でこのように自分の情報を引けば、同じスクリプトを何台に流しても、台ごとに違う値(ホスト名など)を設定できます。
CHECK 3ここまでの確認
IMDSv2 でインスタンスメタデータを読むとき、最初にやることは?
答えと解説
答え: 2. PUT でセッショントークンを取得する
IMDSv2 は 2 段階です。まずトークンを PUT で取得し、以降の GET にそのトークンをヘッダーで付けます。「インスタンスメタデータとは何か」を読み直してください。
キーを置かずに AWS を呼べるのはなぜか
EC2 上のアプリが S3 を読み書きするとき、IAM ユーザーのアクセスキーを設定ファイルに書く方法は避けます。漏えいの危険があり、ローテーションの手間も増えるからです。代わりに使うのが、IAM ロールをインスタンスプロファイル経由でインスタンスに付ける方法です。インスタンスプロファイルは、ロールを EC2 に渡すための入れ物です。
仕組みは次のとおりです。
- 必要な権限(たとえば特定バケットの読み取り)を持つ IAM ロールを作る。
- そのロールを、インスタンスプロファイルとしてインスタンスに付ける。
- インスタンス上の AWS SDK や CLI は、メタデータの窓口から一時的な認証情報を取得して API を呼ぶ。
- 一時的な認証情報には期限があり、期限が切れる前に新しいものに自動で更新される。
SDK は、既定の認証情報の探し方(既定のチェーン)の中にこの取得を含んでいるので、コードにキーを書く必要がありません。つまりメタデータの窓口は、「自分の情報」だけでなく「ロールの一時認証情報」の受け渡し口でもあります。
| 方法 | キーの保管 | ローテーション | 漏えいしたとき |
|---|---|---|---|
| アクセスキーを設定ファイルに置く | ファイルに残る | 人が手でやる | 長く使われ続ける |
| ロール(インスタンスプロファイル) | 置かない | 自動 | 期限が切れて無効になる |
注意点として、権限は付けすぎないようにします。ロールに強い権限を付けると、そのインスタンスに入れた人(や侵入した人)が、その権限をそのまま使えてしまいます。必要な操作だけを許可するのが基本です。
CHECK 4ここまでの確認
EC2 上のアプリが S3 を呼ぶとき、設定ファイルにキーを置かずに済ませる方法は?
答えと解説
答え: 1. IAM ロールをインスタンスプロファイルで付ける
インスタンスプロファイル経由でロールを付けると、一時的な認証情報がインスタンスに渡され、自動で更新されます。「キーを置かずに AWS を呼べるのはなぜか」を読み直してください。
起動が失敗・遅いときはどこを見るか
最後に、うまくいかないときの切り分けの順番です。起動の流れの順に、上から見ていきます。
| 症状 | まず見る場所 | 考えられること |
|---|---|---|
| pending のまま進まない、すぐ terminated になる | 状態の理由(インスタンスの詳細に出る) | 容量不足、EBS や上限の問題など |
| running だがチェック失敗 | システム/インスタンスのステータスチェック | 基盤の障害か、OS・ネットワーク設定の不具合か |
| 入れるが設定が反映されていない | ユーザーデータのログ | スクリプトの失敗、まだ実行中 |
| AWS の API が拒否される | アタッチされたロールとその権限 | ロールが付いていない、権限が足りない |
ユーザーデータの実行結果は、Linux では cloud-init のログに残ります。出力は /var/log/cloud-init-output.log で追えるので、スクリプトの途中でどこまで進んだかを確認できます。
まとめ
EC2 の起動を、順番に並べ直します。AMI からインスタンスが作られて pending から running になり、ユーザーデータが最初の 1 回だけ初期設定を行い、メタデータの窓口から自分の情報とロールの一時認証情報を取り、その認証情報で AWS を呼びます。止めるときは、停止(EBS は残りインスタンスストアは消える)と終了(戻せない)を使い分けます。
この「起動のたびに同じ状態になる」性質が、次に読む Auto Scaling の土台です。台数を自動で増減できるのは、ユーザーデータと AMI でどのインスタンスも同じ姿で立ち上がるからです。
READ ALSO — 学習中向け・段2 構成
Amazon EC2 Auto Scaling とは何か|台数を自動で増減し、壊れた1台を入れ替える仕組み
参照ソース
- Amazon EC2 インスタンスのライフサイクル(AWS 公式ドキュメント) — 状態の遷移、課金のタイミング、再起動・停止・休止・終了の違いの根拠
- EC2 インスタンスのユーザーデータ(AWS 公式ドキュメント) — 16 KB の上限、既定で最初の起動時のみ、root で実行、cloud-init のログの根拠
- インスタンスメタデータサービスの設定(AWS 公式ドキュメント) — IMDSv1 / IMDSv2、トークンの有効期間(最大 6 時間)、169.254.169.254 の根拠


