AccessDenied when calling the ListQueues operation - amazon-web-services

This is quite strange when call list queues command using AWS-CLI with the attached policy not working unless I set value for Resource to arn:aws:sqs:*:*:*.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sqs:*",
"Resource": "arn:aws:sqs:*:45*****65:local-*"
}
]
}
I expect the below command should return all the Queues that start with local-* but I got AccessDenied.
aws sqs list-queues --queue-name-prefix local-*
But for the same Queue, I am able to get its attributes.
aws sqs get-queue-attributes --queue-url https://us-west-2.queue.amazonaws.com/0****5/local-myqueue --attribute-names All
Do I need to changes something in policy or is the behavior of list queue is different?
Thanks in Advance.

According to Actions, Resources, and Condition Keys for Amazon SQS - AWS Identity and Access Management, the SQS commands do not accept conditions. Therefore, the ListQueues() command either works completely (showing all matching queues) or does not return anything (due to Access Denied). The only way to limit which queues are returned is to use the queue-name-prefix.
The Resource attribute in the policy will determine upon which queue various commands can run, which is why you are able to get attributes for a queue matching local-*. If you tried to get the details of a queue named public-xxx, it would be denied. (But ListQueues operates on the service, not a particular queue.)

Related

Lambda trigger doesn't replicate to SQS source across accounts

I'm trying to add an SQS as a source/trigger to a lambda. I can do this just fine if both components reside within the same account. When I add the trigger to the lambda, the lambda trigger configuration replicates over to the SQS queue to pair the two.
When I try this same thing on my lambda when the SQS is remote in a different account the Lambda trigger is established, but when viewing the remote SQS it doesn't show a trigger configured. This seems to result in the trigger not working on the lambda when a message is added to the queue. The SQS policy on the remote queue is also giving permissions explicitly to the other account as well.
Any thoughts?
Scenario:
Amazon SQS queue in Account-A
AWS Lambda function in Account-B
Goal: SQS triggers Lambda function
Since this involves cross-account access, you will need to grant permissions for the IAM Role used by the Lambda function to access the SQS queue. (Lambda pulls from the queue, rather than SQS pushing to Lambda.)
The steps are:
In the SQS queue, edit the Access Policy to include permission for the IAM Role used by the Lambda function:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-1:root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:ap-southeast-2:ACCOUNT-1:queue-name"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-2:role/lambda-role-name"
},
"Action": [
"SQS:ChangeMessageVisibility",
"SQS:DeleteMessage",
"SQS:ReceiveMessage",
"SQS:GetQueueAttributes"
],
"Resource": "arn:aws:sqs:ap-southeast-2:ACCOUNT-1:queue-name"
}
]
}
The first part of this policy is automatically created by SQS and allows the owning account to use the queue. The second part allows the IAM Role from Account-2 to access the queue in Account-1. The policy was created automatically by SQS when I created the queue and provided the ARN of the IAM Role. However, I had to add SQS:GetQueueAttributes because the Lambda function calls it too.
In the AWS Lambda function in Account-B, click + Trigger, select SQS and enter the ARN of the SQS queue from Account-A
I tried all this and was successfully able to put a message in SQS in Account-B, and then saw Lambda process it in Account-B.

How to create an IAM Policy for SQS queues for a specific Cognito Identity

I am trying to create a IAM policy to be applied to a SQS queue. The policy should restrict access to the queue to a single Cognito federated identity.
I found this reference from amazon on how to achieve this but am having trouble applying the policy to the SQS queue.
Here is the policy I am trying to apply.
{
"Version": "2012-10-17",
"Id": "arn:aws:sqs:us-west-2:604080725100:Test2.fifo/SQSDefaultPolicy",
"Statement": [
{
"Sid": "Sid1528133390193",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "SQS:*",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:ff1b33f4-7f66-47a5-b7ff-9696b0e1fb52",
"cognito-identity.amazonaws.com:sub": ["us-east-1:4a6d7e43-4522-41fb-9248-b5b79933b8e9"]
}
}
}
]
}
The online UI for editing the policy shows in the review screen:
Allow None
All SQS Actions (SQS:*)
StringEquals
cognito-identity.amazonaws.com:aud: "us-east-1:ff1b33f4-7f66-47a5-b7ff-9696b0e1fb52"
cognito-identity.amazonaws.com:sub: "us-east-1:4a6d7e43-4522-41fb-9248-b5b79933b8e9"
Once I press apply the following error is given:
Failed to save changes to the policy document. Reason: com.amazonaws.services.sqs.model.AmazonSQSException: We encountered an internal error. Please try again.
I am not sure what is wrong with the policy. I am looking for any help fixing the policy or a different policy that achieve limiting the SQS queue to a single Cognito identity.
Unfortunately SQS only supports a subset of the condition keys and the cognito user id is not one of them. I have read an article which solved this problem by creating random queue names which are readable by all users, but practically unguessable.

AWS Lambda#Edge debugging

I'm currently working on a lambda#edge function.
I cannot find any logs on CloudWatch or other debugging options.
When running the lambda using the "Test" button, the logs are written to CloudWatch.
When the lambda function is triggered by a CloudFront event the logs are not written.
I'm 100% positive that the event trigger works, as I can see its result.
Any idea how to proceed?
Thanks ahead,
Yossi
1) Ensure you have provided permission for lambda to send logs to cloudwatch. Below is the AWSLambdaBasicExecutionRole policy which you need to attach to the exection role which you are using for your lambda function.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
2) Lambda creates CloudWatch Logs log streams in the CloudWatch Logs regions closest to the locations where the function is executed. The format of the name for each log stream is /aws/lambda/us-east-1.function-name where function-name is the name that you gave to the function when you created it. So ensure you are checking the cloudwatch logs in the correct REGION.
In case anyone finds it useful.
The fact that AWS prefixes your function name, which breaks the built-in "CloudWatch at a glance" Dashboard, and that Lambda#Edge runs across multiple regions inspired me to create this CloudWatch Dashboard template that gives you similar standard monitoring for all regions in one dashboard.

IAM Policy using Condition ec2:ResourceTag not working

I have n x EC2 instances that I wish to limit ec2 actions to instances with the same key/value tag (I.E. platform=dev).
I'm looking at doing this using an IAM Policy attached to the group their default IAM user is in.
Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/tag:platform": "dev"
}
}
}
]}
I set this up as per the online AWS docs: Example Policies for Working With the AWS CLI or an AWS SDK
I check it in the Policy Simulator and it works as expected (pass in a dev and it's allowed, otherwise denied).
Then on one of the servers with the tag key/pair of platform=dev, I run aws ec2 describe-instances I get the response:
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
but if I remove the Condition it works. I don't understand what I'm doing wrong. Any help would be gratefully received!
The problem is that not every API Action & Resource will accept the ec2:ResourceTag/tag in the condition.
I think you're probably granting overly-broad permissions (Action: ec2:*), so figure out what actions your instances will need do, and then decide how to restrict them.
The list of actions, resources and conditions keys can be found at Supported Resource-Level Permissions for Amazon EC2 API Actions.
I have ran into this issue before, it had something to do with combining wildcards and conditions. What solved it for us was being more explicit on the action (e.g ["ec2:DescribeInstances"]), and on the resource as well (arn:aws:ec2:region:accountid:instance/*).

AWS security group rules deployment (lambda->SQS)

On AWS we've implemented functionality that AWS lambda pushes message to AWS queue;
However during this implementation I had to manuall grant permissions to AWS lambda to add message to particular queue. And this apporach with manual clicks not so good for prod deployment.
Any suggestions how to automate process of adding permissions between AWS services (mainly lambda and SQS) and cretate "good" deployment package for prod env ?
Each Lambda function has an attached role, which you can specify permissions for in the IAM dashboard. If you give the Lambda functions' role the permission to push to an SQS queue, you're good to go. For example, attach this JSON as a custom role (see http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSExamples.html):
{
"Version": "2012-10-17",
"Id": "Queue1_Policy_UUID",
"Statement":
{
"Sid":"Queue1_SendMessage",
"Effect": "Allow",
"Principal": {
"AWS": "111122223333"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:444455556666:queue1"
}
}
You can use asterisks to give permission to multiple queues, like:
"Resource": "arn:aws:sqs:us-east-1:444455556666:production-*"
To give sendMessage permission to all queues that start with production-.