def lambda_handler()

in templates/aws-cloudfront-waf/source/custom_resource/custom-resource.py [0:0]


def lambda_handler(event, context):
    log = logging.getLogger()
    responseStatus = 'SUCCESS'
    reason = None
    responseData = {}
    resourceId = event['PhysicalResourceId'] if 'PhysicalResourceId' in event else event['LogicalResourceId']
    result = {
        'StatusCode': '200',
        'Body': {'message': 'success'}
    }

    try:
        # ------------------------------------------------------------------
        # Set Log Level
        # ------------------------------------------------------------------
        log_level = str(os.getenv('LOG_LEVEL').upper())
        if log_level not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
            log_level = 'ERROR'
        log.setLevel(log_level)

        # ----------------------------------------------------------
        # Read inputs parameters
        # ----------------------------------------------------------
        log.info(event)
        request_type = event['RequestType'].upper() if ('RequestType' in event) else ""
        log.info(request_type)

        # ----------------------------------------------------------
        # Process event
        # ----------------------------------------------------------
        if event['ResourceType'] == "Custom::ConfigureAppAccessLogBucket":
            lambda_log_parser_function = event['ResourceProperties']['LogParser'] if 'LogParser' in event[
                'ResourceProperties'] else None
            lambda_partition_s3_logs_function = event['ResourceProperties'][
                'MoveS3LogsForPartition'] if 'MoveS3LogsForPartition' in event['ResourceProperties'] else None
            lambda_parser = True if event['ResourceProperties']['ScannersProbesLambdaLogParser'] == 'yes' else False
            athena_parser = True if event['ResourceProperties']['ScannersProbesAthenaLogParser'] == 'yes' else False

            if 'CREATE' in request_type:
                configure_s3_bucket(log, event['ResourceProperties']['Region'],
                                    event['ResourceProperties']['AppAccessLogBucket'])
                add_s3_bucket_lambda_event(log, event['ResourceProperties']['AppAccessLogBucket'],
                                           lambda_log_parser_function,
                                           lambda_partition_s3_logs_function,
                                           lambda_parser,
                                           athena_parser)

            elif 'UPDATE' in request_type:
                old_lambda_app_log_parser_function = event['OldResourceProperties']['LogParser'] if 'LogParser' in \
                                                                                                    event[
                                                                                                        'OldResourceProperties'] else None
                old_lambda_partition_s3_logs_function = event['OldResourceProperties']['MoveS3LogsForPartition'] \
                    if 'MoveS3LogsForPartition' in event['OldResourceProperties'] else None
                old_lambda_parser = True if event['OldResourceProperties'][
                                                'ScannersProbesLambdaLogParser'] == 'yes' else False
                old_athena_parser = True if event['OldResourceProperties'][
                                                'ScannersProbesAthenaLogParser'] == 'yes' else False

                if (event['OldResourceProperties']['AppAccessLogBucket'] != event['ResourceProperties'][
                    'AppAccessLogBucket'] or
                        old_lambda_app_log_parser_function != lambda_log_parser_function or
                        old_lambda_partition_s3_logs_function != lambda_partition_s3_logs_function or
                        old_lambda_parser != lambda_parser or
                        old_athena_parser != athena_parser):

                    remove_s3_bucket_lambda_event(log, event['OldResourceProperties']["AppAccessLogBucket"],
                                                  old_lambda_app_log_parser_function,
                                                  old_lambda_partition_s3_logs_function)
                    add_s3_bucket_lambda_event(log, event['ResourceProperties']['AppAccessLogBucket'],
                                               lambda_log_parser_function,
                                               lambda_partition_s3_logs_function,
                                               lambda_parser,
                                               athena_parser)

            elif 'DELETE' in request_type:
                remove_s3_bucket_lambda_event(log, event['ResourceProperties']["AppAccessLogBucket"],
                                              lambda_log_parser_function, lambda_partition_s3_logs_function)
        elif event['ResourceType'] == "Custom::ConfigureWafLogBucket":
            lambda_log_parser_function = event['ResourceProperties']['LogParser'] if 'LogParser' in event[
                'ResourceProperties'] else None
            lambda_partition_s3_logs_function = None
            lambda_parser = True if event['ResourceProperties']['HttpFloodLambdaLogParser'] == 'yes' else False
            athena_parser = True if event['ResourceProperties']['HttpFloodAthenaLogParser'] == 'yes' else False

            if 'CREATE' in request_type:
                add_s3_bucket_lambda_event(log, event['ResourceProperties']['WafLogBucket'],
                                           lambda_log_parser_function,
                                           lambda_partition_s3_logs_function,
                                           lambda_parser,
                                           athena_parser)

            elif 'UPDATE' in request_type:
                old_lambda_app_log_parser_function = event['OldResourceProperties']['LogParser'] if 'LogParser' in \
                                                                                                    event[
                                                                                                        'OldResourceProperties'] else None
                old_lambda_parser = True if event['OldResourceProperties'][
                                                'HttpFloodLambdaLogParser'] == 'yes' else False
                old_athena_parser = True if event['OldResourceProperties'][
                                                'HttpFloodAthenaLogParser'] == 'yes' else False

                if (event['OldResourceProperties']['WafLogBucket'] != event['ResourceProperties']['WafLogBucket'] or
                        old_lambda_app_log_parser_function != lambda_log_parser_function or
                        old_lambda_parser != lambda_parser or
                        old_athena_parser != athena_parser):
                    remove_s3_bucket_lambda_event(log, event['OldResourceProperties']["WafLogBucket"],
                                                  old_lambda_app_log_parser_function,
                                                  lambda_partition_s3_logs_function)
                    add_s3_bucket_lambda_event(log, event['ResourceProperties']['WafLogBucket'],
                                               lambda_log_parser_function,
                                               lambda_partition_s3_logs_function,
                                               lambda_parser,
                                               athena_parser)

            elif 'DELETE' in request_type:
                remove_s3_bucket_lambda_event(log, event['ResourceProperties']["WafLogBucket"],
                                              lambda_log_parser_function,
                                              lambda_partition_s3_logs_function)

        elif event['ResourceType'] == "Custom::ConfigureWebAcl":
            # Manually delete ip sets to avoid throttling occurred during stack deletion due to API call limit 
            if 'DELETE' in request_type:
                scope = os.getenv('SCOPE')
                if 'WAFWhitelistSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFWhitelistSetIPV4Name'],
                                  event['ResourceProperties']['WAFWhitelistSetIPV4'])
                if 'WAFBlacklistSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFBlacklistSetIPV4Name'],
                                  event['ResourceProperties']['WAFBlacklistSetIPV4'])
                if 'WAFHttpFloodSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFHttpFloodSetIPV4Name'],
                                  event['ResourceProperties']['WAFHttpFloodSetIPV4'])
                if 'WAFScannersProbesSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFScannersProbesSetIPV4Name'],
                                  event['ResourceProperties']['WAFScannersProbesSetIPV4'])
                if 'WAFReputationListsSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFReputationListsSetIPV4Name'],
                                  event['ResourceProperties']['WAFReputationListsSetIPV4'])
                if 'WAFBadBotSetIPV4' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFBadBotSetIPV4Name'],
                                  event['ResourceProperties']['WAFBadBotSetIPV4'])
                if 'WAFWhitelistSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFWhitelistSetIPV6Name'],
                                  event['ResourceProperties']['WAFWhitelistSetIPV6'])                    
                if 'WAFBlacklistSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFBlacklistSetIPV6Name'],
                                  event['ResourceProperties']['WAFBlacklistSetIPV6'])
                if 'WAFHttpFloodSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFHttpFloodSetIPV6Name'],
                                  event['ResourceProperties']['WAFHttpFloodSetIPV6'])
                if 'WAFScannersProbesSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFScannersProbesSetIPV6Name'],
                                  event['ResourceProperties']['WAFScannersProbesSetIPV6'])
                if 'WAFReputationListsSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFReputationListsSetIPV6Name'],
                                  event['ResourceProperties']['WAFReputationListsSetIPV6'])                    
                if 'WAFBadBotSetIPV6' in event['ResourceProperties']:
                    delete_ip_set(log, scope,
                                  event['ResourceProperties']['WAFBadBotSetIPV6Name'],
                                  event['ResourceProperties']['WAFBadBotSetIPV6'])

            send_anonymous_usage_data(log, event['RequestType'], event['ResourceProperties'])

        elif event['ResourceType'] == "Custom::ConfigureAWSWAFLogs":
            if 'CREATE' in request_type:
                put_logging_configuration(log, event['ResourceProperties']['WAFWebACLArn'],
                                          event['ResourceProperties']['DeliveryStreamArn'])

            elif 'UPDATE' in request_type:
                delete_logging_configuration(log, event['OldResourceProperties']['WAFWebACLArn'])
                put_logging_configuration(log, event['ResourceProperties']['WAFWebACLArn'],
                                          event['ResourceProperties']['DeliveryStreamArn'])

            elif 'DELETE' in request_type:
                delete_logging_configuration(log, event['ResourceProperties']['WAFWebACLArn'])

        elif event['ResourceType'] == "Custom::GenerateAppLogParserConfFile":
            stack_name = event['ResourceProperties']['StackName']
            error_threshold = int(event['ResourceProperties']['ErrorThreshold'])
            block_period = int(event['ResourceProperties']['WAFBlockPeriod'])
            app_access_log_bucket = event['ResourceProperties']['AppAccessLogBucket']

            if 'CREATE' in request_type:
                generate_app_log_parser_conf_file(log, stack_name, error_threshold, block_period, app_access_log_bucket,
                                                  True)
            elif 'UPDATE' in request_type:
                generate_app_log_parser_conf_file(log, stack_name, error_threshold, block_period, app_access_log_bucket,
                                                  False)

            # DELETE: do nothing

        elif event['ResourceType'] == "Custom::GenerateWafLogParserConfFile":
            stack_name = event['ResourceProperties']['StackName']
            request_threshold = int(event['ResourceProperties']['RequestThreshold'])
            block_period = int(event['ResourceProperties']['WAFBlockPeriod'])
            waf_access_log_bucket = event['ResourceProperties']['WafAccessLogBucket']

            if 'CREATE' in request_type:
                generate_waf_log_parser_conf_file(log, stack_name, request_threshold, block_period,
                                                  waf_access_log_bucket,
                                                  True)
            elif 'UPDATE' in request_type:
                generate_waf_log_parser_conf_file(log, stack_name, request_threshold, block_period,
                                                  waf_access_log_bucket,
                                                  False)
            # DELETE: do nothing

        elif event['ResourceType'] == "Custom::AddAthenaPartitions":
            if 'CREATE' in request_type or 'UPDATE' in request_type:
                add_athena_partitions(
                    log,
                    event['ResourceProperties']['AddAthenaPartitionsLambda'],
                    event['ResourceProperties']['ResourceType'],
                    event['ResourceProperties']['GlueAccessLogsDatabase'],
                    event['ResourceProperties']['AppAccessLogBucket'],
                    event['ResourceProperties']['GlueAppAccessLogsTable'],
                    event['ResourceProperties']['GlueWafAccessLogsTable'],
                    event['ResourceProperties']['WafLogBucket'],
                    event['ResourceProperties']['AthenaWorkGroup'])

            # DELETE: do nothing

    except Exception as error:
        log.error(error)
        responseStatus = 'FAILED'
        reason = str(error)
        result = {
            'statusCode': '500',
            'body': {'message': reason}
        }

    finally:
        # ------------------------------------------------------------------
        # Send Result
        # ------------------------------------------------------------------
        if 'ResponseURL' in event:
            send_response(log, event, context, responseStatus, responseData, resourceId, reason)

        return json.dumps(result)