Amazon S3 で共同作業 / FTPクライアントからのアクセスを許可

いろいろなウェブサービスの画像データをAmazon S3に保存しているんだけど、
たまに共同作業も必要になる。
他のプロジェクトのデータも共存しているので、
特定のディレクトリだけにアクセスさせたいところ。

  
IAMで簡単そうだったけど、意外とハマるところもあった。
いろんなブログがあったけど、結局Amazonのブログがすごい分かりやすかった。

Writing IAM policies: Grant access to user-specific folders in an Amazon S3 bucket

こんな感じでFTPみたいに使えたらデベロッパーじゃない人も分かりやすいよね。
Screen Shot 2015-02-01 at 5.04.56 PM

  
構成は下のようになっていて、sharedだけを共同作業用に使いたい。
other-project1 / other-project2 / my-project はそれぞれS3のルートにあるBucket。

  • other-project1(Bucket)
  • other-project2
  • my-project
    • shared
    • admin

IAM

IAMが何なのかはこのページの動画が分かりやすい。
IAM とは? - AWS Identity and Access Management
  
ひとまずIAMでグループとユーザーをつくっておく。
Group / Permissions / Attach Another Policy にいく。
Custom Policy を選んで Selectボタンを押すと自分でPolicyが書けます。

Screen Shot 2015-02-01 at 6.19.37 PM

Policy Template とか Policy Generator とかあって、
それも便利だけど今回は Custom でやる。

ブレイクダウン

S3のバケットの表示を許可する

ListAllMyBuckets だけでOKかと思ってたけど GetBucketLocation もいるみたいです。
Resourceは arn:aws:s3:::* としておかないと、
S3コンソールを使った時にsharedまで辿りつけない。ので当然sharedの中身もさわれない。

1
2
3
4
5
6
   {
     "Sid": "AllowUserToSeeBucketListInTheConsole",
     "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::*"]
   }

  
sharedフォルダのだけをアクセス許可

Condition を使ってsharedだけを指定。
delimiter も指定しておくのがベストプラクティスだそうです。

1
2
3
4
5
6
7
   {
     "Sid": "AllowListingOfMyProjectBucket",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::my-project"],
     "Condition":{"StringEquals":{"s3:prefix":["","shared/"],"s3:delimiter":["/"]}}
   }

  
sharedフォルダの中身を表示許可

上の内容だけで十分じゃかないかと思ってしまうけど、
StringEquals を使っているのでその中のファイルが対象にならない。
*(ワイルドカード)を使いたいので、 StringLike を使うのだと。

これを "Resource": ["arn:aws:s3:::my-project/shared/*"] をしてはいけない理由は、
ListBucket はバケットレベルにしか対応してないからとのこと。sharedフォルダはBucketではないので、そこを指定するのに StringLike すると。
普段使っているフォルダのように、バケットは階層にはなってないのですね。だからサブフォルダーならぬサブバケットのようなものは存在しない。データは並列で root/sub/file.txt と指定したところで、それがAmazon S3 コンソールで確認できるようなフォルダーの中身を示しているわけではないと。

Amazon S3 stores data in a flat structure; you create a bucket, and the bucket stores objects. Amazon S3 doesn't have a hierarchy of sub-buckets or folders; however, tools like the AWS Management Console can emulate a folder hierarchy to present folders in a bucket by using the names of objects (also known as keys).

1
2
3
4
5
6
7
   {
     "Sid": "AllowListingOfSharedFolder",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::my-project"],
     "Condition":{"StringLike":{"s3:prefix":["shared/*"]}}
   }

  
sharedフォルダの中では何でも許可

ListBucket に対してこちらは my-project/shared/* と指定してOK。

1
2
3
4
5
6
   {
     "Sid": "AllowAllS3ActionsInUserFolder",
     "Effect": "Allow",
     "Action": ["s3:*"],
     "Resource": ["arn:aws:s3:::my-project/shared/*"]
   }

全部まとめると

こんな感じ。
先のページからほぼ引用ですが。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
 "Version":"2012-10-17",
 "Statement": [
   {
     "Sid": "AllowUserToSeeBucketListInTheConsole",
     "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::*"]
   },
  {
     "Sid": "AllowListingOfMyProjectBucket",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::my-project"],
     "Condition":{"StringEquals":{"s3:prefix":["","shared/"],"s3:delimiter":["/"]}}
    },
   {
     "Sid": "AllowListingOfUserFolder",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::my-project"],
     "Condition":{"StringLike":{"s3:prefix":["shared/*"]}}
   },
   {
     "Sid": "AllowAllS3ActionsInUserFolder",
     "Effect": "Allow",
     "Action": ["s3:*"],
     "Resource": ["arn:aws:s3:::my-project/shared/*"]
   }
 ]
}

FTPを使ってアクセス

IAM Management Console

Open Connectionを選択すると S3 が選べる。
他のFTPクライント(FileZillaとか)でもできるのかは調べていない。
  
Users / Security Credentials / Manage Access Keys からKeyとSecretを取得。
Cyberduckをインストールして、
Key(Username) / Secret(Password) / Path を入力。
Pathは my-project/shared です。

Screen Shot 2015 02 01 at 5.50.51 PM

Amazon コンソールからアクセス

ユーザーにパスワードを与える必要があります。
Password Policyでいろいろティックして保存。

Screen Shot 2015-02-01 at 6.06.07 PM

Users / Sign in Credentials / Manage Password からパスワードを設定できます。
サインインURLは Dashboard に戻ると確認できます。
IAM users sign-in link というやつです。

  
以上。
チームメイトにCyberduckをイントール / 接続してもらった後は自由にファイルをさわられるはず。
便利!

参考

ARNsについて
Amazon Resource Names (ARNs) and AWS Service Namespaces - Amazon Web Services

  

何かありましたらコメントをどうぞ

comments powered by Disqus

人気の記事

950 Points チリ出身のギタリストが弾くドラゴンボールZがむちゃくちゃかっこいい…
774 Points Wordpress + Heroku + PostgreSQL + Amazon S3 = ¥0 / 無料でサイト運営
700 Points Rubyのチートシート 変数 / クラス / モジュール
524 Points Rubyのチートシート / アクティブサポート
451 Points 紙のデザイナーがウェブ開発できるようになるまでに必要なこと
435 Points Rails / Google Analyticsのデータを使って分析や管理画面のためのグラフをつくる
323 Points RailsとHerokuでノーティフィケーションをプッシュする / PusherとTurbolinksの兼ね合い
222 Points Rails / RSpec テスト書いたことない メンドクサイ(n´Д`)という時のチートシート
193 Points Rails / Ajaxを使って画面遷移しない一時保存機能をつける
193 Points Protractorでスクレイピングしてみた