Automating AWS Billing Notifications: Building a Serverless Solution with AWS Lambda and Telegram Integration

Automating AWS Billing Notifications: Building a Serverless Solution with AWS Lambda and Telegram Integration

Introduction :-

In the rapidly evolving landscape of cloud computing, managing costs is a paramount concern. Keeping a close eye on your AWS billing information is crucial for financial oversight and optimization. This guide explores a serverless solution to receive AWS billing updates in real-time, leveraging the power of AWS Lambda and the convenience of Telegram, a widely used messaging platform.

Pre-requestites :-

  • An Aws account with full access

  • Telegram account.

Setting-up a Telegram Bot --

  1. Open the Telegram app and search for “BotFather.”

  2. Start a chat with BotFather by using the /start command. Upon initiating the chat, BotFather will present a list of commands.Within the list of commands, utilize the /newbot command to create a new bot.

  3. Provide a name and username for the new bot as per your preference. Follow the setup instructions prompted by BotFather.

  4. Once the setup is complete, make a note of the API Token for your new bot. The API Token is typically displayed in the following format: 1234567890:ABCdefghIJKlmnOpqrstUVWxyz1234567890 as shown in the below picture.

Creating a Lambda Function :-

  1. Login to the AWS Management Console and navigate to the IAM service.

  2. Create an IAM Policy with the below provided JSON Policy.

  3. Note : Please add the YOUR_ACCOUNT_ID in below IAM Policy befor using.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:YOUR_ACCOUNT_ID:*",
                "arn:aws:logs:us-east-1:YOUR_ACCOUNT_ID:log-group:/aws/lambda/aws_monitoring:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ce:*",
                "budgets:*"
            ],
            "Resource": "*"
        }
    ]
}

4. Create an IAM Role with Lambda Full Permissions and attach the above Created IAM Policy to the role and Note down the ARN of the created IAM Role.

5. Now Navigate to the Lambda service and Create a Function with with Python 3.9/3/10 runtime.

6. Configure Basic Information:

  • Function Name: Enter a name for your function, e.g., “Billing-Function”

  • Runtime: Choose “Python 3.9” or any version that supports your code.

  • Execution Role: Choose “Use an existing role” and select the IAM role you created in above steps.

7. Copy and paste the provided Python code into the Lambda function code editor and replace the Api token and Chat-id with your values. To get TELEGRAM_CHAT_ID, please go to https://t.me/RawDataBot bot and type /start to get your chat id.

import os
import json
import boto3
import requests
from datetime import datetime, timedelta

TELEGRAM_API_TOKEN = "YOUR API TOKEN"
TELEGRAM_CHAT_ID = "YOUR CHAT-ID"
AWS_REGION = 'us-east-1'  # Change to your AWS region
YOUR_AWS_ACCOUNT_ID="YOUR AWS Account-id"

def send_telegram_message(message):
    url = f'https://api.telegram.org/bot{TELEGRAM_API_TOKEN}/sendMessage'
    params = {
        'chat_id': TELEGRAM_CHAT_ID,
        'text': message,
        'parse_mode': 'Markdown'  # Specify MarkdownV2 parsing mode
    }

    response = requests.get(url, params=params)
    if response.status_code != 200:
        print(f"Failed to send message to Telegram. Status code: {response.status_code}")
    else:
        print("Message sent successfully to Telegram.")

def lambda_handler(event, context):
    # Set up AWS Cost Explorer client
    ce_client = boto3.client('ce', region_name=AWS_REGION)

    # Get today's date
    current_date = datetime.utcnow().strftime('%Y-%m-%d')
    start_of_month = datetime.utcnow().replace(day=1).strftime('%Y-%m-%d')
    last_month_start = (datetime.utcnow().replace(day=1) - timedelta(days=1)).replace(day=1).strftime('%Y-%m-%d')

    # Get month-to-date cost
    mtd_response = ce_client.get_cost_and_usage(
        TimePeriod={'Start': start_of_month, 'End': current_date},
        Granularity='MONTHLY',
        Metrics=['BlendedCost']
    )
    month_to_date_cost = round(float(mtd_response['ResultsByTime'][0]['Total']['BlendedCost']['Amount']),2)

    # Get last month's total cost
    last_month_response = ce_client.get_cost_and_usage(
        TimePeriod={'Start': last_month_start, 'End': start_of_month},
        Granularity='MONTHLY',
        Metrics=['BlendedCost']
    )
    last_month_cost = round(float(last_month_response['ResultsByTime'][0]['Total']['BlendedCost']['Amount']),2)

    # Compose message
    message = (
        f"*AWS Billing Info:*\n"
        f"_Month-to-date Cost:_ *{month_to_date_cost} USD*\n"
        f"_Last Month's Total Cost:_ *{last_month_cost} USD*\n"
    )
    print(message)

    # Send message to Telegram
    send_telegram_message(message)

8. Save the Function and Test it by configuring a test event.

9. Check your Telegram Bot for the AWS billing information.

Note :- If you’re facing issue while testing the function then clone the code from our source-code repository and Replace the Token and Chat-id Values with your values and install the requirements then upload the file via making it as a zip and then test it.

#use below command to install requirements
pip install -r requirements.txt -t .

#use below command to create a zip file.
zip lambda_function.zip -r .

Conclusion :-

Embracing serverless architecture not only enhances efficiency but also provides a cost-effective and scalable solution. By integrating AWS Lambda with Telegram, we’ve created a seamless channel for receiving immediate billing updates. This not only ensures timely financial insights but also reflects the innovative ways in which serverless technologies can be harnessed for practical, real-world applications. As organizations strive for greater agility and automation, this approach represents a step forward in optimizing cloud management processes.