AWS クロスアカウント権限管理 「リソースポリシーからrootに許可するパターン」編
クロスアカウントで色々いじっていて、IAMの権限管理についてのパターンがなんとなくわかってきたのでメモします。
クロスアカウントでの権限管理は色々なパターンがあるようですが、今回扱うのは「AアカウントのリソースポリシーでBアカウントのrootを許可→Bアカウントの中でポリシーアタッチ」のパターンです。
具体的に見ていきましょう。まずはよくあるS3のパターンです。
別アカウントのS3バケットにLambdaからアクセスする
ここではアカウントID:111111111111
のアカウント1
からアカウントID:0000000000000000
のアカウント0
のS3バケットにアクセスしたいとします。
アカウント0のコンソールで、S3のバケットポリシーを以下のように設定します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Example permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::1111111111111:root" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKET_NAME/*" } ] }
ここではアカウント1のrootユーザーに対してS3バケットへのアクセスを許可しています。
次に、許可をもらったアカウント1のコンソールで以下のポリシーを作成し、S3バケットにアクセスするLambdaにアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::BUCKET_NAME/*", "Effect": "Allow" } ] }
これで、ポリシーをアタッチされたLambdaはアカウント0のS3バケットに対してアクセスすることができるようになります。
まずはアカウントのrootユーザーに権限を与える → 権限を得たroot(admin)ユーザーがリソースに対して権限を与えるという流れでわかりやすいと思います。
もちろん、最初にバケットポリシーで許可したActionしかできないようになっているので、例えば今回の場合s3:GetObject以外の操作権限はLambda にもrootユーザーにも与えられていません。
LambdaからObjectを新たにPUTしたりするためには、再びアカウント0の管理者にバケットポリシーからs3:PutObjectを許可してもらう必要があります。
別アカウントのLambdaにLambdaからアクセスする
先ほどと同様にアカウント1のLambdaからアカウント0のLambdaにアクセスしたいとします。
Lambdaの場合はリソースポリシーというものがあるので、ここで、アカウント1のrootユーザーに権限を与えます。
参考: AWS Lambda でリソースベースのポリシーを使用する (Lambda 関数ポリシー) - AWS Lambda
この操作は現在AWS CLIやAPIでしか行えないようです。
aws lambda add-permission \ --function-name FUNC_NAME \ --statement-id Example permissions \ --action lambda:InvokeFunction \ --principal 111111111111 \ --output json
上記のコマンドを実行すると以下のjsonが返ってきます。
{ "Statement": "{\"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:YOUR_REGION:000000000000:function:FUNC_NAME\", \"Effect\":\"Allow\", \"Principal\":{\"AWS\":\"111111111111\"}, \"Sid\":\"Example permissions\"}" }
CLIなので、見ためは違いますが、やっていることとしては先ほどのバケットポリシーと対して変わりません。アカウント1のrootユーザーに対してアカウント0のLambdaへのlambda:InvokeFunction
の権限を与えています。
次に、アカウント1のコンソールから、Lambda(アクセスする方)の実行ロールにアカウント0のLambdaへアクセスする権限を与えるポリシーをアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "lambda:InvokeFunction" ], "Resource": "arn:aws:lambda:YOUR_REGION:000000000000:function:FUNC_NAME", "Effect": "Allow" } ] }
これで、アカウント1のLambdaからアカウント0のLambdaにアクセスすることができるようになります。
おまけ: kmsのキーポリシーをIAMポリシーで管理する
実はクロスアカウントの権限管理以外にも、似たような権限の与え方をするパターンがあります。
それが、KMSのキーポリシーです。
AWSでは若干複雑なことに、KMSで作ったCMKに対する権限をKMSのキーポリシーで管理するということになっています。
ただ、特にLambdaに関しては実行ロールに付与されているIAMポリシーでLambdaの権限を管理できた方がわかりやすいため、IAMポリシーで管理できた方が便利だと思います。
そういった場合に、キーポリシーをIAMポリシーで管理できるようにするキーポリシーの書き方が以下です。
{ "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111111111111:root"}, "Action": "kms:*", "Resource": "*" }
これで、IAMポリシーでKMSのCMKの権限を管理できるようになります。 Lambdaの実行ロールには以下の権限を付与します。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "kms:*" ], "Resource": "arn:aws:kms:YOUR_REGION:111111111111:key/xxxxxxxxxx", "Effect": "Allow" } ] }