はじめに
EC2 アプリケーションは S3 からレポートを読み取る必要があります。インスタンスプロファイルを通じてアプリケーションに IAM ロールを割り当て、実際のレポート読み取りを確認し、権限を取り消したときの動作を観察します。
EC2 の起動、User Data、基本的な IAM ポリシーを理解していることが前提です。この新しい環境には、アプリケーションイメージ、ネットワーク、キーペア、架空のデータを含む S3 バケットが用意されています。アプリケーションインスタンスとその認可用リソースを作成します。
認定試験との関連
このラボでは最小権限とワークロードのロールを練習し、AWS Certified Cloud Practitioner のセキュリティ目標のタスク 2.3 と、コンピューティング目標のタスク 3.3 の理解に役立てます。
ロールのないアプリケーションを起動する
このステップではレポートサーバーを起動し、アプリケーションがまだ S3 を読み取れないことを確認します。
作業ディレクトリで、用意されたイメージ、ネットワーク、レポートバケットの ID を読み込みます。
cd /home/labex/project
source launch.env
用意された起動スクリプトを確認します。アプリケーションの S3 バケットとオブジェクトキーを設定しますが、認証情報は渡しません。
cat role-user-data.sh
この設定で role-server という名前のサーバーを起動します。
aws ec2 \
run-instances \
--image-id "$AMI_ID" \
--instance-type t3.micro \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$SECURITY_GROUP_ID" \
--key-name report-key \
--count 1 \
--user-data file://role-user-data.sh \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=role-server}]'
ID を保存します。
INSTANCE_ID=$(aws ec2 \
describe-instances \
--filters Name=tag:Name,Values=role-server \
--query 'Reservations[0].Instances[0].InstanceId' \
--output text)
aws ec2 \
wait instance-running \
--instance-ids "$INSTANCE_ID"
AWS View を開き、Refresh resources をクリックして role-server を選択し、Check application をクリックします。HTTP 200 と Role report server を確認します。次に Read S3 report をクリックします。HTTP 503 と Application storage unavailable が期待されます。実行中のアプリケーションにはまだロールの認証情報がありません。
EC2 上のアプリケーションはインスタンスメタデータを通じて、割り当てられたロールの一時認証情報を取得できます。AWS SDK はその情報を使って API リクエストに署名します。公式の EC2 ロールガイドでは、この手順を説明しています。ターミナルの認証情報をアプリケーションへコピーせず、ロールを設定します。
インスタンスプロファイルでアクセスを許可する
このステップでは、ロールの信頼ポリシーと権限ポリシーを作成し、ロールをインスタンスプロファイルに追加してサーバーに関連付けます。
信頼ポリシーは、誰がロールを引き受けられるかを定義します。EC2 サービスを信頼する JSON ポリシーを作成します。区切り文字を引用符で囲んだヒアドキュメントにより、JSON がそのまま保持されます。
cat > ec2-trust.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
JSON
この信頼ポリシーで report-reader ロールを作成します。
aws iam \
create-role \
--role-name report-reader \
--assume-role-policy-document file://ec2-trust.json
権限ポリシーは、引き受けたロールが実行できる操作を定義します。このアプリケーションに必要なのは report.csv に対する s3:GetObject だけです。オブジェクト ARN にはバケットとキーの両方が含まれます。前の引用符付きヒアドキュメントとは異なり、以下の引用符なしの JSON は $REPORT_BUCKET を用意されたバケット名に展開します。
cat > read-report.json <<JSON
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::$REPORT_BUCKET/report.csv"
}]
}
JSON
展開されたリソース ARN を確認します。
cat read-report.json
このインラインポリシーをロールに追加します。
aws iam \
put-role-policy \
--role-name report-reader \
--policy-name ReadReport \
--policy-document file://read-report.json
インスタンスプロファイルは IAM ロールを EC2 に提供します。CLI を使う場合、ロールとプロファイルを別々に作成します。分かりやすくするため、同じ名前のプロファイルを作成します。
aws iam \
create-instance-profile \
--instance-profile-name report-reader
ロールをプロファイルに追加します。
aws iam \
add-role-to-instance-profile \
--instance-profile-name report-reader \
--role-name report-reader
既存のインスタンスにプロファイルを関連付け、削除時に使う関連付け ID を保存します。
ASSOCIATION_ID=$(aws ec2 \
associate-iam-instance-profile \
--instance-id "$INSTANCE_ID" \
--iam-instance-profile Name=report-reader \
--query 'IamInstanceProfileAssociation.AssociationId' \
--output text)
関連付けを確認します。
aws ec2 \
describe-iam-instance-profile-associations \
--association-ids "$ASSOCIATION_ID" \
--query 'IamInstanceProfileAssociations[].{Instance:InstanceId,State:State,Profile:IamInstanceProfile.Arn}'
associated と report-reader プロファイルを確認します。AWS View を更新し、Read S3 report をクリックします。HTTP 200 と period,total、Q1,320 が期待されます。アプリケーションは SDK のロール認証情報を使って実際の S3 オブジェクトを取得します。関連付けがまだ伝播中であれば、少し待ってからリクエストを再試行してください。
このロールは 1 つのオブジェクトの読み取りを許可し、バケット全体へのアクセスや管理者権限は与えません。インスタンスプロファイルガイドでは、プロファイルによるロールの提供と、関連付け変更の伝播に時間がかかる理由を説明しています。
権限の取り消しを確認する
このステップではロールのレポート権限を削除し、認可の失敗とアプリケーションの障害を区別します。
自分で作成したインラインポリシーだけを削除します。
aws iam \
delete-role-policy \
--role-name report-reader \
--policy-name ReadReport
ロールに残っているインラインポリシーを一覧表示します。
aws iam \
list-role-policies \
--role-name report-reader
空の PolicyNames 一覧が期待されます。インスタンスプロファイルは関連付けられたままですが、ロールはレポートの読み取りを許可しなくなります。
AWS View で Check application をクリックし、HTTP 200 を確認します。サーバーはまだ実行中です。次に Read S3 report をクリックします。HTTP 403 と Access denied が期待されます。権限変更がまだ伝播していない場合は、少し待って再度リクエストしてください。正常なヘルス応答と S3 の拒否が同時に見られる場合、インスタンス停止やアプリケーション欠落ではなく認可の問題を示します。
SDK は一時認証情報をキャッシュすることがあります。ロールの権限を削除すると、その認証情報で実行できる操作が変わります。インスタンスプロファイルの削除によって、すでに発行された認証情報が直ちに失効するわけではありません。
インスタンスとロールを削除する
このステップでは、自分で作成した関連付け、サーバー、プロファイル、ロールを削除します。
保存した関連付け ID でプロファイルの関連付けを解除します。
aws ec2 \
disassociate-iam-instance-profile \
--association-id "$ASSOCIATION_ID"
アプリケーションインスタンスを終了します。
aws ec2 \
terminate-instances \
--instance-ids "$INSTANCE_ID"
aws ec2 \
wait instance-terminated \
--instance-ids "$INSTANCE_ID"
使わなくなったインスタンスプロファイルからロールを削除します。
aws iam \
remove-role-from-instance-profile \
--instance-profile-name report-reader \
--role-name report-reader
空のプロファイルを削除します。
aws iam \
delete-instance-profile \
--instance-profile-name report-reader
インラインポリシーは権限取り消し時に削除済みです。自分のロールを削除します。
aws iam \
delete-role \
--role-name report-reader
インスタンスが終了したことを確認します。
aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}'
指定した名前のロールとプロファイルがないことを確認します。
aws iam \
list-roles \
--query "Roles[?RoleName=='report-reader'].RoleName"
aws iam \
list-instance-profiles \
--query "InstanceProfiles[?InstanceProfileName=='report-reader'].InstanceProfileName"
両方の一覧が [] であることを確認します。AWS View を更新して、サーバーが実行中の対象ではないことを確認してください。用意された S3 データ、ネットワーク、キーペアはそのまま残します。
まとめ
IAM ロールに EC2 の信頼関係と 1 つの S3 オブジェクトの読み取り権限を設定し、インスタンスプロファイルでロールを提供して、アプリケーションが実際にレポートを読み取ることを確認しました。その後、権限を取り消し、S3 の拒否とアプリケーションの正常稼働を区別しました。最後にインスタンス、プロファイル、ロールを削除しました。



