问题
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