Python Lambda函数写入csv并上传到S3

Python Lambda函数写入csv并上传到S3,python,amazon-web-services,csv,amazon-s3,aws-lambda,Python,Amazon Web Services,Csv,Amazon S3,Aws Lambda,我有一个Python脚本,可以获取未使用的安全组的详细信息。 我想把它写入CSV文件并上传到S3 Bucket 当我在本地机器上测试它时,它会在本地机器上写入CSV。但当我将其作为lambda函数执行时,它需要一个地方来保存CSV。所以我使用s3 import boto3 import csv ses = boto3.client('ses') def lambda_handler(event, context): with open('https://unused******-

我有一个Python脚本,可以获取未使用的安全组的详细信息。 我想把它写入CSV文件并上传到S3 Bucket

当我在本地机器上测试它时,它会在本地机器上写入CSV。但当我将其作为lambda函数执行时,它需要一个地方来保存CSV。所以我使用s3

import boto3
import csv

ses = boto3.client('ses')

def lambda_handler(event, context):
    with open('https://unused******- 
    1.amazonaws.com/Unused.csv', 'w') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow([
            'Account Name',
            'Region',
            'Id'
        ])
        ec2 = boto3.resource('ec2')
        sgs = list(ec2.security_groups.all())
        insts = list(ec2.instances.all())

        all_sgs = set([sg.group_id for sg in sgs])
        all_inst_sgs = set([sg['GroupId'] for inst in insts for sg in
        inst.security_groups])

        unused_sgs = all_sgs - all_inst_sgs


        for elem in unused_sgs:
            writer.writerow([
                Account_Name,
                region,
                elem
                ])
我想将“elem”的结果写入csv文件并上传到S3 Bucket。
敬请告知。

如果CSV文件较小,请将其写入/tmp文件夹,然后将该文件上载到S3。如果它很大(比如说,大于~200MB),那么您可能应该将其流式传输到S3

通过使用
StringIO()
,您不需要将csv保存到本地,只需将IO上载到S3即可。请尝试我的代码,如果有什么问题,请告诉我,因为我无法测试代码,但它适用于其他情况

import boto3
import csv
import io

s3 = boto3.client('s3')
ses = boto3.client('ses')

def lambda_handler(event, context):
    csvio = io.StringIO()
    writer = csv.writer(csvio)
    writer.writerow([
        'Account Name',
        'Region',
        'Id'
    ])

    ec2 = boto3.resource('ec2')
    sgs = list(ec2.security_groups.all())
    insts = list(ec2.instances.all())

    all_sgs = set([sg.group_id for sg in sgs])
    all_inst_sgs = set([sg['GroupId'] for inst in insts for sg in
    inst.security_groups])

    unused_sgs = all_sgs - all_inst_sgs

    for elem in unused_sgs:
        writer.writerow([
            Account_Name,
            region,
            elem
            ])

    s3.put_object(Body=csvio.getvalue(), ContentType='application/vnd.ms-excel', Bucket='bucket', Key='name_of.csv') 
    csvio.close()

如果您的csv文件很小,请遵循jarmod的建议,否则您可以使用lambda启动一个临时ec2实例(您可以选择xlarge size以获得更好的性能),其中包含用户_数据。用户数据将在一个强大且健康的ec2上执行所有csv进程,但记住在进程完成后终止实例(终止命令也可以包含在用户数据中)。

从多个帐户生成库存,并使用Lambda函数将其推送到s3存储桶

创建SSM参数存储,使IAM承担帐户的角色

姓名:“rolearnlist”

键入:“StringList”

值:“arn:

创建一个Lambda函数,如下所示

import boto3
import json
import datetime
import csv

lambda_client = boto3.client('lambda')
ssm_client = boto3.client('ssm')
s3_client = boto3.resource("s3")
sts_client = boto3.client('sts')

def lambda_handler(event, context):

time = datetime.datetime.now().strftime ('%Y-%m-%d-%H-%M-%S')
bucket = s3_client.Bucket('expo2020-core-master-me-south-1-agent-bucket')
file_name = ('backup_job_weekly_report_' + time + '.csv')
s3_path = 'Inventory/Weekly/' + file_name

fieldnames = ['Account Id','Backup Job Id', 'Backup State', 'Resource Arn', 'Resource Type', 'Start By','Creation Date']

rolearnlist = []
rolearnlist_from_ssm = ssm_client.get_parameter(Name='rolearnlist')
rolearnlist_from_ssm_list = rolearnlist_from_ssm['Parameter']['Value'].split(",")
rolearnlist = rolearnlist_from_ssm_list

with open('/tmp/file_name', 'w', newline='') as csvFile:
    w = csv.writer(csvFile, dialect='excel')
    w.writerow(fieldnames)

    for rolearn in rolearnlist:
        awsaccount = sts_client.assume_role(
            RoleArn=rolearn,    
            RoleSessionName='awsaccount_session'
        )

        ACCESS_KEY = awsaccount['Credentials']['AccessKeyId']
        SECRET_KEY = awsaccount['Credentials']['SecretAccessKey']
        SESSION_TOKEN = awsaccount['Credentials']['SessionToken']

        backup = boto3.client('backup', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, aws_session_token=SESSION_TOKEN)
        response = backup.list_backup_jobs()

        for i in response['BackupJobs']:
            AccountId = i.get('AccountId')
            BackupJobId = i.get('BackupJobId')
            BackupState = i.get('State')
            ResourceArn = i.get('ResourceArn')
            ResourceType = i.get('ResourceType')
            StartBy = i.get('StartBy')
            CreationDate = i.get('CreationDate')

            raw =   [
                    AccountId,
                    BackupJobId,
                    BackupState,
                    ResourceArn,
                    ResourceType,
                    StartBy,
                    CreationDate,
                    ]

            w.writerow(raw)
            raw = []
csvFile.close()

bucket.upload_file('/tmp/file_name', s3_path)

/tmp/
目录提供512MB的存储空间。请确保在函数结束时删除文件,因为容器可能会再次用于后续调用。@jarmod谢谢您的回答。。文件大小仅以KB为单位。谢谢@Lamanus。得到一个错误。应为unicode参数,获得“str”:TypeError回溯(上次调用):lambda_处理程序“Id”中的文件“/var/task/lambda_function.py”,第13行TypeError:应为unicode参数,获取'str'结束请求ID:b56f2c6f-4c56-4793-a828-bbefd9cf017b报告请求ID:b56f2c6f-4c56-4793-a828-bbefd9cf017b持续时间:0.64毫秒计费持续时间:100毫秒内存大小:128 MB最大使用内存:65 MB请调试代码并让我知道哪行出现错误。顺便说一句,我为s3客户机定义添加了一行5,这是以前缺少的。我做了一些修复,现在可以正常工作了。。是的,我已经定义了s3。。StringIO()应为字节(IO)。它现在很酷。我还必须将此文件(csv)附加到电子邮件并通过ses发送。请帮助我如何阅读此文件并附上。我认为最好上传一个新问题。我不擅长ses和原始电子邮件。检查。使用ec2处理繁重的工作负载比依赖lambda提供更好的性能,lambda具有内存、CPU和存储限制。文件大小非常小。那样的话,我想兰姆达应该没问题。