If you find yourself with an issue that the API Gateway cannot invoke your lambda due to an access denied issue:
AccessDeniedException: User: arn:aws:sts::ACCOUNT_ID:assumed-role/xxxxxx-EDS-API-Gateway-TaskDef-use1-PreProduction/b8884262-4cdd-4ee1-84a7-7676d1d5b914 is not authorized to perform: lambda:InvokeFunction on resource: YOUR_LAMBDA_ARN status code: 403, request id: 3e61d932-968e-4d15-b84e-b3eb61f0a30b
You can add a permission to your Lambda that will allow cross acount access:
LambdaInvokePermissionPreProd:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: YOUR_LAMBDA_ARN HERE
Principal: AN_ACCOUNT_ID_HERE
LambdaInvokePermissionProd:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: YOUR_LAMBDA_ARN HERE
Principal: ANOTHER_ACCOUNT_ID_HERE
This is actually adds a function policy to your lambda which controls who can access your lambda. This is not to be confused with the Lambda role in which the lambda executes, ie the execution policy which only controls what the lambda itself can or can not access.
Actually it might be easier to see the whole file, right?
# Welcome to Serverless!
#
# This file is the main config file for your service.
# It's very minimal at this point and uses default values.
# You can always add more config options for more control.
# We've included some commented out config examples here.
# Just uncomment any of them to get that config option.
#
# For full config options, check the docs:
# docs.serverless.com
#
# Happy Coding!
# Trigger
service: MyService
package:
individually: true
provider:
name: aws
region: \({file(config/config.yml):region}
role: LambdaRole
vpc:
securityGroupIds:
- Ref: LambdaSecurityGroup
subnetIds: \){file(config/config.yml):subnetIds}
functions:
NotifyPW:
handler: Lambda::MyService.Functions::Get
runtime: dotnetcore2.0
package:
artifact: 'artifact-Deploy.zip'
events:
- http:
path: get
method: get
environment:
ENVIRONMENT: '\({file(config/config.yml):shortenvironment}'
resources:
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: 204992-MyService-\){file(config/config.yml):shortenvironment}
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: 204992-MyService-\({file(config/config.yml):shortenvironment}-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- "sqs:*Queue*"
- "sqs:*Message*"
Resource:
- "arn:aws:sqs:us-east-1:*"
Effect: Allow
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- logs:DescribeLogStreams
Resource:
- arn:aws:logs:*:*:*
Effect: Allow
- Action:
- "sqs:SendMessage"
- "sqs:ReceiveMessage"
Resource:
- "arn:aws:sqs:us-east-1:*:*"
Effect: Allow
- Action:
- 'ec2:CreateNetworkInterface'
- 'ec2:DescribeNetworkInterfaces'
- 'ec2:DeleteNetworkInterface'
Resource: '*'
Effect: Allow
- Action:
- 'events:*Rule*'
Resource: '*'
Effect: Allow
- Action:
- 'lambda:InvokeFunction'
Resource: '*'
Effect: Allow
LambdaSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: '204992 MyService Security Group'
VpcId: \){file(config/config.yml):vpcId}
LambdaInvokePermissionEdpPreProd:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: YOUR_LAMBDA_ARN
Principal: AN_ACCOUNT_ID_HERE
LambdaInvokePermissionEdpProd:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: YOUR_LAMBDA_ARN
Principal: ANOTHER_ACCOUNT_ID_HERE