0

I have a below aws lambda code which is basically for ONTAP FileSystem monitoring and works if I do not integrate that to Dynamodb, while using this for now its giving me an error element does not match the schema.

Being a First time user of DynamoDB, i would love you seek some guidance on this.

Code:

import json
import os
import boto3
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    fsx = boto3.client('fsx')
    cloudwatch = boto3.client('cloudwatch') 
    ses = boto3.client('ses')
    region_name = os.environ['AWS_REGION']
    dynamodb = boto3.resource('dynamodb', region_name=region_name)
    dbtable = dynamodb.Table('FsxNMonitorFsx')
    now = datetime.utcnow()
    start_time = (now - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ')
    end_time = now.strftime('%Y-%m-%dT%H:%M:%SZ')
    table =  []
    result = []
    next_token = None
    while True:
        if next_token:
            response = fsx.describe_file_systems(NextToken=next_token)
        else:
            response = fsx.describe_file_systems()
        for filesystem in response.get('FileSystems'):
            filesystem_id = filesystem.get('FileSystemId')
            table.append(filesystem_id)
        next_token = response.get('NextToken')
        if not next_token:
            break
    try:
        # Create the DynamoDB table if it does not exist
        dbtable = dynamodb.create_table(
            TableName='FsxNMonitorFsx',
            KeySchema=[
                {
                    'AttributeName': filesystem_id,
                    'KeyType': 'HASH' 
                },
                {
                    'AttributeName': 'alert_sent',
                    'KeyType': 'RANGE'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': filesystem_id,
                    'AttributeType': 'S'
                },
                {
                    'AttributeName': 'alert_sent',
                    'AttributeType': 'B'
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )
        # Wait for the table to be created
        dbtable.meta.client.get_waiter('table_exists').wait(TableName='FsxNMonitorFsx')
    except ClientError as e:
        if e.response['Error']['Code'] != 'ResourceInUseException':
            raise
    # Code to retrieve metric data and check if alert needs to be sent
    for filesystem_id in table:
        response = cloudwatch.get_metric_data(
            MetricDataQueries=[
                {
                    'Id': 'm1',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageCapacity',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                },
                {
                    'Id': 'm2',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageUsed',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                }
            ],
            StartTime=start_time,
            EndTime=end_time
        )
        storage_capacity = response['MetricDataResults'][0]['Values']
        storage_used = response['MetricDataResults'][1]['Values']
        if storage_capacity:
            storage_capacity = storage_capacity[0]
        else:
            storage_capacity = None
        if storage_used:
            storage_used = storage_used[0]
        else:
            storage_used = None
        if storage_capacity and storage_used:
            percent_used = (storage_used / storage_capacity) * 100
        else:
            percent_used = None
        ######################################################################
        ### Check if an alert has already been sent for this filesystem_id ###
        ######################################################################
        response = dbtable.get_item(
            Key={'filesystem_id': filesystem_id}
                )
        if 'Item' in response:
            alert_sent = response['Item']['alert_sent']
        else:
            alert_sent = False
        # Send alert if storage usage exceeds threshold and no alert has been sent yet
        if percent_used > 80 and not alert_sent:
            email_body = "Dear Team,<br><br> Please Find the FSx ONTAP FileSystem Alert Report Below for the {} region.".format(region)
            email_body += "<br></br>"
            email_body += "<table>"
            email_body += "<tr>"
            email_body += "<th style='text-align: left'>FileSystemId</th>"
            email_body += "<th style='text-align: right'>Used %</th>"
            email_body += "</tr>"
            for fs in result:
                if fs['percent_used'] > 80:
                    email_body += "<tr>"
                    email_body += "<td style='text-align: left'>" + fs['filesystem_id'] + "</td>"
                    email_body += "<td style='text-align: right; color:red;'>" + str(round(fs['percent_used'], 2)) + "%</td>"
                    email_body += "</tr>"
            email_body += "</table>"
            email_body += "<br></br>"
            email_body += "Sincerely,<br>AWS FSx Alert Team"
            email_subject = "FSx ONTAP FileSystem Alert Report - {}".format(region) 
            ses.send_email(
                Source='[email protected]',
                Destination={
                    'ToAddresses': ['[email protected]'],
                },
                Message={
                    'Subject': {
                        'Data': email_subject
                    },
                    'Body': {
                        'Html': {
                            'Data': email_body
                        }
                    }
                }
            )
            dbtable.update_item(
                TableName='FsxNMonitorFsx',
                Key={'filesystem_id': {'S': filesystem_id}},
                UpdateExpression='SET alert_sent = :val',
                ExpressionAttributeValues={':val': {'BOOL': True}}
            )
    return {
        'statusCode': 200,
        'body': json.dumps('Email sent!')
    }
    

Result without using DB:

FileSystemId    Used %
fs-0c700005a823f755c    87.95%
fs-074999ef7111b8315    84.51%

Execution Error:

[ERROR] ClientError: An error occurred (ValidationException) when calling the GetItem operation: The provided key element does not match the schema

Code edit based on the feedback:

import os
import boto3, json
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError

fsx = boto3.client('fsx')
cloudwatch = boto3.client('cloudwatch')
ses = boto3.client('ses')
region_name = os.environ['AWS_REGION']
dynamodb = boto3.resource('dynamodb', region_name=region_name)


def lambda_handler(event, context):

    now = datetime.utcnow()
    start_time = (now - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ')
    end_time = now.strftime('%Y-%m-%dT%H:%M:%SZ')
    table = []
    result = []
    next_token = None
    while True:
        if next_token:
            response = fsx.describe_file_systems(NextToken=next_token)
        else:
            response = fsx.describe_file_systems()
        for filesystem in response.get('FileSystems'):
            filesystem_id = filesystem.get('FileSystemId')
            table.append(filesystem_id)
        next_token = response.get('NextToken')
        if not next_token:
            break
    try:
        # Create the DynamoDB table if it does not exist
        dbtable = dynamodb.Table('FsxNMonitorFsx')
        dbtable = dynamodb.create_table(
            TableName='FsxNMonitorFsx',
            KeySchema=[
                {
                    'AttributeName': 'filesystem_id',
                    'KeyType': 'HASH'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'filesystem_id',
                    'AttributeType': 'S'
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )
        # Wait for the table to be created
        dbtable.meta.client.get_waiter(
            'table_exists').wait(TableName='FsxNMonitorFsx')
    except ClientError as e:
        if e.response['Error']['Code'] != 'ResourceInUseException':
            raise
    # Code to retrieve metric data and check if alert needs to be sent
    for filesystem_id in table:
        response = cloudwatch.get_metric_data(
            MetricDataQueries=[
                {
                    'Id': 'm1',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageCapacity',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                },
                {
                    'Id': 'm2',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageUsed',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                }
            ],
            StartTime=start_time,
            EndTime=end_time
        )
        storage_capacity = response['MetricDataResults'][0]['Values']
        storage_used = response['MetricDataResults'][1]['Values']
        if storage_capacity:
            storage_capacity = storage_capacity[0]
        else:
            storage_capacity = None
        if storage_used:
            storage_used = storage_used[0]
        else:
            storage_used = None
        if storage_capacity and storage_used:
            percent_used = (storage_used / storage_capacity) * 100
        else:
            percent_used = None
        ######################################################################
        ### Check if an alert has already been sent for this filesystem_id ###
        ######################################################################
        response = dbtable.get_item(
            Key={'filesystem_id': filesystem_id}
                )
        if 'Item' in response:
            alert_sent = response['Item']['alert_sent']
        else:
            alert_sent = False
        # Send alert if storage usage exceeds threshold and no alert has been sent yet
        if percent_used > 80 and not alert_sent:
            email_body = "Dear Team,<br><br> Please Find the FSx ONTAP FileSystem Alert Report Below for the {} region.".format(
                region_name)
            email_body += "<br></br>"
            email_body += "<table>"
            email_body += "<tr>"
            email_body += "<th style='text-align: left'>FileSystemId</th>"
            email_body += "<th style='text-align: right'>Used %</th>"
            email_body += "</tr>"
            for fs in result:
                if fs['percent_used'] > 80:
                    email_body += "<tr>"
                    email_body += "<td style='text-align: left'>" + \
                        fs['filesystem_id'] + "</td>"
                    email_body += "<td style='text-align: right; color:red;'>" + \
                        str(round(fs['percent_used'], 2)) + "%</td>"
                    email_body += "</tr>"
            email_body += "</table>"
            email_body += "<br></br>"
            email_body += "Sincerely,<br>AWS FSx Alert Team"
            email_subject = "FSx ONTAP FileSystem Alert Report - {}".format(
                region_name)
            ses.send_email(
                Source='[email protected]',
                Destination={
                    'ToAddresses': ['[email protected]'],
                },
                Message={
                    'Subject': {
                        'Data': email_subject
                    },
                    'Body': {
                        'Html': {
                            'Data': email_body
                        }
                    }
                }
            )
            dbtable.put_item(
                Item={
                    'filesystem_id': filesystem_id,
                    'alert_sent': now.strftime('%Y-%m-%d %H:%M:%S')
                }
            )

    return {
        'statusCode': 200,
        'body': json.dumps('Email sent!')
    }

Above doesnt through any error but send empty e-mail and keep Db also empty, i'm lost a bit

enter image description here

2 Answers 2

2

You have another problem on your lambda function as well. You are creating table with variable of filesystem_id. I think you want to create table partition key as filesystem_id not with variable value of filesystem_id

dbtable = dynamodb.create_table(
            TableName='FsxNMonitorFsx',
            KeySchema=[
                {
                    'AttributeName': 'filesystem_id',
                    'KeyType': 'HASH' 
                },
                {
                    'AttributeName': 'alert_sent',
                    'KeyType': 'RANGE'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'filesystem_id',
                    'AttributeType': 'S'
                },
                {
                    'AttributeName': 'alert_sent',
                    'AttributeType': 'B'
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )

And you can not use get_item with only Hash_key you need you use query if you want to fetch data only with filesystem_id.

UPDATE LAMBDA CODE

import os
import boto3
import json
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError

fsx = boto3.client('fsx')
cloudwatch = boto3.client('cloudwatch')
ses = boto3.client('ses')
region_name = os.environ['AWS_REGION']
dynamodb = boto3.resource('dynamodb', region_name=region_name)
dbtable = dynamodb.Table('FsxNMonitorFsx')


def lambda_handler(event, context):

    now = datetime.utcnow()
    start_time = (now - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ')
    end_time = now.strftime('%Y-%m-%dT%H:%M:%SZ')
    filesystem_ids = []
    result = []
    next_token = None
    # get all filesystem_ids
    while True:
        if next_token:
            response = fsx.describe_file_systems(NextToken=next_token)
        else:
            response = fsx.describe_file_systems()
        for filesystem in response.get('FileSystems'):
            filesystem_id = filesystem.get('FileSystemId')
            filesystem_ids.append(filesystem_id)
        next_token = response.get('NextToken')
        if not next_token:
            break

    # create table if not exist
    # I think here is not good point to create table. (I prefer you create table outside of this lambda)
    try:
        # Create the DynamoDB table if it does not exist
        dbtable = dynamodb.create_table(
            TableName='FsxNMonitorFsx',
            KeySchema=[
                {
                    'AttributeName': 'filesystem_id',
                    'KeyType': 'HASH'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'filesystem_id',
                    'AttributeType': 'S'
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )
        # Wait for the table to be created
        dbtable.meta.client.get_waiter(
            'table_exists').wait(TableName='FsxNMonitorFsx')
    except ClientError as e:
        if e.response['Error']['Code'] != 'ResourceInUseException':
            raise

    # Code to retrieve metric data and check if alert needs to be sent
    for filesystem_id in filesystem_ids:
        response = cloudwatch.get_metric_data(
            MetricDataQueries=[
                {
                    'Id': 'm1',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageCapacity',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                },
                {
                    'Id': 'm2',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageUsed',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                }
            ],
            StartTime=start_time,
            EndTime=end_time
        )
        storage_capacity = response['MetricDataResults'][0]['Values']
        storage_used = response['MetricDataResults'][1]['Values']
        if storage_capacity:
            storage_capacity = storage_capacity[0]
        else:
            storage_capacity = None
        if storage_used:
            storage_used = storage_used[0]
        else:
            storage_used = None
        if storage_capacity and storage_used:
            percent_used = (storage_used / storage_capacity) * 100
        else:
            percent_used = None
        ######################################################################
        ### Check if an alert has already been sent for this filesystem_id ###
        ######################################################################
        response = dbtable.get_item(Key={'filesystem_id': filesystem_id})
        if 'Item' in response:
            alert_sent = response['Item']['alert_sent']
        else:
            alert_sent = False
        # Send alert if storage usage exceeds threshold and no alert has been sent yet
        if percent_used > 80 and not alert_sent:
            result.append({'filesystem_id': filesystem_id, 'percent_used': percent_used})

    header = f"""
                Dear Team,<br><br> Please Find the FSx ONTAP FileSystem Alert Report Below for the {region_name} region.
                <br></br>
                <table>
                <tr>
                <th style='text-align: left'>FileSystemId</th>
                <th style='text-align: right'>Used %</th>
                </tr>
                """
    body = ""
    for fs in result:
        body += f"""
                <tr>
                    <td style='text-align: left'>{fs['filesystem_id']}</td>
                    <td style='text-align: right; color:red;'>{str(round(fs['percent_used'], 2))}%</td>
                </tr>
                """

    footer = f"""</table>
                <br></br>
                Sincerely,<br>AWS FSx Alert Team
                FSx ONTAP FileSystem Alert Report - {region_name}
                """
    email_body = header + body + footer
    ses.send_email(
        Source='[email protected]',
        Destination={
            'ToAddresses': ['[email protected]'],
        },
        Message={
            'Subject': {
                'Data': "Emai Subject"
            },
            'Body': {
                'Html': {
                    'Data': email_body
                }
            }
        }
    )

    for fs in result:
        filesystem_id = fs['filesystem_id']
        dbtable.put_item(
            Item = {
                'filesystem_id': filesystem_id,
                'alert_sent': True
            }
        )
    return {
        'statusCode': 200,
        'body': json.dumps('Email sent!')
    }
Sign up to request clarification or add additional context in comments.

7 Comments

To get an item you need to provide the complete primary key. In your case, your key is composite (contains both hash and range) so you need to supply both the filesystem_id value (hash key) and the alert_sent value (range key) when calling get_item. If you want all items for a given filesystem_id then you can call query, supplying just the filesystem_id.
@user2023 not sure what you're asking me to do. Have you resolved the 2 problems that Mehmet pointed you at (incorrect attribute name and incorrect key supplied to get_item) and the code now works? If so, Mehmet should get credit for that. I was simply clarifying what was meant by the get_item/hash_key part of the answer.
@user2023 Can you explain what is not working? When I check your email template you have a for loop for fs in result: result is empty you dont push anything so that this loop will not executed.
@user2023 I explained your problem in my previous message your result object is empty so that you get an email with empty body. Check my updated answers code part.
My provided table creation is different with yours so that you are getting error. Can you drop your table then re-run lambda. It will create table for you. Your existing table has a compound key but you don't need it. Only filesystem_id is enough for table.
|
1

You are setting your table with a Partition Key and Sort Key, but your GetItem only indicates the Partition Key. You can do one of two things:

Supply Sort Key also

 response = dbtable.get_item(
            Key={
                'filesystem_id': filesystem_id,
                'alert_sent': alert_value
                }
             )

Use Query

Note: This option will return multiple items, if multiple items should exist for a given filesystem_id

response = dbtable.query(
    KeyConditionExpression='#id=:id',
    ExpressionAttributeValues={':id':filesystem_id},   
    ExpressionAttributeNames={'#id':'filesystem_id'}
)

Table Creation

filesystem_id should be a string not your variables value.

KeySchema=[
                {
                    'AttributeName': 'filesystem_id',
                    'KeyType': 'HASH' 
                },
                {
                    'AttributeName': 'alert_sent',
                    'KeyType': 'RANGE'
                }
            ],

Lambda clients

Clients should be created outside of the request handler

import json
import os
import boto3
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError
fsx = boto3.client('fsx')
cloudwatch = boto3.client('cloudwatch') 
ses = boto3.client('ses')
region_name = os.environ['AWS_REGION']
dynamodb = boto3.resource('dynamodb', region_name=region_name)
dbtable = dynamodb.Table('FsxNMonitorFsx')

def lambda_handler(event, context):


Code

import os
import boto3, json
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError

fsx = boto3.client('fsx')
cloudwatch = boto3.client('cloudwatch')
ses = boto3.client('ses')
region_name = os.environ['AWS_REGION']
dynamodb = boto3.resource('dynamodb', region_name=region_name)
dbtable = dynamodb.Table('FsxNMonitorFsx')

def lambda_handler(event, context):

    now = datetime.utcnow()
    start_time = (now - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ')
    end_time = now.strftime('%Y-%m-%dT%H:%M:%SZ')
    table = []
    result = []
    next_token = None
    while True:
        if next_token:
            response = fsx.describe_file_systems(NextToken=next_token)
        else:
            response = fsx.describe_file_systems()
        for filesystem in response.get('FileSystems'):
            filesystem_id = filesystem.get('FileSystemId')
            table.append(filesystem_id)
        next_token = response.get('NextToken')
        if not next_token:
            break
    try:
        # Create the DynamoDB table if it does not exist
        dbtable = dynamodb.create_table(
            TableName='FsxNMonitorFsx',
            KeySchema=[
                {
                    'AttributeName': 'filesystem_id',
                    'KeyType': 'HASH'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'filesystem_id',
                    'AttributeType': 'S'
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )
        # Wait for the table to be created
        dbtable.meta.client.get_waiter(
            'table_exists').wait(TableName='FsxNMonitorFsx')
    except ClientError as e:
        if e.response['Error']['Code'] != 'ResourceInUseException':
            raise
    # Code to retrieve metric data and check if alert needs to be sent
    for filesystem_id in table:
        response = cloudwatch.get_metric_data(
            MetricDataQueries=[
                {
                    'Id': 'm1',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageCapacity',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                },
                {
                    'Id': 'm2',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/FSx',
                            'MetricName': 'StorageUsed',
                            'Dimensions': [
                                {
                                    'Name': 'FileSystemId',
                                    'Value': filesystem_id
                                },
                                {
                                    'Name': 'StorageTier',
                                    'Value': 'SSD'
                                },
                                {
                                    'Name': 'DataType',
                                    'Value': 'All'
                                }
                            ]
                        },
                        'Period': 60,
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                }
            ],
            StartTime=start_time,
            EndTime=end_time
        )
        storage_capacity = response['MetricDataResults'][0]['Values']
        storage_used = response['MetricDataResults'][1]['Values']
        if storage_capacity:
            storage_capacity = storage_capacity[0]
        else:
            storage_capacity = None
        if storage_used:
            storage_used = storage_used[0]
        else:
            storage_used = None
        if storage_capacity and storage_used:
            percent_used = (storage_used / storage_capacity) * 100
        else:
            percent_used = None
        ######################################################################
        ### Check if an alert has already been sent for this filesystem_id ###
        ######################################################################
        response = dbtable.get_item(
            Key={'filesystem_id': filesystem_id}
                )
        if 'Item' in response:
            alert_sent = response['Item']['alert_sent']
        else:
            alert_sent = False
        # Send alert if storage usage exceeds threshold and no alert has been sent yet
        if percent_used > 80 and not alert_sent:
            email_body = "Dear Team,<br><br> Please Find the FSx ONTAP FileSystem Alert Report Below for the {} region.".format(
                region_name)
            email_body += "<br></br>"
            email_body += "<table>"
            email_body += "<tr>"
            email_body += "<th style='text-align: left'>FileSystemId</th>"
            email_body += "<th style='text-align: right'>Used %</th>"
            email_body += "</tr>"
            for fs in result:
                if fs['percent_used'] > 80:
                    email_body += "<tr>"
                    email_body += "<td style='text-align: left'>" + \
                        fs['filesystem_id'] + "</td>"
                    email_body += "<td style='text-align: right; color:red;'>" + \
                        str(round(fs['percent_used'], 2)) + "%</td>"
                    email_body += "</tr>"
            email_body += "</table>"
            email_body += "<br></br>"
            email_body += "Sincerely,<br>AWS FSx Alert Team"
            email_subject = "FSx ONTAP FileSystem Alert Report - {}".format(
                region_name)
            ses.send_email(
                Source='[email protected]',
                Destination={
                    'ToAddresses': ['[email protected]'],
                },
                Message={
                    'Subject': {
                        'Data': email_subject
                    },
                    'Body': {
                        'Html': {
                            'Data': email_body
                        }
                    }
                }
            )
            dbtable.update_item(
                TableName='FsxNMonitorFsx',
                Key={'filesystem_id': {'S': filesystem_id}},
                UpdateExpression='SET alert_sent = :val',
                ExpressionAttributeValues={':val': {'BOOL': True}}
            )
    return {
        'statusCode': 200,
        'body': json.dumps('Email sent!')
    }

3 Comments

-@Lee Hannigan, thanks a lot for explaining , So when you say use Query that mean i should remove dbtable.get_item? Would you mind keeping the whole code into a right formate that will help me learning out of it about how to fit it in a proper way.
I've not tested your code as there are too many moving parts to replicate in a short timeframe. But what I done was remove the sort key from your table, you were using a BOOL but defined it as a Binary, which was never going to work either. I assume filesystem_id will be unique.
This doesn't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.