简体   繁体   中英

Using boto3 to create and attach an EBS volume to an EC2 instance

I have an existing EC2 instance with two EBS volumes attached to it. I want to add a 3rd EBS volume to this EC2 instance using boto3.

Here is what I am thinking:

Or is there a simpler way of doing this? Is there a function in boto3 that I can use to add a new EBS volume to an existing EC2 instance?

Try this...

 '''
 Creation State:
 'State': 'creating'|'available'|'in-use'|'deleting'|'deleted'|'error'

 Attachment State:
 'State': 'attaching'|'attached'|'detaching'|'detached'
 '''

 #create_and_attach_volume
def create_and_attach_volume(ec2_client, availability_zone, DryRunFlag, device, 
instance_id):
try:
    response= ec2_client.create_volume(
        AvailabilityZone=availability_zone,
        Encrypted=False,
        #Iops=100,
        #KmsKeyId='string',
        Size=10,
        #SnapshotId='string',
        VolumeType='gp2',    #standard'|'io1'|'gp2'|'sc1'|'st1',
        DryRun=DryRunFlag
        )
    #pprint(response)

    if response['ResponseMetadata']['HTTPStatusCode']== 200:
        volume_id= response['VolumeId']
        print('***volume:', volume_id)

        ec2_client.get_waiter('volume_available').wait(
            VolumeIds=[volume_id],
            DryRun=DryRunFlag
            )
        print('***Success!! volume:', volume_id, 'created...')

except Exception as e:
        print('***Failed to create the volume...')
        print(type(e), ':', e)

#botocore.exceptions.ClientError:
#An error occurred (InvalidParameterCombination) when calling the CreateVolume 
operation: The parameter iops is not supported for gp2 volumes.
if volume_id:
    try:
        print('***attaching volume:', volume_id, 'to:', instance_id)
        response= ec2_client.attach_volume(
            Device=device,
            InstanceId=instance_id,
            VolumeId=volume_id,
            DryRun=DryRunFlag
            )
        #pprint(response)

        if response['ResponseMetadata']['HTTPStatusCode']== 200:
            ec2_client.get_waiter('volume_in_use').wait(
                VolumeIds=[volume_id],
                DryRun=False
                )
            print('***Success!! volume:', volume_id, 'is attached to instance:', 
  instance_id)

    except Exception as e:
        print('***Error - Failed to attach volume:', volume_id, 'to the instance:', instance_id)
        print(type(e), ':', e)

#botocore.exceptions.ClientError:
#An error occurred (IncorrectState) when calling the AttachVolume operation: vol- 
0fcc7c3319a885513 is not 'available'.
#An error occurred (InvalidParameterValue) when calling the AttachVolume operation: 
Invalid value '/dev/sdc' for unixDevice. Attachment point /dev/sdc is already in use

#__main__
session= boto3.session.Session()
region_name= session.region_name
#region_name='ap-south-1'
availability_zone='ap-south-1a'
bdm='/dev/sdc'
instance_id='i-08364669ada3804d3'

start= -perf_counter()
ec2_client= boto3.client('ec2', region_name=region_name)
create_and_attach_volume(ec2_client, availability_zone, DryRunFlag=False, bdm, 
instance_id)
print('***duration:', (start+ perf_counter()), 'secs')

There is no "single API call" that combines both actions.

You are correct to create a volume and then attach it.

Try this....

import time

import boto3

ec2 = boto3.client('ec2')
response = ec2.describe_instances()
instance_dict = {}
count = 1
print('  {0:3}    {1:30s}  {2:15s}     {3:15s}   {4:15s}   {5:10s}'.format("S No. ", "NAME", "INSTANCE ID", "IP ADDRESS",'AvailabilityZone', "STATE"))
print('----------------------------------------------------------------------------------------------------------------- \n')
for reservation in response["Reservations"]:
    for instance in reservation["Instances"]:
        if instance['State']['Name'] == "running":
            if instance.__contains__("Tags"):
                print('  {0:3}    {1:30s}  {2:15s}   {3:15s}   {4:15s}   {5:10s}'.format(
                    count, instance["Tags"][0]["Value"], instance["InstanceId"],
                    instance["PublicIpAddress"], instance['Placement']['AvailabilityZone'], "RUNNING"))
                instance_dict[count] = instance["InstanceId"],instance['Placement']['AvailabilityZone']
                count += 1
            else:
                print('  {0:3}    {1:30s}  {2:15s}   {3:15s}   {4:15s}   {5:10s}'.format(
                    count, "No Name", instance["InstanceId"], instance["PublicIpAddress"],instance['Placement']['AvailabilityZone'], "RUNNING"))
                instance_dict[count] = instance["InstanceId"],instance['Placement']['AvailabilityZone']
                count += 1
        elif instance['State']['Name'] == "stopped":
            if instance.__contains__("Tags"):
                print('  {0:3}    {1:30s}  {2:15s}   {3:15s}   {4:15s}   {5:10s}'.format(
                    count, instance["Tags"][0]["Value"], instance["InstanceId"], "No IP ADDRESS", instance['Placement']['AvailabilityZone'],
                    "STOPPED"))
                instance_dict[count] = instance["InstanceId"],instance['Placement']['AvailabilityZone']
                count += 1
            else:
                print('  {0:3}    {1:30s}  {2:15s}   {3:15s}   {4:15s}   {5:10s}'.format(
                    count, "No Name", instance["InstanceId"], "No IP ADDRESS", instance['Placement']['AvailabilityZone'], "STOPPED"))
                instance_dict[count] = instance["InstanceId"],instance['Placement']['AvailabilityZone']
                count += 1
print()
iId = int(input('On which instance you want to add Volume : '))

az = instance_dict[iId][1]

size = input("Enter Size of Volume (default: 10): ")

response= ec2.create_volume(
            AvailabilityZone=az,
            Encrypted=False,
            #Iops=100,
            #KmsKeyId='string',
            Size=int(size),
            #SnapshotId='string',
            VolumeType='gp2',    #standard'|'io1'|'gp2'|'sc1'|'st1',
            DryRun=False)
print("Volume ID : ", response['VolumeId'])
time.sleep(10)
response= ec2.attach_volume(Device="/dev/sdc", InstanceId=instance_dict[iId][0], VolumeId=response['VolumeId'])
print("State : ",response['State'])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM