S3はIAMと組み合わせることにより、ファイルサーバ(Windowsの共有的な)のような構成を組むことも可能です。先にいうと、バケット単位での設定は結構簡単ですが、バケットは同じ、ディレクトリで分離という方法をなんとかします。
やりたいこと
目指すはコモンセンス(と私が思う)Windowsの共有です。 バケットは1つ、その中にディレクトリが2つあり、片方にはアクセスできるが、片方にはファイルの読み書きは無論、ディレクトリ内のファイル一覧も見れないように設定したい。
知っておいたほうがいいこと
S3に実はディレクトリはない
KVSと言って良いです。各オブジェクト(Value)に、ファイルパス(Key)が付いていると理解します。後々この概念が無いと理解出来ません。
ListAllMyBucketはほぼ必須
この権限は、自分(AWSアカウント)の持っているバケットを全部見せる権限です。S3のGUIブラウザ CloudBerryとかを使うならば、この設定をしておかないと、いきなりエラーが出たりします。ログイン後のディレクトリ&バケットを指定できるGUIツールの場合は、必須ではありません。この権限はあくまでバケット一覧を見せるだけで、バケットの中身は見れません。
Deny > Allow > 設定なし(Deny)
覚えておきましょう。一旦Allowで許してもDenyでかき消せるということです。ただし今回の設定では使いません。
リソース絞り or S3:Prefix絞り
IAMの設定では、arn:で始まるリソースで絞るか、Condition & s3:prefixで絞るかになりますが、どっちでもいいわけではなく、使い分けが必要です。下記の例では、バケットのトップディレクトリに対してListBucketを許していますが、これをConditionを使わずリソースだけでやってしまうと、バケット全体という意味になってしまいます。特にActionによっては、conditionでないとマズイものもあるので、Actionに応じてどちらにするかを決めましょう。
設定例
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets" ], "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::<your bucket>" ], "Condition": { "StringEquals": { "s3:prefix": [ "" ] } } }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::<your bucket>" ], "Condition": { "StringLike": { "s3:prefix": [ "B/*" ] } } }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::<your bucket11>/B/*" ] } ] }
説明
最初のListAllMyBucket
これは前述の通り。まあ必須です。
最初のListBucket
ListBucketはバケットの中身をList(lsやdir)できる権限。ここでいきなりCondition s3:prefixを使います。他所で書かれているのは、ここでCondtionを使わないでリソースだけで絞ってあるため、Aの中身もList出来てしまうという話が多いです。それに対し、 Condition s3:prefix = "" を指定することにより、明示的にバケット名直下のディレクトリに対してListできるように指定します。
2番めのListBucket
今度は本当にアクセスできるB/ディレクトリに対してListが効くようにします。
最後のPut,Get,Delete...
ここで実際にファイルの読み書きを設定します。
Denyを使う場合
上記のListBucketでs3:prefixで絞らず、Denyを後付して権限を奪う方法もありますが、例えばアクセスさせたくないディレクトリが増えた場合、その都度Denyルールを追記する必要があります。Groupで管理しても、これは結構大変です。なので、なるべくDenyを使わない方法にこだわった。
他に気になること
今回はバケット直下にディレクトリがある想定ですが、深い階層のディレクトリにこれをやろうとすると、考えないといけないっすね。。