2017-03-07 113 views
1

在調用boto3中的create_snapshot()方法時是否可以添加標籤?當我運行下面的代碼:在使用boto3創建EBS快照時添加標籤

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()方法在事後添加標籤的唯一途徑?

+0

是的。 'create_tags'是爲EC2資源添加標籤的唯一方法。 – helloV

回答

1

EC2 API中的基礎CreateSnapshot action沒有任何規定可以在創建快照的同時添加標籤。你必須在創建它之後返回並標記它。

看起來奇怪的是,API(以及CLI)的響應實際上包含了一個空標籤數組......但這就是它的實現方式。

0

看一看我的備份腳本:

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