はじめる前に
- 必須AWS アカウントを持ち、マネジメントコンソールにサインインできること
- 必須EC2 インスタンスを起動し、ユーザーデータやセキュリティグループを設定した経験があること
- 必須S3 でバケットを作り、ファイルをアップロードした経験があること
- あると良い「アクセスキー(プログラムから AWS を操作するための鍵)」という言葉を聞いたことがある
※ このハンズオンは すべてコンソールだけで完結します。サーバーへのログイン(SSH)は不要で、動作確認はブラウザで行います。コマンドはユーザーデータに貼り付けるだけです。
参照する公式ドキュメント
手順に迷ったときや、用語の意味を確かめたいときに開きましょう。
※ リンク切れの場合は、ページタイトルで検索してください。
背景・シナリオ
EC2 サーバーの上で動くプログラムから、S3 のファイルを読みたい——よくある場面です。素朴にやろうとすると、AWS を操作するためのアクセスキー(鍵)をサーバーの中に書いておく方法が思い浮かびます。しかしこれは危険です。鍵をサーバーに埋め込むと、サーバーを覗かれたり、設定を間違えて公開したりしたときに、その鍵が丸ごと盗まれてしまいます。しかも、長期間使える鍵だと、被害が長く続きます。
そこで使うのが IAM ロールです。EC2 にロールを「持たせて」おくと、サーバーには鍵を一切書かなくても、AWS が自動的に、必要な権限を一時的に渡してくれます。今回は、S3 を読む権限を持つロールを EC2 に付け、サーバーが鍵なしで S3 のファイルを取得して表示するところを確かめます。
「ロール」って、ユーザーと何が違うの?
ユーザーが「人にひもづく身分証」なら、ロールは「役割(立場)にひもづく、付け替えできる権限のセット」です。EC2 にロールを付けると、そのサーバーが一時的にその役割になり、ロールに許可された操作だけができます。終われば返せます。
鍵を書かないのに、どうやって権限が渡るの?
ロールを付けた EC2 には、AWS が一時的な認証情報を自動で用意します。サーバー上のプログラム(今回は aws コマンド)は、それを自動で受け取って使います。有効期限つきで自動更新されるため、長期の鍵を持ち歩くより安全です。
S3 を読む権限を持つ IAM ロールを作って EC2 に付け、サーバーがアクセスキーを一切埋め込まずに S3 のファイルを取得し、ブラウザでその内容が表示されることを確認する。
つくる構成
EC2 に「S3 読み取り」の IAM ロールを付けます。サーバーは鍵を持たず、ロールから渡される一時的な権限で S3 のファイルを取得します。取得した内容をブラウザで表示して確認します。
message.txt を保管
権限は、付けた IAM ロールから一時的に・自動で渡されているからです。
要件
以下の要件を満たし、EC2 がロールの権限で S3 を読めることをブラウザで確認してください。
| No | 要件 |
|---|---|
| 1 | リージョンは「東京(ap-northeast-1)」を使用する。 |
| 2 | S3 バケットを 1 つ作成し(非公開のまま)、中身の分かるテキストファイル message.txt(例:「これは S3 から取得したファイルです」)をアップロードする。 |
| 3 | EC2 用の IAM ロールを作成する。信頼するサービスは EC2、権限は S3 の読み取り(例:マネージドポリシー AmazonS3ReadOnlyAccess)。 |
| 4 | EC2 インスタンスを 1 台起動し、手順 3 のロールをアタッチする。ユーザーデータで Apache を起動し、ロールの権限で S3 から message.txt を取得して表示用に配置する。HTTP(80)を許可し、パブリック IP を付ける。 |
| 5 | ブラウザで EC2 のパブリック IP にアクセスし、S3 から取得したファイルの内容が表示されることを確認する(サーバーには鍵を一切書いていない)。 |
構築の進め方
「S3 にファイルを置く → ロールを作る → ロールを付けて EC2 を起動 → ブラウザで確認」の順に進みます。サーバーに鍵を書かない、という点を意識してください。
-
S3 バケットを作り、ファイルを置く(非公開のまま)
リージョンが東京であることを確認し、S3 でバケットを 1 つ作成します(非公開のまま)。
message.txtというテキストファイルを作り(中に「これは S3 から取得したファイルです」などと書く)、アップロードします。公開しないのがポイントバケットは非公開のままにします。誰でも見られる状態ではないので、EC2 が読めるのは「ロールの権限のおかげ」だとはっきり分かります。
-
EC2 用の IAM ロールを作成する
IAM コンソールの「ロール」→「ロールを作成」を開きます。信頼されたエンティティで「AWS のサービス」→「EC2」を選びます。次の許可ポリシーの画面で
AmazonS3ReadOnlyAccessを検索してチェックを入れ、ロール名(例:ec2-s3-read-role)を付けて作成します。信頼されたエンティティタイプ
AWS のサービスEC2 など AWS のサービスに引き受けさせる別の AWS アカウント他アカウントに引き受けさせるウェブアイデンティティ外部 ID プロバイダー向けユースケース
EC2EC2 インスタンスにロールを渡すLambdaLambda 関数にロールを渡す↳「AWS のサービス」→「EC2」を選びます
「誰に持たせるロールか」を決める信頼するサービスに EC2 を選ぶことで、「このロールは EC2 が引き受けられる」という意味になります。許可ポリシー(S3 読み取り)が、その役割でできることの中身です。今回は学習のため読み取り全般を許可しますが、実際は対象のバケットだけに絞るのが望ましいです。
-
ロールを付けて EC2 を起動する(ユーザーデータで S3 から取得)
EC2 を 1 台起動します。Amazon Linux 2023・無料利用枠タイプ、パブリック IP の自動割り当てを有効、HTTP(80)を許可します。「高度な詳細」の「IAM インスタンスプロフィール」で、手順 2 のロール(
ec2-s3-read-role)を選びます。同じ「高度な詳細」の「ユーザーデータ」に、次を貼り付けます(バケット名は自分のものに置き換え)。#!/bin/bash dnf install -y httpd systemctl enable --now httpd # 付けた IAM ロールの権限で S3 からファイルを取得する(鍵は書かない) aws s3 cp s3://バケット名/message.txt /var/www/html/index.html
この 1 行に鍵が無いことに注目aws s3 cp …の行には、アクセスキーもパスワードも書かれていません。それでも S3 から取得できるのは、EC2 に付けたロールが、一時的な権限を自動で渡しているからです(awsコマンドは Amazon Linux に最初から入っています)。 -
ブラウザで確認する
インスタンスが「実行中」になって数分待ったら、パブリック IPv4 アドレスにブラウザでアクセスします。S3 に置いた
message.txtの内容(例:「これは S3 から取得したファイルです」)が表示されるはずです。サーバーに鍵を書かずに、S3 のファイルを読み出せました。表示まで少し待つ起動直後は、ユーザーデータの実行(Apache の導入と S3 からの取得)に 1〜2 分かかることがあります。すぐ表示されないときは、少し待ってから再読み込みしてみましょう。
つまずきポイント
初学者がよく引っかかる箇所を先回りでまとめました。答えそのものは載せていませんが、「どこを見直せばよいか」の手がかりとして使ってください。
「アクセスしても、ファイルの中身が出てこない(空や既定ページ)」
S3 からの取得に失敗していると、表示用のファイルが作られません。①EC2 に IAM ロール(ec2-s3-read-role)がアタッチされているか、②ロールに S3 読み取り権限が付いているか、③ユーザーデータのバケット名・ファイル名(message.txt)が正しいかを見直しましょう。ロールが無い・権限が足りないと、取得は拒否されます。
「タイムアウトして、ページ自体が表示されない」
これはロールの問題ではなく、ネットワーク側の典型です。①セキュリティグループで HTTP(80)が許可されているか、②パブリック IP アドレスが付いているか、③http:// でアクセスしているかを確認しましょう。ページは開くが中身が空、という場合は Pitfall 01 のほうを見直します。
完了チェック
要件の再確認ではなく、画面のどこを見れば達成を確認できるかをまとめました。S3・IAM・EC2 コンソールとブラウザを開いて、次を順に確かめましょう。
- S3 バケットが非公開のままで、
message.txtが入っている。 - IAM の「ロール」に
ec2-s3-read-roleがあり、S3 読み取りの権限と、EC2 が信頼されている設定になっている。 - EC2 インスタンスの詳細で、IAM ロールが
ec2-s3-read-roleとしてアタッチ済みになっている。 - ブラウザで EC2 のパブリック IP を開くと、S3 のファイルの内容が表示される。
- ユーザーデータのどこにも、アクセスキーやパスワードを書いていない(鍵なしで読めている)。
考えてみよう
手を動かすことに加えて、次の問いに自分の言葉で答えられるようにしておくと、理解がより深まります。
- アクセスキー(長期の鍵)をサーバーに書いておく方法と、IAM ロールを付ける方法では、安全性にどんな差があるでしょうか。鍵が「漏れたとき」を想像して比べてみましょう。
ヒント
埋め込んだ長期の鍵が漏れると、その鍵は(消すまで)ずっと有効で、被害が長く続きます。ロールが渡す認証情報は一時的で自動更新されるため、仮に一時的に漏れても有効期限で使えなくなります。「鍵の寿命」と「埋め込む場所」という観点で考えてみましょう。 - 今回はロールに「S3 の読み取り全般」を許可しました。実際の運用では、これをどう絞るとより安全になるでしょうか。
ヒント
「すべての S3」ではなく「このバケットだけ」「読み取りだけ(書き込み・削除は不可)」のように、必要な範囲だけに絞れます(最小権限)。許可を狭くするほど、万一のときにできることも限られます。「その役割が本当に必要な操作だけ」を許可する、という観点で考えてみましょう。 - EC2 だけでなく、Lambda などの他のサービスも IAM ロールで権限を受け取れます。なぜ AWS は、サービスにロールを「持たせる」かたちを基本にしているのでしょうか。共通する利点を考えてみましょう。
ヒント
どのサービスでも「鍵を埋め込まない・一時的な権限・必要な分だけ」を共通の作法にできる、という利点があります。サービスごとにバラバラの鍵管理をするより、ロールで統一したほうが安全で管理も楽、という観点で考えてみましょう。
後片づけ
作ったものを片づけます。EC2 は起動している間ずっと課金されるため、忘れず終了しましょう。
- EC2 インスタンスを終了する:「インスタンス」で対象を選び、「インスタンスを終了(Terminate)」します。
- IAM ロールを削除する(任意):もう使わない場合、IAM の「ロール」で
ec2-s3-read-roleを削除できます。 - S3 のオブジェクトとバケットを削除する:
message.txtを削除し、バケットを空にしてから削除します。 - セキュリティグループを削除する(任意):このハンズオン用に作ったものは、インスタンス終了後に削除できます。
消し忘れて困るのは EC2 のほう
IAM ロールやポリシーの存在には料金がかかりません。一方、EC2 インスタンスは起動している間ずっと課金されます。片づけでは、まず EC2 の終了を優先しましょう。デフォルト VPC などの既定リソースは消さないようにします。
コストに関する注意: IAM ロール・ポリシーの作成や利用に料金はかかりません。料金が発生するのは、主に起動した EC2 インスタンス(t2.micro / t3.micro などは無料利用枠の対象)と、インスタンスに付くディスク(EBS ボリューム)、割り当てられる public IPv4 アドレスです。S3 も保管データ量・リクエストに応じた料金(小さなファイルなら少額・無料枠の範囲が多い)がかかります。使い終えたら、上の「後片づけ」で EC2 の終了と S3 の削除を行いましょう。最新の料金は AWS の公式料金ページで確認してください。