I have been encountering a hard limit on lambda function policy when trying to provision access for a cloudwatch event rule to trigger the lambda function on a scheduled basis.
An error occurred (PolicyLengthExceededException) when calling the AddPermission operation: The final policy size (20670) is bigger than the limit (20480).
It works for a new lambda function, but eventually its policy will bloat and will hit a hard limit on the number on cloudwatch event rule that can access it.
Some said to re-create the function (delete/create), but this won't be an option in a production environment where cloudwatch events are already configured in it, resulting to the existing ones to lose access to the lambda function.
Using the aws cli, i was able to extract the policy of my lambda function, it loooks like this:
"Statement": [{
"Sid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:*",
"Resource": "arn:aws:lambda:xxxxx:xxxxxxxxxxx:function:xxxxxxxxxxxxx",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:xxxxxxx:xxxxxx:rule/xxxxxxxxx"
}
}
}]
So i was looking onto something like for the AWS:SourceArn
arn:aws:events:xxxxxxx:xxxxxx:rule/*
To avoid hitting a hard limit, but i cannot seem to do it. Even in the lambda function itself on the console, you won't be able to create such a rule that will allow all cloudwatch event of a specified account to have access to the lambda function using a wildcard '*'.
Suggestions are much welcome. Thank you guys
This was accepted without an error:
$ aws lambda add-permission --function-name function_name\
--action 'lambda:InvokeFunction' --principal events.amazonaws.com \
--statement-id '1' \
--source-arn arn:aws:events:ap-southeast-2:123456789012:rule/*
This will accept all CloudWatch Events rules.
You could instead name your rules such that the ones you want to allow can all have the same prefix in their name, eg:
--source-arn arn:aws:events:ap-southeast-2:123456789012:rule/Event-*
I used the above CLI command but got an error in the console, please find the attached screenshot of the errorenter image description here. Please find below function policy of lambda:
{ "Version": "2012-10-17", "Id": "default", "Statement": [
{
"Sid": "events-access",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:096280016729:function:leto_debug_log",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:us-east-1:096280016729:rule/*"
}
}
}
] }
Related
I am trying to connect an API Gateway build to my lambda which has versioned aliases.
This is the setup:
AWS Lambda
Lambda functionName Has two aliases, staging and production. Staging is pointing to $LATEST and production is pointing to the last stable version (let's say version 1).
API Gateway
The API has two stages, staging and production. Each stage is to be associated with a specific lambda alias. funcName is a stage variable added to each stage as either staging or production. The resources are setup as follows:
Resources:
/route1
ANY METHOD -> lambda function -> functionName:${stageVariables.funcName}
/route2/{proxy+}
ANY METHOD -> lambda function -> functionName:${stageVariables.funcName}
When I add these resources and methods AWS let's me know to manually update the lambda function's policies to allow the API to call them using the following script:
For route1:
aws lambda add-permission
--function-name "arn:aws:lambda:us-west-2:account-id:function:functionName:staging"
--source-arn "arn:aws:execute-api:us-west-2:account-id:7aupeov6ak/*/*/route1"
--principal apigateway.amazonaws.com
--statement-id 30bdb347-9b5b-4eed-9221-d3d8de3e6def
--action lambda:InvokeFunction
For route2
aws lambda add-permission
--function-name "arn:aws:lambda:us-west-2:account-id:function:functionName:staging"
--source-arn "arn:aws:execute-api:us-west-2:account-id:7aupeov6ak/*/*/route2/*"
--principal apigateway.amazonaws.com
--statement-id 30bdb347-9b5b-4eed-9221-d3d8de3e6def
--action lambda:InvokeFunction
Policy after CLI commands:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "30bdb347-9b5b-4eed-9221-d3d8de3e6def",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-west-2:account-id:function:functionName:staging",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-west-2:account-id:7aupeov6ak/*/*/route2/*"
}
}
},
{
"Sid": "30bdb347-9b5b-4eed-9221-d3d8de3e6def",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-west-2:account-id:function:functionName:staging",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-west-2:account-id:7aupeov6ak/*/*/route2/*"
}
}
}
]
}
The commands go through successfully, and the policies are added to the lambda alias, however, when I check triggers both are throwing the following error:
"The API with ID 7aupeov6ak doesn’t include a resource with path /route1 having an integration arn:aws:lambda:us-west-2:account-id:function:functionName:staging on the ANY method."
I read both of these tutorials and it appears I've done everything correctly.
https://www.contentstack.com/blog/tech-talk/deploying-aws-lambda-in-different-environments/
https://aws.amazon.com/blogs/compute/using-api-gateway-stage-variables-to-manage-lambda-functions/
I am trying to add SQS as a trigger to my Lambda function running in AWS-VPC but it throws error as :
An error occurred when creating the trigger: The provided execution role does not have permissions to call ReceiveMessage on SQS (Service: AWSLambda; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: d34b7525-5c69-4434-a015-112e8e74f447; Proxy: null)
Tried via adding AWSLambdaVPCAccessExecutionRole to the policy for
the role as well via IAM. But no luck!
I am unable to figure where I am making a mistake? Please help me out, if anyone had similar experience in past or knows how to resolve it. Thanks you in advance!
Please attach managed policy AWSLambdaSQSQueueExecutionRole in your lambda execution role.
If your lambda function is working with any other aws services, you can try creating custom role and add specific permissions.
In aws if any service want to access any another service you need those specific permission in role.
for more information on lambda permission please check Managed lambda permissions
You need to add the following actions to the IAM Role attached to your lambda:
sqs:ReceiveMessage
sqs:DeleteMessage
sqs:GetQueueAttributes
Otherwise your lambda will not be able to receive any message from the queue. DeleteMessage action allows to remove a message from queue once its successfully processed. As a resource set the ARN of your SQS queue. Policy should look like this:
{
"Action": [
"sqs:DeleteMessage",
"sqs:ReceiveMessage",
"sqs:GetQueueAttributes"
],
"Resource": "arn:aws:sqs:region:accountid:queuename",
"Effect": "Allow"
}
If you're looking for a managed policy, have a look at AWSLambdaSQSQueueExecutionRole.
Attach a policy for a lambda role you might have to change account_number to your account no if you need to invoke another lambda form this lambda
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:**eu-west-1**:**account_number:function**:*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream",
"logs:CreateLogGroup"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"sqs:*"
],
"Resource": "*"
}
]
}
I want to send notification from SNS (Account A) to Lambda (Account B). Followed this tutorial but still getting below error:
https://docs.aws.amazon.com/lambda/latest/dg/with-sns-example.html
Error code: AccessDeniedException - Error message: User: arn:aws:sts::AccountA:assumed-role/AdministratorAccessRole/A12345 is not authorized to perform: lambda:AddPermission on resource: arn:aws:lambda:us-east-1:AccountB:function:TestLambda
Below what I did:
1. In Account A, added below policy in Access Policy of SNS:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "_abc_",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB:root"
},
"Action": [
"SNS:Subscribe",
"SNS:Receive"
],
"Resource": "arn:aws:sns:us-east-1:AccountA:TriggerLambdaB-SNS"
}
]
}
2. In Account B, added below policy in Resource-Based Policy of Lambda:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "_abc_",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:AccountB:function:TestLambda",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:sns:us-east-1:AccountA:TriggerLambdaB-SNS"
}
}
}
]
}
I am able to see the SNS Name under Trigger Lambda section of my Lambda in Account B. But when I am trying to Subscribe the Lambda under SNS, then getting this error. Please guide what am I missing here.
Is it because I am having different types of Role in these accounts like AdminAccessRole in Account A and FederatedRoleAccess in Account B?
You need to run the aws sns subscribe in Account-B (with the Lambda function), not Account-A (with the SNS function).
Otherwise, your setup seems correct.
When I tried running the subscribe command from Account-A, it said:
An error occurred (AuthorizationError) when calling the Subscribe operation: The account ACCOUNT-A is not the owner of the lambda function arn:aws:lambda:ap-southeast-2:ACCOUNT-B:function:foo
While this error is different to yours, your command appears to have been run from Account-A (with SNS) rather than Account-B (with Lambda).
Side-note: There appears to be a small error in the Tutorial: Using AWS Lambda with Amazon Simple Notification Service documentation, where the Resource-Based policy for Lambda (the second one in your Question) is showing a SourceArn that refers to Account-B-Lambda, whereas it should be Account-A-SNS. However, you appear to have gotten this correct in your policy above.
In AWS's Config, I set a rule called: "lambda-function-public-access-prohibited". This says it runs its own lambda to "check", but I can't seem to find much else on what it's doing or how it determines that it's publicly accessible.
Can anyone point me to documentation on this or know what it's doing exactly?
Thank you!
This is the AWS Reference
Under Function policy, if the policy allows actions for the principal element “” or {“AWS”: “”}, it is publicly accessible.
Consider adding the following IAM condition to scope access to your account only.
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "<account_id>"
}
}
}
source: https://hub.steampipe.io/mods/turbot/aws_compliance/controls/control.pci_v321_lambda_1?context=benchmark.pci_v321/benchmark.pci_v321_lambda
EDIT: This config rule was triggered by an S3 bucket resource attached to the lambda. In the console's resource-based policy form, you can specify an AWS account number. Once specified this will automatically create the above policy. After rescanning your config rules should appear as resolved.
Make sure you don't give * in resource or actions, so as to get all resources who have AWS account can access your lambda.
{
"Sid": "lambdaAccess",
"Effect": "Allow",
"Action": [
"lambda:*"
],
"Resource": "*"
},
Instead you can give ARN in resources and specific action like read, write, get access in action item.
Recommended :
{
"Sid": "lambdaAccess",
"Effect": "Allow",
"Action": [
"lambda:GetFunction"
],
"Resource": "arn:aws-us:lambda:us-west-1:123456789:function:lambda1234"
},
I am trying to build a Kibana dashboard fed with twitter data collected via AWS Kinesis firehose where data passes into an S3 bucket which triggers a Lambda function which passes the data to AWS Elastic Search and then to Kibana. I am following this blog https://aws.amazon.com/blogs/big-data/building-a-near-real-time-discovery-platform-with-aws/
The data is loading into the S3 bucket correctly but it never arrives in Kibana, I believe this is because the Lambda function is not being triggered by events in S3 as I would have hoped (there are no invocations or logs). I think this is because I have not set permissions properly. The Lambda function can be invoked manually by the test event.
On the Lambda function page I chose an existing role which I called lambda_s3_exec_role which has the AWSLambdaExecute policy attached to it but I feel I'm missing something else more specific to S3. I have been unable to follow this line in the blog in the create lambda function section because I do not recognise those options:
"10. Choose lambda_s3_exec_role (if this value does not exist, choose Create new role S3 execution role)."
Can anyone help me create the appropriate role/policy for the Lambda function, or spot what the problem may be?
From view permissions on the Lambda function I currently have:
FUNCTION POLICY
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "****",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "****",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:s3:::****"
}
}
}
]
}
EXECUTION ROLE
{
"roleName": "lambda_s3_exec_role",
"policies": [
{
"document": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::*"
}
]
},
"name": "AWSLambdaExecute",
"id": "****",
"type": "managed",
"arn": "arn:aws:iam::aws:policy/AWSLambdaExecute"
}
]
}
The permissions you have listed look OK so I am going to try provide some steps that might help find the issue as it is difficult to understand specifically where your issue might be.
Does the execution role have the trust relationship with a trusted entity of lambda.amazonaws.com
Does your event prefix match the prefix in firehose. In the tutorial they are both twitter/raw-data/. If firehose is writing to a path that isn't the event prefix then the event won't be invoked.
Does the lambda trigger any errors when you manually invoke it
Does the lambda write to the logs when you manually invoke it
Test the lambda using dummy data (example data below)
CLI
aws lambda invoke \
--invocation-type RequestResponse \
--function-name helloworld \
--region region \
--log-type Tail \
--payload file://dummy_event.json \
--profile adminuser \
outputfile.txt
Example data
source
dummy_event.json
{
"Records":[
{
"eventVersion":"2.0",
"eventSource":"aws:s3",
"awsRegion":"us-west-2",
"eventTime":"1970-01-01T00:00:00.000Z",
"eventName":"ObjectCreated:Put",
"userIdentity":{
"principalId":"AIDAJDPLRKLG7UEXAMPLE"
},
"requestParameters":{
"sourceIPAddress":"127.0.0.1"
},
"responseElements":{
"x-amz-request-id":"C3D13FE58DE4C810",
"x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
},
"s3":{
"s3SchemaVersion":"1.0",
"configurationId":"testConfigRule",
"bucket":{
"name":"sourcebucket",
"ownerIdentity":{
"principalId":"A3NL1KOZZKExample"
},
"arn":"arn:aws:s3:::sourcebucket"
},
"object":{
"key":"HappyFace.jpg",
"size":1024,
"eTag":"d41d8cd98f00b204e9800998ecf8427e",
"versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko"
}
}
}
]
}
Struggled with this for a long time and eventually realized that your rule that triggers the lambda cannot have exactly the same name as the lambda itself or it won't work.