Created
May 27, 2015 12:29
-
-
Save iMilnb/df47cd6aea9eeac153ff to your computer and use it in GitHub Desktop.
AWS EC2 simple manipulation script using python and boto3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Simple [boto3](https://github.com/boto/boto3) based EC2 manipulation tool | |
# | |
# To start an instance, create a yaml file with the following format: | |
# | |
# frankfurt: | |
# - subnet-azb: | |
# - type: t2.micro | |
# image: image-tagname | |
# name: myinstance | |
# key: mykey | |
# data: 10 | |
# ipaddr: 10.1.1.2 | |
# sg: [ssh-icmp-reply, http-https] | |
# | |
# where `data` is the size, in GB of an optional secondary block device | |
# hardcoded to be referenced as `/dev/xvdb` | |
# | |
# In this file you can list many instances after the subnet, multiples subnets | |
# after the region, and also multiples regions. | |
# | |
# Then call: ./script.py create /path/to/file.yaml | |
# | |
# To terminaye this instance and its associated volumes: | |
# | |
# $ ./script.py rm <aws instance id> | |
# | |
# To list all the instances within a region: | |
# | |
# $ ./script.py ls | |
# | |
# `rm` and `ls` functions need the `EC2REGION` environment variable to be setup | |
# according to the content of ~/.aws/credentials, refer to: | |
# http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html | |
# for more information on `awscli`. | |
import boto3 | |
import os | |
import sys | |
import yaml | |
import time | |
if len(sys.argv) < 2: | |
print "usage: {0} <function> [arguments]" | |
sys.exit(1) | |
region = os.environ.get('EC2REGION') | |
if region is None: | |
print "Please add a region or set the EC2REGION environment variable." | |
sys.exit(1) | |
print "> working on region: {0}".format(region) | |
def init_session(r = None): | |
if r is None: | |
r = region | |
s = boto3.session.Session(profile_name=r) | |
return s.resource('ec2') | |
def ls(): | |
ec2 = init_session() | |
for i in ec2.instances.all(): | |
if i.tags is None: | |
continue | |
for t in i.tags: | |
if t['Key'] == 'Name': | |
print "{0} / {1} {2} ({3}) - [{4}]".format( | |
region, i.id, t['Value'], i.instance_type, i.state['Name'] | |
) | |
def get_id_from_tag(ec2obj, tag): | |
for o in ec2obj.filter(Filters=[{'Name': 'tag:Name', 'Values': [tag]}]): | |
return o.id | |
return None | |
def mktag(val): | |
return [{'Key': 'Name', 'Value': val}] | |
def create(): | |
if len(sys.argv) < 3: | |
print("usage: {0} create <path/to/description.yaml>") | |
sys.exit(1) | |
try: | |
with open(sys.argv[2], 'r') as f: | |
y = yaml.load(f.read()) | |
except IOError: | |
print "{0} not found.".format(sys.argv[2]) | |
sys.exit(1) | |
for reg in y: # loop through regions | |
ec2 = init_session(reg) | |
for azlst in y[reg]: # loop through AZ list | |
for az in azlst: # loop through AZ | |
for instance in azlst[az]: | |
if 'awsid' in instance: | |
reply = raw_input( | |
'{0} exists as {1}, continue? [y/N] '.format( | |
instance['name'], instance['awsid'] | |
) | |
) | |
if reply[0] != 'y': | |
continue | |
image = get_id_from_tag(ec2.images, instance['image']) | |
sg = [] | |
for sglist in instance['sg']: | |
sg.append(get_id_from_tag(ec2.security_groups, sglist)) | |
subnet = get_id_from_tag(ec2.subnets, az) | |
if 'data' in instance: | |
blockdevmap = [ | |
{ | |
'DeviceName': '/dev/xvdb', | |
'Ebs': { | |
'VolumeSize': instance['data'], | |
'DeleteOnTermination': True, | |
} | |
} | |
] | |
else: | |
blockdevmap = [] | |
print("creating instance {0}".format(instance['image'])) | |
rc = ec2.create_instances( | |
ImageId = image, | |
MinCount = 1, | |
MaxCount = 1, | |
KeyName = instance['key'], | |
SecurityGroupIds = sg, | |
InstanceType = instance['type'], | |
BlockDeviceMappings = blockdevmap, | |
SubnetId = subnet, | |
PrivateIpAddress = instance['ipaddr'] | |
) | |
iid = rc[0].id | |
print( | |
"tagging instance id {0} to {1}".format( | |
iid, instance['name'] | |
) | |
) | |
# give the instance a tag name | |
ec2.create_tags( | |
Resources = [iid], | |
Tags = mktag(instance['name']) | |
) | |
instance['awsid'] = iid | |
with open(sys.argv[2], 'w') as f: | |
yaml.dump(y, f, default_flow_style=False) | |
if not blockdevmap: | |
continue | |
devlst = [] | |
print("waiting for block devices to rise") | |
while not devlst: | |
devlst = ec2.Instance(iid).block_device_mappings | |
time.sleep(1) | |
for dev in devlst: | |
dname = dev['DeviceName'][5:] | |
print( | |
"tagging volume {0} to {1}_{2}".format( | |
dev['Ebs']['VolumeId'], | |
dname, | |
instance['name'] | |
) | |
) | |
ec2.create_tags( | |
Resources = [dev['Ebs']['VolumeId']], | |
Tags = mktag( | |
'{0}_{1}'.format( | |
dname, instance['name'] | |
) | |
) | |
) | |
def rm(): | |
if len(sys.argv) < 3: | |
print("usage: {0} rm <aws instance id>") | |
sys.exit(1) | |
ec2 = init_session() | |
try: | |
ec2.instances.filter(InstanceIds=[sys.argv[2]]).terminate() | |
except: | |
print('error while terminating {0}'.format(sys.argv[2])) | |
sys.exit(1) | |
if __name__ == '__main__': | |
getattr(sys.modules[__name__], sys.argv[1])() |
can you please give an example of yaml file including region and subnet, or describe the yaml file content. Thanx in advance.
can u send tell the codes to start or stop instances of aws using python?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
can you please provide a code for creating ec2 instance through python boto3 in aws. in which simply create security group key pair volume and ec2 instance.