Error while doing AWS Lambda Cross Account integration with AWS SNS - amazon-web-services

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.

Related

AWS SQS permissions for AWS Lambda Cross Account

I'm using the AWS SQS service, and I'm having a hard time defining permissions on my SQS queue. In my setup I'm using the AWS Lambda service, which is triggered when an object is pushed onto an S3 bucket.
However to keep my question briefly, this is what I want to achieve:
Object is pushed to a S3 bucket,
S3 bucket triggers AWS Lambda,
Lambda does some calculations and pushes an event to my SQS queue (Permission needs to be defined)
Application reads from SQS
Lambda and SQS queue are in different AWS account-
Steps followed-
Added permission for access role assumed by lambda in SQS access policy-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::accountid:role/rolename",
]
},
"Action": "SQS:SendMessage",
"Resource": "https://sqs.us-east-1.amazonaws.com/accountid/qsqqueuename"
}
]
}
SQS queue has KMS key enabled so gave permission in kms access policy to the same role
The role assumed by lambda has following access-
{
"Action": [
"s3:PutObject",
"s3:GetObject",
"kms:Decrypt",
"kms:Encrypt",
"sqs:SendMessage",
"kms:DescribeKey",
"s3:ListBucket",
"ssm:GetParameter",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": [
"arn:aws:kms:us-east-1:accountid:key/kmskey5809e1338be5",
"arn:aws:sqs:us-east-1:accountid:sqaqueuename"
],
"Effect": "Allow",
"Sid": "mailboxaccess"
},
My lambda is giving the error-
An error occurred (AccessDenied) when calling the SendMessage operation: Access to the resource https://queue.amazonaws.com/ is denied.
Any suggestions?
The problem was the arn for sqs..I had provided an HTTP address for the queue whereas need to provide an arn.

AWS SQS access policy block default access to SQS

I have a SQS setup in AWS with an access policy which allows another account's SNS to push message,
and an instance with an IAM role allowing the instance to communicate with the queue.
I found that if I apply the access policy of SQS, the instance cannot access the SQS. Removing it, the instance can work with the queue.
Is there an explanation which can explan this?
Remove the access policy from the queue, works;
SQS Policy as following:
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "First",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "${module.elmo-s-rem-sqs-user-sync-service.primary_queue_arn}",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "${local.pivot_topic_arn}"
}
}
}
]
}
Have a tried by removing the Principal part, that could let the simulator pass. But the sns couldn't publish message any more.

AWS allow any user of a specific account to send messages to a queue

I am trying to configure the SQS policy for a queue to authorize all principles of an account to send messages to this queue, according to the documentation here:
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "Sqs policy1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789:root"
]
}
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:eu-west-1:123456789:my_queue"
}
]
}
Will this allow any principle of this account to send messages to my_queue or will it only allow the root user?
Or should I use the below policy with a condition instead?
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "Sqs policy1",
"Effect": "Allow",
"Principal": {
"AWS": "*"
}
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:eu-west-1:123456789:my_queue"
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "123456789"
}
}
}
]
}
TIA
The documentation says:
When you use an AWS account identifier as the principal in a policy, you delegate authority to the account. All identities inside the account can access the resource if they have the appropriate IAM permissions attached to explicitly allow access. This includes IAM users and roles in that account.
According to this, your first approach will allow all of your users to send messages.
Only first policy is valid. The second policy will not work, the way you may think. The reason is that aws:SourceAccount is only used for service-to-service requests, not IAM users or roles. The most common example of when aws:SourceAccount is used is for S3:
For example, when an Amazon S3 bucket update triggers an Amazon SNS topic post, the Amazon S3 service invokes the sns:Publish API operation. The bucket is considered the source of the SNS request and the value of the key is the account ID associated with the bucket.
Send-messages requests made by IAM users/roles in the second account will be denied because for these entities there is no aws:SourceAccount.

Secrets Manager - rotate secret with lambda in another account

In a project I'm working on, the secrets are stored in a centralized company Secrets Manager, in a specific AWS account (SECRETS_ACCOUNT).
Project resources (including lambda functions) are in a project specific account (PROJECT_ACCOUNT).
I'm trying to set up secrets rotation, but I get stuck on this error message:
AccessDeniedException: Secrets Manager cannot invoke the specified Lambda function. Ensure that the function policy grants access to the principal secretsmanager.amazonaws.com.
The lambda resource-based policy:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "SecretsManager",
"Effect": "Allow",
"Principal": {
"Service": "secretsmanager.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-1:PROJECT_ACCOUNT:function:secret-rotation"
}
]
}
The lambda role trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I don't know if it matters, both accounts are in the same region.
Did I miss something? Do I need to add additional permissions to allow a Secrets Manager from another account to invoke the lambda? Do the lambda and the secret have to be in the same account?
Thanks in advance,
Please run the below command to resolve the error "AccessDeniedException: Secrets Manager cannot invoke the specified Lambda function. Ensure that the function policy grants access to the principal secretsmanager.amazonaws.com."
in AWS Cli
aws lambda add-permission --function-name arn:aws:lambda:us-east-1:757147756798:function:"secret name here without quotes" --principal secretsmanager.amazonaws.com --action lambda:InvokeFunction --statement-id SecretsManagerAccess

Unable to add trigger to AWS Lambda

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