アインデンティティベースのポリシーとリソースベースのポリシーの整理

記事タイトルとURLをコピーする

はじめに

はじめまして。
5月にサーバーワークスに入社し、アプリケーションサービス部に配属となりました兼安と申します

4人家族の我が家は最近推しの子ブームです。
家の中でずっとOPテーマが流れています。
私自身はまだハマっていないのですが、なんだか家族に推しきられそうです。

仕事では先日API GatewayとLambdaにハマりました。
原因調査していたら自分の中でアインデンティティベースのポリシーとリソースベースのポリシーが整理できたので書き残してみます。

API GatewayからのLambda実行に失敗する

API Gatewayの後ろにLambdaを置く

上記のようにAPI Gatewayの後ろにLambdaを配置。
APIを作って叩いてみたところ、Internal Server Errorが発生しました。
原因は、API GatewayがLambdaを呼び出す権限がなかったことです。
Lambda側のリソースベースのポリシーステートメントでAPI Gatewayからの呼び出しを許可することで解決しました。

具体的な手順は、Lambdaの「設定」の「アクセス権限」タブにある「リソースベースのポリシーステートメント」にApi Gatewayから実行を許可するポリシードキュメントを追加です。

Lambdaのアクセス権の画面

「リソースベースのポリシーステートメント」に記載したポリシードキュメント

{  
  "Version": "2012-10-17",  
  "Id": "default",  
  "Statement": [  
    {  
      "Sid": "Sid",  
      "Effect": "Allow",  
      "Principal": {  
        "Service": "apigateway.amazonaws.com"  
      },  
      "Action": "lambda:InvokeFunction",  
      "Resource": "arn:aws:lambda:ap-northeast-1:AWSアカウントID:function:Lambda関数名"  
    }  
  ]  
}  

この現象は、API Gateway側でLambdaの実行権限を持つロールを設定することでも対応できます。

目的のLambda関数の実行権限を持ったロールを用意し、API Gatewayの「統合リクエスト」の「実行ロール」にセットすればOKです。

API Gatewayの統合リクエスト

ロールのポリシードキュメント

{  
    "Version": "2012-10-17",  
    "Statement": [  
        {  
            "Action": "lambda:InvokeFunction",  
            "Resource": "arn:aws:lambda:ap-northeast-1:AWSアカウントID:function:Lambda関数名",  
            "Effect": "Allow"  
        }  
    ]  
}  

アインデンティティベースのポリシーとリソースベースのポリシーの整理

API Gatewayの実行ロール=アインデンティティベースのポリシー 、Lambdaのリソースベースのポリシーです。

アインデンティティベースのポリシーとリソースベースのポリシーは、
一言で言うとDeny優先、AllowはOR条件です。

参考: docs.aws.amazon.com

API Gateway
実行ロール
Lambda
リソースベースのポリシーステートメント
結果
- lambda:InvokeFunction、Allow 実行可能
lambda:InvokeFunction、Allow - 実行可能
lambda:InvokeFunction、Deny lambda:InvokeFunction、Allow 実行不可

OR条件なのでAPI GatewayとLambdaならば、どちらかで実行権限を付与すればよいとなります。
なお、LambdaのリソースベースのポリシーステートメントにはDenyの設定は書けないようです。

アインデンティティベースのポリシーとリソースベースのポリシーの組み合わせの例

API GatewayとLambda以外の例を調べてみました。
リソースベースのポリシーがサービスごとに呼称が違いますが、同じ動きです。

LambdaからS3バケットへのファイルアップロード

Lambda
実行ロール
S3
バケットポリシー
結果
- s3:PutObject、Allow アップロード可能
s3:PutObject、Allow - アップロード可能
s3:PutObject、Deny s3:PutObject、Allow アップロード不可
s3:PutObject、Allow s3:PutObject、Deny アップロード不可

LambdaからSQSへのキュー発行

Lambda
実行ロール
SQS
アクセスポリシー
結果
- sqs:SendMessage、Allow 発行可能
sqs:SendMessage、Allow - 発行可能
sqs:SendMessage、Deny sqs:SendMessage、Allow 発行不可
sqs:SendMessage sqs:SendMessage、Deny 発行不可

LambdaからSNSトピックの発行

Lambda
実行ロール
SNS
アクセスポリシー
結果
- sns:Publish、Allow 発行可能
sns:Publish、Allow - 発行可能
sns:Publish、Deny sns:Publish、Allow 発行不可
sns:Publish、Allow sns:Publish、Deny 発行不可

最後に

冒頭の現象の解決に苦戦したのは、途中でアインデンティティベースのポリシーとリソースベースのポリシーを併用してしまい、
AND条件だったかOR条件だったかこんがらがってしまったからです。

アインデンティティベースのポリシーとリソースベースのポリシーは、どちらでもやりたいことが実現できるのが少々厄介ですね。
設定の統一感が失われるなど混乱を避けるため、整理してから作業に臨むことにします。

兼安 聡(執筆記事の一覧)

アプリケーションサービス部 DS1課所属
AWS12冠。
広島在住です。
最近認定スクラムマスターになりました。今日も明日も修行中です。