Add tag while creating EBS snapshot using boto3

时光总嘲笑我的痴心妄想 提交于 2019-12-19 09:08:31

问题


Is it possible to add a tag when invoking the create_snapshot() method in boto3? When I run the following code:

client = boto3.client('ec2')

root_snap_resp = client.create_snapshot(
    Description='My snapshot description',
    VolumeId='vol-123456',
    Tags=[{'Key': 'Test_Key', 'Value': 'Test_Value'}]
)

I get the following error:

botocore.exceptions.ParamValidationError: Parameter validation failed:
Unknown parameter in input: "Tags", must be one of: DryRun, VolumeId, Description

Is the only way to add a tag after the fact using the create_tags() method?


回答1:


In April, 2018, the original answer (and the question itself) were made obsolete...

You can now specify tags for EBS snapshots as part of the API call that creates the resource or via the Amazon EC2 Console when creating an EBS snapshot.

https://aws.amazon.com/blogs/compute/tag-amazon-ebs-snapshots-on-creation-and-implement-stronger-security-policies/

...unless you are using an older version of an SDK that does not implement the feature.

The same announcement extended resource-level permissions to snapshots.

The underlying CreateSnapshot action in the EC2 API doesn't have any provision for adding tags simultaneously with the creation of the snapshot. You have to go back and tag it after creating it.




回答2:


Have a look at my backup script:

import boto3
import collections
import datetime

ec = boto3.client('ec2')

def lambda_handler(event, context):
    reservations = ec.describe_instances(
        Filters=[
            {'Name':'tag:Backup', 'Values':['Yes','yes']}
        ]
    ).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 = 30

        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,
            )

            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: %s" % (snapshot_name)

            ec.create_tags(
                Resources=[
                    snap['SnapshotId'],
                ],
                Tags=[
                    {'Key': 'Name', 'Value': snapshot_name},
                    {'Key': 'Description', 'Value': "Created by lambda automated backups"}
                ]
            )

    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}
            ]
        )

And this this my script to delete old backups that have "delete_on" tag with value of today in the YYYY-MM-DD format

import boto3
import re
import datetime

ec = boto3.client('ec2')
iam = boto3.client('iam')

"""
This function looks at *all* snapshots that have a "DeleteOn" tag containing
the current day formatted as YYYY-MM-DD. This function should be run at least
daily.
"""

def lambda_handler(event, context):
    account_ids = list()
    try:
        """
        You can replace this try/except by filling in `account_ids` yourself.
        Get your account ID with:
        > import boto3
        > iam = boto3.client('iam')
        > print iam.get_user()['User']['Arn'].split(':')[4]
        """
        iam.get_user()
    except Exception as e:
        # use the exception message to get the account ID the function executes under
        account_ids.append(re.search(r'(arn:aws:sts::)([0-9]+)', str(e)).groups()[1])


    delete_on = datetime.date.today().strftime('%Y-%m-%d')
    filters = [
        {'Name': 'tag-key', 'Values': ['DeleteOn']},
        {'Name': 'tag-value', 'Values': [delete_on]},
    ]
    snapshot_response = ec.describe_snapshots(OwnerIds=account_ids, Filters=filters)


    for snap in snapshot_response['Snapshots']:
        print "Deleting snapshot %s" % snap['SnapshotId']
        ec.delete_snapshot(SnapshotId=snap['SnapshotId'])



回答3:


ec2 = boto3.resource('ec2')
volume = ec2.Volume('vol-xxxxxxxxxx')
snapshot = ec2.create_snapshot(
    VolumeId=volume.id,
    TagSpecifications=[
        {
        'ResourceType': 'snapshot',
        'Tags' : volume.tags,
        },
    ],
    Description='Snapshot of volume ({})'.format(volume.id),
)

@fender4645 You can now specify tags for EBS snapshots as part of the API call that creates the resource.



来源:https://stackoverflow.com/questions/42659418/add-tag-while-creating-ebs-snapshot-using-boto3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!