In today’s fast-changing world of cloud computing, it’s crucial to manage AWS resources efficiently. One important task is keeping track of Reserved Instances (RIs) to save costs and use resources wisely. This guide will show you how to set up a simple system that sends AWS Reserved Instance alerts to Slack, helping you stay on top.
Reserved Instances (RIs) can save you a lot of money compared to On-Demand pricing in AWS. But if you don’t monitor them properly, they can expire without you noticing, leading to unexpected costs. You can stay informed about upcoming expirations by quickly automating alerts and taking action. This guide will teach you how to create a Lambda function that sends notifications to Slack, making it easy to integrate into your daily routine.
The Importance of Managing AWS Reserved Instances
Managing RIs effectively is critical for several reasons:
-
Cost Savings: RIs offer significant discounts over On-Demand pricing, helping you optimize your cloud spending.
-
Resource Utilization: Properly tracking RIs ensures that you are making the best use of your cloud resources without wasting or under-utilizing them.
-
Operational Efficiency: Automation of alerts reduces the manual effort involved in monitoring RIs, allowing your team to focus on more strategic tasks.
Practical Use Cases for RI Alerts
-
Finance Teams: Keeping track of RIs helps in budgeting and financial forecasting, ensuring that costs remain predictable and within allocated budgets.
-
IT Operations: IT teams can automate the monitoring process, ensuring that no RI expires unnoticed, which could lead to costly On-Demand charges.
-
Cloud Architects: They can use this system to maintain optimal infrastructure planning and scaling, ensuring resource availability and cost efficiency.
Step-by-Step Implementation
Step 1: Create a Lambda Function
-
Go to the AWS Management Console and find the Lambda service.
-
Click on the Create function.
-
Choose an Author from scratch.
-
Give your function a name, like
RIExpirationNotifier
, and select Python 3.13 as the runtime. -
Click the Create function.
Step 2: Configure the Lambda Function
- Create a file named
lambda_function.py
and add the following code:
import boto3 import datetime import os import json import urllib3 HOOK = os.environ["SLACK_HOOK"] EVAL_PERIOD_IN_DAYS = int(os.environ["EVAL_PERIOD_IN_DAYS"]) # Default is 30 days http = urllib3.PoolManager() ec2 = boto3.client('ec2') rds = boto3.client('rds') def lambda_handler(event, context): expiring_ec2_ris = check_ec2_reserved_instances() expiring_rds_ris = check_rds_reserved_instances() response = check_expiring_ris(expiring_ris=expiring_ec2_ris + expiring_rds_ris) print(response) def check_ec2_reserved_instances(): try: response = ec2.describe_reserved_instances() except Exception as e: notify_slack({"text": f"Error calling AWS API: {e}"}) return [] reserved_instances = response['ReservedInstances'] expiring_ec2_ris = [] for ri in reserved_instances: expiration_date = ri['End'] time_now = get_local_time() instance_type = ri["InstanceType"] expires_in = (expiration_date-time_now).days if 0 < expires_in <= EVAL_PERIOD_IN_DAYS: expiring_ec2_ris.append((instance_type, str(expires_in))) return expiring_ec2_ris def check_rds_reserved_instances(): try: response = rds.describe_reserved_db_instances() except Exception as e: notify_slack({"text": f"Error calling AWS API: {e}"}) return [] reserved_instances = response['ReservedDBInstances'] expiring_rds_ris = [] for ri in reserved_instances: duration = datetime.timedelta(seconds=ri['Duration']) expiration_date = ri['StartTime'] + duration time_now = get_local_time() instance_type = ri["DBInstanceClass"] expires_in = (expiration_date - time_now).days if 0 < expires_in <= EVAL_PERIOD_IN_DAYS: expiring_rds_ris.append((instance_type, str(expires_in))) return expiring_rds_ris def check_expiring_ris(expiring_ris): if expiring_ris: slack_message = read_json('slack_base_message.json') for instance_type, expires_in in expiring_ris: slack_message["blocks"].append({ "type": "section", "fields": [ {"type": "mrkdwn", "text": instance_type}, {"type": "mrkdwn", "text": f'{expires_in} days'} ] }) return notify_slack(slack_message=slack_message) return f'No expiring reserved instances {EVAL_PERIOD_IN_DAYS} days from now' def get_local_time(): return datetime.datetime.now(datetime.timezone.utc).astimezone() def notify_slack(slack_message): enc_msg = json.dumps(slack_message).encode('utf-8') http.request('POST', HOOK, body=enc_msg, headers={'Content-type': 'application/json'}) def read_json(path_to_json_file): with open(path_to_json_file, 'r') as file: return json.load(file)
-
Set the environment variables
SLACK_HOOK
andEVAL_PERIOD_IN_DAYS
in your Lambda function configuration. -
Deploy the Lambda function.
Step 3: Create JSON File for Slack Message Formatting
- Create a file named
slack_base_message.json
. - Copy and paste the following content into the file:
{ "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": ":mega: *The following reserved instances are about to expire:*" } }, { "type": "section", "fields": [ {"type": "mrkdwn", "text": ":computer: *Instance type*"}, {"type": "mrkdwn", "text": ":hourglass: *Expires in*"} ] } ] }
- Include this file in your Lambda function’s deployment package.
Step 4: Configure an EventBridge Schedule
-
Go to the AWS Management Console and navigate to the EventBridge service.
- Select Trigger configuration “EventBridge CloudWatch Events“
-
Click Create rule.
-
Enter a name for the rule, like
DailyRIExpirationCheck
. -
Under Rule type, select Schedule.
-
Set the schedule to run daily at 9 AM Philippine time using the cron expression
0 1 * * ? *
(since 9 AM Philippine time is 1 AM UTC). -
Choose the target Lambda function
RIExpirationNotifier
. -
Click Create.
Conclusion
Setting up Reserved Instance notifications via Slack is a proactive approach to managing your AWS resources effectively. By integrating AWS Budgets, Lambda, and EventBridge, you gain real-time insights into upcoming expirations, helping you maintain cost efficiency and avoid unexpected charges. This automated solution ensures that your team stays informed and can act swiftly to renew or adjust resources as needed. Start implementing this setup today to streamline your cloud resource management and enhance operational efficiency.