asm*_*dkj 3 amazon-s3 amazon-web-services boto3 aws-lambda amazon-efs
我将 Lambda 连接到 EFS,我想使用 Lambda 将小文件从 S3 下载到 EFS。
我将 Lambda 函数连接到文件系统,并添加了权限为 777 的访问点。
我在 Lambda 中有这个小的 python 函数可以下载到挂载:
import json
import boto3
import time
import os
s3 = boto3.client('s3')
def lambda_handler(event, context):
s3.download_file('my_bucket', 'img.jpg', '/mnt/my-efs/img.jpg')
return{
"statusCode": 200
}
Run Code Online (Sandbox Code Playgroud)
我在 1 分钟后超时(这应该不到一秒钟)。
如果我为 下载/tmp/img.jpg,这有效。即使我将文件从复制/tmp/到/mnt/my-efs/该工程。
我为 Lambda 用户提供了这个 IAM:
AmazonEC2FullAccess
AmazonS3FullAccess
AmazonVPCFullAccess
AWSLambdaVPCAccessExecutionRole
AmazonElasticFileSysstemClientReadWriteAccess
AmazonElasticFileSysstemClientFullAccess
Run Code Online (Sandbox Code Playgroud)
为什么我不能使用 Lambda 从 S3 下载文件到 EFS?
这是一个很大的棘手问题,所以让我们慢慢来,确保我们涵盖了所有的运动部件。如果其中一些是多余的,我深表歉意,但我想确保外行人拥有所有正确的部分。如果您认为我遗漏了什么,请告诉我。
设置:
serverless.yaml1.serverless.yaml
我使用的是无服务器,所以这就是我的serverless.yaml文件的样子。
iamRoleStatements:
- Effect: Allow
Action:
- elasticfilesystem:ClientMount
- elasticfilesystem:ClientWrite
- elasticfilesystem:ClientRootAccess
Resource:
- arn:aws:elasticfilesystem:us-west-2:123456789:file-system/fs-123456789
Run Code Online (Sandbox Code Playgroud)
这些是我将文件从 S3 下载到 EFS 驱动器位置所需的最低权限。同样,该项目使用无服务器,因此如果您不使用无服务器,所有这些都可以转换为 cloudFormation 模板。
在处理程序函数下......
functions:
myFunc:
handler: handler.handle
package:
exclude:
- env/**
- node_modules/**
description: Lambda to download S3 file to SFTP EFS folder.
events:
- s3:
bucket: some-bucket
event: s3:ObjectCreated:*
rules:
- prefix: some-folder/
- suffix: .jpg
existing: true
fileSystemConfig:
localMountPath: /mnt/my-efs
arn: arn:aws:elasticfilesystem:us-west-2:123456789:access-point/fsap-12345678910
Run Code Online (Sandbox Code Playgroud)
注意:我从我的serverless.yaml文件中遗漏了很多,只包含了与 EFS 设置有关的部分。
2. AWS EFS 接入点设置
File System: 选择一个下拉选项Name - optional 取一个名字Root directory path - optional:这将映射到 EC2 或 SFTP 服务器上的底层文件系统。我使用的是 sftp 服务器,所以我只需在 sftp 服务器上输入地址。sftp.companyX.com/images. 此位置将映射到Local Mount PathEFS 配置窗口中您的 Lambda 设置中的设置(我们将在步骤 3 中详细介绍)。User ID: 1054| 找到您的/etc/passwd/文件并验证这是否适用于托管 EFS 驱动器的服务器。我认为这1054是amazon linux的默认设置,但如果您在 EFS 主机上运行不同的操作系统,则应验证此值。Group ID: 1054 (见最后一行)Owner User ID: 1054 (见最后一行)Owner Group ID: 1054 (见最后一行)POSIX permissions to apply to the root directory path:777| 了解这些权限会转化为您的iamRoleStatements.Action价值观;如果它们不同,777则应适当设置。3. EFS 的 Lambdas 添加
EFS File System: (从下拉选择中选择)Local Mount Path: | 超级重要,例如/mnt/my-efs。这部分是非常不直观的 IMO。无论您想要什么位置,此位置都将映射到Root directory path您在构建接入点时配置的(上面的步骤 2.4)。意思是,如果您下载一个调用它的 s3 文件img.jpg,/mnt/my-efs/.它将将该文件放入sftp.company.com/images/img.jpg.4. 将项目下载到 EFS 驱动器
def download_files_to_efs(self, event):
"""
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
"""
key = event.get('Records')[0].get('s3').get('object').get('key') # some-bucket/some-folder/img.jpg
efs_loci = f"/mnt/my-efs/images/{key.split('/')[-1]}" # '/mnt/my-efs/images/img.jpg
result = self.s3.download('some-bucket', key, efs_loci)
if result:
print('Download Success...')
else:
print('Ask Stack Overflow :/')
return { 'status_code': 200 }
Run Code Online (Sandbox Code Playgroud)
5. 验证您的文件是否在 EFS 中
def get_files_from_path(file_path):
"""
Returns the files found at the file_path
:param file_path: string
:return list:
"""
# NOTE: file_path = '/my-efs/
found_files = []
for _, _, f in os.walk(file_path):
found_files.append(f)
if found_files:
print('efs files: ', found_files)
return found_files
Run Code Online (Sandbox Code Playgroud)
这里要特别注意!请注意,我没有从/mnt/my-efs/i read from 中读取/my-efs,这是因为 EFS/目录映射到/mntLambda 环境中的目录。
完成的
注意:如果我遗漏了某些内容,请随时发表评论,如果可以,我也会添加。不幸的是,我无法共享 repo,因为它是一个与工作相关的项目(受保护)。
| 归档时间: |
|
| 查看次数: |
1912 次 |
| 最近记录: |