Amazon S3 で共同作業 / FTPクライアントからのアクセスを許可
いろいろなウェブサービスの画像データをAmazon S3に保存しているんだけど、
たまに共同作業も必要になる。
他のプロジェクトのデータも共存しているので、
特定のディレクトリだけにアクセスさせたいところ。
IAMで簡単そうだったけど、意外とハマるところもあった。
いろんなブログがあったけど、結局Amazonのブログがすごい分かりやすかった。
Writing IAM policies: Grant access to user-specific folders in an Amazon S3 bucket
こんな感じでFTPみたいに使えたらデベロッパーじゃない人も分かりやすいよね。
構成は下のようになっていて、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が書けます。
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を使ってアクセス
Open Connectionを選択すると S3 が選べる。
他のFTPクライント(FileZillaとか)でもできるのかは調べていない。
Users / Security Credentials / Manage Access Keys からKeyとSecretを取得。
Cyberduckをインストールして、
Key(Username) / Secret(Password) / Path を入力。
Pathは my-project/shared
です。
Amazon コンソールからアクセス
ユーザーにパスワードを与える必要があります。
Password Policyでいろいろティックして保存。
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