Firehoseの変換LambdaがLambda.InvokeAccessDeniedになるのはARNの修飾子が足りないから

  • AWS
  • Firehose
  • Lambda
  • IAM

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

Kinesis Data Firehoseの変換Lambdaで、こういうエラーが出た。

{
"errorCode": "Lambda.InvokeAccessDenied",
"errorMessage": "Access was denied. Ensure that the access policy allows access to the Lambda function."
}

Lambdaの呼び出し自体を許可するIAMポリシーは用意してあった。

{
"Sid": "XXXXXXXXXXX",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:GetFunctionConfiguration"
],
"Resource": "arn:aws:lambda:ap-northeast-1:111111111111:function:transform-lambda"
}

アクションは合ってるし、関数ARNも合ってる。それでもAccessDenied。

直った修正

Resourceの末尾に :* を足したら通った。

"Resource": "arn:aws:lambda:ap-northeast-1:111111111111:function:transform-lambda:*"

なぜ足りなかったか

Lambdaは無修飾ARN(function:transform-lambda)と、バージョン/エイリアス付きの修飾ARN(function:transform-lambda:$LATEST や function:transform-lambda:1 など)を別物として扱う。IAMのResourceマッチングは基本的に完全一致なので、無修飾ARNだけを許可していても、修飾付きARNでの呼び出しには一致しない。

実際、AWSコンソールが変換Lambdaを設定したときに自動生成するIAMロールのポリシーを見ると、Resourceは最初から修飾子付きになっている。

{
"Sid": "lambdaProcessing",
"Effect": "Allow",
"Action": ["lambda:InvokeFunction", "lambda:GetFunctionConfiguration"],
"Resource": "arn:aws:lambda:us-east-1:XXXXXXXXXXXX:function:exampleLambdaFunction:$LATEST"
}

つまりFirehoseは変換Lambdaを呼ぶとき、内部的には修飾子付きのARN($LATEST相当)で呼んでいるらしい。手動でポリシーを書くときに無修飾ARNだけ許可してしまうと、このズレでAccessDeniedになる、という理解。

sequenceDiagram
    participant F as Firehose
    participant L as Lambda
    F->>L: Invoke(arn:...:function:transform-lambda:$LATEST)
    Note over F,L: Resourceが無修飾ARNだけだと不一致でAccessDenied

対応の選択肢

  • :* を付ける → 全バージョン・全エイリアスを許可
  • :$LATEST を明示的に付ける → 最新バージョンだけに絞れる

バージョン運用をしないなら:*で十分。エイリアス切り替えなどでバージョン管理をしているなら:$LATESTや具体的なエイリアス名にした方が事故が少なそう。

未確認

Firehoseが実際にどの修飾子で呼んでいるかはCloudTrailのイベント履歴で確認できるはずだが、そこまでは追ってない。上の「$LATEST相当で呼んでいる」というのはAWSコンソールの自動生成ポリシーからの推測で、実機での検証はしていない。