We believe your privacy is very important. We use cookies to track your behaviour and provide a better experience
Backend Helpers | Automation and Software Development for Cloud Applicationses
Amazon EC2 is a service that provides computer power in the cloud. In our previous post we cover the basis of this service. Today we are going to demonstrate how to use python to access AWS EC2 functionality.
Boto3 is a Python3 client library for Amazon Web Services. The following command installs this library in your local system:
pip3 install boto3
There are two options for configuring boto. The first one is to define the environment variables AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
and AWS_DEFAULT_REGION
export AWS_ACCESS_KEY_ID="MY_KEY" export AWS_SECRET_ACCESS_KEY="MY_AWS_SECRET_ACCESS_KEY" export AWS_DEFAULT_REGION="eu-west1"
The second one is to create a ~/.boto file and copy the following content:
[Credentials] aws_access_key_id = YOURACCESSKEY aws_secret_access_key = YOURSECRETKEY region = eu-west1
The following code shows some basic examples of using AWS EC2 using python:
# Lists all ec2 regions import boto3 ec2 = boto3.client('ec2') result = ec2.describe_regions() result.keys() for region in result['Regions']: print(region)
# Lists availability zones for a given region import boto3 ec2 = boto3.client('ec2', region_name='us-west-2') result = ec2.describe_availability_zones() result.keys() for zone in result['AvailabilityZones']: print(zone)
The following code uses the create_security_group function to create a new group:
from botocore.exceptions import ClientError import boto3 import argparse def get_or_create_security_group(name, description): """ Search by group_name, if doesn't exits, it is created """ try: ec2 = boto3.client('ec2') return ec2.describe_security_groups(GroupNames=[name]) except ClientError as e: if e.response['Error']['Code'] == 'InvalidGroup.NotFound': group_id = ec2.create_security_group(GroupName=name, Description=description)['GroupId'] return group_id else: raise def main(): parser = argparse.ArgumentParser() parser.add_argument('--name', required=True) parser.add_argument('--description', required=True) args = parser.parse_args() result = get_or_create_security_group(args.name, args.description) for group in result['SecurityGroups']: print('keys: {}'.format(', '.join(group.keys()) )) print('GroupName: {}'.format(group['GroupName'])) print('Description: {}'.format(group['Description'])) if __name__ == '__main__': main()
python get_or_create_security_group.py --name=my-group-test \ --description='example security group with ec2 access'
The following example uses the authorize_ingress function to grant ssh access to a security group:
import boto3 import argparse def authorize_security_group( ip_protocol='tcp', region='us-west-2', name=None, from_port=None, to_port=None, cidr_ip=None): """ Authorize cidr_ip access to a security group """ response = boto3.client('ec2').describe_security_groups(GroupNames=[name]) group_id = response['SecurityGroups'][0]['GroupId'] security_group = boto3.resource('ec2').SecurityGroup(group_id) return security_group.authorize_ingress( IpProtocol=ip_protocol, FromPort=from_port, ToPort=to_port, CidrIp=cidr_ip) def main(): parser = argparse.ArgumentParser() parser.add_argument('--name', required=True) parser.add_argument('--region', default='us-west-2') parser.add_argument('--ip_protocol', default='tcp') parser.add_argument('--from_port', required=True, type=int) parser.add_argument('--to_port', required=True, type=int) parser.add_argument('--cidr_ip', required=True) args = parser.parse_args() result = authorize_security_group( ip_protocol=args.ip_protocol, region=args.region, name=args.name, from_port=args.from_port, to_port=args.to_port, cidr_ip=args.cidr_ip) print(result) if __name__ == '__main__': main()
python autorize_security_group.py --name=my-group-test \ --ip_protocol=tcp --from_port=22 \ --to_port=22 --cidr_ip=0.0.0.0/32
The following code uses the revoke_ingress function to revoke SSH to a security group:
import boto3 import argparse def revoque_from_security_group( ip_protocol='tcp', region='us-west-2', name=None, from_port=None, to_port=None, cidr_ip=None): """ Revoque cidr_ip access to a security group """ response = boto3.client('ec2').describe_security_groups(GroupNames=[name]) group_id = response['SecurityGroups'][0]['GroupId'] security_group = boto3.resource('ec2').SecurityGroup(group_id) return security_group.revoke_ingress( IpProtocol=ip_protocol, FromPort=from_port, ToPort=to_port, CidrIp=cidr_ip) def main(): parser = argparse.ArgumentParser() parser.add_argument('--name', required=True) parser.add_argument('--region', default='us-west-2') parser.add_argument('--ip_protocol', default='tcp') parser.add_argument('--from_port', required=True, type=int) parser.add_argument('--to_port', required=True, type=int) parser.add_argument('--cidr_ip', required=True) args = parser.parse_args() result = revoque_from_security_group( ip_protocol=args.ip_protocol, region=args.region, name=args.name, from_port=args.from_port, to_port=args.to_port, cidr_ip=args.cidr_ip) print(result) if __name__ == '__main__': main()
python revoke_security_group.py --name=my-group-test \ --ip_protocol=tcp --from_port=22 --to_port=22 \ --cidr_ip=0.0.0.0/32 --region=us-west-2
The function create_key_pair creates a ssh key pair for a specific region:
import boto3 import argparse import os def create_key_pair(key_dir, key_name): f_path = os.path.join(key_dir, key_name) ec2 = boto3.client('ec2') key = ec2.create_key_pair(KeyName=key_name) with open(f_path, 'a+') as f: f.write(key['KeyMaterial']) return key def main(): parser = argparse.ArgumentParser() parser.add_argument('--key_name', required=True) parser.add_argument('--key_dir', required=True) args = parser.parse_args() key = create_key_pair(args.key_dir, args.key_name) print(key['KeyFingerprint']) if __name__ == '__main__': main()
python create_key_pair.py --key_name test_key.pem --key_dir ~/.ssh/
The following code shows how to use the function create_volume:
import boto3 import argparse def create_volume(region, zone, size_gb): ec2 = boto3.client('ec2' , region_name=region) v = ec2.create_volume( Size=size_gb, AvailabilityZone=zone) return v def main(): parser = argparse.ArgumentParser() parser.add_argument('--size_gb', type=int,required=True) parser.add_argument('--region', required=True) parser.add_argument('--zone', required=True) args = parser.parse_args() result = create_volume( args.region, args.zone, args.size_gb) print(result) if __name__ == '__main__': main()
python create_ebs_volume.py --region=eu-west-1 --zone=eu-west-1a --size_gb=1
The function run_instances may be used to create one or more instances.
import boto3 import argparse import time def launch_instance(ami, instance_type, group_name, min_count=1, max_count=1): ec2 = boto3.client('ec2') response = ec2.describe_security_groups(GroupNames=[group_name]) group_id = response['SecurityGroups'][0]['GroupId'] return ec2.run_instances( ImageId=ami,SecurityGroupIds=[group_id], InstanceType=instance_type, MinCount=min_count, MaxCount=max_count) def main(): parser = argparse.ArgumentParser() parser.add_argument('--ami', required=True) parser.add_argument('--instance_type', required=False, default='t1.nano') parser.add_argument('--group_name', required=True) args = parser.parse_args() result = launch_instance( ami=args.ami, instance_type=args.instance_type, group_name=args.group_name ) print(result) if __name__ == '__main__': main()
python launch_instance.py --ami ami-047bb4163c506cd98 \ --instance_type=t2.nano --group_name=my-group-test --zone=eu-west-1a
AWS instances have a root hard drive, but when an instance is stopped the root volume associated to that instance disappears. The following example uses the function attach_volume to append a second hard drive to a ec2 instance. This disk won't be destroyed if the instance is destroyed.
import boto import boto.ec2 import argparse def attach_volume( region='us-west-2', volume_id=None, instance_id=None, device_name='/dev/sdb'): ec2 = boto.ec2.connect_to_region(region) volume = ec2.get_all_volumes(volume_ids=volume_id)[0] volume.attach(instance_id, device_name) return volume def main(): parser = argparse.ArgumentParser() parser.add_argument('--region', default='us-west-2') parser.add_argument('--volume_id', required=True) parser.add_argument('--instance_id', required=True) parser.add_argument('--device_name', default='sdb') args = parser.parse_args() v = attach_volume( region=args.region, volume_id=args.volume_id, device_name=args.device_name, instance_id=args.instance_id) print(v) if __name__ == '__main__': main()
python attach_volume.py --volume_id=vol-05457b66dd0389d53 \ --instance_id=i-073577bf60eea7224 --device_name=/dev/xvdb