The function's role, assumable only by Lambda 24 , grants exactly what the handler does: two reads on one table, writes to its log group (declared above it, 14 days' retention) and the calls that attach it to the VPC:
ApiRole:
Type: AWS::IAM::Role
Properties:
RoleName: booknest-api
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal: {Service: lambda.amazonaws.com}
Action: sts:AssumeRole
Policies:
- PolicyName: read-catalog-and-log
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: [dynamodb:GetItem, dynamodb:Scan]
Resource: !GetAtt BooksTable.Arn
- Effect: Allow
Action: [logs:CreateLogStream, logs:PutLogEvents]
Resource: !GetAtt ApiLogGroup.Arn
- Effect: Allow
Action: [ec2:CreateNetworkInterface, ec2:DescribeNetworkInterfaces,
ec2:DescribeSubnets, ec2:DeleteNetworkInterface,
ec2:AssignPrivateIpAddresses, ec2:UnassignPrivateIpAddresses]
Resource: "*"Shortcuts such as AmazonDynamoDBReadOnlyAccess read every table in the account; this role has no write, no other table and no logs:CreateLogGroup. AWS 24 documents the EC2 24 list for VPC-attached functions and requires it on "*"; a deny keyed on lambda:SourceFunctionArn stops the function's own code from using it. The named role needs CAPABILITY_NAMED_IAM (IAM for CloudFormation).