Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role associated with lamba doesn't have permission to SQS queue #20

Open
Voochichichi opened this issue Jan 18, 2017 · 6 comments
Open

Comments

@Voochichichi
Copy link

Using this plugin (Awesome, love it!) and I can't seem to get the role configuration to work properly.

So here's an extract from my serverless.yml

service: testProject

provider:
  name: aws
  runtime: dotnetcore1.0


plugins:
  - serverless-plugin-lambda-dead-letter

functions:
  Handler-TestHandler:
    handler: CsharpHandlers::Test.testProject.Handler::TestHandler
    deadLetter:
      targetArn:
        GetResourceArn: TestDlq
    events:
      - stream: arn:aws:kinesis:ap-southeast-2:*:stream/TestStream

resources:
  Resources:
    TestStream:
      Type: AWS::Kinesis::Stream
      Properties:
        Name: TestStream
        ShardCount: 1
    TestDlq:
        Type: AWS::SQS::Queue
        Properties:
          QueueName: TestDlq
    TestDlqPolicy:
        Type: AWS::SQS::QueuePolicy
        Properties:
          Queues:
            - Ref: TestDlq
          PolicyDocument: {
            "Version":"2012-10-17",
            "Statement":[
              {
                "Effect":"Allow",
 	              "Principal": "*",
                "Action":["SQS:*"],
                "Resource":"*"
              }
            ]}

The SQS is getting created with these permissions (I've really opened it up just to get it to work, then i'll scale it back correctly once i accomplish that)
image
(Im not even sure if I need to give the above policy document, I would have thought permission would come from the functions ROLE, much like how the Kinesis stream permissions work, through the role)

The SQS is being associated correctly to the lambda function:
image
However as you can see I have a warning that the Role does not have permissions to that SQS queue

I've got a role being created with the following inline policy which can correctly access the Kinesis stream I have asked it subscribe to, and to CloudWatch in general...

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream"
            ],
            "Resource": "arn:aws:logs:ap-southeast-2:*:*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-southeast-2:*:*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "kinesis:GetRecords",
                "kinesis:GetShardIterator",
                "kinesis:DescribeStream",
                "kinesis:ListStreams"
            ],
            "Resource": [
                "arn:aws:kinesis:ap-southeast-2:*:stream/TestStream",
            ],
            "Effect": "Allow"
        }
    ]
}

I would have assumed that the above general policy would also specific access to the SQS DLQ, but it does not?

@gmetzker
Copy link
Owner

gmetzker commented Jan 18, 2017

I had a few iterations trying to figure out the policy as well. With the proposal from #10 there might be a more simplified syntax that would compile the queue resource and policy document for you.

Until then here is the syntax I used in the custom resources...

I can't say which one of these is causing your issue but I noticed a few differences:

  • You seem to missing the ID in the policy document.
  • The Statement in the policy document might need an SID as well.
  • For Principal I used AWS: "*"
  • For Resource I directly referenced the queue.
  • I added a condition on the arn so the policy only applies when it matches the Lambda Function arn.
    • To reference the lambda functions in the Fn::GetAtt you have to infer what serverless is going to use as the Lambda logical id. In CF. In my case serverlessLambda ==> ServerlessLambdaLambaFunction

Let me know if this works for you.

functions:
  serverlessLambda:
    name: my-serverless-lambda
    description: Lambda to test the serverless utility
    
    deadLetter:

      # Use the ARN of a resource defined in the resources section.
      targetArn:
        GetResourceArn: ServerlessTplLambdaDlQueue


resources:
    Resources:
      ServerlessTplLambdaDlQueue:
        Type: AWS::SQS::Queue
        Properties:
          QueueName: my-serverless-lambda-retry-queue

      ServerlessTplLambdaDlQueuePolicy:
        Type: AWS::SQS::QueuePolicy
        Properties:
          Queues:
            - Ref: ServerlessTplLambdaDlQueue
          PolicyDocument:

            # This probably needs something more unique 
            # like 'Fn::GetAtt: [ServerlessTplLambdaDlQueue, Arn]'  + '/SQSPolicy'
            Id: ServerlessTplLambdaDlQueueId  

            Version: '2012-10-17' 
            Statement:
              - Sid: Allow-Lambda-SendMessage
                Effect: Allow
                Principal:
                   AWS: "*"
                Action:
                  - SQS:SendMessage
                Resource:
                  Ref: ServerlessTplLambdaDlQueue
                Condition:
                  ArnEquals:
                    aws:SourceArn:
                      Fn::GetAtt: [ServerlessLambdaLambdaFunction, Arn]

@Voochichichi
Copy link
Author

Thanks for your reply gmetzker, I've deployed again with

  • A (very similar) ID on the policy document
  • Adding the same SID to the statement as above
  • I've used the same Principal and Action as above
  • The resource for the policy is ok
  • I've also followed the pattern above for the ArnEquals, and I can see that has worked as in the SQS permissions, the correct arn is in place.
    image

However the ROLE policy attached to the lambda function is still exactly the same as i described above (I'm not sure if I'm meant to see any reflection of this in there). And i still see the same message under the functions SQS queue selector
image

I've been able to attach an AWS managed policy to the function's role manually as a work around. We can continue to utilise your extension with that in place, as re-deploying the function doesn't UNDO that policy which is nice. It would be nice however to have our serverless.yml be able to deploy all of our infrastructure correctly for this function without requiring any manual intervention/edits.

Let me know if there's any more information that would be useful to work out how we can accomplish this. Thanks for your quick response/help so far!

@gmetzker
Copy link
Owner

gmetzker commented Jan 18, 2017

Interesting. I was under the impression all that was needed was a QueuePolicy, but perhaps the lambda role needs general SQS permission.

In my I'm using an existing IAM role that probably has something like SQS:*
In my environment I typically don't have permissions to modify policies or create roles. I don't think the plugin should modify existing policies but perhaps it could could compile them in auto-magically if iamRoleStatements were being assigned.

Have you tried setting the iamRoleStatements described here? This might be the preferred method.

I need to research a little bit and see if there are analogous scenarios. Do you know if serverless adds SNS or S3 access to the iamRoleStatements if you specify an SNS or S3 event handler?

@gmetzker
Copy link
Owner

@AirEssY I've release version 1.2.0 the syntax should be simplified and it will eliminate the need to create the queue or policy in the Resources section.

Your Lambda will still need a role that has SQS permissions though.

@gmetzker
Copy link
Owner

gmetzker commented Feb 1, 2017

On second thought i need to do some more investigation on this. According to the docs serverless can create a default IAM role with rights to some resources.

In my environment I am required to use a predefined role. So I didn't see that serverless has the ability of creating a role for you.

@gmetzker gmetzker reopened this Feb 1, 2017
@occasl
Copy link

occasl commented Dec 15, 2017

IMHO, you like won't be creating roles in an enterprise environment. A devops will provide that to you, as in my case. The strange thing is that I had to put this permission on the role rather than the user that is running it. I suppose that is because the Lambda is what needs the SQS perms to publish to it out of EC2, so you need to add AmazonSQSFullAccess as well as AWSLambdaVPCAccessExecutionRole to the role you define your serverless.yml file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants