Zappa icon indicating copy to clipboard operation
Zappa copied to clipboard

Minimum AWS policies for example.

Open wesleykerr opened this issue 9 years ago • 58 comments

I’m looking to kick of a project with Zappa, but per company rules the default policies for AWS access are a bit too lax (allow * is forbidden), so can we get the minimum set of AWS policies to run the example provided?

wesleykerr avatar Aug 12 '16 15:08 wesleykerr

Yeah, this is a really good one that definitely needs addressing. I'm actually not super sure. It's very liberal out of the gate, but it absolutely needs a way to run in a minimum-permissions kinda way. Let's see.

For the execution policy, I think this is all that's necessary:

ASSUME_POLICY = """{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "apigateway.amazonaws.com",
          "lambda.amazonaws.com",
          "events.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}"""

and for the attach policy:

ATTACH_POLICY = """{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                 "logs:CreateLogGroup",
                 "logs:CreateLogStream",
                 "logs:PutLogEvents",
                 "logs:DescribeLogStreams"
            ],
            "Resource": "arn:aws:logs:YOUR_LOG_RESOURCE_ARN"
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "arn:aws:lambda:YOUR_LAMBDA_FUNCTION_ARN"
            ]
        },
    ]
}"""

Plus permissions for whatever AWS resources you're using on top of that.

Don't quote me on that, but that's my first guess. Leaving this ticket open until we can figure this out and get it documented.

Miserlou avatar Aug 12 '16 16:08 Miserlou

Related https://github.com/Miserlou/Zappa/issues/241

Miserlou avatar Aug 12 '16 16:08 Miserlou

Thanks! I'll start working with that and see where that can get me.

wesleykerr avatar Aug 12 '16 20:08 wesleykerr

Great! Please report back with what you find out so we can add it to the documentation.

Miserlou avatar Aug 12 '16 20:08 Miserlou

This is what I've learned so far (note: I am not an AWS expert) from adding actions on errors while deploying.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::<account_id>:role/<zappa-role>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:PutRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:ListVersionsByFunction",
                "lambda:UpdateFunctionCode"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

wesleykerr avatar Aug 14 '16 22:08 wesleykerr

Ah okay, nice. I think you can probably remove "iam:PutRolePolicy" once you define a working policy and set manage_roles to false.

On Sun, Aug 14, 2016 at 3:11 PM, Wesley Kerr [email protected] wrote:

This is what I've learned so far (note: I am not an AWS expert) from adding actions on errors while deploying.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:GetRole", "iam:PutRolePolicy" ], "Resource": [ "" ] }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::<account_id>:role/" ] }, { "Effect": "Allow", "Action": [ "apigateway:DELETE", "apigateway:GET", "apigateway:PATCH", "apigateway:POST", "apigateway:PUT", "events:PutRule", "events:PutTargets", "lambda:AddPermission", "lambda:CreateFunction", "lambda:DeleteFunction", "lambda:GetFunction", "lambda:ListVersionsByFunction", "lambda:UpdateFunctionCode" ], "Resource": [ "" ] } ] }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Miserlou/Zappa/issues/244#issuecomment-239700951, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIi049kAxxjB2eegVMDtH8dpaYVTn3_ks5qf5KggaJpZM4JjOKC .

Miserlou avatar Aug 14 '16 22:08 Miserlou

Does logging work with that? ex zappa tail

Miserlou avatar Aug 15 '16 00:08 Miserlou

I need to try that. I will give it a try tomorrow.

wesleykerr avatar Aug 16 '16 02:08 wesleykerr

The only thing I had to add in addition to @wesleykerr's doc above is "events:ListRules" and a policy that gives access to the S3 bucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::nameofmybucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:CreateMultipartUpload",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::nameofmybucket/*"
            ]
        }
    ]
}

smoll avatar Aug 23 '16 20:08 smoll

Thanks for reporting your findings, @smoll . Can you try zappa tail with that?

Miserlou avatar Aug 23 '16 22:08 Miserlou

When I do zappa tail dev I get

ClientError: An error occurred (AccessDeniedException) when calling the DescribeLogStreams 
operation: User: arn:aws:iam::<my-aws-account-id>:user/circleci-zappa is not authorized to 
perform: logs:DescribeLogStreams on resource: 
arn:aws:logs:us-east-1:<my-aws-account-id>:log-group:/aws/lambda/parentfoldername-dev:log-stream:

Edit: looks like logs:FilterLogEvents and logs:DescribeLogStreams are all you need.

smoll avatar Aug 24 '16 03:08 smoll

I started noticing a lot of these in CI:

ClientError: An error occurred (LimitExceededException) when calling the PutTargets operation: The requested resource exceeds the maximum number allowed.

and I saw lots of duplicate keep warm schedules in the Lambda > Triggers tab. I believe adding "events:RemoveTargets" will fix this.

smoll avatar Aug 26 '16 13:08 smoll

@smoll related: https://github.com/Miserlou/Zappa/issues/286

Miserlou avatar Aug 26 '16 18:08 Miserlou

I kept getting errors with the basic flask formation until I included cloudformation permissions.

"cloudformation:*"

dhbradshaw avatar Nov 18 '16 16:11 dhbradshaw

To add to this conversation, I used CloudTrail to log AWS operations issued by Zappa during an app deploy and update. Below you'll find the list. This list, and the following process, might be useful for you.

To repeat:

  • Make a user like "zappadeployer" and attach the policy "AdministratorAccess" so nothing is forbidden.
  • Enable CloudTrail to log all events to a bucket.
  • Deploy a simple hello world Flask app using that user
  • Update the app with a code change, to exercise the update process
  • Disable CloudTrail logging
  • Wait for logs to appear in the bucket
  • Analyze the logs.

Once the logs were in my bucket, I downloaded them like this:

% aws s3 cp --recursive s3://my-bucket-for-logs/cloudtrail/ .

Then I issued this oneliner with jq to capture the user, service and operation. Then I grepped for the "zappadeployer" user (could've used jq, but ran out of time to figure it out) and counted unique occurrences. Here's what I see (account number redacted):

% find . -type f -name '*.gz' | xargs gzcat | jq -cS 'select(has("awsAccountId") == false) | .Records | .[] | [.userIdentity.arn, .eventSource, .eventName]' | grep -i zappa | sort | uniq -c
   2 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","CreateDeployment"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","CreateResource"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","CreateRestApi"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","DeleteMethod"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","DeleteResource"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","DeleteRestApi"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","GetApiKeys"]
   4 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","GetResources"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","PutIntegration"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","PutMethod"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","apigateway.amazonaws.com","UpdateStage"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","CreateStack"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","DeleteStack"]
   5 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","DescribeStackResource"]
   9 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","DescribeStacks"]
   3 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","ListStackResources"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","cloudformation.amazonaws.com","UpdateStack"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","DeleteRule"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","DescribeRule"]
   4 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","ListRules"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","ListTargetsByRule"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","PutRule"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","PutTargets"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","events.amazonaws.com","RemoveTargets"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","iam.amazonaws.com","GetRole"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","iam.amazonaws.com","GetRolePolicy"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","kms.amazonaws.com","DescribeKey"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","AddPermission20150331v2"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","CreateFunction20150331"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","DeleteFunction20150331"]
   5 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","GetFunction20150331v2"]
   3 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","GetPolicy20150331v2"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","ListVersionsByFunction20150331"]
   2 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","RemovePermission20150331v2"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","UpdateFunctionCode20150331v2"]
   1 ["arn:aws:iam::000000000000:user/zappadeployer","lambda.amazonaws.com","UpdateFunctionConfiguration20150331v2"]
  27 ["arn:aws:iam::000000000000:user/zappadeployer","logs.amazonaws.com","DescribeLogStreams"]
   6 ["arn:aws:iam::000000000000:user/zappadeployer","s3.amazonaws.com","DeleteObject"]
   4 ["arn:aws:iam::000000000000:user/zappadeployer","s3.amazonaws.com","GetObject"]
  10 ["arn:aws:iam::000000000000:user/zappadeployer","s3.amazonaws.com","HeadBucket"]
   4 ["arn:aws:iam::000000000000:user/zappadeployer","s3.amazonaws.com","PutObject"]

(I may have also tried to delete the deployed app, I don't remember.)

Hope that helps.

aimichal avatar Dec 21 '16 06:12 aimichal

Well, if someone have no idea where to add the policies...

Go to "https://console.aws.amazon.com/iam/home#/users", and find the user that you want to modify, click it. Then you will go to "https://console.aws.amazon.com/iam/home#/users/[YOUR-USER-NAME]", in the "Permissions" panel, there is a button on the bottom "Add inline policy". Click this, and you will go to some "Set Permission" page, choose "Custom Policy", and click "Select".

Set whatever name you like...

And paste the your policies into that new file.

Updated Thanks aimichal, now i understand what your post means. But using your log method, i still can't find out the minimum policies that works for me.

Luckily, refering to MihaZelnik's answer, i finally found the policies working for me. These policies won't create any error during deploy, update and undeploy commands. (At least for me...)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::[ROLE-ID]:role/ZappaLambdaExecution"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListTargetsByRule",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:GetPolicy",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::[BUCKET-NAME-IN-SETTINGS-JSON]"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:CreateMultipartUpload",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::[BUCKET-NAME-IN-SETTINGS-JSON]/*"
            ]
        }
    ]
}

ysong-sc avatar Dec 21 '16 10:12 ysong-sc

@ysong-sc You're welcome.

Some words of caution:

Attaching the the AWS-managed policy "AdministratorAccess" to a user gives unlimited access. See here for an explanation of the "AdministratorAccess" managed policy:

http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html

The inline policy you added in the previous step (which has a few "Allow" rules) is superseded by "AdministratorAccess".

While the unlimited access granted by the policy "AdministratorAccess" will make Zappa work, this policy should be attached to a user in exceptional cases. Following the principle of least privilege, I do not recommend attaching this policy to users of limited operations, like deployments. See this document:

http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html

My hope is that the process (and report) can be used to craft a limited policy for Zappa.

aimichal avatar Dec 21 '16 17:12 aimichal

This is working for me

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::<account_id>:role/ZappaLambdaExecution"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListTargetsByRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:ListVersionsByFunction",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents",
                "route53:ListHostedZones",
                "route53:ChangeResourceRecordSets",
                "route53:GetHostedZone"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket_name>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:CreateMultipartUpload",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket_name>/*"
            ]
        }
    ]
}

Edit: I added "route53:ListHostedZones", "route53:ChangeResourceRecordSets", "route53:GetHostedZone" for Let's Encrypt

mihazelnik avatar Dec 21 '16 20:12 mihazelnik

It's great to see development in narrowing AWS polices for Zappa (and serverless).

If nobody beats me to it, I'll script a python implementation of @aimichal's CloudTrail technique to work out the minimal policies and turn them into a policy document. But that's for 2017. Happy holidays.

topiaruss avatar Dec 24 '16 10:12 topiaruss

I fall into the error report by @smoll ClientError: An error occurred (LimitExceededException) when calling the PutTargets operation: The requested resource exceeds the maximum number allowed. At every update a new target is inserted into Events->Rules. Deleting the rule and updating again resolve the problem. But this must be done every 4 update.

ddepaoli3 avatar Dec 27 '16 14:12 ddepaoli3

@ysong-sc Your updated policy worked well for me. Saved me a lot of time. Thanks! :+1: I added "s3:CreateBucket" to get Zappa to create the S3 bucket after I had deleted it manually.

shirish87 avatar Jan 01 '17 07:01 shirish87

I just got some permissions errors when using the latest policy above in travis - think its because Im now using VPC config to run the lambda functions with subnets and security groups... I needed to add:

ec2:DescribeSecurityGroups ec2:DescribeSubnets ec2:DescribeVpcs ec2:DescribeVpcsRequest events:PutRule

danielwhatmuff avatar Jan 04 '17 01:01 danielwhatmuff

For all the copy+paste people out there (like me!) the above permissions have a typo, DescibeSubnets should be DescribeSubnets.

Change to: "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:DescribeVpcsRequest",

eely22 avatar Feb 09 '17 16:02 eely22

updated now @eely22 ..sorry!

danielwhatmuff avatar Feb 27 '17 05:02 danielwhatmuff

Would be great for us to find a way to build deployment automation of these Zappa deployment permissions. CloudFormation template?

aehlke avatar Mar 07 '17 18:03 aehlke

In what sense? Do you need them to be dynamically managed? You can use the manage_roles and attach_policy settings to do what you need, maybe.

My other longer-term plan is to steal the AST-parsing IAM-generator from Chalice.

Possibly related: https://github.com/Miserlou/Zappa/issues/634

Miserlou avatar Mar 07 '17 18:03 Miserlou

Could zappa itself only set the above minimal policy? I was surprised that it gave itself basically wildcard permissions. While folks could hardcode their policy using attach_policy, this isn't as desirable because certain aspects of the policy may not be known at run time (e.g. exact uids), complicating deployment.

philipn avatar Mar 09 '17 03:03 philipn

Also needs route53:ListResourceRecordSets in order to use zappa certify to update an existing domain. See https://github.com/Miserlou/Zappa/issues/723

edit: and apigateway:OPTIONS for the same use case.

aehlke avatar Mar 15 '17 18:03 aehlke

Another one for the list: events:ListRuleNamesByTarget

danielwhatmuff avatar Mar 17 '17 04:03 danielwhatmuff

Starting from zappa==0.40.0 the default role name has changed with the project env lambda name prepended:

        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "iam:CreateRole"
            ],
            "Resource": [
                "arn:aws:iam::<account_id>:role/<lambda_name>-ZappaLambdaExecutionRole"
            ]
        }

Alternatively you can change the role_name in your settings.

michi88 avatar Apr 02 '17 10:04 michi88

You may also need the following permissions for zappa to setup SNS event handling:

SNS:ListSubscriptionsByTopic SNS:Unsubscribe SNS:Subscribe

bxm156 avatar May 17 '17 20:05 bxm156

I found that I needed the following setup to be able to deploy and undeploy

There were a few more rules needed from the original listed by @MihaZelnik

When zappa initially creates a new stage, it needs iam:AttachRolePolicy and iam:CreateRole, if a new bucket is being made it needs s3:CreateBucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreateRole",
                "iam:GetRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::<account_id>:role/*-ZappaLambdaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListTargetsByRule",
                "events:ListRuleNamesByTarget",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:GetPolicy",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents",
                "route53:ListHostedZones",
                "route53:ChangeResourceRecordSets",
                "route53:GetHostedZone",
                "s3:CreateBucket",
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket name from zappa_settings.json>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:CreateMultipartUpload",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket name from zappa_settings.json>/*"
            ]
        }
    ]
}

audiolion avatar May 24 '17 11:05 audiolion

Would it be cool to put this in a file in the repo so we can PR against it?

It could be split in main policy and a few extra for the optional features like LetEncrypt, SNS etc.

Bartvds avatar May 26 '17 09:05 Bartvds

I think this would be helpful @Bartvds . My configuration above includes the necessary perms for when Zappa is managing IAM roles, if you setup the roles yourself then you can get away with fewer permissions. I'd probably just throw up the PR and wait for feedback. The amount of comments in this thread and the length of time that it has been going on seems to lend credence to it being a problem

audiolion avatar May 26 '17 12:05 audiolion

Cool, I put it up in PR #894

Bartvds avatar May 26 '17 18:05 Bartvds

For anyone who comes here, with version 0.43, I needed to add lambda:GetFunctionConfiguration to my Zappa role.

smizell avatar Jul 20 '17 21:07 smizell

If you, like myself, have clients that won't let you set up too permissive policies on their AWS accounts, then you might want to take away "iam:PutRolePolicy" and add to your zappa_settings.json the key:

"manage_roles": false

Then attach to your IAM user one of the inline policies proposed here. Only make sure that at least the following two statements are there:

"Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::<account_id>:role/<project_name>-<env>-ZappaExecutionRole"
            ]
        },
        (.......)
]

These will essentially let the <project_name>-<env>-ZappaExecutionRole role to assume the permissions assigned to the IAM user you are using in Zappa (profile_name key).

Finally, since Zappa won't manage roles automatically, then you must manually create a service role to the default name:

<project_name>-<env>-ZappaExecutionRole

Or name it something else in your settings files under the keyrole_name.

Then edit the role's trust relationship as follows:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "apigateway.amazonaws.com",
          "lambda.amazonaws.com",
          "events.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

If your head is about to blow off with this, then don't panic, read this first and come back to here, things will become much more clear:

https://start.jcolemorrison.com/aws-iam-policies-in-a-nutshell/

joarleymoraes avatar Jul 28 '17 19:07 joarleymoraes

An authoritative how to on this with working Zappa policies to allow deployment with manual init would be great. Till then I have to use throwaway accounts to fiddle with Zappa.

whatnick avatar Aug 18 '17 04:08 whatnick

I think the permissions issue has to be addressed in the broader context for example multiple users, how the IAM roles and lambda function will have access to rest of AWS infrastructure and so on. People could look at DuploCloud platform ([https://portal.duplocloud.net]) which helps address this. I have written a tutorial on how one can use zappa to deploy a python application in AWS using DuploCloud platform, w/o worrying about any permissions stuff. The user does not even need a AWS account on his own... https://www.linkedin.com/pulse/deploy-existing-web-applications-serverless-using-aws-thiruvengadam

thvenket avatar Sep 28 '17 04:09 thvenket

Minor feedback on the policy offered by audiolion May 24th.
Thank you , this has been helpful in giving me a good starting point. I get a warning "Unrecognized actions- CreateMultipartUpload" . This appears to be redundant as it in included in PutObject, but it also does not appear to cause any harm.

rls-vault avatar Jun 30 '18 02:06 rls-vault

This feature request could be supported by implementing #1540

brylie avatar Sep 17 '18 09:09 brylie

Does Zappa perform certain activities on an hourly or similar basis? I am trying to get the minimum permissions setup, but it seems that my app only works for a few hours, then it fails (Internal Service Error) because of lack of a certain permission. The logs also stop to Cloudwatch so I can't debug. For context, I am using Zappa with RDS in a VPC (which requires a NAT/Internet gateway and additional setup to access the VPC & internet). I can't figure out the missing permission and it only starts working again when I open it up to * temporarily and change it back (which then it only works a couple hours before failing again)

EDIT: For those running into a similar issue, it ended up being related to Network interface permissions. If you are using RDS and need your function to talk to both the VPC and internet, enabling these seemed to fix it for me:

"ec2:CreateNetworkInterface",
"ec2:DetachNetworkInterface",
"ec2:DeleteNetworkInterfacePermission",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterfacePermission",
"ec2:DescribeNetworkInterfaceAttribute",
"ec2:ResetNetworkInterfaceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:DeleteNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DescribeNetworkInterfacePermissions"

ameenmaali avatar Nov 17 '18 02:11 ameenmaali

Does Zappa perform certain activities on an hourly or similar basis? I am trying to get the minimum permissions setup, but it seems that my app only works for a few hours, then it fails (Internal Service Error) because of lack of a certain permission. The logs also stop to Cloudwatch so I can't debug. For context, I am using Zappa with RDS in a VPC (which requires a NAT/Internet gateway and additional setup to access the VPC & internet). I can't figure out the missing permission and it only starts working again when I open it up to * temporarily and change it back (which then it only works a couple hours before failing again)

EDIT: For those running into a similar issue, it ended up being related to Network interface permissions. If you are using RDS and need your function to talk to both the VPC and internet, enabling these seemed to fix it for me:

"ec2:CreateNetworkInterface",
"ec2:DetachNetworkInterface",
"ec2:DeleteNetworkInterfacePermission",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterfacePermission",
"ec2:DescribeNetworkInterfaceAttribute",
"ec2:ResetNetworkInterfaceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:DeleteNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DescribeNetworkInterfacePermissions"

Hi @ameenmaali . Why it's different with arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole? Does it need more actions to talk with RDS rather than normal VPC servers?

toughrogrammer avatar Mar 11 '19 13:03 toughrogrammer

Hey @toughrogrammer, I actually was not aware of that role when I was setting this up. But it looks like that would work, although I'd have to test to verify. It's been a while since I tested, but I remember testing with only some of the ec2:x permissions and I was still having the issue, so I added all these. But based on the documentation, it seems like it was indeed what I was looking for.

ameenmaali avatar Mar 11 '19 16:03 ameenmaali

Just used this successfully.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListVersionsByFunction",
                "logs:DescribeLogStreams",
                "route53:GetHostedZone",
                "events:PutRule",
                "s3:CreateBucket",
                "iam:CreateRole",
                "lambda:InvokeAsync",
                "cloudformation:DescribeStackResource",
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy",
                "apigateway:DELETE",
                "events:ListRuleNamesByTarget",
                "apigateway:PATCH",
                "cloudformation:UpdateStack",
                "events:ListRules",
                "lambda:DeleteFunction",
                "events:RemoveTargets",
                "logs:FilterLogEvents",
                "apigateway:GET",
                "events:ListTargetsByRule",
                "cloudformation:ListStackResources",
                "iam:GetRole",
                "events:DescribeRule",
                "lambda:InvokeFunction",
                "apigateway:PUT",
                "lambda:GetFunction",
                "route53:ListHostedZones",
                "lambda:UpdateFunctionConfiguration",
                "route53:ChangeResourceRecordSets",
                "cloudformation:DescribeStacks",
                "lambda:UpdateFunctionCode",
                "events:DeleteRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "apigateway:POST",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DescribeVpcsRequest",
                "lambda:RemovePermission",
                "lambda:GetPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:iam::<account id -- see in 'my account'>:role/*-ZappaLambdaExecutionRole",
                "arn:aws:s3:::<s3 bucket as per zappa settings>"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::<s3 bucket as per zappa settings>/*"
        }
    ]
}

andytwoods avatar Apr 18 '19 12:04 andytwoods

Needed to add "cloudfront:UpdateDistribution" to the VisualEditor0 section to support zappa certify.

vshih avatar May 30 '19 19:05 vshih

Just used this successfully. Needed to add a few more permissions.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListVersionsByFunction",
                "logs:DescribeLogStreams",
                "route53:GetHostedZone",
                "events:PutRule",
                "s3:CreateBucket",
                "iam:CreateRole",
                "lambda:InvokeAsync",
                "cloudformation:DescribeStackResource",
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy",
                "apigateway:DELETE",
                "events:ListRuleNamesByTarget",
                "apigateway:PATCH",
                "cloudformation:UpdateStack",
                "events:ListRules",
                "lambda:DeleteFunction",
                "events:RemoveTargets",
                "logs:FilterLogEvents",
                "apigateway:GET",
                "events:ListTargetsByRule",
                "cloudformation:ListStackResources",
                "iam:GetRole",
                "events:DescribeRule",
                "lambda:InvokeFunction",
                "apigateway:PUT",
                "lambda:GetFunction",
                "route53:ListHostedZones",
                "lambda:UpdateFunctionConfiguration",
                "route53:ChangeResourceRecordSets",
                "cloudformation:DescribeStacks",
                "lambda:UpdateFunctionCode",
                "events:DeleteRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "apigateway:POST",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DescribeVpcsRequest",
                "lambda:RemovePermission",
                "lambda:GetPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:iam::<account id -- see in 'my account'>:role/*-ZappaLambdaExecutionRole",
                "arn:aws:s3:::<s3 bucket as per zappa settings>"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::<s3 bucket as per zappa settings>/*"
        }
    ]
}

hey @andytwoods , thanks for the post . Did you make any changes on top of it or is this the final version ..?

rakekris avatar Jun 04 '19 19:06 rakekris

@rakekris I got the above initially but then moved over to "manage_roles": true.

andytwoods avatar Jun 05 '19 05:06 andytwoods

I followed @joarleymoraes example and some combinations of the policy statements here to come up with the following that works using manage_roles: false. This means I manually created the role in IAM and set role_arn in the settings file to point to the created role's ARN.

Here is the role's inline policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                # This ends up being the ARN of the role this inline policy is on I believe.
                # At least it worked for me when I did it that way.
                "arn:aws:iam::<account_id>:role/<project_name>-<env>-ZappaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListTargetsByRule",
                "events:ListRuleNamesByTarget",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:GetPolicy",
                "lambda:InvokeAsync",
                "lambda:InvokeFunction",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "cloudfront:UpdateDistribution",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents",
                "route53:ListHostedZones",
                "route53:ChangeResourceRecordSets",
                "route53:GetHostedZone",
                "s3:CreateBucket"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<s3 bucket as per zappa settings>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:CreateMultipartUpload",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::<s3 bucket as per zappa settings>/*"
            ]
        }
    ]
}

Here is the role's trust relationship policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "events.amazonaws.com",
          "apigateway.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Since my lambda's are accessing resources in a VPC, I also had to attach the AWSLambdaVPCAccessExecutionRole policy to the role.

I seem to be able to deploy, certify, undeploy, and tail using this.

Edit: I had to also attach the AWSLambdaBasicExecutionRole policy to the role to allow creation of cloudwatch streams and logging to them.

ryancausey avatar Jun 24 '19 01:06 ryancausey

At the time of writing this comment (zappa==0.48.2), I've managed to deploy everything using the following policy attached to my AWS user:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/*-ZappaLambdaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListRuleNamesByTarget",
                "events:ListTargetsByRule",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetAlias",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:GetPolicy",
                "lambda:InvokeFunction",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "logs:DeleteLogGroup",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::zappa-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::zappa-*/*"
            ]
        }
    ]
}

gdavoian avatar Sep 29 '19 15:09 gdavoian

I am giving Zappa a try and it seems that there are some additional permissions required to use zappa certify. I had to specify cloudfront:UpdateDistribution and route53:ListHostedZones (on all resources) as well.

Majsvaffla avatar Oct 06 '19 20:10 Majsvaffla

For AWS CDK users, here are the settings that worked for me:

    /** S3 BUCKET FOR ZAPPA LAMBDAS */
    const zappaBucket = new s3.Bucket(this, 'ZappaBucket', {
      bucketName: `zappa-${this.stackName.toLowerCase()}`,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
    });

    /** IAM ROLE FOR ZAPPA LAMBDAS */
    const zappaRole = new iam.Role(this, 'ZappaRole', {
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
      description: `Role for Zappa Lambda: ${this.stackName}.`,
      roleName: `application-${this.stackName.toLowerCase()}-ZappaLambdaExecutionRole`,
    });
    const zappaStatement = new iam.PolicyStatement({
      actions: ['sts:AssumeRole'],
    });
    zappaStatement.addServicePrincipal('apigateway.amazonaws.com');
    zappaStatement.addServicePrincipal('events.amazonaws.com');
    if (zappaRole.assumeRolePolicy) zappaRole.assumeRolePolicy.addStatements(zappaStatement);
    // Add Basic Lambda role
    zappaRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'));
    // S3 Bucket access
    zappaBucket.grantReadWrite(zappaRole);
    // Add Required Policies for Zappa to run
    const zappaBasePolicy = new iam.Policy(this, 'ZappaBasePolicy', {
      policyName: 'ZappaBasePolicy',
    });
    zappaBasePolicy.addStatements(new iam.PolicyStatement({
      actions: [
        'apigateway:DELETE',
        'apigateway:GET',
        'apigateway:PATCH',
        'apigateway:POST',
        'apigateway:PUT',
        'events:DeleteRule',
        'events:DescribeRule',
        'events:ListRules',
        'events:ListRuleNamesByTarget',
        'events:ListTargetsByRule',
        'events:PutRule',
        'events:PutTargets',
        'events:RemoveTargets',
        'lambda:AddPermission',
        'lambda:CreateFunction',
        'lambda:DeleteFunction',
        'lambda:GetAlias',
        'lambda:GetFunction',
        'lambda:GetFunctionConfiguration',
        'lambda:GetPolicy',
        'lambda:InvokeFunction',
        'lambda:ListVersionsByFunction',
        'lambda:RemovePermission',
        'lambda:UpdateFunctionCode',
        'lambda:UpdateFunctionConfiguration',
        'cloudformation:CreateStack',
        'cloudformation:DeleteStack',
        'cloudformation:DescribeStackResource',
        'cloudformation:DescribeStacks',
        'cloudformation:ListStackResources',
        'cloudformation:UpdateStack',
        'logs:DeleteLogGroup',
        'logs:DescribeLogStreams',
        'logs:FilterLogEvents',
      ],
      resources: ['*'],
    }));
    zappaRole.attachInlinePolicy(zappaBasePolicy);

thibaut-pro avatar Mar 07 '20 07:03 thibaut-pro

I added apigateway.UpdateRestApiPolicy to https://github.com/Miserlou/Zappa/issues/244#issuecomment-536315403 list - This is required when performing an lambda update with API Gateway attached.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/*-ZappaLambdaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListVersionsByFunction",
                "logs:DescribeLogStreams",
                "events:PutRule",
                "lambda:GetFunctionConfiguration",
                "cloudformation:DescribeStackResource",
                "apigateway:DELETE",
                "apigateway:UpdateRestApiPolicy",
                "events:ListRuleNamesByTarget",
                "apigateway:PATCH",
                "events:ListRules",
                "cloudformation:UpdateStack",
                "lambda:DeleteFunction",
                "events:RemoveTargets",
                "logs:FilterLogEvents",
                "apigateway:GET",
                "lambda:GetAlias",
                "events:ListTargetsByRule",
                "cloudformation:ListStackResources",
                "events:DescribeRule",
                "logs:DeleteLogGroup",
                "apigateway:PUT",
                "lambda:InvokeFunction",
                "lambda:GetFunction",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:DescribeStacks",
                "lambda:UpdateFunctionCode",
                "events:DeleteRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "apigateway:POST",
                "lambda:RemovePermission",
                "lambda:GetPolicy"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketMultipartUploads",
                "s3:CreateBucket",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::zappa-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": "arn:aws:s3:::zappa-*/*"
        }
    ]
}

dashk avatar Apr 10 '20 11:04 dashk

I added apigateway.UpdateRestApiPolicy to #244 (comment) list - This is required when performing an lambda update with API Gateway attached.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/*-ZappaLambdaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListVersionsByFunction",
                "logs:DescribeLogStreams",
                "events:PutRule",
                "lambda:GetFunctionConfiguration",
                "cloudformation:DescribeStackResource",
                "apigateway:DELETE",
                "apigateway:UpdateRestApiPolicy",
                "events:ListRuleNamesByTarget",
                "apigateway:PATCH",
                "events:ListRules",
                "cloudformation:UpdateStack",
                "lambda:DeleteFunction",
                "events:RemoveTargets",
                "logs:FilterLogEvents",
                "apigateway:GET",
                "lambda:GetAlias",
                "events:ListTargetsByRule",
                "cloudformation:ListStackResources",
                "events:DescribeRule",
                "logs:DeleteLogGroup",
                "apigateway:PUT",
                "lambda:InvokeFunction",
                "lambda:GetFunction",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:DescribeStacks",
                "lambda:UpdateFunctionCode",
                "events:DeleteRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "apigateway:POST",
                "lambda:RemovePermission",
                "lambda:GetPolicy"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketMultipartUploads",
                "s3:CreateBucket",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::zappa-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": "arn:aws:s3:::zappa-*/*"
        }
    ]
}

To zappa update, IAM should contains lambda:DeleteFunctionConcurrency

rscarrera27 avatar May 22 '20 05:05 rscarrera27

Is it worth adding lambda:DeleteFunctionConcurrency to the policy, or should update and deploy be considered separate policies? I'm not sure what the better practice would be.

shermaza avatar Aug 03 '20 22:08 shermaza

I'm getting this to run in CI/CD and just want to run zappa update <app> with the bare minimum of permissions. For this I distilled a more narrow set of permissions like this. It's working with zappa 0.52.0. Note that first deployment is done with zappa deploy from an administrator's machine with broader permissions.

WARNING THIS IS JUST FOR ZAPPA UPDATE, not for deploy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "UploadFunctionCode",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::<S3_BUCKET>",
                "arn:aws:s3:::<S3_BUCKET>/*"
            ]
        },
        {
            "Sid": "UpdateLambda",
            "Effect": "Allow",
            "Action": [
                "lambda:DeleteFunctionConcurrency",
                "lambda:GetAlias",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:InvokeFunction",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration"
            ],
            "Resource": [
                "arn:aws:lambda:*:<ACCOUNT_ID>:function:<APP_NAME>"
            ]
        },
        {
            "Sid": "IAMToGetAndPassTheRole",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/<APP_NAME>-ZappaLambdaExecutionRole"
            ]
        },
        {
            "Sid": "UpdateCloudFormationStack",
            "Effect": "Allow",
            "Action": [
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack"
            ],
            "Resource": [
                "arn:aws:cloudformation:<REGION>:<ACCOUNT_ID>:stack/<APP_NAME>",
                "arn:aws:cloudformation:<REGION>:<ACCOUNT_ID>:stack/<APP_NAME>/*"
            ]
        },
        {
            "Sid": "UpdateAPIGatewayGetTheRESTAPIIdFromTheConsole",
            "Effect": "Allow",
            "Action": [
                "apigateway:GET",
                "apigateway:POST",
                "apigateway:PATCH",
                "apigateway:PUT",
                "apigateway:UpdateRestApiPolicy"
            ],
            "Resource": [
                "arn:aws:apigateway:*::/restapis/<REST_API_ID>",
                "arn:aws:apigateway:*::/restapis/<REST_API_ID>/*"
            ]
        }
    ]
}

WARNING THIS IS JUST FOR ZAPPA UPDATE, not for deploy

jtwaleson avatar Dec 28 '20 11:12 jtwaleson

This repo from Cisco Security has a zappa deployment policy document that is well-written, as well as some explanation of how to use it, an example zappa_settings.json, etc: https://github.com/CiscoSecurity/tr-05-serverless-microsoft-defender-for-endpoint

The actual zappa lambda deployer policy document:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/*ZappaLambdaExecutionRole"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRules",
                "events:ListRuleNamesByTarget",
                "events:ListTargetsByRule",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:DeleteFunctionConcurrency",
                "lambda:GetAlias",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:GetPolicy",
                "lambda:InvokeFunction",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "logs:DeleteLogGroup",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::zappa-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::zappa-*/*"
            ]
        }
    ]
}

charlesreid1 avatar Oct 16 '21 16:10 charlesreid1