提供的执行角色没有调用EC2上的DescribeNetworkInterfaces的权限

问题描述 投票:0回答:12

当我在此函数中输入任何代码(例如

console.log();
)并单击“保存”时,会发生错误:

提供的执行角色无权调用 EC2 上的DescribeNetworkInterfaces

exports.handler = (event, context, callback) => {
  callback(null, 'Hello from Lambda');
  console.log(); // here is my code   
};

我将函数与角色绑定:

lambda_excute_execution(Policy:AmazonElasticTranscoderFullAccess)

且此功能目前未绑定任何触发器。

然后,我给角色

AdministratorAccess
策略,我可以正确保存我的源代码。

该角色在今天之前可以成功运行函数。

有人知道这个错误吗?

aws-lambda terraform amazon-iam roles policy
12个回答
261
投票

如果您尝试在 VPC 中部署 Lambda 而不为其提供所需的网络接口相关权限

ec2:DescribeNetworkInterfaces
ec2:CreateNetworkInterface
ec2:DeleteNetworkInterface
(请参阅 AWS 论坛),此错误很常见。

例如,这是一个允许将 Lambda 部署到 VPC 中的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeNetworkInterfaces",
        "ec2:CreateNetworkInterface",
        "ec2:DeleteNetworkInterface",
        "ec2:DescribeInstances",
        "ec2:AttachNetworkInterface"
      ],
      "Resource": "*"
    }
  ]
}

100
投票

如果您使用 terraform,只需添加:

resource "aws_iam_role_policy_attachment" "AWSLambdaVPCAccessExecutionRole" {
    role       = aws_iam_role.lambda.name
    policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}

55
投票

通过托管策略

  • 授予 Lambda 必要的权限,以深入了解生产 RDS 数据库驻留在私有子网中的 VPC。
  • 正如@portatlas 上面提到的,
    AWSLambdaVPCAccessExecutionRole
    托管策略就像手套一样合适(我们都知道使用 IAM 托管策略是 AWS 推荐的最佳实践)。
  • 这适用于已附加服务角色的 Lambda。

AWS CLI

1.获取 Lambda 服务角色

  • 向 Lambda API 请求函数配置,从中查询角色,输出到文本以获得不带引号的返回。
    aws lambda get-function-configuration \
        --function-name <<your function name or ARN here>> \
        --query Role \
        --output text
    
  • 返回,乘
    your-service-role-name
    前往#2
    your-service-role-name
    

2.将托管策略
AWSLambdaVPCAccessExecutionRole
附加到服务角色

aws iam attach-role-policy \
    --role-name your-service-role-name \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole

CDK 2 TypeScript

const lambdaVPCExecutionRole:iam.Role = new iam.Role(this, `createLambdaVPCExecutionRole`, {
    roleName        : `lambdaVPCExecutionRole`,
    assumedBy       : new iam.ServicePrincipal(`lambda.amazonaws.com`),
    description     : `Lambda service role to operate within a VPC`,
    managedPolicies : [
        iam.ManagedPolicy.fromAwsManagedPolicyName(`service-role/AWSLambdaVPCAccessExecutionRole`),
    ],
});

const lambdaFunction:lambda.Function = new lambda.Function(this, `createLambdaFunction`, {
    runtime : lambda.Runtime.NODEJS_14_X,
    handler : `lambda.handler`,
    code    : lambda.AssetCode.fromAsset(`./src`),
    vpc     : vpc,
    role    : lambdaVPCExecutionRole,
});

38
投票

这其实是一个很常见的问题。

您可以通过向“权限”选项卡下的 Lambda 执行角色添加自定义内联策略来解决此问题。

只需添加以下内容:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeNetworkInterfaces",
        "ec2:CreateNetworkInterface",
        "ec2:DeleteNetworkInterface",
        "ec2:DescribeInstances",
        "ec2:AttachNetworkInterface"
      ],
      "Resource": "*"
    }
  ]
}

如果您需要更多信息(Terraform、CloudFormation 和 AWS Console)或感到困惑,这里有一个带图片的完整教程:https://ataiva.com/the-provided-execution-role-does-not-have -在 EC2 上调用创建网络接口的权限/

此外,最近的一系列步骤如下:

  1. 在 Lambda 函数下,选择“配置”

  2. 选择“权限”

  3. 选择执行角色:

  4. 选择“添加权限”

  5. 创建内联策略

  6. 选择“JSON”

  7. 粘贴上面的 JSON 并选择“审核”。


21
投票

似乎已经有很多不同的方式回答了这个问题,但截至本文发布时,AWS 已经有了托管策略。如果您只需搜索 AWSLambdaVPCAccessExecutionRole,您将能够附加它,并且此方法对我有用。

这是阿恩:

arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole

12
投票

只需转到执行角色 -> 附加策略 -> 搜索“AWSLambdaVPCAccessExecutionRole”并添加它。


10
投票

Cloudformation 和 AWS SAM 用户的示例。

此示例 lambda 角色定义添加了托管

AWSLambdaVPCAccessExecutionRole
并解决了问题:

Type: "AWS::IAM::Role"
Properties:
  RoleName: "lambda-with-vpc-access"
  ManagedPolicyArns:
    - "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
  AssumeRolePolicyDocument:
    Version: "2012-10-17"
    Statement:
      - Effect: Allow
        Action:
          - sts:AssumeRole
        Principal:
          Service:
            - lambda.amazonaws.com

4
投票

经过一些实验,这是一个使用“最小权限”的解决方案。它是用 Python 编写的,适用于 AWS CDK。然而,同样的方法也适用于普通的 JSON

iam.PolicyDocument(
    statements=[
        iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=["ec2:DescribeNetworkInterfaces"],
            resources=["*"],
        ),
        iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=["ec2:CreateNetworkInterface"],
            resources=[
                f"arn:aws:ec2:{region}:{account_id}:subnet/{subnet_id}"
                f"arn:aws:ec2:{region}:{account_id}:security-group/{security_group_id}",
                f"arn:aws:ec2:{region}:{account_id}:network-interface/*",
            ],
        ),
        iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=["ec2:DeleteNetworkInterface"],
            resources=[f"arn:aws:ec2:{region}:{account_id}:*/*"],
        ),
    ],
),

2
投票

只是因为还没有足够的答案;)我认为这是最简单的方法。如果您使用的是 Web 管理控制台,那么当您首先创建 Lambda 函数时,只需在底部展开“高级设置”并选中“启用 VPC”并选择您的 vpc...简单!在执行此操作之前,我与 RDS 代理的连接超时。完成此操作(没有其他任何操作)后 - 效果很好!


1
投票

这是解决错误的快速但肮脏的方法。

在 AWS 控制台上打开

IAM
,选择附加到 Lambda 函数的角色并为其授予
EC2FullAccess
权限。

这将允许您通过授予 EC2 控制访问权限来更新 Lambda VPC。 请务必删除角色的权限,该功能仍然运行。

它比永久附加某些权限更安全还是更不安全?有争议。


1
投票

如果您使用 SAM,您只需添加到模板中的全局变量中,如下所示:

Globals:
  Function:
    VpcConfig:
      SecurityGroupIds:
        - sg-01eeb769XX2d6cc9b
      SubnetIds:
        - subnet-1a0XX614
        - subnet-c6dXXb8b
        - subnet-757XX92a
        - subnet-8afXX9ab
        - subnet-caeXX7ac
        - subnet-b09XXd81

(当然,你可以全部放入变量,或者参数!)

然后,在 Lambda 函数中,将策略添加到属性中,如下所示:

  BasicFunction:
    Type: AWS::Serverless::Function
    Properties:
      Policies:
      - AWSLambdaVPCAccessExecutionRole
      - AWSLambdaBasicExecutionRole

0
投票

这绝对是一个奇怪的错误,但是您确定您添加的示例代码是您在 lambda 中使用的代码吗?

因为在您的代码中,您试图在通过回调返回控制权后在 lambda 中记录一些内容。换句话说,首先你告诉你的 lambda 你已经完成了。接下来,当它忙于关闭并返回结果时,您尝试进行一些日志记录...

所以首先,我会尝试这个:

exports.handler = (event, context, callback) => {
    console.log('this is a test');
    // do stuff
    callback(null, 'Hello from Lambda'); // only do a callback *after* you've run all your code
};

看看是否能解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.