【问题标题】:Add tag while creating EBS snapshot using boto3使用 boto3 创建 EBS 快照时添加标签
【发布时间】:2017-07-28 07:37:20
【问题描述】:

在boto3中调用create_snapshot()方法时可以加标签吗?当我运行以下代码时:

client = boto3.client('ec2')

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

我收到以下错误:

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

在事后使用 create_tags() 方法添加标签是唯一的方法吗?

【问题讨论】:

  • 是的。 create_tags 是为 EC2 资源添加标签的唯一方法。

标签: amazon-ec2 boto3


【解决方案1】:

2018 年 4 月,原始答案(以及问题本身)已过时...

您现在可以在创建资源的 API 调用中指定 EBS 快照的标签,或者在创建 EBS 快照时通过 Amazon EC2 控制台指定标签。

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

...除非您使用的是未实现该功能的旧版 SDK。

同一公告将资源级权限扩展到快照。

EC2 API 中的底层CreateSnapshot action 没有任何规定可以在创建快照的同时添加标签。你必须在创建后返回并标记它。

【讨论】:

【解决方案2】:

看看我的备份脚本:

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

这是我的脚本,用于删除带有“delete_on”标签的旧备份,其值为 YYYY-MM-DD 格式

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 您现在可以为 EBS 快照指定标签,作为创建资源的 API 调用的一部分。

    【讨论】:

      猜你喜欢
      • 2016-07-09
      • 2020-02-02
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      • 2018-09-04
      • 2020-11-27
      相关资源
      最近更新 更多