Amazon web services 触发与EFS关联的Lambda函数时未下载S3文件
我正在使用无服务器框架创建一个Lambda函数,当S3上传触发时(将Amazon web services 触发与EFS关联的Lambda函数时未下载S3文件,amazon-web-services,amazon-s3,aws-lambda,serverless-framework,amazon-efs,Amazon Web Services,Amazon S3,Aws Lambda,Serverless Framework,Amazon Efs,我正在使用无服务器框架创建一个Lambda函数,当S3上传触发时(将test.vcf上传到S3://trigger test/uploads/),该函数将上传的文件从S3下载到EFS(特别是/mnt/EFS/vcfs/文件夹)。我对EFS非常陌生,并遵循AWS文档设置EFS访问点,但当我部署此应用程序并上载测试文件以触发Lambda函数时,它无法下载该文件,并在CloudWatch日志中出现以下错误: [ERROR] FileNotFoundError: [Errno 2] No such fi
test.vcf
上传到S3://trigger test/uploads/
),该函数将上传的文件从S3下载到EFS(特别是/mnt/EFS/vcfs/
文件夹)。我对EFS非常陌生,并遵循AWS文档设置EFS访问点,但当我部署此应用程序并上载测试文件以触发Lambda函数时,它无法下载该文件,并在CloudWatch日志中出现以下错误:
[ERROR] FileNotFoundError: [Errno 2] No such file or directory: '/mnt/efs/vcfs/test.vcf.A0bA45dC'
Traceback (most recent call last):
File "/var/task/handler.py", line 21, in download_files_to_efs
result = s3.download_file('trigger-test', key, efs_loci)
File "/var/runtime/boto3/s3/inject.py", line 170, in download_file
return transfer.download_file(
File "/var/runtime/boto3/s3/transfer.py", line 307, in download_file
future.result()
File "/var/runtime/s3transfer/futures.py", line 106, in result
return self._coordinator.result()
File "/var/runtime/s3transfer/futures.py", line 265, in result
raise self._exception
File "/var/runtime/s3transfer/tasks.py", line 126, in __call__
return self._execute_main(kwargs)
File "/var/runtime/s3transfer/tasks.py", line 150, in _execute_main
return_value = self._main(**kwargs)
File "/var/runtime/s3transfer/download.py", line 571, in _main
fileobj.seek(offset)
File "/var/runtime/s3transfer/utils.py", line 367, in seek
self._open_if_needed()
File "/var/runtime/s3transfer/utils.py", line 350, in _open_if_needed
self._fileobj = self._open_function(self._filename, self._mode)
File "/var/runtime/s3transfer/utils.py", line 261, in open
return open(filename, mode)
我的直觉是,这与Lambda函数中指定的本地装载路径有关,而与EFS访问点配置的详细信息部分中的根目录路径有关。最后,我希望上传到S3的test.vcf
文件下载到EFS文件夹:/mnt/EFS/vcfs/
相关文件:
serverless.yml:
service: LambdaEFS-trigger-test
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
stage: dev
region: us-west-2
vpc:
securityGroupIds:
- sg-XXXXXXXX
- sg-XXXXXXXX
- sg-XXXXXXXX
subnetIds:
- subnet-XXXXXXXXXX
functions:
cfnPipelineTrigger:
handler: handler.download_files_to_efs
description: Lambda to download S3 file to EFS folder.
events:
- s3:
bucket: trigger-test
event: s3:ObjectCreated:*
rules:
- prefix: uploads/
- suffix: .vcf
existing: true
fileSystemConfig:
localMountPath: /mnt/efs
arn: arn:aws:elasticfilesystem:us-west-2:XXXXXXXXXX:access-point/fsap-XXXXXXX
iamRoleStatements:
- Effect: Allow
Action:
- s3:ListBucket
Resource:
- arn:aws:s3:::trigger-test
- Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- arn:aws:s3:::trigger-test/uploads/*
- Effect: Allow
Action:
- elasticfilesystem:ClientMount
- elasticfilesystem:ClientWrite
- elasticfilesystem:ClientRootAccess
Resource:
- arn:aws:elasticfilesystem:us-west-2:XXXXXXXXXX:file-system/fs-XXXXXX
plugins:
- serverless-iam-roles-per-function
package:
individually: true
exclude:
- '**/*'
include:
- handler.py
handler.py:
import json
import boto3
s3 = boto3.client('s3', region_name = 'us-west-2')
def download_files_to_efs(event, context):
"""
Locates the S3 file name (i.e. S3 object "key" value) the initiated the Lambda call, then downloads the file
into the locally attached EFS drive at the target location.
:param: event | S3 event record
:return: dict
"""
print(event)
key = event.get('Records')[0].get('s3').get('object').get('key') # bucket: trigger-test, key: uploads/test.vcf
efs_loci = f"/mnt/efs/vcfs/{key.split('/')[-1]}" # '/mnt/efs/vcfs/test.vcf
print("key: %s, efs_loci: %s" % (key, efs_loci))
result = s3.download_file('trigger-test', key, efs_loci)
if result:
print('Download Success...')
else:
print('Download failed...')
return { 'status_code': 200 }
EFS接入点详细信息:
service: LambdaEFS-trigger-test
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
stage: dev
region: us-west-2
vpc:
securityGroupIds:
- sg-XXXXXXXX
- sg-XXXXXXXX
- sg-XXXXXXXX
subnetIds:
- subnet-XXXXXXXXXX
functions:
cfnPipelineTrigger:
handler: handler.download_files_to_efs
description: Lambda to download S3 file to EFS folder.
events:
- s3:
bucket: trigger-test
event: s3:ObjectCreated:*
rules:
- prefix: uploads/
- suffix: .vcf
existing: true
fileSystemConfig:
localMountPath: /mnt/efs
arn: arn:aws:elasticfilesystem:us-west-2:XXXXXXXXXX:access-point/fsap-XXXXXXX
iamRoleStatements:
- Effect: Allow
Action:
- s3:ListBucket
Resource:
- arn:aws:s3:::trigger-test
- Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- arn:aws:s3:::trigger-test/uploads/*
- Effect: Allow
Action:
- elasticfilesystem:ClientMount
- elasticfilesystem:ClientWrite
- elasticfilesystem:ClientRootAccess
Resource:
- arn:aws:elasticfilesystem:us-west-2:XXXXXXXXXX:file-system/fs-XXXXXX
plugins:
- serverless-iam-roles-per-function
package:
individually: true
exclude:
- '**/*'
include:
- handler.py
- 详细信息
根目录路径:
/vcfs
- POSIX
用户ID
:1000
组ID
:1000
- 根目录创建权限
所有者用户ID
:1000
所有者组ID
:1000
- 应用于根目录路径的POSIX权限
:777
您的本地路径是
localMountPath:/mnt/efs
。因此,在代码中,您应该只使用此路径(而不是/mnt/efs/vcfs
):
EFS文件系统中是否已经存在
vcfs
目录?您似乎不会在当前不存在的任何地方创建它。不,但我记得在AWS文档中读到,您在访问点中建立的EFS目录创建权限将允许创建当前不存在的目录。在SSHing到EFS挂载的EC2实例中并在/mnt/EFS/
中手动创建vcfs
目录后,我还尝试部署此应用程序,但仍然会遇到上述相同的错误。当我SSH到EFS挂载的EC2实例中时,我确实看到了/mnt/efs/vcfs/test.vcf
和您的更正。唯一奇怪的是handler.py
返回Download failed
,因此results
变量为空(即使下载成功)。。。