def lambda_handler()

in static/Reliability/200_Testing_Backup_and_Restore_of_Data/Code/lambda_function.py [0:0]


def lambda_handler(event, context):
    print('Incoming Event:' + json.dumps(event))

    try:
        if event['Records'][0]['Sns']['Subject'] == 'Restore Test Status':
            print('No action required, deletion of new resource confirmed.')
            return
    except Exception as e:
            print(str(e))
            return

    job_type = event['Records'][0]['Sns']['Message'].split('.')[-1].split(' ')[1]

    try:
        if 'failed' in event['Records'][0]['Sns']['Message']:
            print('Something has failed. Please review the job in the AWS Backup console.')
            return 'Job ID:' + event['Records'][0]['Sns']['Message'].split('.')[-1].split(':')[1].strip()
        elif job_type == 'Backup':
            backup_job_id = event['Records'][0]['Sns']['Message'].split('.')[-1].split(':')[1].strip()
            backup_info = backup.describe_backup_job(
                            BackupJobId=backup_job_id
                        )
            #get backup job details
            recovery_point_arn = backup_info['RecoveryPointArn']
            iam_role_arn = backup_info['IamRoleArn']
            backup_vault_name = backup_info['BackupVaultName']
            resource_type = backup_info['ResourceType']

            metadata = backup.get_recovery_point_restore_metadata(
                BackupVaultName=backup_vault_name,
                RecoveryPointArn=recovery_point_arn
            )

            #determine resource type that was backed up and get corresponding metadata
            if resource_type == 'DynamoDB':
                metadata['RestoreMetadata']['targetTableName'] = metadata['RestoreMetadata']['originalTableName'] + '-restore-test'
            elif resource_type == 'EBS':
                ec2 = boto3.client('ec2')
                region = event['Records'][0]['Sns']['TopicArn'].split(':')[3]
                volumeid = event['Records'][0]['Sns']['Message'].split('.')[2].split('/')[1]

                metadata['RestoreMetadata']['availabilityZone'] = ec2.describe_volumes(
                VolumeIds=[
                    volumeid
                ]
                )['Volumes'][0]['AvailabilityZone']
            elif resource_type == 'RDS':
                metadata['RestoreMetadata']['DBInstanceIdentifier'] = event['Records'][0]['Sns']['Message'].split('.')[2].split(':')[7] + '-restore-test'
            elif resource_type == 'EFS':
                metadata['RestoreMetadata']['PerformanceMode'] = 'generalPurpose'
                metadata['RestoreMetadata']['newFileSystem'] = 'true'
                metadata['RestoreMetadata']['Encrypted'] = 'false'
                metadata['RestoreMetadata']['CreationToken'] = metadata['RestoreMetadata']['file-system-id'] + '-restore-test'
            elif resource_type == 'EC2':
                metadata['RestoreMetadata']['CpuOptions'] = '{}'
                metadata['RestoreMetadata']['NetworkInterfaces'] = '[]'

            #API call to start the restore job
            print('Starting the restore job')
            restore_request = backup.start_restore_job(
                    RecoveryPointArn=recovery_point_arn,
                    IamRoleArn=iam_role_arn,
                    Metadata=metadata['RestoreMetadata']
            )

            print(json.dumps(restore_request))

            return
        elif job_type == 'Restore':
            restore_job_id = event['Records'][0]['Sns']['Message'].split('.')[-1].split(':')[1].strip()
            topic_arn = event['Records'][0]['Sns']['TopicArn']
            restore_info = backup.describe_restore_job(
                            RestoreJobId=restore_job_id
                        )
            resource_type = restore_info['CreatedResourceArn'].split(':')[2]

            print('Restore from the backup was successful. Deleting the newly created resource.')

            #determine resource type that was restored and delete it to save cost
            if resource_type == 'dynamodb':
                dynamo = boto3.client('dynamodb')
                table_name = restore_info['CreatedResourceArn'].split(':')[5].split('/')[1]

                # Include recovery validation checks for DynamoDB here

                print('Deleting: ' + table_name)
                delete_request = dynamo.delete_table(
                                    TableName=table_name
                                )
            elif resource_type == 'ec2':
                ec2 = boto3.client('ec2')
                ec2_resource_type = restore_info['CreatedResourceArn'].split(':')[5].split('/')[0]
                if ec2_resource_type == 'volume':
                    volume_id = restore_info['CreatedResourceArn'].split(':')[5].split('/')[1]

                    # Include recovery validation checks for EBS here

                    print('Deleting: ' + volume_id)
                    delete_request = ec2.delete_volume(
                                VolumeId=volume_id
                            )
                elif ec2_resource_type == 'instance':
                    instance_id = restore_info['CreatedResourceArn'].split(':')[5].split('/')[1]
                    print('Validating data recovery before deletion.')

                    #validating data recovery
                    instance_details = ec2.describe_instances(
                                InstanceIds=[
                                    instance_id
                                ]
                            )
                    public_ip = instance_details['Reservations'][0]['Instances'][0]['PublicIpAddress']

                    http = urllib3.PoolManager()
                    url = public_ip
                    try:
                        resp = http.request('GET', url)
                        print("Received response:")
                        print(resp.status)

                        if resp.status == 200:
                            print('Valid response received. Data recovery validated. Proceeding with deletion.')
                            print('Deleting: ' + instance_id)
                            delete_request = ec2.terminate_instances(
                                        InstanceIds=[
                                            instance_id
                                        ]
                                    )
                            message = 'Restore from ' + restore_info['RecoveryPointArn'] + ' was successful. Data recovery validation succeeded with HTTP ' + str(resp.status) + ' returned by the application. ' + 'The newly created resource ' + restore_info['CreatedResourceArn'] + ' has been cleaned up.'
                        else:
                            print('Invalid response. Validation FAILED.')
                            message = 'Invalid response received: HTTP ' + str(resp.status) + '. Data Validation FAILED. New resource ' + restore_info['CreatedResourceArn'] + ' has NOT been cleaned up.'
                    except Exception as e:
                        print(str(e))
                        message = 'Error connecting to the application: ' + str(e)
            elif resource_type == 'rds':
                rds = boto3.client('rds')
                database_identifier = restore_info['CreatedResourceArn'].split(':')[6]

                # Include recovery validation checks for RDS here

                print('Deleting: ' + database_identifier)
                delete_request = rds.delete_db_instance(
                            DBInstanceIdentifier=database_identifier,
                            SkipFinalSnapshot=True
                        )
            elif resource_type == 'elasticfilesystem':
                efs = boto3.client('efs')
                elastic_file_system = restore_info['CreatedResourceArn'].split(':')[5].split('/')[1]

                # Include recovery validation checks for EFS here

                print('Deleting: ' + elastic_file_system)
                delete_request = efs.delete_file_system(
                            FileSystemId=elastic_file_system
                        )

            sns = boto3.client('sns')

            print('Sending final confirmation')
            #send a final notification
            notify = sns.publish(
                TopicArn=topic_arn,
                Message=message,
                Subject='Restore Test Status'
            )

            print(json.dumps(notify))

            return
    except Exception as e:
        print(str(e))
        return