serverless / serverless

⚑ Serverless Framework – Use AWS Lambda and other managed cloud services to build apps that auto-scale, cost nothing when idle, and boast radically low maintenance.

Home Page:https://serverless.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

EC2 permissions for VPC not set on first deploy

gozup opened this issue Β· comments

Hi Guys,

I have multiple serverless projects up and running, but today I wanted to set up a new one, and I can't figured it out.

My project is inside a VPC, and I have a permission error on the "AWS::Lambda::Function" role:

Your access has been denied by EC2, please make sure your function execution role have permission to CreateNetworkInterface. EC2 Error Code: UnauthorizedOperation. EC2 Error Message: You are not authorized to perform this operation.

But my serverless.yml is setup the same way than my working projects:

service: AwesomeService
frameworkVersion: "=1.2.1"
custom: ${file(./environments/serverless/${env:NODE_ENV}.yml)}
provider:
  name: aws
  cfLogs: true
  runtime: nodejs4.3
  region: eu-central-1
  stage: ${self:custom.stage}
  memorySize: ${self:custom.memorySize}
  timeout: ${self:custom.timeout}
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DetachNetworkInterface"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"
  vpc: ${self:custom.vpc}
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          method: post
          path: hello
          cors: true
          integration: lambda

As you can see, I clearly set the iamRoleStatements for EC2. Moreover, I read this in the documentation:

Further, if you have specified VPC security groups and subnets for your lambdas to use then the EC2 rights necessary to attach to the VPC via an ENI will be added into the default IAM policy.

But when the role is created, the inline policy attached is the following:

{
	"Version": "2012-10-17",
	"Statement": [{
		"Action": ["logs:CreateLogGroup", "logs:CreateLogStream"],
		"Resource": ["arn:aws:logs:eu-central-1:111118746979:log-group:/aws/lambda/AwesomeService-development-hello:*"],
		"Effect": "Allow"
	}, {
		"Action": ["logs:PutLogEvents"],
		"Resource": ["arn:aws:logs:eu-central-1:111118746979:log-group:/aws/lambda/AwesomeService-development-hello:*:*"],
		"Effect": "Allow"
	}]
}

No rights about EC2 are added...
Does anyone have an idea?

Many thanks

I figured it out finally... You must do a first deploy of your service WITH the EC2 iamRoleStatements but WITHOUT the VPC key. Once the deployed has ended, then you can add the VPC info to your serverless.yml and make a new deploy...

Is it possible to get a fix of it?

+1

Confirmed what @gozup said, if you first deploy serverless without VPC configuration, it goes through, and then you modify serverless.yml to add the VPC then the deployment works fine, and I confirm the Lambdas are running from the VPC requested. Just something to do with the CF workflow for initial-deployment.

I got it working by adding DependsOn for both, role and policy, to function in Resources. It's not very sleek to add manually that to every function. @eahefnawy, @flomotlik @pmuens, will there be any downsides if that DependsOn is added to default cloudformation stack?

provider:
  name: aws
  runtime: nodejs4.3
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DetachNetworkInterface"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"
  vpc:
    securityGroupIds:
      - sg-xxxxxx
    subnetIds:
      - subnet-xxxxxx
      - subnet-xxxxxx
      - subnet-xxxxxx

functions:
  hello:
    handler: handler.hello

resources:
  Resources:
    HelloLambdaFunction:
      Type: "AWS::Lambda::Function"
      DependsOn:
        - IamRoleLambdaExecution
        - IamPolicyLambdaExecution

Thanks for reporting @gozup πŸ‘
Yes, we have different problems introduced due to the lack of DependsOn usage. @nicka recently wrote this PR which should resolve several DependsOn issues:

#2743

Would be great if this could be tested to see if it resolves the bug!

@pmuens, I used the PR version to test that demo code and it deployed just fine. I can try later with a real project that uses VPC, but I think @nicka got it fixed.

I also got the real project successfully deployed with PR version.

@laardee happy to hear that! The PR definitely works with the default uses cases where users rely on the frameworks auto generated IAM role and policy. In the case of providing custom roles it still requires some more work.

Duplicate of #1786.

Sorry guess, encountered this issue again today on brand new stacks... :(

Serverless 1.3.0:

Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - bandlab-migrator-foo
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - RollbackLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - MigrateLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - SeedLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - CurrentVersionLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - RollbackLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - MigrateLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - RollbackLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - MigrateLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - SeedLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - SeedLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - CurrentVersionLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - CurrentVersionLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::IAM::Policy - IamPolicyLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - CurrentVersionLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - RollbackLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - MigrateLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - SeedLambdaFunction
CloudFormation - CREATE_FAILED - AWS::Lambda::Function - RollbackLambdaFunction
CloudFormation - CREATE_FAILED - AWS::Lambda::Function - MigrateLambdaFunction
CloudFormation - CREATE_FAILED - AWS::Lambda::Function - SeedLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - CurrentVersionLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - CurrentVersionLambdaFunction
CloudFormation - ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack - bandlab-migrator-foo
CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::Function - CurrentVersionLambdaFunction
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - SeedLambdaFunction
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - RollbackLambdaFunction
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - CurrentVersionLambdaFunction
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - MigrateLambdaFunction
CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution
CloudFormation - DELETE_COMPLETE - AWS::IAM::Policy - IamPolicyLambdaExecution
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - MigrateLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - RollbackLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - SeedLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - CurrentVersionLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - RollbackLogGroup
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - SeedLogGroup
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - MigrateLogGroup
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - CurrentVersionLogGroup
CloudFormation - DELETE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - ROLLBACK_COMPLETE - AWS::CloudFormation::Stack - bandlab-migrator-foo
Serverless: Deployment failed!

  Serverless Error ---------------------------------------

     An error occurred while provisioning your stack: RollbackLambdaFunction
     - Your access has been denied by EC2, please make sure
     your function execution role have permission to CreateNetworkInterface.
     EC2 Error Code: UnauthorizedOperation. EC2 Error Message:
     You are not authorized to perform this operation..

Currently experimenting with AWS::CloudFormation::WaitCondition and the results are πŸ‘

Example:

Resources:
  WaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle

  WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: IamPolicyLambdaExecution
    Properties:
      Handle:
        Ref: WaitHandle
      Timeout: 10
      Count: 0

  MigrateLambdaFunction:
    DependsOn: WaitCondition

  SeedLambdaFunction:
    DependsOn: WaitCondition

  CurrentVersionLambdaFunction:
    DependsOn: WaitCondition

  RollbackLambdaFunction:
    DependsOn: WaitCondition

Already tested with adding this to existing stacks and performed stacks updates without issues. Updating the IAM roles/polices between stack updates triggered the wait condition properly. I'll start working on a new PR with the wait condition fix.

with 1.3.0 i get same problem as @gozup described

Reopening this one. Thanks for the investigation @nicka πŸ‘

Just for clarity, FYI with v1.4 I still get this. ;) In a few published projects that REQUIRE VPC, I have to specifically warn/explain to people to deploy with VPC commented out first, and then uncomment it. This bug is particularly annoying to have to explain, and I'm running into this more and more since I'm doing lots of in-VPC automation via Lambda these days. Hope someone can +1 work on this soon?

+1, this issue is causing me headaches, too.

Thanks for commenting @jarrettj πŸ‘

So this bug is still present? Any special config we can use to reproduce it? Thanks in advance!

Reopening...

Closing this one since it should've been resolved in the meantime.

I am having the same issue as well. Deploying with the required roles first and only afterwards adding the VPC configuration and redeploying works.

I am having the same issue as well. Deploying with the required roles first and only afterwards adding the VPC configuration and redeploying works.

@jochenvdv thanks for commenting. Can you please provide more information about your setup?

What version of Serverless are you using?
How does your serverless.yml file look like?

I have this issue too. I tried with v1.12.1 and v1.16.1. Specifying the IAM policy manually and removing the vpc code during the first run works.

provider:
    name: aws
    runtime: nodejs6.10
    iamRoleStatements:
      -  Effect: "Allow"
         Action:
          - "ec2:CreateNetworkInterface"
          - "ec2:DescribeNetworkInterfaces"
          - "ec2:DetachNetworkInterface"
          - "ec2:DeleteNetworkInterface"
        Resource: "*"
    vpc:
      securityGroupIds:
        - sg-xxxxxxx
      subnetIds:
        - sn-xxxxxxx
        - sn-xxxxxxx

I added the IamRoleStatements part to make it work.

@pmuens I'm on 1.16.1 and am using a serverless.yml very similar to that of @TomVanBerlo.

That's strange... Serverless used to add a ManagedPolicy dependency to the IAM AWS VPC policy automatically. Specifying the VPC policy explicitly should not be necessary anymore.

@pmuens Can you check if this behavior was broken by any PR?

Thanks for getting back @jochenvdv and @TomVanBerlo πŸ‘

@HyperBrain AFAIK we haven't touched any code related to the VPC setup in recent PRs.
Any chance to get a full serverless.yml so that we can deploy and reproduce this real quick?

Otherwise the output of a compiled CloudFormation template would be nice as well.

Thanks in advance!

Any resolution for this? I am getting this issue in v1.16.

Error log

An error occurred while provisioning your stack: Function- The provided execution role does not have permissions to call CreateNetworkInterface on EC2.

serverless.yml

provider:
  name: aws
  runtime: nodejs6.10
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DetachNetworkInterface"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"
  vpc:
    securityGroupIds:
      - sg-id
    subnetIds:
      - subnet-id1
      - subnet-id2

I'm on Serverless 1.21.1
I tried adding an existing Lambda to the default VPC security group and subnet, and I got the "The provided execution role does not have permissions to call CreateNetworkInterface on EC2." error.

I manually added the role statements like this

provider:
  name: aws
  runtime: nodejs6.10
  stage: Backend
  environment: ${file(${env:BUCKET}.env.yml)}
  region: us-east-1
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DetachNetworkInterface"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"

And configured my Lambda function like this (We have other functions in there, some have custom roles built in the resources section, and I replaced the group and subnet ID to random names for privacy)

functions:
  migrate:
    handler: handler.migrate
    DependsOn: IamPolicyLambdaExecution
    memorySize: 128
    timeout: 5
    events:
    - http:
        path: migrate
        method: get
    vpc:
      securityGroupIds:
        - sg-1234
      subnetIds:
        - subnet-a1
        - subnet-b1
        - subnet-c1
        - subnet-d1
        - subnet-e1

EDIT : Adding the EC2 permissions, updating the serverless deployment then adding the VPC configuration works.

Thanks for the update @vKongv and @lems3 πŸ‘

I'll re-open this one since it looks like this bug is back again...

From the research I did in the past it's a 1/3 change it being able to deploy with the ec2 statements in your iamRoleStatements. Only way is to add the Managed Policy Arn from AWS into your custom IAM role (which the sls framework does).

I had this issue yesterday but the deploy with roles config THEN deploy with vpc config worked, but now today, in a new project, I still get the "The provided execution role does not have permissions to call CreateNetworkInterface on EC2" error even when following the steps laid out earlier.

Edit: I happened to have a no op Lambda method in my setup. I commented that out and redid the steps and it worked.

For anybody finding this issue, it's not broken I guess you're just missing the following properties within your IAM custom roles.

# note that these rights are needed if you want your function to be able to communicate with resources within your vpc
ManagedPolicyArns:
  - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole

For more info: https://serverless.com/framework/docs/providers/aws/guide/iam#one-custom-iam-role-for-all-functions

When it was introduced: e879b2a

@pmuens I strongly believe you can close this issue.

@nicka
If we look at the commit you linked, we can read : When VPC configuration is provided the default AWS AWSLambdaVPCAccessExecutionRole will be associated with your Lambda execution role. In case custom roles are provided be sure to include the proper

Which is not true. I had to add manually the policies to my iamRoleStatement first, deploy once, then add my lambda to the VPC. My lambda is using the default role, not a custom one. Not following this procedure was leading me to an error while deploying my environment.

So, I don't think this should be close...

Have you tried it lately @lems3 ? If you don't override the role it automatically adds that managed role, if you do override the role then you just have to add the managed property to your custom role. I just confirmed with two of my projects that used to exhibit these problems, the first deploy issues seem to be completely gone.

Not since my comment 21 days ago. So it may have been fixed in a recent commit by what you have observed with your projects.

EDIT : I think I should have added that my latest reply was to bring light about the intended use of the framework by the commit @nicka linked and how it didn't worked that way 21 days ago. If we can confirm this is fixed, this issue is gone ;-)

@lems3 Are you using a custom role for your function?

To clarify the following should never be used:

provider:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DetachNetworkInterface"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"

You should always add the managed policy if you have a custom role and a VPC setup. CloudFormation/AWS has some timing issues which basically resolves the IAM role creation too fast which causes the Lambda permissions error. Since a managed policy comes with your account (it's already present) the timing issue is gone.

@nicka No. The function doesn't have a custom role. It uses the iamRoleStatement provided by Serverless. And I wasn't adding anything to the basic role at first when I tried my deployment. I had to add the policies manually first, then add the VPC configuration to the lambda.

So, if Serverless is supposed to add the policies automatically when using VPC in one function, I can confirm it was not working. If it's working now, the issue can be closed.

This seems to be broken for me on 1.23.0. I am not specifying a custom role at all. I am relying on the fact that specifying vpc info should automatically add the permission. This seems to be happening because I can watch the role in the IAM console and see it added, but the timing seems to be off. It still fails and then reverts the policy change.

❯ serverless deploy -v
 
 Serverless Warning --------------------------------------
 
  A valid environment variable to satisfy the declaration 'env:DB_HOST' could not be found.
 
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (5.43 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - lambda-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - SendEmailLambdaFunction
CloudFormation - UPDATE_FAILED - AWS::Lambda::Function - SendEmailLambdaFunction
CloudFormation - UPDATE_ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack - lambda-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - SendEmailLambdaFunction
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - SendEmailLambdaFunction
CloudFormation - UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - lambda-dev
CloudFormation - UPDATE_ROLLBACK_COMPLETE - AWS::CloudFormation::Stack - lambda-dev
Serverless: Operation failed!
 
  Serverless Error ---------------------------------------
 
  An error occurred: SendEmailLambdaFunction - The provided execution role does not have permissions to call CreateNetworkInterface on EC2.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.7.0
     Serverless Version:     1.23.0
service: lambda

provider:
  name: aws
  runtime: nodejs6.10
  region: us-west-2

functions:
  sendEmail:
    handler: XXXXX
    memorySize: 128
    events:
      - sns:
          arn: arn:aws:sns:us-west-2:XXX
    environment:
      DB_HOST: ${env:DB_HOST}
    vpc:
      securityGroupIds:
        - XXX
      subnetIds:
        - XXX

This seems to definitely be a timing issue of adding the AWS managed policy taking a while to go into effect before the role attempts to use it.

The best workaround I have found is to manually go into the console, and add the AWSLambdaVPCAccessExecutionRole managed policy to the role. Wait a few seconds and then the deploy should be successful. This is the same change the cloud formation template is doing so the change is idempotent and everything is fine from then on.

commented

I'm experiencing this using 1.24. I tried deploying first without the vpc configuration and then you modify serverless.yml to add the VPC configuration, then deploy again. That works but prevents automated deployments. Is there a way to specify an the "serverless.yml" file to use for deployment, then I could keep 2 around one without the VPC config and another with?

Any plans for fixing this issue?

What @inuwan suggested worked well for me. For the uninitiated, if you have additional roles added to each lambda function you will have to add the necessary EC2 privileges to those roles as well.

Same issue here using 1.25.0, the @inuwan suggestion not worked for me.

Same issue here using 1.27.3. Adding the role explicitly as @nicka suggested does fix it, but since the documentation explicitly says this isn't needed either the documentation should be updated or this should be fixed.

Same issue here using 1.27.3, using the default IAM role.

Thanks for opening @gozup πŸ‘

We've published some new releases in the meantime with some fixes around that. I'll close this issue for now. Feel free to re-open if this is still a problem.

+1 this is still an issue

@jacoc Could you open a new ticket with detailed configuration and steps to reproduce?
+1 does not add any information to investigate.

@exoego : CREATE_FAILED The provided execution role does not have permissions to call CreateNetworkInterface on EC2 (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; ....

This issue is back again, using 2.3.0. Have many other Lambdas with custom IAM role statements, yet never had to define the EC2 perms before, now all of a sudden I get this complaint. Why.

If you are using a VPC and if you are using a custom execution role:

provider:
    name: aws
    role: arn:aws:iam::xxxxxxxxx:role/my-execution-role
    ...

Then you need to make sure this role has AWSLambdaVPCAccessExecutionRole policy attached to it

Im getting the same issue. Custom rules are little confused me on console and config file updates didnt worked.