【AWS】IAMロールを付与して、EC2のみS3バケットを操作できるようにする
概要
AWSのIAM(Identity and Access Management)の学習のため、IAMロールを作成し、特定のEC2インスタンスだけがS3バケットのファイルを操作できる状態を実現します。
構成図
EC2インスタンスがS3バケットの一覧表示・データ取得・書き込みをできるようにします。
S3バケットを作成する
S3バケットとは
S3バケットは、Amazon S3(Simple Storage Service)上でデータを保存するためのコンテナのことです。S3では、ファイルやデータのようなオブジェクトをバケット内に保存できます。バケットはデータを整理するフォルダのようなイメージです。
Azureで言うと、Blob Storageサービスに該当します。
作成手順
Amazon S3ページから「バケットを作成」を選択します。
- 一般的な設定
- バケット名: bucket-for-ec2
- AWS リージョン: アジアパシフィック(東京)ap-northeast-1
- オブジェクト所有者
- ACL無効(推奨)に✅
- このバケットのブロックパブリックアクセス設定
- パブリックアクセスを全てブロックに✅
- バケットのバージョニング
- バケットのバージョニング: 無効にするに✅
- デフォルトの暗号化
- 暗号化タイプ: Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)
- バケットキー: 有効にする
「バケットを作成」ボタンを押します。
暗号化のタイプ
暗号化のタイプの項目で、SSE-S3とSSE-KMSが選択できます。SSE-S3は、AmazonS3側でキーの管理を行なってくれるタイプです。一方で、SSE-KMSは、AWSのキーマネジメントサービス(KMS)を使って、ユーザー自身でキーを管理するタイプです。SSE-KMSでは、実際にKMSにリソースを作って使用します。
同一アカウント内のリソースからS3を使用する用途では、AWS側にキー管理を丸っとお任せするSSE-S3で十分のようです。このS3を他のアカウントのリソースからアクセスさせたい場合は、SSE-KMSを選択します。他のアカウント使用者にキーを提供するため、SSE-KMSを選択し、KMSにキーを作成しておく必要があります。
今回は異なるアカウントからアクセスするような複雑なことは行いませんので、当然**(SSE-S3)**を選択します。
S3バケットを操作するためのロール・ポリシーを作成する
今回、EC2からS3バケットに対して、一覧表示・データ取得・書き込みの操作ができるようにします。これを実現するには、次の3ステップを踏む必要があります。
- 特定のS3バケットに一覧表示・データ取得・書き込みする権限を持つカスタムポリシーを作成する
- IAMロールを作成し、1で作成したポリシーを関連付けする
- 2のIAMロールをEC2インスタンスに関連付けする
この手順を踏むことで、EC2インスタンスからS3バケットへの一覧表示・データ取得・書き込みの操作ができるようになります。
IAMポリシー / IAMロールとは
ポリシーやロールを作成する前に、IAMポリシー&IAMロールとは何か確認しておきます。
IAMロール
- AWSリソースに一時的にアクセス権限を付与するためのものです
- IAMユーザーと異なり、ユーザー名やパスワードなどの永続的な資格情報を持ちません。その代わりに、必要なタイミングで一時的に使用するセキュリティトークンが発行されます
IAMポリシー
- AWSリソースに対するアクセス権限を定義したものです
- IAMユーザー、IAMロール、IAMグループに関連付けして使用します。関連付けして初めて、ポリシーは効力発揮します。
- 複数のポリシーを意味のある単位でまとめたものがIAMロールと考えることができます。ポリシーを一つも持たないIAMロールは何の権限も持たないため、実質的には何の効力もありません。
JSON形式のIAMポリシー
下記は、IAMポリシーをJSON形式で表現したものです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket-for-ec2/*",
"arn:aws:s3:::bucket-for-ec2"
]
}
]
}
上記の例が定義していることをまとめると、
- bucket-for-ec2というS3バケットとその中のオブジェクトに対する(Resource)
- 書き込み、読み取り、一覧表示というアクションを(Action)
- 許可する(Effect)
ということになります。
Effect
次の項目以降で指定するアクションを"許可する(Allow)"のか"拒否する(Deny)"のかを指定する項目です。
Action
AWSサービスのアクションのリストです。
例えば、
- ec2:RunInstances: インスタンスを起動する。
- ec2:DescribeSecurityGroups: セキュリティグループの詳細情報を取得する。
- s3:ListBucket: S3バケットの一覧表示をする
など無数のアクションがあります。
Resource
ここで定義するポリシーが適用されるAWSリソース(Amazon Resource Name)のリストです。今回の例だと、書き込み、読み取り、一覧表示が許可される先のS3バケットとS3バケット内のオブジェクトが指定されています。
IAMポリシーを作成する
では、実際にポリシーを作成していきます。
AWSコンソールからIAMページに移動し、ポリシーを選択します。
- ポリシーを作成を押す
- アクセス許可を指定
- サービスを選択: S3を選択
-
アクセスレベル: 以下の3つを選択
- リスト: ListBucket
- 読み取り: GetObject
- 書き込み: PutObject
- リソース
- 特定を選択
- ARNを追加
-
bucket
- 任意のbucket name: bucket-for-ec2(先ほど作成したS3バケット)
- 任意のリソース: bucket-for-ec2
-
object
- 任意のbucket name: bucket-for-ec2
- 任意のobject name: *(bucket-for-ec2の全てのオブジェクトを指定)
-
bucket
- ポリシー名: PolicyForTestBucket
アクセス許可で何をできるかを指定しています。一方、リソースではどのリソースに対してを指定しています。このケースでは、先ほど作成したbucket-for-ec2というS3バケットを指定しました。このポリシーは、bucket-for-ec2というS3バケットに対して、リスト表示、読み取り、書き込みの操作ができることを示しています。
ポリシーを作成します。すると、カスタマー管理のポリシーが追加されているのが分かります。
ポリシーをJSONで確認する
作成後のポリシーをJSONで確認すると、以下のようになっています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket-for-ec2/*",
"arn:aws:s3:::bucket-for-ec2"
]
}
]
}
IAMロールを作成する
続いて、今作成したポリシーを関連付けるIAMロールを作成します。
AWSコンソールからIAMページに移動し、ロールを選択します。
- ロールを作成を押す
- 信頼されたエンティティタイプ: AWSのサービス
- ユースケース
- サービスまたはユースケース: EC2
- ユースケース: EC2
- 許可を追加
- 許可ポリシー: PolicyForTestS3Bucket(先ほど作成したカスタムのポリシー)
- 名前、確認、および作成
- ロール名: RoleForTestS3Bucket
EC2にIAMロールをアタッチする
EC2に作成したIAMロールをアタッチします。アタッチすることで初めて、EC2はS3バケットへの操作ができるようになります。
EC2のインスタンスのページに移ります。
- IAMロールを紐付けたいEC2インスタンスにチェックを付けます
- アクション > セキュリティ > IAMロールを変更
- IAMロール: RoleForTestS3Bucket(先ほど作成したIAMロール)
IAMロールの更新を押します。
EC2インスタンスの詳細ページのセキュリティタブから関連付けされたIAMロールが確認できます。
EC2からS3への操作を行う
EC2へのIAMロール付与が完了していますので、作成したS3バケットに対して書き込み、一覧表示、データ取得ができるようになったはずです。確認していきます。
まずはEC2インスタンスにSSH接続します。
テスト用のファイルを作成して、S3バケットにアップロードできることを確認します。
[ec2-user@ip-** ~]$ touch test.txt
[ec2-user@ip-** ~]$ aws s3 cp test.txt s3://bucket-for-ec2/documents/test.txt
upload: ./test.txt to s3://bucket-for-ec2/documents/test.txt
続いて、一覧表示できることを確認します。
[ec2-user@ip-** ~]$ aws s3 ls s3://bucket-for-ec2/documents/
2023-09-23 02:34:44 0 test.txt
先ほどアップロードしたファイルがあることが確認できました。
最後に、ファイルをダウンロードします。
[ec2-user@ip-** ~]$ aws s3 cp s3://bucket-for-ec2/documents/test.txt test_downloaded.txt
download: s3://bucket-for-ec2/documents/test.txt to ./test_downloaded.txt
[ec2-user@ip-** ~]$ ls
test.txt test_downloaded.txt
S3バケットにあるtest.txt
をEC2ローカルにtest_downloaded.txt
としてダウンロードされたことが確認できました。
IAMロールがアタッチされていない場合
テストのため、EC2にアタッチされたIAMロール(RoleForTestS3Bucket)をデタッチします。
その後、S3バケット内のオブジェクトの一覧表示を試みます。
[ec2-user@ip-** ~]$ aws s3 ls s3://bucket-for-ec2
Unable to locate credentials. You can configure credentials by running "aws configure".
ご覧の通り、EC2からS3バケットの一覧表示ができなくなりました。
Discussion