はじめに
今回は分かったふりをしながら使っていたIAMポリシーについて勉強したので記事にしてみました。
ポリシーってなんのためにあるの
いきなりですが、
「誰が」「どのリソースの」「何に対して」「どんな操作を」「許可 or 拒否する」
ポリシーの考え方はこれだけです
そして、作ったポリシーを「何か」に割り当てるだけ、です。
その「何か」には
- アイデンティティ
- リソース
があります。
アイデンティティ
アイデンティティというのはこんな感じです。
IAMユーザーやIAMロールに割り当てます。
このポリシーをアイデンティティベースのポリシーと言います。
リソース
リソースはAWSの各リソースですね。
LambdaやS3に割り当てます。
このポリシーをリソースベースのポリシーと言います。
この二つのポリシーには少し違いがありますが、ポリシーに対する考え方的な部分ははじめに書いた通り
「誰が」「どのリソースの」「何に対して」「どんな操作を」「許可 or 拒否する」
だけです。
ポリシーの書き方
上記の考え方をもとにポリシーを書く際は
- 誰が:Principal
- どのAWSリソースの:Actionの左側
- 何に対して:Resource
- どんな操作:Actionの右側
- 許可 or 拒否:Effect
このようになります。
細かい設定もありますが、まずはこれを覚えていれば概要は把握できるはずです。
ポリシーの割り当て方
では、ポリシーの何がややこしいのかイラストを交えながら見ていきましょう。
今回の登場人物は
- ジョン
- Lambda
- S3
ジョン(IAMユーザー)とLambdaはそれぞれ、S3のオブジェクトを取得したいと思っています。
この時、誰にどんなポリシーを割り当てればいいでしょうか?
私はここがIAMポリシーでつまずく部分でした。
いくつかパターンがあるので分解しながら見ていきましょう。
パターン1:ジョンにS3を操作するポリシーを割り当てる
パターン2:S3にジョンとLambdaから操作できるポリシーを割り当てる
パターン3:LambdaにS3を操作するポリシーを割り当てる
ざっくり分解するとこうなります。
先に軽く触れますが、この「パターン3」は正確ではないです。
正確には「LambdaにS3を操作できるポリシーを割り当てたロールを割り当てる」です。
詳細は後述します。
ジョンのアイデンティティベースのポリシー
ではまず、ジョンがS3のhtmlバケットを取得するポリシーを見ていきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::html/*"
}
]
}
これは単純ですね。
- Actionの左側:S3
- Resource:S3のhtmlオブジェクト
- Actionの右側:GetObject(オブジェクトを取得する)
- Effect:Allow(許可する)
S3のリソースベースのポリシー
次はS3がLambdaとジョンからのアクセスを許可するポリシーです
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::{ACCOUNT_ID}:user/John",
"arn:aws:iam::{ACCOUNT_ID}:role/service-role/{lambdaに割り当てたrole名}"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::html/*"
}
]
}
基本的な考え方はジョンに対するポリシーと同じなので省略します。
しかし、このリソースベースのポリシーにはアイデンティティベースのポリシーにはなかった「Principal」があります。
Principalは翻訳すると「主体」や「主要」という意味です。
「誰が」の部分です。
これは、アイデンティティベースのポリシーは対象となる相手が決まっているのでPrincipalは必要ありません。
ジョンに割り当てるポリシーにわざわざ「これはジョンのポリシーです」と書く必要はありませんね。
しかし、リソースベースのポリシーは主体がS3自身ではなく別のリソースのため、Principalを書く必要があります。
Lambdaにロールを割り当てる
では、最後にLambdaです。
先に書いた通り、Lambdaに直接S3を操作するためのポリシーを割り当てることはできません。
ポリシーを作成して、一旦IAMロールにポリシーを割り当てる必要があります。
Lambdaにもリソースベースのポリシーは存在しますが、それは別のリソースやユーザーがLambdaを操作する場合に使用します。
自分に対しての「許可」「拒否」はできるけど、他のリソースに対しての「許可」「拒否」はできない、ということです。
少し前置きが長くなってしまいましたが、Lambda用にIAMロールに割り当てるポリシーを見てみましょう
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::HTML/*"
}
]
}
このポリシーはロールに割り当てるので「Principal」がありません。
ロールに割り当てるので、これはアイデンティティベースのポリシーです。
LambdaからS3を操作するには、このポリシーを割り当てたロールをLambdaに割り当てる必要があります。
信頼ポリシー
上記のポリシーで{アカウントID}というのを指定していました。
もし、これを他のアカウントのIDにするとどうなるでしょう?
そうです、アカウントを跨いで操作を実行することができます。
しかし、これには信頼ポリシーというものを使って権限の付与を行う必要があります。
これに関しては私の説明の100万倍わかりやすい記事があったので、こちらを参考にして下さい。本当にわかりやすいです。
参考:https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/
まとめ
ポリシーはリソース同士を組み合わせる時には必ずと言ってもいいほど使われます。
よく触る設定なので、なんとなく分かっているフリをしていましたが、実際に勉強してみると理解できていない部分がありました。
これを機に、よくわからず作成した無駄なカスタムポリシーを削除して綺麗なポリシー管理をしていきたいと思います。