aws/chalice

An error occurred (PolicyLengthExceededException) when calling the AddPermission operation

Closed this issue ยท 11 comments

The Policy was not being correctly autogenerated as it did not include DynamoDB permissions, so I added lines manually to .chalice/policy.json, and build using "chalice deploy --no-autogen-policy".

This has been working just fine for the last day, however when deploying now, I'm getting the following error:

botocore.exceptions.ClientError: An error occurred (PolicyLengthExceededException) when calling the AddPermission operation: The final policy size (20789) is bigger than the limit (20480).

Nothing has changed in policy.json, and the deploy command was correctly working an hour ago.

I've tried slimming down .chalice/policy.json, but still getting the same error and the same size report (20789).

I've tried deleting the Role from AWS and redeploying. I then get my .chalice/policy.json shown to me and asked if I want to use it, and I select "y". The same error is presented.

I have the same issue, did some research it's the issue on lambda,
i tried the following (which just reset everything)

aws lambda list-functions --> functionname
aws lambda delete-function --function-name functionname

and then just deploy again, it should work (work on mine)

Thanks Jason. I ended up killing the EC2 instance I was using for development and spun up another, copying the app.py and policy.json back into it, and it published correctly. Your solution would have been much cleaner!

No problem KarlXerri

I ran into this too. This is not the IAM policy for the function that is too long, but the resource policy that allows API Gateway to invoke the Lambda function. What is happening is that Chalice is generating a policy statement for every deploy and appending it to the policy. This makes the policy too big after many deploys. When you deleted the function, this is clearing that policy, but this will happen to you again if you deploy a lot.

The part of the code that is causing this problem is here. Every deploy will just append a new statement here until the policy is too big and you get this error.

It seems like this policy never changes, so a fix could be to have Chalice only add the policy when the function is first created. Thoughts?

Any luck figuring out why this happens ? I just ran into this , but oddly I was able to deploy twice before the error occurred.

Below is the error I see :

Error: Error when deploying: An error occurred (PolicyLengthExceededException) when calling the AddPermission operation: The final policy size (20732) is bigger than the limit (20480).

I am on OSX and python 2.7.11

Sounds like a bug, taking a look...

An update, the code that causes this is here:

https://github.com/awslabs/chalice/blob/master/chalice/deployer.py#L306-L317

I suggest that the code look to see if the policy exists first with something like:

policy = self.lambda_client.get_policy(FunctionName=fn_name)['Policy']
policy = json.loads(policy)
policy_exists = False
for stmt in policy['Statement']:
    if stmt['Action'] = 'lambda:InvokeFunction'
        policy_exists = True
if not policy_exists:
    self.lambda_client.add_permission(...)

That would be much more ideal than having a huge policy.

For those of you looking for a quick solution:

def clean_policy(fn_name):
    client = boto3.client('lambda') 
    policy = client.get_policy(FunctionName=fn_name)['Policy']
    statements = json.loads(policy)['Statement'] 
    sid_list = [item['Sid'] for item in statements][:-1]
    for sid in sid_list:       
        print("Removing policy SID {}".format(sid))
        client.remove_permission(FunctionName=fn_name, StatementId=sid)
    print(client.get_policy(FunctionName=fn_name))

I posted solution elsewhere, copy-pasting here:

I am using gulp-awslambda instead.
The error looks to be of AWS lambda instead.

ISSUE:
Re-deploying an existing lambda is failing

SOLUTION:

  1. delete lambda function
  2. re-create it

Sorry @manoharreddyporeddy but it really sounds like a very bad solution, unless you are only creating and deploying your API from the AWS console without using any CI/CD.

Let's say your lambda function (or API Gateway for that matter) is created from a stack (cloudformation or SAM), you are deleting an object from a stack which will lose its unique id and your whole stack will be crashed and you don't have any control to recreate a lambda function with the true unique id (I am not speaking of the name here, but of the ARN).

From what I have seen, there was two problems:

  1. indeed doing multiple deployments of the same APIs was duplicating the policy. It was fixed (sorry don't have time to find the ticket)
  2. this hard limit of 20kb per policy, which will not change and depends of the number and size of your routes (hence path parameters). Passing path parameters as query string parameters is a solution, but you should not have to change your API design due to this problem.

Now, instead of adding policies for each route/endpoints, you could create an IAM role allowing API Gateway to call your Lambda (https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#d0e1938)

@lpalbou
If I had infinite time, all my replies will be perfect.
Intent was not to be perfect, but to share what I found, so that

others can use or improve. To save the day, anything that works is a solution, instead of spending many many hours of futile attempt.

It's possible, there is better options in config given by AWS at this time, and/or the documentation has improved. I don't remember what I wrote in my above reply an year & half ago. Hope yours works and is better, to someone else.