{"id":13625962,"url":"https://github.com/aws-samples/aws-cost-explorer-report","last_synced_at":"2025-04-16T11:30:59.220Z","repository":{"id":38290676,"uuid":"127775651","full_name":"aws-samples/aws-cost-explorer-report","owner":"aws-samples","description":"Python SAM Lambda module for generating an Excel cost report with graphs, including month on month cost changes. Uses the AWS Cost Explorer API for data.","archived":true,"fork":false,"pushed_at":"2022-08-01T13:29:43.000Z","size":841,"stargazers_count":432,"open_issues_count":17,"forks_count":166,"subscribers_count":27,"default_branch":"master","last_synced_at":"2024-11-08T15:46:51.839Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aws-samples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-02T15:34:32.000Z","updated_at":"2024-10-19T12:29:34.000Z","dependencies_parsed_at":"2022-08-09T02:31:20.469Z","dependency_job_id":null,"html_url":"https://github.com/aws-samples/aws-cost-explorer-report","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-samples%2Faws-cost-explorer-report","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-samples%2Faws-cost-explorer-report/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-samples%2Faws-cost-explorer-report/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-samples%2Faws-cost-explorer-report/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aws-samples","download_url":"https://codeload.github.com/aws-samples/aws-cost-explorer-report/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249235030,"owners_count":21235131,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:02:06.682Z","updated_at":"2025-04-16T11:30:58.908Z","avatar_url":"https://github.com/aws-samples.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"## AWS Cost Explorer Report Generator\n\nPython SAM Lambda module for generating an Excel cost report with graphs, including month on month cost changes. Uses the AWS Cost Explorer API for data.\n\n![screenshot](https://github.com/aws-samples/aws-cost-explorer-report/blob/master/screenshot.png)\n\n## License Summary\n\nThis sample code is made available under a modified MIT license. See the LICENSE file.\n\n## AWS Costs\n\n* AWS Lambda Invocation \n  * Usually [Free](https://aws.amazon.com/free/)  \n* Amazon SES \n  * Usually [Free](https://aws.amazon.com/free/)\n* Amazon S3\n  * Minimal usage\n* AWS Cost Explorer API calls   \n  * [$0.01 per API call (about 25 calls per run)](https://aws.amazon.com/aws-cost-management/pricing/)\n\n## Prerequisites\n\n* [awscli](https://aws.amazon.com/cli)\n* Configure AWS credentials for target account\n  * run `aws configure` \n* [Cost Explorer enabled](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-explorer-signup.html)\n* [Verfied Amazon SES Sender email](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/verify-email-addresses.html)\n* If you verify an email, you can send from/to that address.\n* To send to other addresses, you need to [move SES out of sandbox mode](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html).  \n \nDocker (optional for building the lambda python package with updated https://pypi.python.org/ third-party libraries)\n\n## Easy Deploy (us-east-1 only)\nIf you do not need to modify the code, just deploy the included easy_deploy.yaml using AWS Cloudformation via the console.\n\n## Deploying (SAM / Script)\nUpdate the values in deploy.sh for your AWS account details.  \n\n  | Variable      | Description                                            |\n  | ------------- | ------------------------------------------------------ |\n  | S3_BUCKET     | S3 Bucket to use                                       |\n  | SES_SEND      | Email list to send to (comma separated)                |\n  | SES_FROM      | SES Verified Sender Email                              |\n  | SES_REGION    | SES Region                                             |\n  | COST_TAGS     | List Of Cost Tag Keys (comma separated)                |\n  | CURRENT_MONTH | true / false for if report does current partial month  |\n  | DAY_MONTH     | When to schedule a run. 6, for the 6th by default      |\n  | TAG_KEY       | Provide tag key e.g. Name                              |\n  | TAG_VALUE_FILTER       | Provide tag value to filter e.g. Prod*        |\n  | LAST_MONTH_ONLY         | Specify true if you wish to generate for only last month  |\n\nAnd then run `sh deploy.sh`\n\n## Deploy Manually (Lambda Console)\n\n1. Create a lambda function (python 3.8 runtime), and update the code to the contents of src/lambda.py\n2. Create a lambda IAM execution role with ce:, ses:, s3:, organizations:ListAccounts\n3. Configure the dependency layer: arn:aws:lambda:us-east-1:749981256976:layer:CostExplorerReportLayer:1\n4. Update ENV Variables in Lambda console\n   * Details in table above. \n5. Create a trigger (CloudWatch Event)\n\n## Running / Testing\n\nOnce the Lambda is created, find it in the AWS Lambda console.\nYou can create ANY test event (as the event content is ignored), and hit the test button for a manual run.\n\nhttps://docs.aws.amazon.com/lambda/latest/dg/tutorial-scheduled-events-test-function.html\n\n## Building the Lambda Layer (Optional, for if you want to build your own AWS Lambda layer for use with the script)\nRun build.sh to build a new AWS lambda layer with the required Python libraries.\nThis requires Docker, as it builds the package in an Amazon Linux container.\n\n`sh build.sh`\n\n## Customise the report\nEdit the `main_handler` segment of src/lambda.py  \n\n```python\ndef main_handler(event=None, context=None): \n    costexplorer = CostExplorer(CurrentMonth=False)\n    #Default addReport has filter to remove Support / Credits / Refunds / UpfrontRI\n    #Overall Billing Reports\n    costexplorer.addReport(Name=\"Total\", GroupBy=[],Style='Total',IncSupport=True)\n    costexplorer.addReport(Name=\"TotalChange\", GroupBy=[],Style='Change')\n    costexplorer.addReport(Name=\"TotalInclCredits\", GroupBy=[],Style='Total',NoCredits=False,IncSupport=True)\n    costexplorer.addReport(Name=\"TotalInclCreditsChange\", GroupBy=[],Style='Change',NoCredits=False)\n    costexplorer.addReport(Name=\"Credits\", GroupBy=[],Style='Total',CreditsOnly=True)\n    costexplorer.addReport(Name=\"Refunds\", GroupBy=[],Style='Total',RefundOnly=True)\n    costexplorer.addReport(Name=\"RIUpfront\", GroupBy=[],Style='Total',UpfrontOnly=True)\n    #GroupBy Reports\n    costexplorer.addReport(Name=\"Services\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"SERVICE\"}],Style='Total',IncSupport=True)\n    costexplorer.addReport(Name=\"ServicesChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"SERVICE\"}],Style='Change')\n    costexplorer.addReport(Name=\"Accounts\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"LINKED_ACCOUNT\"}],Style='Total')\n    costexplorer.addReport(Name=\"AccountsChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"LINKED_ACCOUNT\"}],Style='Change')\n    costexplorer.addReport(Name=\"Regions\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"REGION\"}],Style='Total')\n    costexplorer.addReport(Name=\"RegionsChange\", GroupBy=[{\"Type\": \"DIMENSION\",\"Key\": \"REGION\"}],Style='Change')\n    if os.environ.get('COST_TAGS'): #Support for multiple/different Cost Allocation tags\n        for tagkey in os.environ.get('COST_TAGS').split(','):\n            tabname = tagkey.replace(\":\",\".\") #Remove special chars from Excel tabname\n            costexplorer.addReport(Name=\"{}\".format(tabname)[:31], GroupBy=[{\"Type\": \"TAG\",\"Key\": tagkey}],Style='Total')\n            costexplorer.addReport(Name=\"Change-{}\".format(tabname)[:31], GroupBy=[{\"Type\": \"TAG\",\"Key\": tagkey}],Style='Change')\n    #RI Reports\n    costexplorer.addRiReport(Name=\"RICoverage\")\n    costexplorer.addRiReport(Name=\"RIUtilization\")\n    costexplorer.addRiReport(Name=\"RIUtilizationSavings\", Savings=True)\n    costexplorer.addRiReport(Name=\"RIRecommendation\")\n    costexplorer.generateExcel()\n    return \"Report Generated\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws-samples%2Faws-cost-explorer-report","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faws-samples%2Faws-cost-explorer-report","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws-samples%2Faws-cost-explorer-report/lists"}