Unable to add trigger to AWS Lambda - amazon-web-services

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": "*"
}
]
}

Related

Attach IAM Policy to SNS Topic

I am trying deliver a message from an unencrypted SNS topic to an encrypted SQS queue following this guide. I was able to complete the "Configure KMS permissions for AWS services" step, but I am having trouble with the "Configure KMS permissions for producers
" step. I have created the IAM role, however attaching this role to my SNS topic is where I am specifically confused. Here are some questions I have which my own research was unable to answer:
Can an IAM role be attached to a specific item (SNS topic, SQS queue, etc...)? If not, what other way is there to grant permissions to a specific item?
When the instructions mention "producer", is this referring to the SNS topic or the AWS account which owns the SNS topic?
Any and all help is greatly appreciated.
Edit:
Here is my current AWS KMS key policy:
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Allow administration of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${aws_account_id}:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow SNS to use KMS",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
Whenever I add the following statements to my KMS key policy in the Statement list, I get the error "MalformedPolicyDocumentException - Policy contains a statement with no principal":
{
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "${kms_customer_managed_key_arn}"
},
{
"Effect": "Allow",
"Action": [
"sqs:SendMessage"
],
"Resource": "${sqs_queue_arn}"
}
If not, what other way is there to grant permissions to a specific item?
The permissons from the link are attached to your KMS CMK key policy.
When the instructions mention "producer", is this referring to the SNS topic or the AWS account which owns the SNS topic?
The producer is anyone or anything that sends messages. It can be a lambda function, an ec2 instance or IAM user/role. In that case you give the producer permissions to sendMessage and use the KMS key. For lambda it would be in lambda execution role, for instance it would be in an instance role.

AWS Sagemaker + AWS Lambda

I try to use AWS SageMaker following documentation. I successfully loaded data, trained and deployed the model.
deployed-model
My next step have to be using AWS Lambda, connect it to this SageMaker endpoint.
I saw, that I need to give Lambda IAM execution role permission to invoke a model endpoint.
I add some data to IAM policy JSON and now it has this view
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-east-1:<my-account>:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-east-1:<my-account>:log-group:/aws/lambda/test-sagemaker:*"
]
},
{
"Effect": "Allow",
"Action": "sagemaker:InvokeEndpoint",
"Resource": "*"
}
]
}
Problem that even with role that have permission for invoking SageMaker endpoint my Lambda function didn't see it
An error occurred (ValidationError) when calling the InvokeEndpoint operation: Endpoint xgboost-2020-10-02-12-15-36-097 of account <my-account> not found.: ValidationError
I found an error by myself. Problem was in different regions. For training and deploying model I used us-east-2 and for lambda I used us-east-1. Just creating all in same region fixed this issue!

Error while doing AWS Lambda Cross Account integration with AWS SNS

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.

Correct Kinesis stream principal

What principal should be used when specifying a Kinesis stream as a principal in AWS? Specifically I want to write an AWS::Lambda::Permission resource in CloudFormation: the lambda will be triggered by a Kinesis stream. Principal is required from the docs
None of these work for me:
kinesis.amazonaws.com
kinesisstream.amazonaws.com
kinesisstreams.amazonaws.com
kinesis-stream.amazonaws.com
I haven't found any documentation which gives a mapping of service to principal. I found this page, which shows the principal for Kinesis Analytics is kinesisanalytics.amazonaws.com.
I looked at the AWS service namespaces page, but it didn't have any information about principals. The namespace for streams appeared to just be kinesis, but that didn't work for me, as mentioned above.
The correct one is kinesisanalytics.amazonaws.com
Yet let me assume that you want to trigger lambda once a new record putted into kinesis, then all what you need is:
Create IAM Role with the following assume role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
]
}
Create an IAM Role Policy "to be attached to the Role created in step 1":
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:{aws_region}:{account_id}:*:*",
"Effect": "Allow"
},
{
"Effect": "Allow",
"Action": [
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:DescribeStream",
"kinesis:ListStreams"
],
"Resource": "arn:aws:kinesis:{aws_region}:{account_id}:stream/{kinesis_stream_name}"
}]
}
Attach IAM Role from step 1 to the lambda function
Do lambda event source mapping "Add Trigger" with the following attribute:
batch_size = 100
starting position = "LATEST"
Enabled = True

cognito fine grained access control and API gateway

In api gateway, I have the following resource ARN:
arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/*
which provides a link to get a list of members based on a class_id - /members/{id}
A user that is in a class can only see the list of members that belong into that class.
I have specified cognito user pool with the following IAM policy (assume that class1 is class_id)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"mobileanalytics:PutEvents",
"cognito-sync:*",
"lambda:*",
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1"
]
}
]
}
however, when used the link GET /members/class1, I get the following message:
Execution failed due to configuration error: API Gateway could not determine the callers credentials
I checked in cloudwatch, no log from lambda, therefore I think lambda was not executed.
I continued trying with class2. This time the following message was shown:
User:arn:aws:sts::XXXXXXXXXXXX:assumed-role/Cognito-sample_client1/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-2:********8469:syx381ecq9/sample/GET/inspectors/client2
I have checked in policy stimulate and everything worked fine with message Allowed
I have no idea why I could not call lambda? how can I fix this problem?
Thanks
OK, I found the answer. The above policy only allows calling lambda function for
arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1
therefore, when cognito credential has passed, api will try to call lambda but unfortunately, the policy restricts that. In order to get through it, we need to separate it into another statement like the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"mobileanalytics:PutEvents",
"cognito-sync:*",
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:*"
],
"Resource": [
"*"
]
}
]
}
we can customized specific lambda's arn if required