假设每当用户上传文件到 S3 存储桶时,您希望将这些文件以某种方式移动和整理,也就是说,如果用户上传了 .js
文件,我就把它放到 /javascript
文件夹里;如果是 .txt
文件,则放到 txt
文件夹里,依此类推。
这是你想构建的用例吗?如果是的话,这篇文章应该很适合你。好的,不多说,我们直接从示例开始吧。
本文的主要部分:
1- Terraform架构概览
2- 关于AWS服务的介绍
3- 技术部分(Go代码)
4- 结果展示
5- 总结
在我们的架构里,我们需要确保我们的Lambda函数有读取和转移S3存储桶内对象的正确访问权限。
📋 注意: 如果你想了解如何在新文件上传到 S3 存储桶时触发 Lambda 函数,可以点击这里阅读文章:点击这里阅读文章
您的 Lambda 函数需要如下 IAM 权限才能顺利完成任务。
{ Version = "2012-10-17", Statement = [ { Effect = "允许", Action = [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], Resource = "${aws_s3_bucket.image_bucket.arn}/*" } ] }
全屏 / 退出全屏
这是我们用来部署我们函数的Terraform Lambda资源部分,以便部署我们的函数。
resource "aws_lambda_function" "file_organizer_lambda" { filename = "./bootstrap.zip" function_name = "lets-build-function" handler = "main" runtime = "provided.al2" role = aws_iam_role.lambda_execution_role.arn memory_size = "128" timeout = "3" source_code_hash = filebase64sha256("./bootstrap.zip") environment { variables = { REGION = "${var.region}" } } }
进入全屏 退出全屏
关于 AWS 的服务好的,在我们编写酷炫的代码前,先在脑子里构思一下这个想法。
每当用户上传新文件时,我们需要触发一个Lambda函数来执行,该函数会检查文件的扩展名,并将文件根据其扩展名复制到特定文件夹中,通过使用AWS SDK。
下面是一个简单的流程图,帮助你更好地理解我们的功能。
package main import ( "context" "fmt" "path/filepath" "strings" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) var ( svc = s3.New(session.Must(session.NewSession())) bucket = "YOUR_BUCKET_NAME" ) func generateTargetKey(record map[string]interface{}) (string, string, string) { s3Info := record["s3"].(map[string]interface{}) bucketName := s3Info["bucket"].(map[string]interface{})["name"].(string) objectKey := s3Info["object"].(map[string]interface{})["key"].(string) ext := strings.ToLower(filepath.Ext(objectKey)) var folder string switch ext { case ".js": folder = "javascript/" case ".txt": folder = "txt/" default: folder = "others/" } targetKey := folder + filepath.Base(objectKey) return bucketName, objectKey, targetKey } func handler(ctx context.Context, event map[string]interface{}) (string, error) { records := event["Records"].([]interface{}) for _, record := range records { bucketName, objectKey, targetKey := generateTargetKey(record.(map[string]interface{})) if objectKey == targetKey { fmt.Printf("跳过复制 %s,因为它已经在正确的文件夹里了。\n", objectKey) continue } _, err := svc.CopyObject(&s3.CopyObjectInput{ Bucket: aws.String(bucketName), CopySource: aws.String(bucketName + "/" + objectKey), Key: aws.String(targetKey), }) if err != nil { return "", fmt.Errorf("未能复制对象: %v", err) } _, err = svc.DeleteObject(&s3.DeleteObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { return "", fmt.Errorf("未能删除原始对象: %v", err) } fmt.Printf("文件 %s 已移动到 %s\n", objectKey, targetKey) } return "文件处理成功完成", nil } func main() { lambda.Start(handler) }
全屏模式 退出全屏
确保通过运行以下命令保存参数:set GOARCH=arm64
& set GOOS=linux
,并且可以使用 echo %GOARCH%
来确认设置是否成功。
然后运行以下 cmd:
使用Go语言编译main.go
文件生成一个名为bootstrap
的可执行文件:
go build -o bootstrap main.go
全屏 退出全屏
对于使用provided.al2或provided.al2023运行时的Go函数,包含您函数代码的可执行文件必须命名为bootstrap文件。如果您用.zip文件部署函数,在.zip部署包里,bootstrap文件必须放在.zip文件的根目录下。
结果是...就这样。我们上传几个文件到我们的S3存储桶里,看看它们是否如我们所愿地组织好了。
上传之后可以看到文件被移动到了正确的文件夹里。
这是一张带有图片描述的图片链接。
结束语你可以利用这种自动化为你的日常任务创造很多有趣且有用的应用等等。希望这对你是有帮助的。
编程愉快。
如果您还想看到更多这里的内容,请在我的LinkedIn上与我联系。