Archive
Archive for October, 2021
Boto3 Script to create and attach an EBS Volume to an EC2
October 22, 2021
Leave a comment
import boto3 import logging import datetime import argparse import time from datetime import datetime from botocore.exceptions import ClientError logger = logging.getLogger() logger.setLevel(logging.INFO) VolumeList=[] expirationDate = expiration_Date = "" DEFAULT_AWS_Account_ID = "1111222222" DEFAULT_REGION = "us-east-1" def parse_commandline_arguments(): global REGION global AWS_Account_ID global instance_id global server_name global size_of_volume global kms_key parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Boto 2 Scritp to create and attach volume to a given Ec2 Instance.') parser.add_argument("-accountID", "--ownerID", dest="aws_ID", type=str, default=DEFAULT_AWS_Account_ID, help="The AWS Account ID where volume tagging is to be done") parser.add_argument("-r", "--region", dest="region", type=str, default=DEFAULT_REGION, help="Specify the region of the AWS Account") parser.add_argument("-server_name", "--ServerName", dest="servername", type=str, help="Specify the Instance Name to be terminated") parser.add_argument("-volume_size","--Volume_Size",dest="volumesize", type=int, help="Specify the size of new volume to be created and attached") parser.add_argument("-kmsId","--KMS_ID",dest="kms_key_id",type=str, help="Specify the KMS Key ID to encrypt the volume") args = parser.parse_args() REGION = args.region AWS_Account_ID = args.aws_ID server_name = args.servername size_of_volume = args.volumesize kms_key = args.kms_key_id def ec2_client(region): """ Connects to EC2, returns a connection object """ try: conn = boto3.client('ec2', region_name=region) except Exception as e: sys.stderr.write( 'Could not connect to region: %s. Exception: %s\n' % (region, e)) conn = None return conn def wait_for_state (instance, target_state): # Waits for instance to move to desired state # Vol Creation State: 'creating'|'available'|'in-use'|'deleting'|'deleted'|'error' # Vol Attachment State: 'attaching'|'attached'|'detaching'|'detached' status = ec2.Instance(instance).state['Name'] while status != target_state: print("Waiting for Instance - {} to come in {} state" .format(instance,target_state)) time.sleep (5) status = ec2.Instance(instance).state['Name'] def create_and_attach_volume(client,serverName,volSize,kmsId): global VolumeList device = "/dev/sdh" print(serverName) # Get Instance ID from the given Instance Name filters = [ {'Name': 'tag:Name', 'Values': [serverName]} ] for attempt in range(5): try: response = client.describe_instances(Filters=filters)["Reservations"] #response = client.describe_instances() instanceid = response[0]['Instances'][0]['InstanceId'] avaialbilityZone = response[0]['Instances'][0]['Placement']['AvailabilityZone'] print(instanceid + ":" + avaialbilityZone) except BaseException as err: logger.error(err) logger.info("*** ERROR *** during EC2 Describe proceess - retry...") time.sleep(0.5) else: logger.info("--> Done") break else: logger.error("*** ERROR *** - All attempt to describe instance failed - exit with error") raise Exception("*** ERROR *** - Can't describe instance") # Create volume for attempt in range(5): try: response = client.create_volume( AvailabilityZone=avaialbilityZone, Encrypted=True, KmsKeyId=kmsId, Size=volSize, VolumeType='gp3' ## Default Volume Type ) #print(response) except BaseException as err: logger.error(err) logger.info("*** ERROR *** during EC2 Volume creation proceess - retry...") time.sleep(0.5) else: logger.info("--> Done") break else: logger.error("*** ERROR *** - All attempt to create EC2 Volume failed - exit with error") raise Exception("*** ERROR *** - Can't create EBS Volume") if response['ResponseMetadata']['HTTPStatusCode']== 200: volume_id= response['VolumeId'] print('***volume:', volume_id) client.get_waiter('volume_available').wait( VolumeIds=[volume_id] ) print('***Success!! volume:', volume_id, 'created...') VolumeList.append(volume_id) print(VolumeList) # Add tag on newly created Volumes logger.info("Tagging for deletion following Volumes:") for volume in VolumeToDelList: logger.info("- " + volume) for attempt in range(5): try: print("creating Tag for Volume ID {}" .format(VolumeToDelList)) client.create_tags( Resources=VolumeToDelList, Tags=[ { 'Key': 'InsntanceId', 'Value': instanceid } ] ) except BaseException as err: logger.error(err) logger.error("*** ERROR *** during tagging Volumes - retry...") time.sleep(0.6) else: logger.info("--> Done") break else: logger.error("*** ERROR *** - All attempt to tagging volumes - exit with error") raise Exception("*** ERROR *** - Can't tagging Volumes") # Attach Volume to EC2 Instance logger.info("--> Attaching volume to EC2") for attempt in range(5): try: if volume_id: print('***attaching volume:', volume_id, 'to:', instanceid) response = client.attach_volume( Device=device, InstanceId=instanceid, VolumeId=volume_id, DryRun=False ) if response['ResponseMetadata']['HTTPStatusCode']== 200: client.get_waiter('volume_in_use').wait( VolumeIds=[volume_id], DryRun=False ) print('***Success!! volume:', volume_id, 'is attached to instance:', instanceid) except BaseException as err: logger.error(err) logger.error("*** ERROR *** during EC2 Volume attachment process - retry...") time.sleep(0.6) # second else: logger.info("--> Done") break else: logger.error("*** ERROR *** - All attempt to attach volume to instance failed - exit with error") raise Exception("*** ERROR *** - Can't attach volume to EC2") if __name__ == '__main__': try: parse_commandline_arguments() client=ec2_client(REGION) create_and_attach_volume(client,server_name,size_of_volume,kms_key) except Exception as error: logging.error(error) print(str(error))
Happy Reading !!!!
-Anand M
Categories: AWS/Boto3/Python