diff --git a/AWS/AWS_Get_cost_and_usage_by_service_and_type.ipynb b/AWS/AWS_Get_cost_and_usage_by_service_and_type.ipynb new file mode 100644 index 0000000000..8094e34d12 --- /dev/null +++ b/AWS/AWS_Get_cost_and_usage_by_service_and_type.ipynb @@ -0,0 +1,629 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266852e3", + "metadata": { + "execution": { + "iopub.execute_input": "2021-09-14T08:04:28.994722Z", + "iopub.status.busy": "2021-09-14T08:04:28.994452Z", + "iopub.status.idle": "2021-09-14T08:04:29.005991Z", + "shell.execute_reply": "2021-09-14T08:04:29.005065Z", + "shell.execute_reply.started": "2021-09-14T08:04:28.994658Z" + }, + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "\"AWS.png\"" + ] + }, + { + "cell_type": "markdown", + "id": "b6c7847d", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "# AWS - Get cost and usage by service and type\n", + "

Give Feedback | Bug report" + ] + }, + { + "cell_type": "markdown", + "id": "f5907052", + "metadata": { + "execution": { + "iopub.execute_input": "2021-09-14T08:05:41.428494Z", + "iopub.status.busy": "2021-09-14T08:05:41.428138Z", + "iopub.status.idle": "2021-09-14T08:05:41.432127Z", + "shell.execute_reply": "2021-09-14T08:05:41.430935Z", + "shell.execute_reply.started": "2021-09-14T08:05:41.428433Z" + }, + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "**Tags:** #aws #cloud #ce #operations #snippet" + ] + }, + { + "cell_type": "markdown", + "id": "ce780499-ecc8-40d6-997a-43f92b60e0ce", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "**Author:** [Florent Ravenel](https://www.linkedin.com/in/florent-ravenel/)" + ] + }, + { + "cell_type": "markdown", + "id": "dba1251e-f724-4d58-935a-54f5b6c9447b", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "**Last update:** 2023-11-20 (Created: 2021-09-14)" + ] + }, + { + "cell_type": "markdown", + "id": "naas-description", + "metadata": { + "papermill": {}, + "tags": [ + "description" + ] + }, + "source": [ + "**Description:** This notebook leverages the AWS Cost Explorer API to retrieve detailed cost and usage information by service and usage type from an AWS account. By utilizing the Cost Explorer API, users can efficiently access and analyze their AWS costs, enabling better cost management and optimization. Gain insights into your AWS spending with this notebook's integration of the powerful Cost Explorer API." + ] + }, + { + "cell_type": "markdown", + "id": "b4afd1ce-6ede-45aa-8db2-9624bfb24a87", + "metadata": { + "papermill": {}, + "tags": [ + "description" + ] + }, + "source": [ + "**References:**\n", + "- [Using the AWS Cost Explorer API](https://docs.aws.amazon.com/cost-management/latest/userguide/ce-api.html)" + ] + }, + { + "cell_type": "markdown", + "id": "825a5464", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "## Input" + ] + }, + { + "cell_type": "markdown", + "id": "589e943d", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "### Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbbd2c53", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "outputs": [], + "source": [ + "import naas\n", + "try:\n", + " import boto3\n", + "except:\n", + " !pip install boto3\n", + " import boto3\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "10278504", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "### Setup variables\n", + "**Mandatory**\n", + "- `aws_access_key_id`: This variable is used to store the AWS access key ID.\n", + "- `aws_secret_access_key`: This variable is used to store the AWS secret access key.\n", + "- `start_date`: This variable is used to store the first date to get the data from.\n", + "- `end_date`: This variable is used to store the last date to get the data from. It must be the first of a month.\n", + "\n", + "**Optional**\n", + "- `granularity`: This variable is used to define cost granularity by date. Granularity can only be MONTHLY, DAILY or HOURLY.\n", + "- `file_path`: This variable is used to define csv file path to be stored in local with billing details." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fe47224", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "outputs": [], + "source": [ + "# Mandatory\n", + "aws_access_key_id = naas.secret.get(\"AWS_ACCESS_KEY_ID\") or \"YOUR_AWS_ACCESS_KEY_ID\"\n", + "aws_secret_access_key = naas.secret.get(\"AWS_SECRET_ACCESS_KEY\") or \"YOUR_AWS_SECRET_ACCESS_KEY\"\n", + "start_date = \"2023-01-01\"\n", + "end_date = \"2023-12-01\"\n", + "\n", + "# Optional\n", + "granularity = \"MONTHLY\"\n", + "file_path = \"billing_aws.csv\"" + ] + }, + { + "cell_type": "markdown", + "id": "4eb03b12", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "## Model" + ] + }, + { + "cell_type": "markdown", + "id": "8aa2658d", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "### Connect to AWS" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ded6a696", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "outputs": [], + "source": [ + "client = boto3.client(\n", + " \"ce\",\n", + " aws_access_key_id=aws_access_key_id,\n", + " aws_secret_access_key=aws_secret_access_key,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9c7a52b8", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "### Get current cost from AWS billing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "58edcd48", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "outputs": [], + "source": [ + "# Get current cost from AWS billing\n", + "result = client.get_cost_and_usage(\n", + " TimePeriod={\"Start\": start_date, \"End\": end_date},\n", + " Granularity=granularity,\n", + " Metrics=[\"BlendedCost\"],\n", + " GroupBy=[\n", + " {\"Type\": \"DIMENSION\", \"Key\": \"SERVICE\"},\n", + " {\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"},\n", + " ],\n", + ")\n", + "\n", + "# Transform current billing to dataframe\n", + "data_billing = []\n", + "for t in result[\"ResultsByTime\"]:\n", + " for r in t[\"Groups\"]:\n", + " dimension = r[\"Keys\"][0]\n", + " usage_type = r[\"Keys\"][1]\n", + " amount = r[\"Metrics\"][\"BlendedCost\"][\"Amount\"]\n", + " period_start = t[\"TimePeriod\"][\"Start\"]\n", + " period_end = t[\"TimePeriod\"][\"End\"]\n", + " data_billing.append(\n", + " {\n", + " \"Dimension\": dimension,\n", + " \"UsageType\": usage_type,\n", + " \"Amount\": amount,\n", + " \"PeriodStart\": period_start,\n", + " \"PeriodEnd\": period_end,\n", + " }\n", + " )\n", + "\n", + "# Create dataframe\n", + "df_billing = pd.DataFrame(data_billing).astype({\"Amount\": \"float\"})\n", + "\n", + "# Display result\n", + "current_amount = df_billing[\"Amount\"].sum()\n", + "print(\"Current Amount:\", round(current_amount, 2))\n", + "df_billing.head(5)" + ] + }, + { + "cell_type": "markdown", + "id": "64bb4d94", + "metadata": { + "execution": { + "iopub.execute_input": "2021-06-15T17:13:04.069988Z", + "iopub.status.busy": "2021-06-15T17:13:04.069748Z", + "iopub.status.idle": "2021-06-15T17:13:04.092911Z", + "shell.execute_reply": "2021-06-15T17:13:04.091872Z", + "shell.execute_reply.started": "2021-06-15T17:13:04.069964Z" + }, + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "## Output" + ] + }, + { + "cell_type": "markdown", + "id": "8e03dcf1", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "source": [ + "### Save current billing to csv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d676c8d", + "metadata": { + "papermill": {}, + "tags": [ + "awesome-notebooks/AWS/AWS_Daily_biling_notification_to_slack.ipynb" + ] + }, + "outputs": [], + "source": [ + "df_billing.to_csv(file_path)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + }, + "naas": { + "notebook_id": "3e342697d70a5fc4884c84d82b7b2d1efc9f8dde26b142ec2e63c2246dbfd05b", + "notebook_path": "AWS/AWS_Daily_biling_notification_to_slack.ipynb" + }, + "papermill": { + "default_parameters": {}, + "environment_variables": {}, + "parameters": {}, + "version": "2.3.3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "15369ba21db1460284b7b8e9cb622d06": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_4bb52491f55641b4b62c32aa7e0679e1", + "style": "IPY_MODEL_7c0a38e90d65465fb0b6193a4146f9a6" + } + }, + "1aae19e8ce9a49049642ea9c5fd522e4": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "237ff9b58a114ce69a1db5d8d4693e6a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_8908e36294e149c68f2bc6fa1637a0b4", + "style": "IPY_MODEL_c9dd15482da84e72b2a09ba479a75245" + } + }, + "2a26fb87acca44beb611cbb56bc70c09": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "2b2660a06a2446bd842fa3e9c9c6fe08": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "3a7f05b1cac74dc2a203ba8bf2f1fe17": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "3a7f3ca1a92240efa7896385485671fb": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_843aeeced14c4d94a613d8ac1cfa1797" + } + }, + "4bb52491f55641b4b62c32aa7e0679e1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "4d73c28b4d304c5f9657f9934ef4adc5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "568ff82a25a64bfba3610d451acbcc26": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_3a7f05b1cac74dc2a203ba8bf2f1fe17" + } + }, + "58d8487f8bf5487d9bfb521438adb0f2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "78c774bb848a47efb2556442ca642233": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_d7e1ad37e7954862af3449f27cae11a0", + "style": "IPY_MODEL_f338980fb865425eb18b14d5fb8a5e9f" + } + }, + "7c0a38e90d65465fb0b6193a4146f9a6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "825f9fb5a2234ffaaaea0deaf86b206d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_58d8487f8bf5487d9bfb521438adb0f2", + "style": "IPY_MODEL_e4362a71f75649bf93d3d919b63f23ad" + } + }, + "843aeeced14c4d94a613d8ac1cfa1797": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "8908e36294e149c68f2bc6fa1637a0b4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "8da4a28960ea418abebd4f3115fde42b": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_ae604bbf2607454b8aa2366a0beeb88d", + "outputs": [ + { + "data": { + "text/html": "
✅ Copied !
", + "text/plain": "" + }, + "metadata": {}, + "output_type": "display_data" + } + ] + } + }, + "966ac94ef1b44754a7bcf80c42ef6940": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_eed4098f55ec4f2bb3176be711254168" + } + }, + "ae604bbf2607454b8aa2366a0beeb88d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "b00a2988bfde49b7844768963db33daf": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_e26a69e9d8b04eb5a4f96b33ecce581d", + "style": "IPY_MODEL_1aae19e8ce9a49049642ea9c5fd522e4" + } + }, + "c9dd15482da84e72b2a09ba479a75245": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "ca9237340fa04e7888f382da12da4732": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Copy URL", + "layout": "IPY_MODEL_caa17a7ee7ea4b78b1b0c50bb2962e84", + "style": "IPY_MODEL_4d73c28b4d304c5f9657f9934ef4adc5" + } + }, + "caa17a7ee7ea4b78b1b0c50bb2962e84": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "d7b09bb706544af1a4d8b9806dadd5f7": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_2a26fb87acca44beb611cbb56bc70c09" + } + }, + "d7e1ad37e7954862af3449f27cae11a0": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "e26a69e9d8b04eb5a4f96b33ecce581d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "e4362a71f75649bf93d3d919b63f23ad": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "eed4098f55ec4f2bb3176be711254168": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "ef0da7f8494748e284cb1fead6471e1b": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_2b2660a06a2446bd842fa3e9c9c6fe08" + } + }, + "f338980fb865425eb18b14d5fb8a5e9f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + } + }, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}