【问题标题】:Creating a snapshot including description via AWS Lambda通过 AWS Lambda 创建包含描述的快照
【发布时间】:2017-04-12 03:09:14
【问题描述】:

这是我通过 AWS Lambda 创建快照的代码。

import boto3
import collections
import datetime

ec = boto3.client('ec2')

def lambda_handler(event, context):
    reservations = ec.describe_instances(
        Filters=[
            {'Name': 'tag-key', 'Values': ['Backup', 'backup']},
        ]
    ).get(
        'Reservations', []
    )

    instances = sum(
        [
            [i for i in r['Instances']]
            for r in reservations
        ], [])

    print "Found %d instances that need backing up" % len(instances)

    to_tag = collections.defaultdict(list)

    for instance in instances:
        try:
            retention_days = [
                int(t.get('Value')) for t in instance['Tags']
                if t['Key'] == 'Retention'][0]
        except IndexError:
            retention_days = 14

        for volume in ec.volumes.filter(Filters=[
            {'Name': 'attachment.instance-id', 'Values': [instance.id]}
        ]):
            description = 'scheduled-%s.%s-%s' % (instance_name, volume.volume_id, datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))

            print 'description: %s' % (description)

        for dev in instance['BlockDeviceMappings']:
            if dev.get('Ebs', None) is None:
                continue
            vol_id = dev['Ebs']['VolumeId']
            print "Found EBS volume %s on instance %s" % (
            vol_id, instance['InstanceId'])

            snap = ec.create_snapshot(
                VolumeId=vol_id,
            )

            to_tag[retention_days].append(snap['SnapshotId'])

            print "Retaining snapshot %s of volume %s from instance %s for %d days" % (
                snap['SnapshotId'],
                vol_id,
                instance['InstanceId'],
                retention_days,
            )


    for retention_days in to_tag.keys():
        delete_date = datetime.date.today() +     datetime.timedelta(days=retention_days)
        delete_fmt = delete_date.strftime('%Y-%m-%d')
        print "Will delete %d snapshots on %s" % (len(to_tag[retention_days]), delete_fmt)
        ec.create_tags(
            Resources=to_tag[retention_days],
            Tags=[
                {'Key': 'DeleteOn', 'Value': delete_fmt},
            ]
        )

我收到以下回复:

'EC2' object has no attribute 'volumes': AttributeError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 34, in lambda_handler
    for volume in ec.volumes.filter(Filters=[
AttributeError: 'EC2' object has no attribute 'volumes'

我使用 ec = boto3.resource('ec2') 而不是 ec = boto3.client('ec2') em>,我得到了描述,但其他一些诸如 describe_instances 不起作用

那么,请告诉我 boto3.client('ec2')

volumes 的替代品是什么

【问题讨论】:

    标签: amazon-web-services amazon-ec2 aws-lambda boto3


    【解决方案1】:

    boto3.resource 是低级 boto3.client 的抽象,你正在混合两者。如果您使用的是client.describe_instances,请使用client.describe_volumes

    如果您想使用resource.volumes,请使用resource.instances。我更喜欢resource.instances,因为它强大的过滤器和抽象性。如果你使用资源,由于某种原因想要访问底层客户端,你可以使用meta获取低级客户端。

    ec2 = boto3.resource('ec2')
    client = ec2.meta.client
    

    避免处理预订等,使用resource.instances。如果你用谷歌搜索的话,有很多例子。代码行数少,可读性强。

    【讨论】:

    • 感谢您的宝贵建议。我现在要做的就是为快照添加描述。你能告诉我如何在不更改代码的情况下添加它。
    【解决方案2】:

    我遇到了同样的问题,但在我的情况下,我需要将所有标签从 EC2 实例复制到快照,看看我的代码它可能会帮助你或至少指导你:

    https://github.com/christianhxc/aws-lambda-automated-snapshots/blob/master/src/schedule-ebs-snapshot-backups.py

    这样做,您只需要确保实例具有“名称”标签,以便可以将其复制到快照中,因为 CostCenter 标签,我也需要这个

    【讨论】:

      【解决方案3】:

      我发现这些家伙的解决方案是迄今为止最好的:

      https://blog.powerupcloud.com/2016/02/15/automate-ebs-snapshots-using-lambda-function/

      在他们的代码库中有一些描述被添加到快照中的例子。

      【讨论】:

      • 这满足了我的要求。谢谢
      • 此链接已失效
      【解决方案4】:

      我发现在线解决方案https://serverlesscode.com/post/lambda-schedule-ebs-snapshot-backups/ 不符合我的需求,因此我编写了以下备份脚本。这仍然是我的初稿,但我发现它更容易阅读并且对我来说也是一个更好的实现,因为我不是针对实例,而是针对卷。标记也得到了改进。

      import boto3
      import collections
      import datetime
      import os
      
      ec = boto3.client('ec2')
      ec2 = boto3.resource('ec2')
      TAG = os.environ['TAG']
      
      def lambda_handler(event, context):
          volumes = ec.describe_volumes(
              Filters=[
                  {'Name': 'tag-key', 'Values': [ "Backup", TAG ]},
                  {'Name': 'status', 'Values': [ "in-use" ] },
              ]
          ).get(
              'Volumes', []
          )
      
          print "Found {0} volumes that need backing up".format(len(volumes))
      
          for v in volumes:
            vol_id = v['VolumeId']
            print(vol_id)
            vol_name = None
            snap = None
            vol_tags = v.get('Tags', None)
      
            try:
                retention_days = [
                    int(t.get('Value')) for t in vol_tags
                    if t['Key'] == 'Retention'][0]
            except IndexError:
                retention_days = 7
      
            delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
            delete_fmt = delete_date.strftime('%Y-%m-%d')
            print "Will delete volume: {0} on {1}".format(vol_id, delete_fmt)
      
            if vol_tags is not None:
              for tag in vol_tags:
                try:
                  if tag['Key'] == 'Name':
                    vol_name = tag.get('Value')
      
                    print(vol_name)
                    snap = ec.create_snapshot(
                        VolumeId=vol_id,
                    )
      
                    ec2.Snapshot(id=snap['SnapshotId']).create_tags(
                        Tags=[
                            {'Key': 'DeleteOn', 'Value': delete_fmt},
                            {'Key': 'Name', 'Value': vol_name},
                        ]
                    )
      
                    break
                except:
                  print "No Tag key 'Name' found."
      
              print "Retaining snapshot %s of volume %s aka %s for %d days" % (
                  snap['SnapshotId'],
                  vol_id,
                  vol_name,
                  retention_days,
              )
      

      【讨论】:

        【解决方案5】:

        只需复制函数并在代码中找到描述,并将其替换为您自定义的单引号描述。

        希望对你有帮助!

        #Tag to folllow
        #Retention    number of days here
        #backup
        #backup-monthly
        
        import boto3
        import collections
        import datetime
        
        ec = boto3.client('ec2')
        
        def lambda_handler(event, context):
            reservations = ec.describe_instances(
                Filters=[
                    {'Name': 'tag-key', 'Values': ['backup', 'Backup']},
                    # Uncomment this line if need to take snaphsot of running instances only
                    # {'Name': 'instance-state-name', 'Values': ['running']},
                ]
            ).get(
                'Reservations', []
            )
        
            instances = sum(
                [
                    [i for i in r['Instances']]
                    for r in reservations
                ], [])
        
            print "Found %d instances that need backing up" % len(instances)
        
            to_tag = collections.defaultdict(list)
        
            for instance in instances:
                try:
                    retention_days = [
                        int(t.get('Value')) for t in instance['Tags']
                        if t['Key'] == 'Retention'][0]
                except IndexError:
                    retention_days = 7
        
                for dev in instance['BlockDeviceMappings']:
                    if dev.get('Ebs', None) is None:
                        continue
                    vol_id = dev['Ebs']['VolumeId']
                    print "Found EBS volume %s on instance %s" % (
                        vol_id, instance['InstanceId'])
        
                    instance_id = instance['InstanceId']
        
                    snapshot_name = 'N/A'
                    if 'Tags' in instance:
                        for tags in instance['Tags']:
                            if tags["Key"] == 'Name':
                                snapshot_name = tags["Value"]
        
                    print "Tagging snapshot with Name: {} and Instance ID {}".format(snapshot_name, instance_id)
        
                    snap = ec.create_snapshot(
                        Description = 'Description goes here',
                        VolumeId = vol_id,
                        TagSpecifications = [{
                            'ResourceType': 'snapshot',
                            'Tags': [{
                                'Key': 'Name',
                                'Value': snapshot_name
                            }, ]
                        }, ]
                        # DryRun = False
                        )
        
                    to_tag[retention_days].append(snap['SnapshotId'])
        
                    print "Retaining snapshot %s of volume %s from instance %s for %d days" % (
                        snap['SnapshotId'],
                        vol_id,
                        instance['InstanceId'],
                        retention_days,
                    )
        
        
            for retention_days in to_tag.keys():
                delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
                delete_fmt = delete_date.strftime('%Y-%m-%d')
                print "Will delete %d snapshots on %s" % (len(to_tag[retention_days]), delete_fmt)
                ec.create_tags(
                    Resources=to_tag[retention_days],
                    Tags=[
                        {'Key': 'DeleteOn', 'Value': delete_fmt},
                    ]
                )
        

        【讨论】:

          猜你喜欢
          • 2017-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-08
          相关资源
          最近更新 更多