diff options
Diffstat (limited to 'aws-provision-ec2.py')
| -rw-r--r-- | aws-provision-ec2.py | 120 | 
1 files changed, 120 insertions, 0 deletions
diff --git a/aws-provision-ec2.py b/aws-provision-ec2.py new file mode 100644 index 0000000..9eaf3e8 --- /dev/null +++ b/aws-provision-ec2.py @@ -0,0 +1,120 @@ +import boto3 +import os +import time + +# my 'boto3-ec2-user' IAM user with Programmatic access +settings = { +    'aws_access_key_id': 'XXXXXXXXXXXXXXXXXXXX', +    'aws_secret_access_key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', +    'myregion': 'us-east-2' +} + +# create session and get ec2 resource +session = boto3.Session( +    aws_access_key_id = settings['aws_access_key_id'], +    aws_secret_access_key = settings['aws_secret_access_key'], +    region_name=settings['myregion'] +) +ec2 = session.resource('ec2') +ec2client = session.client('ec2') # also create session for the low-level Clients API, I needed it for describe_instances() + + +#check if privkey was already saved to the disk +if os.path.isfile('boto3-ec2-keypair.pem'): +    with open('boto3-ec2-keypair.pem', 'r') as f: +        keypair_str = f.read() +else: +    # create a keypair that will allow us to access instance/vm after it is provisioned +    keypair = ec2.create_key_pair(KeyName='boto3-ec2-keypair') +    outfile = open('boto3-ec2-keypair.pem', 'w') + +    # capture the key and store it in a file +    keypair_str = str(keypair.key_material) +    print('generated keypair:\n{0}'.format(keypair_str)) +    outfile.write(keypair_str) # save privkey so it can be used with 'ssh -i' +    outfile.close() + +yaml_datadisk_dict = { +    'yaml_datadisk_device': "/dev/xvdb", +    'yaml_datadisk_size': "+5G", +    'yaml_datadisk_fs': "xfs", +    'yaml_datadisk_mountpoint': "/data", +} + +# prepare EC2 User Data post install script that will parition the /dev/xvdb disk, create fs, and mount it +myuserdata = ''' +sudo su +echo -e "o\\nY\\nn\\n1\\n\\n\\n\\nw\\nY\\n" | gdisk {yaml_datadisk_device} +mkfs.{yaml_datadisk_fs} {yaml_datadisk_device}1 +mkdir -p {yaml_datadisk_mountpoint} +echo "{yaml_datadisk_device}1 {yaml_datadisk_mountpoint} {yaml_datadisk_fs} defaults 0 0" >> /etc/fstab +mount -a +'''.format(**yaml_datadisk_dict) + + +# create a new micro EC2 instance/vm with Amazon Linux 2 AMI image +instance = ec2.create_instances( +    BlockDeviceMappings = [ +        { +            'DeviceName': '/dev/xvda', +            'Ebs': {'VolumeSize': 9}, +        }, +        { +            'DeviceName': '/dev/xvdb', +            'Ebs': {'VolumeSize': 9}, +        }, +    ], +    ImageId = 'ami-0603cbe34fd08cb81', +    MinCount = 1, +    MaxCount = 1, +    InstanceType = 't2.micro', +    KeyName = 'boto3-ec2-keypair', +    UserData = myuserdata, +    TagSpecifications = [ +        { +            'ResourceType' : 'instance', +            'Tags': [ +                { +                    'Key': 'Name', +                    'Value': 'myBotoEC2micro' +                }, +            ] +        } +    ], +) +# wait until instance's state changes to 'running' +ec2client.wait_until_running() + +# wait until OS boots up, not ideal, could use Waiters but they are in the other 'Clients' API +while instance[0].state == 'pending': +    time.sleep(3) +    instance[0].update() +print("instance id: {0}".format(instance[0].id)) + +# aws ec2 describe-instances --filters Name=tag:Name,Values=myBotoEC2micro --query 'Reservations[*].Instances[*].InstanceId' --output text +res = ec2client.describe_instances( +    Filters=[ +        { +        'Name': 'tag:Name', +        'Values': ['myBotoEC2micro'] +        } +    ] +)  +instanceID = res['Reservations'][0]['Instances'][0]['InstanceId'] +print("again instance id is: {0}".format(instanceID)) + +# boto3 API can only check if the volume is attached to an instance, but not if it is mounted +# our volume that will hold /data was already attached in ec2.create_instances() step +# we will use EC2 User Data to format the /dev/xvdb volume with xfs filesystem & mount it at /data + +# the catch is that EC2 User Data can be only used once during creation/launch of new instance/vm, +# so you need to feed it to ec2.create_instances() + +# get domain name of newly launched instance +publicDNS = res['Reservations'][0]['Instances'][0]['PublicDnsName'] +print("Login to new instance using:\n" \ +    "ssh -i {0} e2c-user@{1}".format('boto3-ec2-keypair.pem', publicDNS)) + + +#for i in ec2.instances.all(): +#    print(i.id)  | 
