Lambda function not working

0

So I am trying to develop a lambda function that can check for maintenance to be done on RDS Instances and if they need to be upgraded. I also wanted to be able to see if my EKS cluster has an Upgrade to be done like it would say in the Upgrade Insights to update to a newer Kubernetes Version, however my lambda function says that the 'EKS' object has no attribute 'list_insights', but according to the boto3 doc it should exist, the reason I am doing this is to be able to get an E-mail telling me if those resources need to be updated or upgraded.

import boto3

def lambda_handler(event, context): rds = boto3.client('rds') sns = boto3.client('sns') eks = boto3.client('eks')

try:
    # Retrieve information about pending maintenance actions
    response_maintenance = rds.describe_pending_maintenance_actions()
    pending_actions_rds = response_maintenance.get('PendingMaintenanceActions', [])

    # Retrieve information about RDS instances
    response_instances = rds.describe_db_instances()
    db_instances = response_instances.get('DBInstances', [])

    # Retrieve information about Amazon EKS clusters
    response_clusters = eks.list_clusters()
    cluster_names = response_clusters.get('clusters', [])
    


    
    
    # Get AWS account ID and region
    aws_account_id = context.invoked_function_arn.split(':')[4]
    aws_region = context.invoked_function_arn.split(':')[3]
    
    
    message = (f"AWS Account ID: {aws_account_id}\n"
               f"AWS Region: {aws_region}\n\n")
    
    
    
    
    
    if pending_actions_rds:
        message += "Pending Maintenance Actions (RDS):\n"
        for action in pending_actions_rds:
            message += (f"Resource Identifier: {action.get('ResourceIdentifier', 'N/A')}\n"
                        f"Action: {action.get('Action', 'N/A')}\n"
                        f"Description: {action.get('Description', 'N/A')}\n\n")
    else:
        message += "No pending maintenance actions for RDS instances.\n\n"
    
    # Check if RDS instances need updates
    message += "RDS Instances:\n"
    for instance in db_instances:
        db_identifier = instance.get('DBInstanceIdentifier', 'N/A')
        db_engine = instance.get('Engine', 'N/A')
        maintenance_window = instance.get('PreferredMaintenanceWindow', 'N/A')
        engine_version = instance.get('EngineVersion', 'N/A')
        latest_engine_version = instance.get('LatestRestorableTime', 'N/A')
        
        if engine_version != latest_engine_version:
            message += (f"DB Identifier: {db_identifier}\n"
                        f"DB Engine: {db_engine}\n"
                        f"Current Engine Version: {engine_version}\n"
                        f"Latest Engine Version: {latest_engine_version}\n"
                        f"Maintenance Window: {maintenance_window}\n"
                        "Needs Update: Yes\n\n")
        else:
            message += (f"DB Identifier: {db_identifier}\n"
                        f"DB Engine: {db_engine}\n"
                        f"Current Engine Version: {engine_version}\n"
                        f"Latest Engine Version: {latest_engine_version}\n"
                        f"Maintenance Window: {maintenance_window}\n"
                        "Needs Update: No\n\n")



    # Check for updates on Amazon EKS clusters
    message += "Amazon EKS Clusters:\n"
    for cluster_name in cluster_names:
        cluster_info = eks.describe_cluster(name=cluster_name)
        cluster_status = cluster_info.get('cluster', {}).get('status', 'N/A')
        current_version = cluster_info.get('cluster', {}).get('version', 'N/A')
        
        # Retrieve information about available updates
        response_insights = eks.list_insights(
            clusterName=cluster_name
        )
        available_updates = response_insights.get('insights ', {})
        
        if available_updates:
            message += (f"Cluster Name: {cluster_name}\n"
                        f"Cluster Status: {cluster_status}\n"
                        f"Current Version: {current_version}\n"
                        "Available Updates:\n")
            for update_id in available_updates:
                message += f"  - {update_id}\n"
            message += "Upgrade Available: Yes\n\n"
        else:
            message += (f"Cluster Name: {cluster_name}\n"
                        f"Cluster Status: {cluster_status}\n"
                        f"Current Version: {current_version}\n"
                        "Upgrade Available: No\n\n")



    # Publish the message to the SNS topic
    sns.publish(
        TopicArn = 'arn:aws:sns:eu-west-1:{accountid}:{name}', 
        Message = message,
        Subject = 'RDS Maintenance/Update and EKS Update Report'  
    )

    print('Notification sent:\n', message)

except Exception as e:
    print('Error:', str(e))
3 Answers
0

The issue you're encountering is likely due to a typo in the attribute name used to retrieve insights from Amazon EKS clusters. Here's the corrected portion of your code

# Retrieve information about available updates
response_insights = eks.list_insights(
    clusterName=cluster_name
)
available_updates = response_insights.get('insights', {})          # Corrected attribute name

In the response_insights.get('insights', {}) line, make sure to use 'insights' instead of 'insights '. The extra space in 'insights ' causes the attribute name to be incorrect, resulting in the error you're experiencing. With this correction, your Lambda function should be able to retrieve insights from Amazon EKS clusters successfully. Let me know if you encounter any further issues!

Hope it clarifies and if does I would appreciate answer to be accepted so that community can benefit for clarity, thanks ;)

profile picture
answered a month ago
  • Good eye, but sadly the issues still persists :(

0

I think I found the issue, when trying to see which version of boto3 the lambda function uses it shows version 1.27.1 and according to the changelogs as far as I have found the eks insights capability was added on the version 1.34.5... Can anyone tell me if I am correct? I'm still new to AWS and am not 100% certain

answered a month ago
0

Are you looking only for resources that are able to be upgraded and send a message? You might have better luck with EventBridge and AWS Health Messages.

You could create an EventBridge rule for these types of messages and send those events to different services or endpoints. Depending on your required business logic, you could simplify your lambda to do some basic tasks, such as look up the business owner on a table, or if you store this data on the resource tags, you could read those tags and use this data to fwd to those folks using sns, or even a slack webhook.

A simple event bridge rule could look like the following. These events include the resource name and you would send these messages to an endpoint of your choice.

{
   “source”: “aws.health”,
    “detail”: {
        “eventTypeCode”: [
            “AWS_RDS_OPERATIONAL_NOTIFICATION”,
            “AWS_RDS_PLANNED_LIFECYCLE_EVENT"
            ]
    }
}

[1] Monitoring AWS Health events with Amazon EventBridge - https://docs.aws.amazon.com/health/latest/ug/cloudwatch-events-health.html.

[2] Monitoring AWS Health events with Amazon EventBridge - Creating an EventBridge rule for AWS Health - https://docs.aws.amazon.com/health/latest/ug/cloudwatch-events-health.html#creating-event-bridge-events-rule-for-aws-health

profile pictureAWS
answered a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions