Petru Porumbescu

0 %
Petru Porumbescu
AWS Certified Developer & Solutions Architect | Python | Git & GitHub | Terraform | Docker
  • Residence:
    United Kingdom
  • Age:
    35
Licenses & Certifications:
  • AWS Certified Developer
  • AWS Certified Solutions Architect
  • HashiCorp Terraform Associate
  • Python for Beginners
  • Pythonic Programming
  • Developing on AWS
  • Python-based Microservices
English
Romanian
Skills:
  • Amazon Web Services (AWS)
  • Cloud Computing
  • Python Programming
  • Docker
  • Terraform
  • Git and Github
  • Linux, Windows, MacOS
  • WordPress
  • Microsoft Office Suite
  • Microsoft 365
  • Microsoft Teams
  • Slack
  • Leadership
  • Communication
  • Troubleshooting
  • Teamwork & Collaboration

Automating AWS EC2 Instance Status Checks with Python

March 21, 2024

Introduction

Welcome to my latest blog post, where I dive into the world of automation with Python, a language that has fascinated me since I began my programming journey. As someone who is currently studying Python, I’ve been eager to test my skills by tackling real-world problems. This post is a reflection of that endeavour, showcasing a script I developed to automate the monitoring of AWS EC2 instances.
“In this post, I’ll share a Python script that automates the process of checking the status of AWS EC2 instances and sends email notifications if the status is not ‘ok’. This is particularly useful for system administrators and DevOps engineers who need to keep an eye on their AWS infrastructure.”
By sharing this script, I hope not only to demonstrate what I’ve learned but also to contribute to the community that has been instrumental in my learning process. Whether you’re a seasoned developer or just starting like me, I believe there’s something valuable to be found in automating mundane tasks and focusing on what truly matters. So, without further ado, let’s dive into the script and explore how it works, step by step.

Prerequisites

Before running the script, make sure you have the following:

  • AWS credentials configured on your machine
  • Required Python libraries installed: boto3schedule
  • Environment variables set for EMAIL_ADDRESS and EMAIL_PASSWORD to send email notifications

Script Walkthrough

Let’s go through the script step by step:

  1. Importing Libraries: The script starts by importing the necessary libraries, including boto3 for interacting with AWS services, schedule for scheduling tasks, logging for logging messages, smtplib for sending emails, time for adding delays, and os for retrieving environment variables.
  2. Configuring Logging: The script configures logging to display log messages with timestamps and log levels.
  3. Initializing AWS Client: The script retrieves the AWS region from an environment variable or defaults to ‘us-east-1’. It then initializes the boto3 client for EC2 in the specified region.
  4. Retrieving Email Credentials: The script retrieves the email address and password from environment variables to be used for sending notifications.
  5. Sending Email Notification: The send_notification function is responsible for sending an email notification when an instance’s status is not ‘ok’. It uses the smtplib library to establish a connection with the SMTP server, logs in with the provided credentials, and sends an email with the instance details and status.
  6. Checking Instance Status: The check_instance_status function is the core of the script. It uses the describe_instance_status API to retrieve the status of all instances in the specified region. It iterates over the instances and checks their instance status and system status. If either status is not ‘ok’, it calls the send_notification function to send an email notification.
  7. Scheduling the Status Check: The script uses the schedule library to schedule the check_instance_status function to run every 5 seconds (or any desired interval).
  8. Running the Script: The script enters a loop that continuously runs the scheduled tasks until it is terminated by the user using a keyboard interrupt (Ctrl+C).

Error Handling

The script includes error handling to catch and log any exceptions that may occur during execution. It handles specific exceptions like ClientError and BotoCoreError for AWS-related errors and catches any other exceptions using a generic Exception block.

For those interested in implementing or adapting this script, here’s the complete code:

import boto3
import schedule
import logging
import smtplib
import time
import os
from botocore.exceptions import ClientError, BotoCoreError

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Retrieve the AWS region from an environment variable or default to a specific region
AWS_REGION = os.environ.get('AWS_REGION', 'us-east-1')

# Initialize boto3 client for a specific region
ec2_client = boto3.client('ec2', region_name=AWS_REGION)

# Retrieve email address and password from environment variables
EMAIL_ADDRESS = os.environ.get('EMAIL_ADDRESS')
EMAIL_PASSWORD = os.environ.get('EMAIL_PASSWORD')


def send_notification(instance_id, status_type, status):
    try:
        with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
            smtp.starttls()
            smtp.ehlo()
            smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
            subject = f"Instance {instance_id} - {status_type} Status: {status}"
            body = f"Instance {instance_id} has {status_type} status: {status}. Please check the instance."
            msg = f"Subject: {subject}\n\n{body}"
            smtp.sendmail(EMAIL_ADDRESS, EMAIL_ADDRESS, msg)
            logging.info(f"Email notification sent for instance {instance_id}")
    except smtplib.SMTPAuthenticationError as e:
        logging.error(f"SMTP authentication error: {e}")
    except Exception as e:
        logging.error(f"An error occurred while sending email: {e}")


def check_instance_status():
    try:
        # Describe all instances' status in the specified region
        paginator = ec2_client.get_paginator('describe_instance_status')
        page_iterator = paginator.paginate(IncludeAllInstances=True)

        for page in page_iterator:
            for status in page.get('InstanceStatuses', []):
                instance_id = status.get('InstanceId', 'N/A')
                ins_status = status['InstanceStatus'].get('Status', 'N/A')
                sys_status = status['SystemStatus'].get('Status', 'N/A')
                state = status['InstanceState'].get('Name', 'N/A')
                logging.info(
                    f"Instance {instance_id} in region {AWS_REGION} is {state} with instance status {ins_status} and system status {sys_status}")

                # Send notification if instance or system status is not 'ok'
                if ins_status != 'ok':
                    send_notification(instance_id, "Instance", ins_status)
                if sys_status != 'ok':
                    send_notification(instance_id, "System", sys_status)

    except (ClientError, BotoCoreError) as e:
        logging.error(f"An AWS error occurred: {e}")
    except Exception as e:
        logging.error(f"An error occurred: {e}")


# Schedule the function to run every 5 seconds (or use a configurable interval)
schedule.every(5).seconds.do(check_instance_status)

try:
    # Run the schedule as long as the script is running
    while True:
        schedule.run_pending()
        time.sleep(1)
except KeyboardInterrupt:
    logging.info("Script was terminated by the user")

Conclusion

This script provides a convenient way to monitor the status of EC2 instances in a specific AWS region and receive email notifications when an instance’s status is not ‘ok’. By leveraging the boto3 library and scheduling tasks with schedule, the script automates the monitoring process and keeps you informed about the health of your instances.Feel free to customize the script based on your specific requirements, such as adjusting the monitoring interval or modifying the email notification content.Remember to set up the necessary environment variables and ensure that your AWS credentials have the required permissions to describe instance status.Happy monitoring!

Posted in Python
Write a comment