method for imaging an instance on AWS EC2

        :param instance_id: string with AWS id of running instance
        :param image_name: string with name to give new image
        :param tag_list: [optional] list of resources tags to add to image
        :return: string with AWS id of image

def create_image(self, instance_id, image_name, tag_list=None):

        '''
            method for imaging an instance on AWS EC2

        :param instance_id: string with AWS id of running instance
        :param image_name: string with name to give new image
        :param tag_list: [optional] list of resources tags to add to image
        :return: string with AWS id of image
        '''

        title = '%s.create_image' % self.__class__.__name__

    # validate inputs
        input_fields = {
            'instance_id': instance_id,
            'image_name': image_name,
            'tag_list': tag_list
        }
        for key, value in input_fields.items():
            if value:
                object_title = '%s(%s=%s)' % (title, key, str(value))
                self.fields.validate(value, '.%s' % key, object_title)

    # check instance state
        self.iam.printer('Initiating image of instance %s.' % instance_id)
        instance_state = self.check_instance_state(instance_id)

    # stop instance
        if instance_state == 'running':
            self.iam.printer('Instance %s is %s.\nStopping instance %s to image it.' % (instance_id, instance_state, instance_id))
            try:
                response = self.connection.stop_instances(
                    InstanceIds=[ instance_id ]
                )
                instance_state = response['StoppingInstances'][0]['CurrentState']['Name']
            except:
                raise AWSConnectionError(title)
        if instance_state == 'stopping':
            from time import sleep
            from timeit import timeit as timer
            self.iam.printer('Instance %s is %s' % (instance_id, instance_state), flush=True)
            delay = 3
            while instance_state == 'stopping':
                self.iam.printer('.', flush=True)
                sleep(delay)
                t3 = timer()
                try:
                    response = self.connection.describe_instances(
                        InstanceIds=[ instance_id ]
                    )
                except:
                    raise AWSConnectionError(title)
                t4 = timer()
                response_time = t4 - t3
                if 3 - response_time > 0:
                    delay = 3 - response_time
                else:
                    delay = 0
                instance_state = response['Reservations'][0]['Instances'][0]['State']['Name']
            self.iam.printer(' done.')
        if instance_state != 'stopped':
            raise Exception('Instance %s is currently in a state that cannot be imaged.' % instance_id)

    # discover tags associated with instance
        old_tags = []
        try:
            response = self.connection.describe_instances(
                    InstanceIds=[ instance_id ]
                )
            instance_tags = response['Reservations'][0]['Instances'][0]['Tags']
            import re
            aws_tag_pattern = re.compile('aws:')
            for i in range(0, len(instance_tags)):
                if not aws_tag_pattern.findall(instance_tags[i]['Key']):
                    tag = {}
                    tag['Key'] = instance_tags[i]['Key']
                    tag['Value'] = instance_tags[i]['Value']
                    old_tags.append(tag)
        except:
            raise AWSConnectionError(title)

    # replace tag list if new tag input
        new_tags = True
        if not tag_list:
            tag_list = self.iam.ingest(old_tags)
            new_tags = False

    # create image of the instance
        try:
            response = self.connection.create_image(
                InstanceId=instance_id,
                Name=image_name
            )
            image_id = response['ImageId']
            self.iam.printer('Image %s is being created.' % image_name)
        except:
            raise AWSConnectionError(title)

    # add tags to image
        self.tag_image(image_id, tag_list)
        if new_tags:
            self.iam.printer('Tags from input have been added to image %s.' % image_id)
        else:
            self.iam.printer('Instance %s tags have been added to image %s.' % (instance_id, image_id))

    # restart instance
        try:
            self.connection.start_instances(
                    InstanceIds=[ instance_id ]
            )
            self.iam.printer('Restarting instance %s now.' % instance_id)
        except:
            raise AWSConnectionError

        return image_id