├── 10-simple-connect.py ├── 30-create-instance.py ├── 31-create-instance-enhanced.py ├── 32-create-instance-enhanced-with-user-data.py ├── 40-simple-volumes.py ├── 41-create-volume.py ├── 42-detach-volume.py ├── 43-make-snapshot.py ├── 60-load-balancer.py ├── 61-create-elb.py ├── 70-list-auto-scale-groups.py ├── 71-create-auto-scale.py ├── 72-cleanup-auto-scaling.py ├── 80-sns.py ├── README ├── disk_usage.py ├── slide.html └── start_instance.py /10-simple-connect.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | # Uses keys from .boto file 4 | conn = boto.ec2.connect_to_region('us-east-1') 5 | 6 | # Alternatively, 7 | #conn = boto.ec2.connect_to_region("us-west-2", 8 | # aws_access_key_id='', 9 | # aws_secret_access_key='') 10 | 11 | # A reservation corresponds to a command to start instances. You can see what instances are associated with a reservation: 12 | reservations = conn.get_all_instances() 13 | 14 | # Can filter 15 | filters = {'instance-state-name' : 'running'} 16 | filters = {'tag:Name': 'PyWebDev Example 3'} 17 | reservations = conn.get_all_instances(filters=filters) 18 | 19 | # An instance object allows you get more meta-data available about the instance: 20 | for r in reservations: 21 | print 'r: ', r 22 | 23 | instances = reservations[0].instances 24 | print 'instances: ', instances 25 | 26 | inst = instances[0] 27 | print inst.instance_type 28 | print inst.placement 29 | print inst.state 30 | print inst.public_dns_name 31 | print dir(inst) 32 | 33 | 34 | # We can then do a few things on an instance: 35 | #conn.stop_instances(instance_ids=['instance-id-1','instance-id-2', ...]) 36 | 37 | # And we can terminate!!!! Danger! 38 | -------------------------------------------------------------------------------- /30-create-instance.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | conn = boto.ec2.connect_to_region('us-east-1') 4 | 5 | 6 | # Simplest example 7 | # Creates an instance with all defaults - you will not be able to SSH into the server. 8 | #conn.run_instances('') 9 | 10 | # Let's not do that. Let's be more specific. 11 | 12 | # More complex 13 | # Red Hat Enterprise Linux 6.4 (ami-7d0c6314) 14 | new_reservation = conn.run_instances( 15 | 'ami-7d0c6314', 16 | key_name='csg', 17 | instance_type='t1.micro', 18 | security_groups=['default']) 19 | 20 | print 'New Instance: ', new_reservation 21 | 22 | 23 | -------------------------------------------------------------------------------- /31-create-instance-enhanced.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | import time 3 | 4 | conn = boto.ec2.connect_to_region('us-east-1') 5 | 6 | # Enhanced creation with Name tag and loop until it is running. 7 | 8 | # Red Hat Enterprise Linux 6.4 (ami-7d0c6314) 9 | new_reservation = conn.run_instances( 10 | 'ami-7d0c6314', 11 | key_name='csg', 12 | instance_type='t1.micro', 13 | security_groups=['default']) 14 | print "New instance created." 15 | 16 | # Add a Name to the instance, then loop to wait for it to be running. 17 | instance = new_reservation.instances[0] 18 | conn.create_tags([instance.id], {"Name":"PyWebDev Example 3a"}) 19 | while instance.state == u'pending': 20 | print "Instance state: %s" % instance.state 21 | time.sleep(10) 22 | instance.update() 23 | 24 | print "Instance state: %s" % instance.state 25 | print "Public dns: %s" % instance.public_dns_name 26 | 27 | -------------------------------------------------------------------------------- /32-create-instance-enhanced-with-user-data.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | import time 3 | 4 | conn = boto.ec2.connect_to_region('us-east-1') 5 | 6 | # Enhanced creation now with the addition of 'user_data' 7 | 8 | user_data_script = """#!/bin/bash 9 | echo "Hello World" >> /tmp/data.txt""" 10 | 11 | # Red Hat Enterprise Linux 6.4 (ami-7d0c6314) 12 | new_reservation = conn.run_instances( 13 | 'ami-7d0c6314', 14 | key_name='csg', 15 | instance_type='t1.micro', 16 | security_groups=['default'], 17 | user_data=user_data_script) 18 | print "New instance created." 19 | 20 | # Add a Name to the instance, then loop to wait for it to be running. 21 | instance = new_reservation.instances[0] 22 | conn.create_tags([instance.id], {"Name":"PyWebDev Example 3b"}) 23 | while instance.state == u'pending': 24 | print "Instance state: %s" % instance.state 25 | time.sleep(10) 26 | instance.update() 27 | 28 | print "Instance state: %s" % instance.state 29 | print "Public dns: %s" % instance.public_dns_name 30 | 31 | -------------------------------------------------------------------------------- /40-simple-volumes.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | conn = boto.ec2.connect_to_region('us-east-1') 4 | 5 | # Let's just list the volumes 6 | 7 | volumes = conn.get_all_volumes() 8 | for v in volumes: 9 | print 'Volume Attach Data: ', v.attach_data.id 10 | print 'Volume Attach Data: ', v.attach_data.instance_id 11 | print 'Volume Attach Data: ', v.attach_data.attach_time 12 | print 'Volume Attach Data: ', v.attach_data.device 13 | print 'Volume Status: ', v.status 14 | print 'Volume Zone: ', v.zone 15 | print '----------------------' 16 | 17 | -------------------------------------------------------------------------------- /41-create-volume.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | conn = boto.ec2.connect_to_region('us-east-1') 4 | 5 | # Create a volume 6 | # create_volume(size, zone, snapshot=None, volume_type=None, iops=None) 7 | vol = conn.create_volume(50, "us-east-1d") 8 | print 'Volume Id: ', vol.id 9 | 10 | # Add a Name tag to the new volume so we can find it. 11 | conn.create_tags([vol.id], {"Name":"PyWebDev Example 3"}) 12 | 13 | #You can check that the volume is now ready and available: 14 | curr_vol = conn.get_all_volumes([vol.id])[0] 15 | print 'Current Volume Status: ', curr_vol.status 16 | print 'Current Volume Zone: ', curr_vol.zone 17 | print 'Current Volume Device: ', curr_vol.attach_data.device 18 | 19 | # Since that is pretty boring, let's attach it to a real instance 20 | instance_id = 'i-d8b25cbb' 21 | result = conn.attach_volume (vol.id, instance_id, "/dev/sdy") 22 | print 'Attach Volume Result: ', result 23 | 24 | # NOTE: 25 | # InvalidParameterValueValue (/dev/sdZZ) for parameter device is invalid. /dev/sdZZ is not a valid EBS device name.a9c4a3c3-b7fc-4344-94a9-0d412f1981e2 26 | 27 | # RHEL requires some extra work... 28 | # To start, on RHEL, Amazon uses your device above, 'sdx', in the console, but at the hardware level creates a device named something like: /dev/xvdad 29 | 30 | # Then you have to format and mount it. 31 | # mkfs.ext3 /dev/xvdad 32 | # echo "/dev/xvdad /mnt/sillyname ext3 noatime 0 0" >> /etc/fstab 33 | -------------------------------------------------------------------------------- /42-detach-volume.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | conn = boto.ec2.connect_to_region('us-east-1') 4 | 5 | conn.detach_volume('vol-d57de68e') 6 | -------------------------------------------------------------------------------- /43-make-snapshot.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | 3 | conn = boto.ec2.connect_to_region('us-east-1') 4 | 5 | # Creating snapshots of your volumes is crazy easy 6 | snapshot = conn.create_snapshot('vol-a468e1ff', 'pywebdev - a sample description') 7 | print 'Snapshot Id: ', snapshot 8 | -------------------------------------------------------------------------------- /60-load-balancer.py: -------------------------------------------------------------------------------- 1 | import boto.ec2.elb 2 | 3 | # Uses keys from .boto file 4 | conn = boto.ec2.elb.connect_to_region('us-east-1') 5 | 6 | # Get all ELB's 7 | # You can also filter: 8 | # conn.get_all_load_balancers(load_balancer_names=['load-balancer-prod']) 9 | all_elb = conn.get_all_load_balancers() 10 | print 'My ELBs: ', all_elb 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /61-create-elb.py: -------------------------------------------------------------------------------- 1 | import boto.ec2.elb 2 | from boto.ec2.elb import HealthCheck 3 | 4 | elb_conn = boto.ec2.elb.connect_to_region('us-east-1') 5 | 6 | # ELB requires a few pieces to be setup 7 | hc = HealthCheck( 8 | interval=20, 9 | healthy_threshold=3, 10 | unhealthy_threshold=5, 11 | target='TCP:22' 12 | # target='HTTP:8080/health' 13 | ) 14 | 15 | zones = ['us-east-1a', 'us-east-1b', 'us-east-1c', 'us-east-1d'] 16 | ports = [(80, 80, 'http')] 17 | #ports = [(80, 8080, 'http'), (443, 8443, 'tcp')] 18 | 19 | # Now create a new load balancer 20 | lb = elb_conn.create_load_balancer('pywebdev-lb', zones, ports) 21 | print 'New ELB: ', lb 22 | print 'New ELB public DNS: ', lb.dns_name 23 | 24 | # Add the health check configuration to the ELB. 25 | lb.configure_health_check(hc) 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /70-list-auto-scale-groups.py: -------------------------------------------------------------------------------- 1 | import boto.ec2.autoscale 2 | from boto.ec2.autoscale import LaunchConfiguration 3 | from boto.ec2.autoscale import AutoScalingGroup 4 | 5 | autoscale_conn = boto.ec2.autoscale.connect_to_region('us-east-1') 6 | 7 | # Get all autoscale groups 8 | ag = autoscale_conn.get_all_groups() 9 | print 'My Autoscale Groups: ', ag 10 | 11 | for group in ag: 12 | print "Auto Scale Group, name: ", group.name 13 | print "Auto Scale Group, launch configuration: ", group.launch_config_name 14 | print "Auto Scale Group, load balancers: ", group.load_balancers 15 | print '-----------------------------------' 16 | 17 | -------------------------------------------------------------------------------- /71-create-auto-scale.py: -------------------------------------------------------------------------------- 1 | import boto.ec2.autoscale 2 | from boto.ec2.autoscale import LaunchConfiguration 3 | from boto.ec2.autoscale import AutoScalingGroup 4 | 5 | autoscale_conn = boto.ec2.autoscale.connect_to_region('us-east-1') 6 | 7 | # 3 Core Concepts 8 | # 9 | # 1. Launch Configuration 10 | # 2. Autoscale Group 11 | # 3. Triggers 12 | 13 | # First setup a Launch Configuration 14 | lc = LaunchConfiguration(name='pywebdev_launch_config', image_id='ami-7bf28712', 15 | instance_type='t1.micro', # defaults to m1.small 16 | key_name='csg', 17 | security_groups=['default']) 18 | result = autoscale_conn.create_launch_configuration(lc) 19 | print 'Launch Configuration Creation Result: ', result 20 | 21 | 22 | # Now we have a Launch Configuration and an ELB. Create and launch the AutoScalingGroup 23 | ag = AutoScalingGroup(group_name='pywebdev_as_group', load_balancers=['pywebdev-lb'], 24 | availability_zones=['us-east-1a', 'us-east-1b', 'us-east-1c', 'us-east-1d'], 25 | launch_config=lc, min_size=2, max_size=4, 26 | connection=autoscale_conn) 27 | result = autoscale_conn.create_auto_scaling_group(ag) 28 | print 'Auto Scaling Group Creation Result: ', result 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /72-cleanup-auto-scaling.py: -------------------------------------------------------------------------------- 1 | import boto.ec2.autoscale 2 | import time 3 | 4 | autoscale_conn = boto.ec2.autoscale.connect_to_region('us-east-1') 5 | 6 | 7 | ag = autoscale_conn.get_all_groups(names=['pywebdev_as_group'])[0] 8 | print "PyWebDev AS Group: ", ag 9 | 10 | # Once the instances have been shutdown, you can delete the autoscale group: 11 | ag.shutdown_instances() 12 | time.sleep(60) 13 | ag.delete() 14 | time.sleep(20) 15 | 16 | # Now get the Launch Configuration 17 | lc = autoscale_conn.get_all_launch_configurations(names=['pywebdev_launch_config'])[0] 18 | print "PyWebDev LC: ", lc 19 | 20 | lc.delete() 21 | 22 | 23 | -------------------------------------------------------------------------------- /80-sns.py: -------------------------------------------------------------------------------- 1 | import boto.sns 2 | 3 | sns_conn = boto.sns.connect_to_region('us-east-1') 4 | 5 | # Name of a SNS topic 6 | arn = 'arn:aws:sns:us-east-1:988683046438:pywebdevdemo' 7 | 8 | message = 'My pyweb SNS' 9 | result = sns_conn.publish(arn,message,'Finished AWS snapshotting') 10 | 11 | print 'Result: ', result 12 | 13 | 14 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | These scripts are meant to be small re-usable examples for various tasks with Boto. They were created for a presentation at the Python Web Development Meetup (http://www.meetup.com/Python-Web-Development/events/114056722/), but are also meant to be a starting point for creating your own scripts. 2 | 3 | 10* through 32* are examples for managing and creating EC2 instances. 4 | 40* through 43* are examples for managing and creating EBS volumes. 5 | 60* through 72* are examples for managing and creating Load Balancers and Auto Scaling Groups. 6 | 80-sns.py is simple example of sending an email notification through SNS. 7 | 8 | Resources: 9 | 10 | http://examples.oreilly.com/0636920020202/ 11 | http://boto.readthedocs.org/en/latest/index.html 12 | Python and AWS Cookbook By Mitch Garnaat 13 | 14 | Other/Todo: 15 | 16 | Sample Code for displaying volume usage - https://github.com/baojie/PythonAWSCode/blob/master/metrics/metric_disk_usage 17 | Backup to AWS EBS via Rsync and Boto - http://www.takaitra.com/posts/384 18 | -------------------------------------------------------------------------------- /disk_usage.py: -------------------------------------------------------------------------------- 1 | import boto 2 | import time 3 | import datetime 4 | import os 5 | 6 | cw = boto.connect_cloudwatch() 7 | print 'cw: ', cw 8 | md = boto.utils.get_instance_metadata() 9 | print 'md: ', md 10 | now = datetime.datetime.utcnow() 11 | 12 | #stats = os.statvfs('/') 13 | #total = float(stats.f_blocks * stats.f_bsize) 14 | #available = float(stats.f_bavail * stats.f_bsize) 15 | #percent_used = int(100 - 100 * (available / total)) 16 | #print 'metric_disk_usage: %d' % percent_used 17 | #cw.put_metric_data(namespace='PAWS', 18 | #name='DiskUsage', 19 | #value=percent_used, 20 | #timestamp=now, 21 | #unit='Percent', 22 | #dimensions=[{'InstanceId' : md['instance-id']}]) 23 | 24 | 25 | -------------------------------------------------------------------------------- /slide.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Amazon AWS and Boto

6 | 7 |
    8 |
  • Demo Amazon Console
  • 9 |
  • Demo of Live Python Examples
  • 10 |
  • Other - Lots of other AWS services, rsync, disk usage metric, costs
  • 11 |
12 | 13 |

Resources

14 |
    15 |
  • http://boto.readthedocs.org/en/latest/index.html
  • 16 |
  • Python and AWS Cookbook By Mitch Garnaat
  • 17 |
  • http://examples.oreilly.com/0636920020202/
  • 18 |
  • I will post this code to github
  • 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /start_instance.py: -------------------------------------------------------------------------------- 1 | import boto.ec2 2 | conn = boto.ec2.connect_to_region('us-east-1') 3 | conn.start_instances(instance_ids=['i-d8b25cbb']) 4 | --------------------------------------------------------------------------------