繁体   English   中英

AWS Lambda 尝试将文件从 S3 存储桶复制到另一个 S3 存储桶时出现无效存储桶名称错误

[英]Invalid bucket name error when AWS Lambda tries to copy files from an S3 bucket to another S3 bucket

我是 python 的新手。我有一个事件触发了 AWS Lambda function,它将文件从 S3 存储桶复制到另一个 S3 存储桶。 我要复制文件的目标 S3 路径是:“dest_bucket/folder1/test”。 当我尝试运行它时它给了我这个错误:

存储桶名称“dest_bucket/folder1/test”无效:存储桶名称必须与正则表达式“^[a-zA-Z0-9.-_]{1,255}$”匹配,或者是与正则表达式“^arn:(aws)”匹配的 ARN . :(s3|s3-object-lambda):[az-0-9] :[0-9]{12}:accesspoint[/:][a-zA-Z0-9-.]{1,63} $|^arn:(aws).*:s3-outposts:[az-0-9]+:[0-9]{12}:outpost[/:][a-zA-Z0-9-]{1 ,63}[/:]接入点[/:][a-zA-Z0-9-]{1,63}$"

源存储桶没有任何文件夹结构。 目标存储桶具有文件夹结构,需要将文件复制到“dest_bucket/folder1/test”下。 错误发生在 lambda function 中:“destination_bucket_name = 'dest_bucket/folder1/test”。 因为,如果我简单地写下不带斜杠的目标存储桶名称,它会起作用吗? 知道我应该怎么写这个吗?

import json
import boto3
import os
import uuid

def lambda_handler(event, context):
    try:
        client = boto3.client('sts')
        response = client.assume_role(RoleArn='arn:aws:iam::xxx:role/xxx_lambda_role',RoleSessionName="lambda")
        session = boto3.Session(aws_access_key_id=response['Credentials']['AccessKeyId'],aws_secret_access_key=response['Credentials']['SecretAccessKey'],aws_session_token=response['Credentials']['SessionToken'])
        print(session)
        print("role has been assumed")
        
        s3_client = boto3.client("s3", aws_access_key_id=response['Credentials']['AccessKeyId'],aws_secret_access_key=response['Credentials']['SecretAccessKey'],aws_session_token=response['Credentials']['SessionToken'])
        #s3_client = boto3.client("s3")
        
        #base = read from parameter store
        #table_partion = read from file
        destination_bucket_name = 'dest_bucket/folder1/test'

        # event contains all information about uploaded object
        print("Event :", event)

        # Source bucket
        source_bucket_name = event['Records'][0]['s3']['bucket']['name']
        print(source_bucket_name)

        # Filename of object (with path)
        file_key_name = event['Records'][0]['s3']['object']['key']
        #file_key_name = 'empty_test.txt'
        print(file_key_name)

        # Copy Source Object
        copy_source_object = {'Bucket': source_bucket_name, 'Key': file_key_name}
        print(copy_source_object)

        # S3 copy object operation
        s3_client.copy_object(CopySource=copy_source_object, Bucket=destination_bucket_name, Key=file_key_name)


        return {
            'statusCode': 200,
            'body': json.dumps('S3 events Lambda!')
        }

    except Exception as e:
        print(e)
        raise e

从文档:

存储桶名称的长度可以介于 3 到 63 个字符之间,并且只能包含小写字符、数字、句点和破折号。

存储桶名称中的每个 label 必须以小写字母或数字开头。

存储桶名称不能包含下划线、以破折号结尾、有连续的句点或在句号旁边使用破折号。

存储桶名称不能格式化为 IP 地址 (198.51.100.24)。

https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html

确保您只使用存储桶名称作为存储桶名称:) 至于“路径”,它在 S3 中真的是一个假的东西——唯一真实的东西是 object 密钥。 斜杠只是该名称中的字符,它们没有特殊含义。

您可以使用:

destination_bucket = 'dest_bucket'
destination_path = 'folder1/test/'

for record in event['Records']:
    source_bucket = record['s3']['bucket']['name']
    source_key = record['s3']['object']['key']

    copy_source_object = {'Bucket': source_bucket, 'Key': source_key}

    destination_key = destination_path + source_key
    s3_client.copy_object(CopySource=copy_source_object, Bucket=destination_bucket, Key=destination_key)

这将遍历事件中的所有传入记录。

然后它将创建一个 object,名称为folder1/test/ + 源 object 的名称(Key)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM