I have been trying to set up a Lambda function, using the CDK; that uses a docker image, from a different account (because reasons). It felt like I was stuck in a chicken & egg situation, where the IAM role to be used was created by the stack, which then failed (because it couldn’t pull the image) and rolled back; deleting the role.
I tried using a wildcard, for the principal:
Statement:
-
Sid: AllowCrossAccountPull
Effect: Allow
Principal:
AWS: "arn:aws:iam::$ACCOUNT_ID:role/$STACK-LambdaServiceRole*"
but that was rejected:
Resource handler returned message: "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Principal not found'
After some digging around in the CDK source code, I was able to create the role first; and set up the cross account permissions before creating the lambda. But I was still getting the same error:
Resource handler returned message: "Lambda does not have permission to access the ECR image. Check the ECR permissions. (Service: Lambda, Status Code: 403, ...
At this point, I did what I should have done originally, and actually read the docs. It turns out that like Fargate tasks use a separate role to start the task, and execute it, so does Lambda. But in this case, one role is played by the service itself.
After a bit more flopping around, I finally had something that worked 🥳
Statement:
-
Sid: CrossAccountPermission
Effect: Allow
Principal:
AWS: "arn:aws:iam::$ACCOUNT_ID:root"
Action:
- "ecr:BatchGetImage"
- "ecr:GetDownloadUrlForLayer"
-
Sid: LambdaECRImageCrossAccountRetrievalPolicy
Effect: Allow
Principal:
Service: "lambda.amazonaws.com"
Action:
- "ecr:BatchGetImage"
- "ecr:GetDownloadUrlForLayer"