【问题标题】:Bad handler error when running AWS Lambda with console使用控制台运行 AWS Lambda 时出现错误的处理程序错误
【发布时间】:2021-08-10 14:17:24
【问题描述】:

我尝试使用 AWS Lambda 进行 Amazon S3 存储桶资源标记。我需要 Lambda 函数从用户那里获取标签并将它们应用于 Amazon S3 存储桶中新上传的对象。

我认为处理程序中的 get_user_tags 是错误的部分

def lambda_handler(event, context):

#Get uncompressed CloudWatch Event data for parsing API calls
def get_unc_cw_event_data(event):
    cw_data_dict = dict()
    cw_data_dict = event['detail']
    return cw_data_dict

#Get resource tags assigned to a specified IAM role 
#Returns a list of key:string,value:string resource tag dictionaries
def get_user_tags(user_name):
    try:
        client = boto3.client('iam')
        response = dict()
        response = client.list_user_tags(
            UserName=user_name
        )
    except botocore.exceptions.ClientError as error:
        print("Boto3 API returned error: ", error)
        print("No Tags Applied To: ", resource_id)
        no_tags = list()
        return no_tags
    return response['Tags']

#Get resource tags stored in AWS SSM Parameter Store 
#Returns a list of key:string,value:string resource tag dictionaries
def get_ssm_parameter_tags(role_name, user_name):
    tag_list = list()
    try:
        path_string = "/auto-tag/" + role_name + "/" + user_name + "/tag"
        ssm_client = boto3.client('ssm')
        get_parameter_response = ssm_client.get_parameters_by_path(
        Path=path_string,
        Recursive=True,
        WithDecryption=True
        )
        for parameter in get_parameter_response['Parameters']:
            tag_dictionary = dict()
            path_components = parameter['Name'].split("/")
            tag_key = path_components[-1]
            tag_dictionary['Key'] = tag_key
            tag_dictionary['Value'] = parameter['Value']
            tag_list.append(tag_dictionary)
        return tag_list

    except botocore.exceptions.ClientError as error:
        print("Boto3 API returned error: ", error)
        tag_list.clear()
        return tag_list

#Apply tags to resource
def set_resource_tags(resource_id, resource_tags):
    # Is this an EC2 resource?
    if re.search("^i-", resource_id):
        try:
            client = boto3.client('ec2')
            response = client.create_tags(
                Resources=[
                    resource_id
                ],
                Tags=resource_tags
            )
            response = client.describe_volumes(
                Filters=[
                    {
                        'Name': 'attachment.instance-id',
                        'Values': [
                            resource_id
                        ]
                    }
                ]
            )
            try:
                for volume in response['Volumes']:
                    ec2 = boto3.resource('ec2')
                    ec2_vol = ec2.Volume(volume['VolumeId'])
                    vol_tags = ec2_vol.create_tags(
                    Tags=resource_tags
                    )
            except botocore.exceptions.ClientError as error:
                print("Boto3 API returned error: ", error)
                print("No Tags Applied To: ", response['Volumes'])
                return False
        except botocore.exceptions.ClientError as error:
            print("Boto3 API returned error: ", error)
            print("No Tags Applied To: ", resource_id)
            return False
        return True
    else:
        return False

data_dict = get_unc_cw_event_data(event)
#data_dict = get_cw_event_data(event)
user_id_arn = data_dict['userIdentity']['arn']
user_id_components = user_id_arn.split("/")
user_id = user_id_components[-1]
#role_arn = data_dict['userIdentity']['sessionContext']['sessionIssuer']['arn']
role_arn = data_dict['userIdentity']['arn']
role_components = role_arn.split("/")
role_name = role_components[-1]
resource_date = data_dict['eventTime']

resource_role_tags = list()
resource_role_tags = get_role_tags(role_name)

resource_parameter_tags = list()
resource_parameter_tags = get_ssm_parameter_tags(role_name, user_id)

resource_tags = list()
resource_tags = resource_role_tags + resource_parameter_tags

created_by = dict()
created_by['Key'] = 'Created by'
created_by['Value'] = user_id
resource_tags.append(created_by)

roleName = dict()
roleName['Key'] = 'Role Name'
roleName['Value'] = role_name
resource_tags.append(roleName)

date_created = dict()
date_created['Key'] = 'Date created'
date_created['Value'] = resource_date
resource_tags.append(date_created)

if 'instancesSet' in data_dict['responseElements']:
    for item in data_dict['responseElements']['instancesSet']['items']:
        resource_id = item['instanceId']
        if set_resource_tags(resource_id, resource_tags):    
            return {
                'statusCode': 200,
                'Resource ID': resource_id,
                'body': json.dumps(resource_tags)
            }
        else:
            return {
                'statusCode': 500,
                'No tags applied to Resource ID': resource_id,
                'Lambda function name': context.function_name,
                'Lambda function version': context.function_version
            }
else:
    return {
        'statusCode': 200,
        'No resources to tag': event['id']
    }

由此产生的错误是这样的:

Response { "errorMessage": "错误处理程序 'resource-auto-tagger-main/source/resource-auto-tagger': 不够 要解包的值(预期为 2,得到 1)”、“errorType”: "Runtime.MalformedHandlerName", "stackTrace": []

我运行了我的第一个 AWS Lambda,因此会很高兴得到任何帮助。

【问题讨论】:

标签: amazon-web-services amazon-s3 aws-lambda python-3.8 tagging


【解决方案1】:

您当然可以使用 AWS Lambda 函数来标记位于 Amazon S3 存储桶中的对象。有一篇开发文章展示了这个用例。它是用Java实现的;但是,它将为您指明正确的方向,并且您可以移植到您的编程语言。

Creating an Amazon Web Services Lambda function that tags digital assets located in Amazon S3 buckets

在此示例中,Lambda 函数读取给定 Amazon S3 存储桶中的所有对象。对于存储桶中的每个对象,它会将图像传递给 Amazon Rekognition 服务以生成一系列标签。每个标签用于创建应用于图像的标签。执行 Lambda 函数后,它会根据给定 Amazon S3 存储桶中的所有图像自动创建标签并将其应用于图像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2013-08-11
    • 2016-12-28
    • 2014-11-16
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多