はじめに
前回の記事では、Terraform を使って EC2 に最小権限の IAM Role を設計・定義する構成を整理しました。
本記事では、前回 Terraform で作成した IAM Role を EC2 に適用し、
- S3 オブジェクトのGet / Listが成功すること
- Put が失敗すること(ReadOnly が保証されていること)
を、EC2 からの実操作で検証します。
検証の前提条件
- Terraform による apply が完了していること
- 以下のリソースが作成済みであること
- EC2 インスタンス
- IAM Role(S3 ReadOnly + SSM)
- IAM Instance Profile
- 検証対象の S3 バケット
- EC2 に IAM Role が正しくアタッチされていること
※ 本記事では IAM ポリシーや Role の定義内容は前回記事で作成したものを使用します。
Session Manager を使って EC2 に接続
下記コマンドを実行し、EC2に接続する。
aws ssm start-session --target <instance_id>
S3 ListBucket(一覧取得)の動作確認
以下コマンドを実行し、検証対象のS3バケットの中身を一覧取得可能であることを確認する。
aws s3 ls s3://<bucket-name>/
出力結果:
2025-12-28 14:18:01 30 test.txt
S3 GetObject(ダウンロード)の動作確認
以下コマンドを実行し、test.txtファイルをダウンロード可能であることを確認する。
aws s3 cp s3://<bucket-name>/test.txt /tmp/downloaded.txt
cat /tmp/downloaded.txt
出力結果:
this is s3 readonly test
S3 PutObject(アップロード)の動作確認
以下のコマンドを実行し、検証対象のS3にファイルのアップロードが失敗することを確認する。
echo "put test" > put_test.txt
aws s3 cp put_test.txt s3://<bucket-name>/put_test.txt
出力結果:
upload failed: ./put_test.txt to s3://<bucket-name>/put_test.txt
An error occurred (AccessDenied) when calling the PutObject operation:
User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/iam-test-ec2-role-dev/i-xxxxxxxxxx
is not authorized to perform: s3:PutObject
on resource: "arn:aws:s3:::<bucket-name>/put_test.txt"
because no identity-based policy allows the s3:PutObject action
躓いた点:SSM 接続時の作業ディレクトリと権限エラー
EC2 に SSM で接続後、S3 ReadOnly ポリシーが正しくアタッチされているかを確認するため、以下のコマンドでGetObjectの動作確認を行いました。
aws s3 cp s3://<bucket-name>/example.txt ./downloaded.txt
しかし、以下のエラーが発生しました。
download failed: s3://<bucket-name>/example.txt to ./downloaded.txt
[Errno 13] Permission denied: u'/usr/bin/downloaded.txt.89D0aCF2'
一見すると「S3 ReadOnly ポリシーが効いていないのでは?」と勘違いしましたが、原因は IAM ではなく、EC2 内のユーザー権限 でした。
原因:SSM 接続時は ec2-user ではなく ssm-user になる
SSM で EC2 に接続した直後、以下のコマンドで作業ディレクトリを確認しました。
cd ~
pwd
すると、ログインユーザーがec2-userではなくssm-userであることが分かりました。
今回のエラーでは、カレントディレクトリが書き込み不可なパスとなっており、S3 からのダウンロード自体は成功しているものの、ローカルへのファイル書き込みでPermission denied が発生していました。
なぜ /tmp では問題なく動作したのか
/tmp ディレクトリは以下の特徴を持っています。
- 全ユーザーに書き込み権限が付与されている
- 一時ファイル置き場として利用される想定
- SSM の ssm-user からも書き込み可能
そのため、ダウンロード先を /tmp に変更することで、正常にファイルを取得できました。
aws s3 cp s3://<bucket-name>/example.txt /tmp/example.txt
この結果から、
- S3 への
GetObjectは正常に許可されている - IAM ポリシー(S3 ReadOnly)が正しくアタッチされている
- エラーの原因は OS 側のファイル権限
であることが確認できました。
学び
- SSM 接続時は
ec2-userではなくssm-userになる - IAM エラーと OS の Permission denied は切り分けが重要
まとめ
本記事では、Terraform で作成したS3 ReadOnly の IAM Roleを EC2 にアタッチし、Session Manager 経由で EC2 に接続した上で、S3 操作の実動確認を行いました。
検証の結果、
-
ListBucket/GetObjectは 正常に成功 -
PutObjectは AccessDeniedとなり、最小権限が保証されていることを確認 - SSM 接続時の
Permission deniedは IAM ではなく OS 側の権限問題 であることを切り分け可能
であることが分かりました。
特に、SSM 接続時はssm-userになる点と、「IAM エラーなのか」「EC2 内の権限エラーなのか」を切り分ける視点は、実務でトラブルシュートを行う上でも重要なポイントだと感じました。
IAM ポリシーの検証では、「できること」だけでなく「できないことを確認する」 ことで、最小権限が正しく設計・適用されているかを明確に証明できます。