DevOps with Boto Python - Part IV
Monty: The Weight Watcher!
Yes, this is Monty: The Weight Watcher! Why? Well, in this tutorial you will learn,
- How to list your weight .. EBS Volumes
- How to add weight .. attach a volume to your EC2 instance
- How to lose weight .. detach a volume from your EC2 instance
Boto: List my weight...EBS Volumes
I will create a new file "Volumes.py" to handle volume manipulation. We will place this file under the "aws" package.
Riteshs-MacBook-Pro-2:DevOps rpatel$ cd aws
Riteshs-MacBook-Pro-2:aws rpatel$ touch Volumes.py
Next, let's add a Volumes class to this file.
import boto.ec2
class Volumes:
def __init__(self):
''' Volumes Constructor '''
Our goal here is to list all volumes. And rightfully so, I will add a function list_volumes to Volumes class. This function will list: available and in-use volumes.
import boto.ec2
class Volumes:
def __init__(self):
''' Volumes Constructor '''
def list_volumes(conn):
''' List Volumes '''
# get all volumes
vols = conn.get_all_volumes()
# if volumes found
if vols:
#loop through volumes
for v in vols:
print 'Volume Id:', v.id
print 'Volume Status:', v.status
print 'Volume Size:', v.size
print 'Zone:', v.zone
print 'Volume Type:', v.type
print 'Encrypted:', v.encrypted
#print attachment set object
attachmentData = v.attach_data
print 'Instance Id:', attachmentData.instance_id
print 'Attached Time:', attachmentData.attach_time
print 'Device:', attachmentData.device
print '**********************************'
Let's review the code above. First we retrieve a volume listing by making a call to conn.get_all_volumes(). If volumes are present in the list then we loop through each volume and print the volume information. Next, we look at the AttachmentSet tied with each volume. We extract instance_id, volume attach_time & device name from the Attachment Set. Simple!
Next we will modify DevOpsMain to make a call to list_volumes.
#!/usr/bin/Python
#Import classes from aws package
from aws import Connection
from aws import EC2Instance
from aws import Volumes
connInst = Connection()
conn = connInst.ec2Connection()
#instantiate Volumes and list volumes
volumeInst = Volumes()
volumeInst.list_volumes(conn)
Now, we go back to Python Interpreter. At the prompt we execute the script and examine the results.
Riteshs-MacBook-Pro-2:DevOps rpatel$ python DevOpsMain.py
Volume Id: vol-1234ce0f
Volume Status: available
Volume Size: 30
Zone: us-east-1a
Volume Type: standard
Encrypted: False
Instance Id:None
Attached Time: None
Device: None
**********************************
And we see the volume listing. Sure enough, you only see 1 volume in the listing and that is because I am only running 1 EBS volume under my account. Make a note that volume listed above is available for use. Instance Id, Attached Time & Device shows None. Which is correct because this volume is not in-use yet. Therefore in the next section we will learn how to attach this volume to our EC2 instance.
Boto: Add more weight...attach a volume
Let's review few pre-requisites before attaching a volume to an instance.
- Volume must be running in the same availability zone as the instance
- Determine the device name you will use for this new volume. e.g. /dev/sda1, /dev/xvdf etc...
- Determine how many volumes you can attach to an instance
- If a volume is encrypted then it can only be attached to an instance that supports EBS encryption
- If a volume has an AWS marketplace code, then:
- The volume can only be attached to a stopped instance
- You must be subscribed to the AWS Marketplace code that is on the volume
- The configuration (instance type, operating system) of the instance must support that specific AWS Marketplace code. For example, you cannot take a volume from a Windows instance and attach it to a Linux instance
- AWS Marketplace product codes are copied from the volume to the instance
These pre-requisites are straight from AWS documentation, but it makes sense. If you do not meet these pre-requisites then you will run into volume attachment errors like below.
InvalidParameterValue</Code><Message>Value (dev/xvda) for parameter device is invalid. dev/xvda is not a valid EBS device name
Error above informs us about an invalid device name.
The instance configuration for this AWS Marketplace product is not supported. Please see http://aws.amazon.com/marketplace/pp?sku=eggbgx9svw4xhzs1omttdv29q for more information about supported instance types, regions, and operating systems
Error above informs us about invalid AWS Marketplace product code.
With pre-requisites out of the way, let's attach a volume to our EC2 instance.I will add attach_volume function to Volumes class.
import boto.ec2
class Volumes:
def __init__(self):
''' Volumes Constructor '''
def list_volumes(self,conn):
''' Lists Volumes from an AWS account '''
def attach_volume(self,conn,volume_id,instance_id):
''' Attaches volue to an EC2 instance '''
#get a specific volume to be attached
vols = conn.get_all_volumes(volume_id)
if vols:
#get volume
volume = vols[0]
#if volume status is available then proceed with attachment
if (volume.status == 'available'):
#check if volume is attached
isattached = volume.attach(instance_id,'/dev/xvdh')
#print message
if isattached:
print 'Volume ', volume_id, ' attached successfully to instance ', instance_id
else:
print 'Error attaching volume ', volume_id, ' to instnace ', instance_id
else:
print 'Volume is in-use'
Very simple piece of code. Let's review it. We are calling conn.get_all_volumes(volume_id). This function call will return volume listing which has a filtered volume. From the list we retrieve one and only volume. After retrieving the volume, we check the volume status. If volume status is available then we proceed with attaching the volume. Next we call volume.attach(instance_id, 'dev/xvdh'). Sure enough, we are attaching the volume to a specific instance and providing a volume device path. With me?
Next let's modify DevOpsMain to make a call to attach_volume. In our function call we are passing volume_id as well as instance_id along with the connection. Sure enough, volume_id is the volume to be attached and the instance_id is to which the volume must be attached. Ah! The tongue twister :-)
#!/usr/bin/Python
#Import classes from aws package
from aws import Connection
from aws import EC2Instance
from aws import Volumes
connInst = Connection()
conn = connInst.ec2Connection()
#instantiate Volumes and list volumes
volumeInst = Volumes()
volumeInst.attach_volume(conn,'vol-1234ce0f','i-1234f1e1')
Next let's execute the script using Python Interpreter.
Riteshs-MacBook-Pro-2:DevOps rpatel$ python DevOpsMain.py
Volume vol-1234ce0f attached successfully to instance i-1234f1e1
If all goes well, you should see a message: Volume attached successfully to instance.
Boto: Lose some weight...detach a volume
In the previous section we attached a volume. Now let's detach the same volume. Not a complicated task and therefore we should be done in no-time, right?
Let's add detach_volume function to Volumes class.
import boto.ec2
class Volumes:
def __init__(self):
''' Volumes Constructor '''
def list_volumes(self,conn):
''' Lists Volumes from an AWS account '''
def attach_volume(self,conn,volume_id,instance_id):
''' Attaches volue to an EC2 instance '''
def detach_volume(self,conn,volume_id):
''' Detaches a specific volume '''
#get a specific volume to be detached
vols = conn.get_all_volumes(volume_id)
#if volume found
if vols:
#retrieve only volume from the list
volume = vols[0]
#if volume status is in-use then detach the volume
if (volume.status == 'in-use'):
#detach the volume
isdetached = volume.detach()
#print message
if isdetached:
print 'Volume ', volume_id, ' detached successfully!'
else:
print 'Error detaching volume ', volume_id
else:
print 'Volume has already been detached'
Again, a very simple piece of code. We search for a specific volume and check the status. If volume status is in-use then we detach the volume. Upon successfully detaching the volume we print a friendly message!
Next, let's modify the DevOpsMain file to make a call to detach_volume
#!/usr/bin/Python
#Import classes from aws package
from aws import Connection
from aws import EC2Instance
from aws import Volumes
connInst = Connection()
conn = connInst.ec2Connection()
#instantiate Volumes and list volumes
volumeInst = Volumes()
volumeInst.detach_volume(conn,'vol-1234ce0f')
And you know what is next! We execute the script using Python Interpreter.
Riteshs-MacBook-Pro-2:DevOps rpatel$ python DevOpsMain.py
Volume vol-1234ce0f detached successfully!
And voila! We see a friendly message: Volume detached successfully!
Easy, right?
In the next tutorial we will learn how to create, remove and list security groups from your cloud environment. I say Monty: The Security Guard!
Project files are located @ github. Fork and enjoy!
See you then!
Hi, I am Ritesh Patel. I live in a beautiful town surrounded by the mountains. C&O Canal is few miles away. State parks are only a distance away & bike trails galore. It is home sweet home Frederick, MD. A passionate developer. Love to cook. Enjoy playing "Bollywood Tunes" on my harmonica. Apart from that just a normal guy.