Decoding the boto3, if you want to launch the EC2 instance using the API. You are in the right place.

The below bunch of code doesn’t use boto3 instead it directly uses the API.

Pre-requisites

  • Ensure you have installed python.
  • virtualenv needs to be installed.

Python Script

Initialize the respected packages

import sys, os, base64, datetime, hashlib, hmac 
import argparse
import requests # pip install requests
requests.packages.urllib3.disable_warnings()
import xml.etree.ElementTree as ET

Initialize the Global variable

# Global Variable
method = 'POST'
service = 'ec2'
host = 'ec2.amazonaws.com'
url = 'https://ec2.amazonaws.com'
url_parameters = 'Action=RunInstances'
ImageId="ami-a4c7edb2"
MinCount="1"
MaxCount="1"
Version="2016-11-15"
content_type = 'application/x-www-form-urlencoded'
request_data = ""
# Create a date for headers and the credential string
t = datetime.datetime.utcnow()
amz_date = t.strftime('%Y%m%dT%H%M%SZ')
date_stamp = t.strftime('%Y%m%d')
algorithm = 'AWS4-HMAC-SHA256'

Decalar the authorization and signature function.

def sign(key, msg):
	return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

def getSignatureKey(key, date_stamp, regionName, serviceName):
	kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp)
	kRegion = sign(kDate, regionName)
	kService = sign(kRegion, serviceName)
	kSigning = sign(kService, 'aws4_request')
	return kSigning

def createAuthorizationHeader(url_parameters, content_type, host, \
				amz_date, request_parameters, \
				method, date_stamp, region, \
				service, algorithm,\
				secret_key, access_key):
	'''
	Create the authorization header with the sha256 signature
	which will be generated w.r.t to secert key of IAM user.
	'''
	canonical_uri = '/'
	canonical_querystring = url_parameters
	canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + amz_date + '\n'
	signed_headers = 'content-type;host;x-amz-date'
	payload_hash = hashlib.sha256(request_parameters).hexdigest()
	canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
	credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request'
	string_to_sign = algorithm + '\n' +  amz_date + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request).hexdigest()
	signing_key = getSignatureKey(secret_key, date_stamp, region, service)
	signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
	authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
	headers = {'content-type':content_type,
			'x-amz-date':amz_date,
			'Authorization':authorization_header}

	return headers

Declare the Instance API function

def createInstanceUsingAPI(url, querystring,data,headers):
	'''
	Function will create the ec2 instance using the AWS api
	 with respective data in urlencoded format
	 and with respective authorization header
	'''
	try :
		request_url = url + '?' + querystring
		r = requests.post(request_url, data=data, headers=headers)
		print 'Response code: %d\n' % r.status_code
		response_result = ET.fromstring(r.text)
		xmlns_value = (response_result.tag).split("}")[0] + "}"
		response_instancesSet = response_result.find(xmlns_value + 'instancesSet')
		response_item = response_instancesSet.find(xmlns_value + 'item')
		print "Instance ID : " + response_item.find(xmlns_value + 'instanceId').text
		print "Instance Launch Time : " + response_item.find(xmlns_value + 'launchTime').text
	except requests.exceptions.Timeout as e:
		print("HTTP Timeout Error Accessing "+request_url)
	except requests.exceptions.ConnectionError as e:
		print("HTTP Connection Error Accessing "+request_url)
	except Exception as e:
		print("Generic Exception "+str(e))

Execute the code

if __name__ == '__main__':
	aws_access_key, aws_secret_key, aws_region, aws_instance_type = inputArgument()
	querystring = 'Action=RunInstances'+\
				'&ImageId=' + ImageId + \
				'&InstanceType=' + aws_instance_type + \
				'&MaxCount=' + MaxCount + \
				'&MinCount=' + MinCount + \
				'&Version=' + Version 
	request_headers = createAuthorizationHeader(querystring, content_type, host, \
				amz_date, request_data, \
				method, date_stamp, aws_region, \
				service, algorithm,
				aws_secret_key, aws_access_key)
	createInstanceUsingAPI(url, querystring,request_data,request_headers)

https://github.com/ahamedyaserarafath/launch_ec2_using_api

GitHub Link, Please feel free to fork and use it

Categorized in:

Tagged in:

,