Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jupyter-naas
GitHub Repository: jupyter-naas/awesome-notebooks
Path: blob/master/AWS/AWS_Send_daily_biling_notification_to_Slack.ipynb
2973 views
Kernel: Python 3

AWS.png

AWS - Send daily biling notification to Slack

Give Feedback | Bug report

Tags: #aws #cloud #storage #slack #operations #automation #naas #asset #scheduler

Last update: 2023-11-20 (Created: 2021-09-14)

Description: This notebook utilizes AWS API and Slack integration to send a daily notification to a designated Slack channel. The notification includes detailed billing information from an AWS account, enabling users to effortlessly track and monitor their AWS spending. Stay informed about your AWS costs with automated daily updates.

Input

Import libraries

from datetime import date, timedelta try: import boto3 except: !pip install boto3 import boto3 import naas import dateutil.relativedelta import pandas as pd from naas_drivers import slack

Setup variables

Mandatory

  • aws_access_key_id: This variable is used to store the AWS access key ID.

  • aws_secret_access_key: This variable is used to store the AWS secret access key.

  • slack_token: This variable is used to store the Slack token.

  • slack_channel: This variable is used to specify the Slack channel.

Optional

  • cron: This variable is used to define the cron schedule for executing the code.

  • file_path: This variable is used to define csv file path to be stored in local with billing details.

# Mandatory aws_access_key_id = naas.secret.get("AWS_ACCESS_KEY_ID") or "YOUR_AWS_ACCESS_KEY_ID" aws_secret_access_key = naas.secret.get("AWS_SECRET_ACCESS_KEY") or "YOUR_AWS_SECRET_ACCESS_KEY" slack_token = naas.secret.get(name="SLACK_TOKEN") or "YOUR_SLACK_TOKEN" slack_channel = "bot-test" # Optional cron = "0 9 * * *" file_path = f"billing_aws_{date.today().isoformat()[:-3]}.csv"

Model

Constants

# Compute dates def last_day_of_month(any_day): # this will never fail # get close to the end of the month for any day, and add 4 days 'over' next_month = any_day.replace(day=28) + timedelta(days=4) # subtract the number of remaining 'overage' days to get last day of current month, or said programattically said, the previous day of the first of next month return next_month - timedelta(days=next_month.day) today = date.today() lastDay = last_day_of_month(today) start_month_date = today - dateutil.relativedelta.relativedelta(months=12) start_date = "{}-{:02d}-{:02d}".format(today.year, today.month, 1) end_date = "{}-{:02d}-{:02d}".format(today.year, today.month, today.day) last_day = "{}-{:02d}-{:02d}".format(lastDay.year, lastDay.month, lastDay.day) print("Start date:", start_date) print("End date:", end_date) print("Last day:", last_day)

Connect to AWS

client = boto3.client( "ce", aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, )

Get current cost from AWS billing

# Get current cost from AWS billing result = client.get_cost_and_usage( TimePeriod={"Start": start_date, "End": end_date}, Granularity="MONTHLY", Metrics=["BlendedCost"], GroupBy=[ {"Type": "DIMENSION", "Key": "SERVICE"}, {"Type": "DIMENSION", "Key": "USAGE_TYPE"}, ], ) # Transform current billing to dataframe data_billing = [] for t in result["ResultsByTime"]: for r in t["Groups"]: dimension = r["Keys"][0] usage_type = r["Keys"][1] amount = r["Metrics"]["BlendedCost"]["Amount"] period_start = t["TimePeriod"]["Start"] period_end = t["TimePeriod"]["End"] data_billing.append( { "Dimension": dimension, "UsageType": usage_type, "Amount": amount, "PeriodStart": period_start, "PeriodEnd": period_end, } ) # Create dataframe df_billing = pd.DataFrame(data_billing).astype({"Amount": "float"}) # Display result current_amount = df_billing["Amount"].sum() print("Current Amount:", round(current_amount, 2)) df_billing.head(5)

Get forecast from AWS

ce_forecast = client.get_cost_forecast( TimePeriod={"Start": end_date, "End": last_day}, Metric="BLENDED_COST", Granularity="MONTHLY", ) forecast = float(ce_forecast["Total"]["Amount"]) print("Forecast Amount:", round(forecast, 2))

Save current billing to csv

df_billing.to_csv(file_path) asset_link = naas.asset.add(path=file_path)

Create message for slack

message = """ Hey there, This is your daily AWS billing notification. - Current spending: [*{:.2f}$*] - Forecast left to spent: [*{:.2f}$*] - End of month estimate: [*{:.2f}$*] <{}|Download the detailed csv file> """.format( float(current_amount), float(forecast), float(current_amount - forecast), asset_link ) image_url = None # Set to None if you don't need it print(message)

Output

Send data to slack

slack.connect(slack_token).send(slack_channel, message)

Add scheduler

naas.scheduler.add(cron=cron) # naas.scheduler.delete()