S3 イベント通知へ Lambda トリガーを設定するときに不明なエラー「Unable to validate the following destination configurations」とメッセージが出るときの対処方法

S3 イベント通知へ Lambda トリガーを設定するときに不明なエラー「Unable to validate the following destination configurations」とメッセージが出るときの対処方法

Clock Icon2021.01.21 05:20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

困っていた内容

S3 イベント通知へ Lambda 関数を追加すると以下のエラーが出ます。どうすれば S3 イベント通知へ Lambda 関数を追加できますか?

S3 コンソール

不明なエラー
予期しないエラーが発生しました。

API レスポンス
Unable to validate the following destination configurations

AWS CLI

$ aws s3api put-bucket-notification-configuration \
    --cli-input-json file://config.json
An error occurred (InvalidArgument) when calling the PutBucketNotificationConfiguration operation: Unable to validate the following destination configurations

どう対応すればいいの?

Lambda 関数に付与されたリソースベースのポリシーを確認してください。リソースベースのポリシーは Lambda コンソールや AWS CLI で確認できます。

Lambda コンソール

[関数] > [アクセス権限タブ] の順に遷移すると見れます。

AWS CLI

$ aws lambda get-policy \
    --function-name <対象の関数名> \
    | jq '.Policy | fromjson'
{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "123456789012_event_permissions_from_<バケット名>_for_<Lambda 関数名>",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:ap-northeast-1:<Lambda 関数がある AWS アカウント ID>:function:<対象の関数名>",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "<S3 バケットがある AWS アカウント ID>"
        },
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::<バケット名>"
        }
      }
    }
  ]
}

S3 イベントの対象となる Lambda 関数すべてに上記リソースベースのポリシーが存在しない場合は、以下どちらかの対応をしてください。

  • S3 コンソールの S3 イベント通知からリソースベースのポリシーが存在しない Lambda 関数を削除し、再度 Lambda 関数を登録する(対象が不明な場合はすべてのイベント通知を登録しなおす)
  • AWS CLI で下記コマンドを実行する
$ aws lambda add-permission \
    --function-name <関数名> \
    --principal s3.amazonaws.com \
    --statement-id <S3EventTrigger など任意のリソースベースのポリシーの識別子> \
    --action "lambda:InvokeFunction" \
    --source-arn arn:aws:s3:::<S3 バケット名> \
    --source-account <S3 バケットがある AWS アカウント ID>

S3 イベントに含まれるすべての Lambda 関数に適切なリソースベースのポリシーを付与した後、再度 S3 イベント通知へ Lambda 関数を追加するとエラーが解消されます。

リソースベースのポリシーの仕組み

Lambda には 2 つの権限設定があります。

  • IAM ロール: Lambda 関数から AWS サービスへアクセスするための権限
  • リソースベースのポリシー: AWS サービスから Lambda 関数へアクセスするための権限

Lambda はイベント駆動で呼び出されますので、どの呼び出し元(トリガー)を信頼するか、リソースベースのポリシーで個別に設定できます。

注意点として、AWS マネジメントコンソールからイベントの対象に Lambda 関数を追加すると、自動でリソースベースのポリシーが作成されます。すべての操作をマネジメントコンソールで行うと、この問題は発生しません。

CloudFormation を含む AWS API、AWS CLI や SDK で Lambda のトリガーイベントを追加するときは、事前にリソースベースのポリシーを追加する必要があります。CloudFormation でリソースベースのポリシーを修正したい場合は、文末の参考資料の AWS::Lambda::Permission ドキュメントを参考にしてください。

[おまけ] 再現手順

これまで説明した挙動をどうすれば再現できるか?(筆者のように事象を再現したい)と思われた方向けの Tips です。

AWS マネジメントコンソールは自動で良い感じにリソースベースのポリシーを追加してくれる親切設計なので、再現するには一工夫必要です。以下の手順通り実施すれば再現できます。

  1. 作成手段問わず Lambda 関数を 2 つ作成(A, B と呼ぶ)
  2. S3 コンソールのバケット詳細画面で [プロパティ] タブを開く
  3. [イベント通知を作成] ボタンをクリック
  4. [Lambda 関数] 欄にAを指定(その他は適当に入力)
  5. [変更の保存] ボタンをクリック
  6. 後述のコマンド例を実施
  7. 「2. 3.」を繰り返す
  8. [Lambda 関数] 欄にBを指定(その他は適当に入力)
  9. [変更の保存] ボタンをクリックで事象再現

コマンド例

$ FunctionName=<A の関数名>

$ Sid=$(aws lambda get-policy \
    --function-name $FunctionName \
    | jq '.Policy | fromjson' \
    | jq '.Statement[].Sid' \
    | sed 's/"//g')

$ aws lambda remove-permission \
    --function-name $FunctionName \
    --statement-id $Sid

参考資料

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.