You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda无法连接Amazon EFS?求Pulumi配置下的解决方案

问题描述

我尝试通过Access Point和挂载目标将Amazon EFS文件系统连接到AWS Lambda函数,对应的Pulumi代码如下:

export const lamdaExecutionRole = new aws.iam.Role("lamda-execution-role", {assumeRolePolicy: `{
 
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow"
    }
  ]
}`,

name:'lamda-execution-role',
 managedPolicyArns: [ 
     lamdaPolicy.arn,
     fileSystemPolicy.arn,
     vpcPolicy.arn,
 ]
}
);

export const lambdaFileSystem = new aws.efs.FileSystem("lamda-file-sysytem", {tags: {
    Name: "efs_for_lambda",
}})

const vpc = new  awsx.ec2.Vpc("vpc");
 const subnetIds = vpc.publicSubnetIds;

const lamdaSecurityGroup = new aws.ec2.SecurityGroup("lamda-security-group", {
  vpcId: vpc.vpcId,
})

export const montTarget = new aws.efs.MountTarget("mount-target", {
        fileSystemId: lambdaFileSystem.id,
        subnetId: subnetIds[0],
        
     })

export  const lamdaAccessPoint = new aws.efs.AccessPoint("lamda-access-point-scor", {
    fileSystemId: lambdaFileSystem.id,
    rootDirectory: {
        path: "/",
        creationInfo: {
            ownerGid: 1000,
            ownerUid: 1000,
            permissions: "777",
        },
    },
    posixUser: {
        gid: 1000,
        uid: 1000,
    },
})

export const lamda = new aws.lambda.Function("aws-lamda-function", {
    code: new pulumi.asset.FileArchive("../app/build/libs/HelloWorldServerless-all.jar"),   
    runtime: aws.lambda.Runtime.Java11,
    handler: "HelloWorldServerless.HelloWorld::handler",
    role: lamdaExecutionRole.arn,
    name: "hello-world",
    memorySize: 300,
    timeout: 100,
    fileSystemConfig: {arn: lamdaAccessPoint.arn, localMountPath :"/mnt/efs"},
    vpcConfig: {
        subnetIds: [subnetIds[0]],
        securityGroupIds: [lamdaSecurityGroup.id],
    },
    
    layers: [ 'arn:aws:lambda:eu-north-1:464622532012:layer:dd-trace-java:8',
              "arn:aws:lambda:eu-north-1:464622532012:layer:Datadog-Extension:38"],    
    environment: {
        variables: {
            DD_API_KEY:"*******",
            DD_CAPTURE_LAMBDA_PAYLOAD: "false",
            DD_LAMBDA_HANDLER: "HelloWorldServerless.HelloWorld::handler",
            DD_LOG_LEVEL: "info",
            FUNCTION_NAME: "hello-world",
            DD_SERVICE: 'hello-world',
            DD_SITE: "datadoghq.eu",
            DD_VERSION: "0.1",
            DD_LOGS_INJECTION: 'true',
            DD_JMXFETCH_ENABLED: 'false',
            DD_TRACE_ENABLED: 'true',
            DD_ENV: 'dev',
            DD_MERGE_XRAY_TRACES: "false",
            DD_FLUSH_TO_LOG: "true"
        },
    },
},
{ dependsOn:montTarget} 
   )

运行以下测试代码时:

import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda"; // ES Modules import

it("should be Hello World ", async  () => { 
    
   const client = new LambdaClient({region:"eu-north-1"});
   const inputPayload = {"body": "{ \"message\": \"Hello from Lambda!\" }"}
   const command = new InvokeCommand({FunctionName:"hello-world" ,Payload:JSON.stringify(inputPayload)});
   const response = await client.send(command);
   expect(response.StatusCode).toBe(200)
   const payLoad = String.fromCharCode.apply(null, response.Payload)
   expect(payLoad).toBe("{\"isBase64Encoded\":false,\"statusCode\":200,\"body\":\"{\\\"message\\\":\\\"HELLO FROM LAMBDA!\\\"}\"}")
   
})

出现错误:EFSMountConnectivityException:函数无法连接ARN为arn:aws:elasticfilesystem:eu-north-1:888219289265:access-point/fsap-05aead28f4e33f496的Amazon EFS文件系统。请检查网络配置并重试。

修复方案

以下是需要调整的几个关键配置点:

1. 配置安全组入站规则,允许Lambda访问EFS

当前Lambda安全组没有任何入站/出站规则,EFS挂载目标也缺少允许NFS流量的安全组配置,这是连接失败的核心原因。

修改代码:

// Lambda安全组:添加出站规则允许NFS流量(端口2049)
const lamdaSecurityGroup = new aws.ec2.SecurityGroup("lamda-security-group", {
  vpcId: vpc.vpcId,
  egress: [
    {
      fromPort: 2049,
      toPort: 2049,
      protocol: "tcp",
      cidrBlocks: [vpc.vpcCidrBlock], // 限制到VPC内部,更安全
    },
    // 保留Lambda访问外部服务的出站规则(比如Datadog)
    {
      fromPort: 0,
      toPort: 0,
      protocol: "-1",
      cidrBlocks: ["0.0.0.0/0"],
    }
  ],
});

// EFS挂载目标专用安全组:允许来自Lambda安全组的NFS流量
const efsMountTargetSg = new aws.ec2.SecurityGroup("efs-mount-target-sg", {
  vpcId: vpc.vpcId,
  ingress: [
    {
      fromPort: 2049,
      toPort: 2049,
      protocol: "tcp",
      securityGroups: [lamdaSecurityGroup.id],
    },
  ],
  egress: [
    {
      fromPort: 0,
      toPort: 0,
      protocol: "-1",
      cidrBlocks: ["0.0.0.0/0"],
    },
  ],
});

// 更新挂载目标,关联EFS专用安全组
export const montTarget = new aws.efs.MountTarget("mount-target", {
  fileSystemId: lambdaFileSystem.id,
  subnetId: subnetIds[0],
  securityGroups: [efsMountTargetSg.id],
});

2. 使用私有子网而非公有子网

Lambda连接EFS时,推荐使用私有子网(公有子网依赖互联网网关,不符合EFS的安全访问最佳实践),修改子网获取逻辑:

// 替换publicSubnetIds为privateSubnetIds
const subnetIds = vpc.privateSubnetIds;

awsx创建的VPC默认会为私有子网配置NAT网关,不影响Lambda访问外部服务。

3. 验证EFS文件系统权限

确保fileSystemPolicy包含允许Lambda角色访问EFS的权限,示例策略如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "${lamdaExecutionRole.arn}"
      },
      "Action": [
        "elasticfilesystem:ClientMount",
        "elasticfilesystem:ClientWrite"
      ],
      "Resource": "${lambdaFileSystem.arn}/*"
    }
  ]
}

4. 完善资源依赖顺序

当前Lambda仅依赖挂载目标,建议同时依赖Access Point,确保所有EFS相关资源就绪后再创建Lambda:

export const lamda = new aws.lambda.Function("aws-lamda-function", {
  // ... 原有配置
}, { dependsOn: [montTarget, lamdaAccessPoint] });

5. 确认VPC DNS配置

检查VPC是否启用了DNS支持(awsx创建的VPC默认启用),否则Lambda无法解析EFS挂载目标的DNS名称。


内容的提问来源于stack exchange,提问作者stein korsveien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:02:15