#!/usr/bin/env python """ reconciler_notifications.py: Lambda that subscribes to an SNS topic. The SNS topic receives notifications related to AMI tag reconciliation events. The reconciler process ensures that the AMI Lifecycle generated AMI tags match the AMI metadata stored in DynamoDB. """ import datetime import json import logging import os import time import traceback import uuid import boto3 # set logging logger = logging.getLogger() logger.setLevel(logging.DEBUG) # boto3 client = boto3.client('logs') # environment variables LOG_GROUP_NAME = os.environ['LOG_GROUP_NAME'] def lambda_handler(event, context): # print the event details logger.debug(json.dumps(event, indent=2)) try: if event and event["Records"]: logger.info(f"New event consumed consisting of {len(event['Records'])} record(s).") for record in event["Records"]: if 'Sns' in record: logger.debug(json.dumps(record['Sns'], indent=2)) sns_record = record['Sns'] log_stream_name = f"{datetime.datetime.now().strftime('%Y/%m/%d/')}{uuid.uuid4()}" logger.debug(f"log_stream_name == {log_stream_name}") # check if the log stream exists describe_response = client.describe_log_streams( logGroupName=LOG_GROUP_NAME, logStreamNamePrefix=log_stream_name, limit=1 ) logger.debug(json.dumps(describe_response, indent=2)) create_log_stream = True if 'logStreams' in describe_response: if len(describe_response['logStreams']) > 0: create_log_stream = False if 'uploadSequenceToken' in describe_response['logStreams'][0]: sequence_token = describe_response['logStreams'][0]['uploadSequenceToken'] timestamp = int(round(time.time() * 1000)) if create_log_stream: client.create_log_stream(logGroupName=LOG_GROUP_NAME, logStreamName=log_stream_name) log_response = client.put_log_events( logGroupName=LOG_GROUP_NAME, logStreamName=log_stream_name, logEvents=[ { 'timestamp': timestamp, 'message': time.strftime('%Y-%m-%d %H:%M:%S') + "\t" + sns_record['Message'] } ] ) else: log_response = client.put_log_events( logGroupName=LOG_GROUP_NAME, logStreamName=log_stream_name, logEvents=[ { 'timestamp': timestamp, 'message': time.strftime('%Y-%m-%d %H:%M:%S') + "\t" + sns_record['Message'] } ], sequenceToken=sequence_token ) except Exception as e: traceback.print_exception(type(e), value=e, tb=e.__traceback__) logger.error(f'AMI Orchestrator Reconciliation Notifier error: {str(e)}') raise ValueError(e)