はじめに
AIエージェントを常時動かしておく基盤がほしくて、AWSのEC2インスタンスを立ててみました。エージェントは「立ち上げっぱなしで待ち受ける」使い方になるので、自分のPCではなく**常時稼働できるサーバ(=EC2)**が必要、という動機です。
AWSをアプリケーションの実行環境として使ったことは何度かあったのですが、EC2を自分で立てて、キーペアやセキュリティグループといったインフラ側まで管理するのは今回が初めてでした。全体としては思っていたよりスムーズに進んだのですが、途中で「EC2のパブリックIP、放っておくと変わるのか」という点に気づき、~/.ssh/config で楽に繋ぐためにIPの固定化まで踏み込みました。
この記事は2部構成です。
- 前半:EC2を立ち上げてSSH接続するまでの手順(自分用の備忘録も兼ねて)
- 後半:EC2のIPを固定化する方法の比較と、今回Elastic IPを選んだ理由
同じところを最初に通る方の参考になれば幸いです。
※記事中のIPアドレス・鍵名・インスタンスID等は、すべてマスキング/例示用の値に置き換えています。
前半:EC2を立ち上げてSSH接続するまで
1. キーペアを作成する
SSHでEC2に入るための鍵です。EC2コンソールの「キーペア」から作成します。
- タイプ:ED25519(新しめで短く安全。RSAでも可)
-
形式:
.pem(Mac/Linuxのssh用。.ppkはWindowsのPuTTY用なので選ばない)
作成すると .pem がダウンロードされます。これを ~/.ssh に置き、権限を絞ります。
$ chmod 400 ~/.ssh/my-ec2-key.pem
chmod 400 は「所有者だけ読める、グループ・その他は権限ゼロ」という意味です。SSHは鍵が他人からも見える権限だと接続を拒否するので、この権限設定は必須です。
補足(macOSのみ):
.pemを「ダウンロード」フォルダからmvしようとするとOperation not permittedで弾かれることがあります。これはmacOSのプライバシー保護でターミナルにフォルダ権限が無いために起きるもので、鍵の問題ではありません。Finderでドラッグ移動するか、システム設定でターミナルにフォルダ権限を付与すれば解決します。
2. セキュリティグループを作成する
セキュリティグループ(SG)は、インスタンスへの通信を「入ってくる(インバウンド)」「出ていく(アウトバウンド)」で管理する仕組みです。
- インバウンド:タイプ=SSH(22)、ソース=マイIP(自分の現在のグローバルIPだけに限定)
- アウトバウンド:デフォルト(すべて許可)のまま
ポイントは、SGがステートフルであること。「行き(インバウンドのSSH)」を許可すれば「帰り」は自動的に通るので、SSHのためにアウトバウンド側で22番を開ける必要はありません。
なお、ソースを「マイIP」にすると自分の回線のIPだけが許可されるので安全な一方、別の回線(カフェ等)に移るとIPが変わって繋がらなくなる点は覚えておきます。
3. EC2インスタンスを起動する
「インスタンスを起動」から、以下を指定します。
- AMI:Amazon Linux 2023
- インスタンスタイプ:無料枠クラスの micro(t2/t3.micro)
- キーペア:1で作成したもの
- ネットワーク設定:既存のセキュリティグループを選択(2で作ったSG)/パブリックIPの自動割り当てを有効(無効だと外からSSHできない)
4. SSHで接続する
インスタンスの詳細に表示されるパブリックIPv4アドレスが接続先です。
$ ssh -i ~/.ssh/my-ec2-key.pem ec2-user@<EC2のパブリックIP>
The authenticity of host '...' can't be established.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
[ec2-user@ip-172-31-x-x ~]$
初回だけホスト鍵の確認を聞かれるので yes。プロンプトが [ec2-user@ip-...]$ に変われば、サーバの中に入れています。ユーザー名が ec2-user なのは Amazon Linux の場合で、OSによって異なります(Ubuntuなら ubuntu)。
ここまでは特に詰まることなく、すんなり接続できました。
5. サーバの中を軽く確認する
一応、中身を確認しておきます。
$ cat /etc/os-release # OS(Amazon Linux 2023)
$ uname -a # カーネル・アーキ(x86_64)
$ nproc && free -h # 1 vCPU / 約1GB(microの実体)
$ curl -s ifconfig.me # 外から見た自分のIP=EC2のパブリックIP
最後の curl が値を返せば、**インスタンスから外へ出られている(アウトバウンドが効いている)**ことの確認になります。
後半:EC2のIPを固定化する
前半で普通に繋げたのですが、運用を考えると一点ひっかかりました。EC2のパブリックIPは、そのままだと変わるのです。
- 再起動(reboot) → IPは変わらない
- 停止→起動(stop→start) → IPが変わる
- 削除(terminate) → IPは消える
つまり日々「停止して翌日また起動」すると、そのたびにIPが変わります。~/.ssh/config にホストを登録して ssh myec2 のように繋ぎたいのに、IPが変わると毎回書き換えることになる。これを避けるために、IPの固定化を調べました。
IP固定化の選択肢を比較してみた
現実的な選択肢は大きく3つでした。
① Elastic IP(AWSの固定IPを割り当てる)
AWSが用意する固定のパブリックIPを確保してインスタンスに紐付ける方法。紐付けている限りIPが変わらないので、~/.ssh/config に静的に書けて一番シンプルです。
- メリット:とにかく簡単。スクリプトも不要。
- デメリット:保有している限り課金される(後述)。複数インスタンスを固定したいと台数分のElastic IPが要る。
② IPを自動更新するスクリプト
aws ec2 describe-instances で「今のパブリックIP」を取得し、~/.ssh/config を自動で書き換える小さなスクリプトを用意する方法。
- メリット:動いている間だけIP課金され、停止中はゼロ。多数のインスタンスをstart/stopするなら相性が良い。
- デメリット:ローカルにAWS CLIの設定が要る。ひと手間かかる。
③ SSM Session Manager(そもそもIPを使わない)
AWS Systems Manager 経由で、インスタンスIDを指定して接続する方法。パブリックIPも22番ポートの開放も不要で、認可はIAMで行う、いま一番モダンなやり方です。
- メリット:IPという概念から解放される。22番を世界に晒さないのでセキュリティも良い。台数が増えてもIDで繋ぐだけ。
- デメリット:インスタンス側にIAMロールを付ける必要があり、その準備にIAM操作の権限が要る。
比較表
| 手段 | IPの安定性 | 停止中の課金 | 複数インスタンス | 導入の手軽さ | 向いている場面 |
|---|---|---|---|---|---|
| ① Elastic IP | 固定 | かかる(保有中ずっと) | 台数分必要 | ◎ すぐ | 主力1台を長く固定運用 |
| ② 自動更新スクリプト | 都度更新 | かからない | 1本で使い回せる | △ CLI設定が要る | 多数をstart/stopする |
| ③ SSM | IP不要 | IP課金自体が不要 | IDで繋ぐだけ | △ IAM準備が要る | チームでの本番運用 |
今回は Elastic IP を選びました(なぜ)
今回は Elastic IP にしました。理由はこんな感じです。
- 今は環境をスクラップ&ビルドするフェーズだけど、運用方針が固まれば1台を固定でずっと使う見込み。だったら主力1台に固定IPを持たせる①がいちばんシンプル。
- 地味に効くのが、Elastic IPは terminate(インスタンス削除)しても消えないという性質。作り直すたびに同じElastic IPを新しいインスタンスに付け直せば、IP(=
~/.ssh/config)は変えずに済む。スクラップ&ビルド期にも都合が良かったです。 - 本命は③のSSMだと思うのですが、SSMはインスタンスにIAMロールを付ける必要があり、今のロール(PowerUserAccess)ではIAM操作ができず、管理者にロール作成を依頼する必要がありました。今回は自分だけで完結でき、手軽な①のElastic IPを選択しています(SSMは権限が整い次第、改めて試す予定)。
注意:Elastic IPの課金ルールが変わっている
ここは知っておくと良いポイントです。古い記事だと「Elastic IPは起動中のインスタンスに紐付いていれば無料」と書かれていることが多いのですが、現在は違います。
- 2024年2月以降、すべてのパブリックIPv4アドレスに課金されるようになりました($0.005/時)。
- Elastic IPは「保有している限り」課金され、インスタンスが停止中でも・どこにも紐付けていなくても同額です。
- 課金が止まるのは、Elastic IPを解放(release)してAWSに返したときだけ。
- ざっくり 1個あたり月$3.6 ≒ 550円くらい(状態問わず)。
「停止しておけばIP代もタダ」ではない、という点だけ押さえておけば大丈夫です。AWSを卒業するときは、インスタンスのterminateだけでなくElastic IPのreleaseも忘れずに。
Elastic IPを割り当ててSSHするまで
やることはシンプルでした。
- EC2の「Elastic IP」から新しいIPを割り当てる
- それをインスタンスに関連付ける
-
~/.ssh/configに登録:
Host myec2
HostName <Elastic IP>
User ec2-user
IdentityFile ~/.ssh/my-ec2-key.pem
これで ssh myec2 だけで入れるようになりました。実行すると、ちょっと面白い表示が出ます。
$ ssh myec2
ED25519 key fingerprint is SHA256:xxxxxxxx...
This host key is known by the following other names/addresses:
~/.ssh/known_hosts: <割り当て直す前のパブリックIP>
[ec2-user@ip-172-31-x-x ~]$
SSHが「この鍵、前に別のIPで会った子と同じだよ」と教えてくれています。ホスト鍵(指紋)が前のIPと同じ=中身は同じインスタンスで、パブリックIPだけがElastic IPに差し替わった、ということが確認できました。IPが固定されたので、以後は ssh myec2 だけ。IP固定なのでスクリプトも要らず、想像よりずっと簡単でした。
まとめ
- 前半:キーペア → セキュリティグループ(SSHはマイIPに限定)→ インスタンス起動(パブリックIP有効)→ SSH接続、という流れでEC2は素直に立ち上がる。
- 後半:EC2のパブリックIPはstop→startで変わるので、
~/.ssh/configで楽に繋ぐにはIP固定化が要る。 - 固定化の選択肢は ①Elastic IP/②IP自動更新スクリプト/③SSM の3つ。使い分けは、主力1台を長く固定なら①、多数をstart/stopするなら②、チームの本番運用なら③(IPを使わない)。
- 今回は「今はスクラップ&ビルド、将来は1台固定」という状況に合わせて①Elastic IPを選択。terminateしても残るので作り直しにも強い。
学び
-
chmod 400は「他者から見える権限を落とす」ためのもので、SSHの鍵には必須。 - セキュリティグループはステートフルなので、SSHのためにアウトバウンドを開ける必要はない。
- PowerUserAccessは「IAM以外はほぼ何でも」。SSMのようにIAMを触る作業は管理者の領域、という権限の線引きを理解できた。
- Elastic IPは2024年2月以降、保有しているだけで課金(停止中・未紐付けでも同額)。古い「紐付け中は無料」の情報は要注意。
最後に
「IPを固定する」という一見地味なテーマでも、選択肢ごとに得意・不得意があって、状況次第で最適解が変わるのが面白かったです。EC2の立ち上げからIP固定化まで、同じ道を最初に通る方の備忘録として参考になれば幸いです。最後まで読んでいただきありがとうございました。
参考リンク
- Amazon EC2 ユーザーガイド(キーペア / セキュリティグループ / Elastic IP)
- AWS「パブリックIPv4アドレスの課金」に関する公式アナウンス(2024年2月〜)
- AWS Systems Manager Session Manager ドキュメント